xref: /openbmc/qemu/target/mips/tcg/translate.c (revision a56ac09f5c37f57059c2a2c5ae6aeff7f7241a84)
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 "exec/target_page.h"
31 #include "semihosting/semihost.h"
32 #include "trace.h"
33 #include "fpu_helper.h"
34 
35 #define HELPER_H "helper.h"
36 #include "exec/helper-info.c.inc"
37 #undef  HELPER_H
38 
39 
40 /*
41  * Many system-only helpers are not reachable for user-only.
42  * Define stub generators here, so that we need not either sprinkle
43  * ifdefs through the translator, nor provide the helper function.
44  */
45 #define STUB_HELPER(NAME, ...) \
46     static inline void gen_helper_##NAME(__VA_ARGS__) \
47     { g_assert_not_reached(); }
48 
49 #ifdef CONFIG_USER_ONLY
50 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
51 #endif
52 
53 enum {
54     /* indirect opcode tables */
55     OPC_SPECIAL  = (0x00 << 26),
56     OPC_REGIMM   = (0x01 << 26),
57     OPC_CP0      = (0x10 << 26),
58     OPC_CP2      = (0x12 << 26),
59     OPC_CP3      = (0x13 << 26),
60     OPC_SPECIAL2 = (0x1C << 26),
61     OPC_SPECIAL3 = (0x1F << 26),
62     /* arithmetic with immediate */
63     OPC_ADDI     = (0x08 << 26),
64     OPC_ADDIU    = (0x09 << 26),
65     OPC_SLTI     = (0x0A << 26),
66     OPC_SLTIU    = (0x0B << 26),
67     /* logic with immediate */
68     OPC_ANDI     = (0x0C << 26),
69     OPC_ORI      = (0x0D << 26),
70     OPC_XORI     = (0x0E << 26),
71     OPC_LUI      = (0x0F << 26),
72     /* arithmetic with immediate */
73     OPC_DADDI    = (0x18 << 26),
74     OPC_DADDIU   = (0x19 << 26),
75     /* Jump and branches */
76     OPC_J        = (0x02 << 26),
77     OPC_JAL      = (0x03 << 26),
78     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
79     OPC_BEQL     = (0x14 << 26),
80     OPC_BNE      = (0x05 << 26),
81     OPC_BNEL     = (0x15 << 26),
82     OPC_BLEZ     = (0x06 << 26),
83     OPC_BLEZL    = (0x16 << 26),
84     OPC_BGTZ     = (0x07 << 26),
85     OPC_BGTZL    = (0x17 << 26),
86     OPC_JALX     = (0x1D << 26),
87     OPC_DAUI     = (0x1D << 26),
88     /* Load and stores */
89     OPC_LDL      = (0x1A << 26),
90     OPC_LDR      = (0x1B << 26),
91     OPC_LB       = (0x20 << 26),
92     OPC_LH       = (0x21 << 26),
93     OPC_LWL      = (0x22 << 26),
94     OPC_LW       = (0x23 << 26),
95     OPC_LWPC     = OPC_LW | 0x5,
96     OPC_LBU      = (0x24 << 26),
97     OPC_LHU      = (0x25 << 26),
98     OPC_LWR      = (0x26 << 26),
99     OPC_LWU      = (0x27 << 26),
100     OPC_SB       = (0x28 << 26),
101     OPC_SH       = (0x29 << 26),
102     OPC_SWL      = (0x2A << 26),
103     OPC_SW       = (0x2B << 26),
104     OPC_SDL      = (0x2C << 26),
105     OPC_SDR      = (0x2D << 26),
106     OPC_SWR      = (0x2E << 26),
107     OPC_LL       = (0x30 << 26),
108     OPC_LLD      = (0x34 << 26),
109     OPC_LD       = (0x37 << 26),
110     OPC_LDPC     = OPC_LD | 0x5,
111     OPC_SC       = (0x38 << 26),
112     OPC_SCD      = (0x3C << 26),
113     OPC_SD       = (0x3F << 26),
114     /* Floating point load/store */
115     OPC_LWC1     = (0x31 << 26),
116     OPC_LWC2     = (0x32 << 26),
117     OPC_LDC1     = (0x35 << 26),
118     OPC_LDC2     = (0x36 << 26),
119     OPC_SWC1     = (0x39 << 26),
120     OPC_SWC2     = (0x3A << 26),
121     OPC_SDC1     = (0x3D << 26),
122     OPC_SDC2     = (0x3E << 26),
123     /* Compact Branches */
124     OPC_BLEZALC  = (0x06 << 26),
125     OPC_BGEZALC  = (0x06 << 26),
126     OPC_BGEUC    = (0x06 << 26),
127     OPC_BGTZALC  = (0x07 << 26),
128     OPC_BLTZALC  = (0x07 << 26),
129     OPC_BLTUC    = (0x07 << 26),
130     OPC_BOVC     = (0x08 << 26),
131     OPC_BEQZALC  = (0x08 << 26),
132     OPC_BEQC     = (0x08 << 26),
133     OPC_BLEZC    = (0x16 << 26),
134     OPC_BGEZC    = (0x16 << 26),
135     OPC_BGEC     = (0x16 << 26),
136     OPC_BGTZC    = (0x17 << 26),
137     OPC_BLTZC    = (0x17 << 26),
138     OPC_BLTC     = (0x17 << 26),
139     OPC_BNVC     = (0x18 << 26),
140     OPC_BNEZALC  = (0x18 << 26),
141     OPC_BNEC     = (0x18 << 26),
142     OPC_BC       = (0x32 << 26),
143     OPC_BEQZC    = (0x36 << 26),
144     OPC_JIC      = (0x36 << 26),
145     OPC_BALC     = (0x3A << 26),
146     OPC_BNEZC    = (0x3E << 26),
147     OPC_JIALC    = (0x3E << 26),
148     /* MDMX ASE specific */
149     OPC_MDMX     = (0x1E << 26),
150     /* Cache and prefetch */
151     OPC_CACHE    = (0x2F << 26),
152     OPC_PREF     = (0x33 << 26),
153     /* PC-relative address computation / loads */
154     OPC_PCREL    = (0x3B << 26),
155 };
156 
157 /* PC-relative address computation / loads  */
158 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
159 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
160 enum {
161     /* Instructions determined by bits 19 and 20 */
162     OPC_ADDIUPC = OPC_PCREL | (0 << 19),
163     R6_OPC_LWPC = OPC_PCREL | (1 << 19),
164     OPC_LWUPC   = OPC_PCREL | (2 << 19),
165 
166     /* Instructions determined by bits 16 ... 20 */
167     OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
168     OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
169 
170     /* Other */
171     R6_OPC_LDPC = OPC_PCREL | (6 << 18),
172 };
173 
174 /* MIPS special opcodes */
175 #define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
176 
177 enum {
178     /* Shifts */
179     OPC_SLL      = 0x00 | OPC_SPECIAL,
180     /* NOP is SLL r0, r0, 0   */
181     /* SSNOP is SLL r0, r0, 1 */
182     /* EHB is SLL r0, r0, 3 */
183     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
184     OPC_ROTR     = OPC_SRL | (1 << 21),
185     OPC_SRA      = 0x03 | OPC_SPECIAL,
186     OPC_SLLV     = 0x04 | OPC_SPECIAL,
187     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
188     OPC_ROTRV    = OPC_SRLV | (1 << 6),
189     OPC_SRAV     = 0x07 | OPC_SPECIAL,
190     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
191     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
192     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
193     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
194     OPC_DSLL     = 0x38 | OPC_SPECIAL,
195     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
196     OPC_DROTR    = OPC_DSRL | (1 << 21),
197     OPC_DSRA     = 0x3B | OPC_SPECIAL,
198     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
199     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
200     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
201     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
202     /* Multiplication / division */
203     OPC_MULT     = 0x18 | OPC_SPECIAL,
204     OPC_MULTU    = 0x19 | OPC_SPECIAL,
205     OPC_DIV      = 0x1A | OPC_SPECIAL,
206     OPC_DIVU     = 0x1B | OPC_SPECIAL,
207     OPC_DMULT    = 0x1C | OPC_SPECIAL,
208     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
209     OPC_DDIV     = 0x1E | OPC_SPECIAL,
210     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
211 
212     /* 2 registers arithmetic / logic */
213     OPC_ADD      = 0x20 | OPC_SPECIAL,
214     OPC_ADDU     = 0x21 | OPC_SPECIAL,
215     OPC_SUB      = 0x22 | OPC_SPECIAL,
216     OPC_SUBU     = 0x23 | OPC_SPECIAL,
217     OPC_AND      = 0x24 | OPC_SPECIAL,
218     OPC_OR       = 0x25 | OPC_SPECIAL,
219     OPC_XOR      = 0x26 | OPC_SPECIAL,
220     OPC_NOR      = 0x27 | OPC_SPECIAL,
221     OPC_SLT      = 0x2A | OPC_SPECIAL,
222     OPC_SLTU     = 0x2B | OPC_SPECIAL,
223     OPC_DADD     = 0x2C | OPC_SPECIAL,
224     OPC_DADDU    = 0x2D | OPC_SPECIAL,
225     OPC_DSUB     = 0x2E | OPC_SPECIAL,
226     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
227     /* Jumps */
228     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
229     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
230     /* Traps */
231     OPC_TGE      = 0x30 | OPC_SPECIAL,
232     OPC_TGEU     = 0x31 | OPC_SPECIAL,
233     OPC_TLT      = 0x32 | OPC_SPECIAL,
234     OPC_TLTU     = 0x33 | OPC_SPECIAL,
235     OPC_TEQ      = 0x34 | OPC_SPECIAL,
236     OPC_TNE      = 0x36 | OPC_SPECIAL,
237     /* HI / LO registers load & stores */
238     OPC_MFHI     = 0x10 | OPC_SPECIAL,
239     OPC_MTHI     = 0x11 | OPC_SPECIAL,
240     OPC_MFLO     = 0x12 | OPC_SPECIAL,
241     OPC_MTLO     = 0x13 | OPC_SPECIAL,
242     /* Conditional moves */
243     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
244     OPC_MOVN     = 0x0B | OPC_SPECIAL,
245 
246     OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
247     OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
248 
249     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
250 
251     /* Special */
252     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
253     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
254     OPC_BREAK    = 0x0D | OPC_SPECIAL,
255     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
256     OPC_SYNC     = 0x0F | OPC_SPECIAL,
257 
258     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
259     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
260     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
261     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
262 };
263 
264 /*
265  * R6 Multiply and Divide instructions have the same opcode
266  * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
267  */
268 #define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
269 
270 enum {
271     R6_OPC_MUL   = OPC_MULT  | (2 << 6),
272     R6_OPC_MUH   = OPC_MULT  | (3 << 6),
273     R6_OPC_MULU  = OPC_MULTU | (2 << 6),
274     R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
275     R6_OPC_DIV   = OPC_DIV   | (2 << 6),
276     R6_OPC_MOD   = OPC_DIV   | (3 << 6),
277     R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
278     R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
279 
280     R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
281     R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
282     R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
283     R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
284     R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
285     R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
286     R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
287     R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
288 
289     R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
290     R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
291     R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
292     R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
293     R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
294 };
295 
296 /* REGIMM (rt field) opcodes */
297 #define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
298 
299 enum {
300     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
301     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
302     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
303     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
304     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
305     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
306     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
307     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
308     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
309     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
310     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
311     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
312     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
313     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
314     OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
315     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
316 
317     OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
318     OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
319 };
320 
321 /* Special2 opcodes */
322 #define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
323 
324 enum {
325     /* Multiply & xxx operations */
326     OPC_MADD     = 0x00 | OPC_SPECIAL2,
327     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
328     OPC_MUL      = 0x02 | OPC_SPECIAL2,
329     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
330     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
331     /* Misc */
332     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
333     OPC_CLO      = 0x21 | OPC_SPECIAL2,
334     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
335     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
336     /* Special */
337     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
338 };
339 
340 /* Special3 opcodes */
341 #define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
342 
343 enum {
344     OPC_EXT      = 0x00 | OPC_SPECIAL3,
345     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
346     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
347     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
348     OPC_INS      = 0x04 | OPC_SPECIAL3,
349     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
350     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
351     OPC_DINS     = 0x07 | OPC_SPECIAL3,
352     OPC_FORK     = 0x08 | OPC_SPECIAL3,
353     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
354     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
355     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
356     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
357     OPC_GINV     = 0x3D | OPC_SPECIAL3,
358 
359     /* MIPS DSP Load */
360     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
361     /* MIPS DSP Arithmetic */
362     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
363     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
364     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
365     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
366     OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,
367     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
368     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
369     /* MIPS DSP GPR-Based Shift Sub-class */
370     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
371     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
372     /* MIPS DSP Multiply Sub-class insns */
373     OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,
374     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
375     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
376     /* DSP Bit/Manipulation Sub-class */
377     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
378     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
379     /* MIPS DSP Append Sub-class */
380     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
381     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
382     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
383     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
384     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
385 
386     /* EVA */
387     OPC_LWLE           = 0x19 | OPC_SPECIAL3,
388     OPC_LWRE           = 0x1A | OPC_SPECIAL3,
389     OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
390     OPC_SBE            = 0x1C | OPC_SPECIAL3,
391     OPC_SHE            = 0x1D | OPC_SPECIAL3,
392     OPC_SCE            = 0x1E | OPC_SPECIAL3,
393     OPC_SWE            = 0x1F | OPC_SPECIAL3,
394     OPC_SWLE           = 0x21 | OPC_SPECIAL3,
395     OPC_SWRE           = 0x22 | OPC_SPECIAL3,
396     OPC_PREFE          = 0x23 | OPC_SPECIAL3,
397     OPC_LBUE           = 0x28 | OPC_SPECIAL3,
398     OPC_LHUE           = 0x29 | OPC_SPECIAL3,
399     OPC_LBE            = 0x2C | OPC_SPECIAL3,
400     OPC_LHE            = 0x2D | OPC_SPECIAL3,
401     OPC_LLE            = 0x2E | OPC_SPECIAL3,
402     OPC_LWE            = 0x2F | OPC_SPECIAL3,
403 
404     /* R6 */
405     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
406     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
407     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
408     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
409     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
410     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
411 };
412 
413 /* Loongson EXT load/store quad word opcodes */
414 #define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
415 enum {
416     OPC_GSLQ        = 0x0020 | OPC_LWC2,
417     OPC_GSLQC1      = 0x8020 | OPC_LWC2,
418     OPC_GSSHFL      = OPC_LWC2,
419     OPC_GSSQ        = 0x0020 | OPC_SWC2,
420     OPC_GSSQC1      = 0x8020 | OPC_SWC2,
421     OPC_GSSHFS      = OPC_SWC2,
422 };
423 
424 /* Loongson EXT shifted load/store opcodes */
425 #define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
426 enum {
427     OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
428     OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
429     OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
430     OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
431     OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
432     OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
433     OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
434     OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
435 };
436 
437 /* Loongson EXT LDC2/SDC2 opcodes */
438 #define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
439 
440 enum {
441     OPC_GSLBX      = 0x0 | OPC_LDC2,
442     OPC_GSLHX      = 0x1 | OPC_LDC2,
443     OPC_GSLWX      = 0x2 | OPC_LDC2,
444     OPC_GSLDX      = 0x3 | OPC_LDC2,
445     OPC_GSLWXC1    = 0x6 | OPC_LDC2,
446     OPC_GSLDXC1    = 0x7 | OPC_LDC2,
447     OPC_GSSBX      = 0x0 | OPC_SDC2,
448     OPC_GSSHX      = 0x1 | OPC_SDC2,
449     OPC_GSSWX      = 0x2 | OPC_SDC2,
450     OPC_GSSDX      = 0x3 | OPC_SDC2,
451     OPC_GSSWXC1    = 0x6 | OPC_SDC2,
452     OPC_GSSDXC1    = 0x7 | OPC_SDC2,
453 };
454 
455 /* BSHFL opcodes */
456 #define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457 
458 enum {
459     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
460     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
461     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
462     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
463     OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
464     OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
465     OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
466     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
467 };
468 
469 /* DBSHFL opcodes */
470 #define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
471 
472 enum {
473     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
474     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
475     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
476     OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
477     OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
478     OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
479     OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
480     OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
481     OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
482     OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
483     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
484 };
485 
486 /* MIPS DSP REGIMM opcodes */
487 enum {
488     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
489     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
490 };
491 
492 #define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
493 /* MIPS DSP Load */
494 enum {
495     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
496     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
497     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
498     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
499 };
500 
501 #define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
502 enum {
503     /* MIPS DSP Arithmetic Sub-class */
504     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
505     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
506     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
507     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
508     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
509     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
510     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
511     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
512     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
513     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
514     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
515     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
516     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
517     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
518     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
519     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
520     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
521     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
522     /* MIPS DSP Multiply Sub-class insns */
523     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
524     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
525     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
526     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
527     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
528     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
529 };
530 
531 #define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
532 enum {
533     /* MIPS DSP Arithmetic Sub-class */
534     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
535     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
536     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
537     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
538     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
539     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
540     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
541     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
542     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
543     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
544     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
545     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
546     /* MIPS DSP Multiply Sub-class insns */
547     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
548     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
549     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
550     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
551 };
552 
553 #define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 enum {
555     /* MIPS DSP Arithmetic Sub-class */
556     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
557     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
558     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
559     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
560     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
561     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
562     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
563     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
564     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
565     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
566     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
567     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
568     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
569     /* DSP Bit/Manipulation Sub-class */
570     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
571     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
572     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
573     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
574     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
575 };
576 
577 #define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
578 enum {
579     /* MIPS DSP Arithmetic Sub-class */
580     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
581     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
582     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
583     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
584     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
585     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
586     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
587     /* DSP Compare-Pick Sub-class */
588     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
589     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
590     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
591     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
592     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
593     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
594     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
595     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
596     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
597     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
598     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
599     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
600     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
601     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
602     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
603 };
604 
605 #define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606 enum {
607     /* MIPS DSP GPR-Based Shift Sub-class */
608     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
609     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
610     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
611     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
612     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
613     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
614     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
615     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
616     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
617     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
618     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
619     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
620     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
621     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
622     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
623     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
624     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
625     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
626     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
627     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
628     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
629     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
630 };
631 
632 #define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
633 enum {
634     /* MIPS DSP Multiply Sub-class insns */
635     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
636     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
637     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
638     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
639     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
640     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
641     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
642     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
643     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
644     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
645     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
646     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
647     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
648     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
649     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
650     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
651     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
652     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
653     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
654     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
655     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
656     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
657 };
658 
659 #define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
660 enum {
661     /* DSP Bit/Manipulation Sub-class */
662     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
663 };
664 
665 #define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
666 enum {
667     /* MIPS DSP Append Sub-class */
668     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
669     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
670     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
671 };
672 
673 #define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
674 enum {
675     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
676     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
677     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
678     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
679     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
680     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
681     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
682     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
683     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
684     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
685     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
686     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
687     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
688     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
689     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
690     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
691     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
692     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
693 };
694 
695 #define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
696 enum {
697     /* MIPS DSP Arithmetic Sub-class */
698     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
699     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
700     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
701     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
702     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
703     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
704     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
705     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
706     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
707     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
708     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
709     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
710     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
711     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
712     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
713     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
714     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
715     /* DSP Bit/Manipulation Sub-class */
716     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
717     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
718     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
719     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
720     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
721     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
722 };
723 
724 #define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
725 enum {
726     /* MIPS DSP Multiply Sub-class insns */
727     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
728     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
729     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
730     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
731     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
732     /* MIPS DSP Arithmetic Sub-class */
733     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
734     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
735     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
736     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
737     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
738     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
739     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
740     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
741     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
742     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
743     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
744     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
745     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
746     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
747     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
748     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
749     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
750     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
751     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
752     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
753     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
754 };
755 
756 #define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
757 enum {
758     /* DSP Compare-Pick Sub-class */
759     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
760     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
761     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
762     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
763     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
764     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
765     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
766     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
767     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
768     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
769     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
770     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
771     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
772     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
773     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
774     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
775     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
776     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
777     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
778     /* MIPS DSP Arithmetic Sub-class */
779     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
780     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
781     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
782     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
783     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
784     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
785     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
786     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
787 };
788 
789 #define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
790 enum {
791     /* DSP Append Sub-class */
792     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
793     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
794     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
795     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
796 };
797 
798 #define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
799 enum {
800     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
801     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
802     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
803     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
804     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
805     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
806     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
807     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
808     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
809     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
810     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
811     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
812     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
813     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
814     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
815     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
816     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
817     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
818     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
819     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
820     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
821     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
822 };
823 
824 #define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
825 enum {
826     /* DSP Bit/Manipulation Sub-class */
827     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
828 };
829 
830 #define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
831 enum {
832     /* MIPS DSP Multiply Sub-class insns */
833     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
834     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
835     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
836     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
837     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
838     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
839     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
840     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
841     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
842     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
843     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
844     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
845     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
846     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
847     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
848     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
849     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
850     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
851     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
852     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
853     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
854     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
855     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
856     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
857     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
858     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
859 };
860 
861 #define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
862 enum {
863     /* MIPS DSP GPR-Based Shift Sub-class */
864     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
865     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
866     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
867     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
868     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
869     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
870     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
871     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
872     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
873     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
874     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
875     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
876     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
877     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
878     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
879     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
880     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
881     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
882     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
883     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
884     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
885     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
886     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
887     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
888     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
889     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
890 };
891 
892 /* Coprocessor 0 (rs field) */
893 #define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
894 
895 enum {
896     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
897     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
898     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
899     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
900     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
901     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
902     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
903     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
904     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
905     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
906     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
907     OPC_C0       = (0x10 << 21) | OPC_CP0,
908     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
909     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
910     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
911     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
912     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
913     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
914     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
915     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
916     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
917     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
918     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
919     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
920     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
921     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
922     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
923 };
924 
925 /* MFMC0 opcodes */
926 #define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
927 
928 enum {
929     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
930     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
931     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
932     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
933     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
934     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
935     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
936     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
937 };
938 
939 /* Coprocessor 0 (with rs == C0) */
940 #define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
941 
942 enum {
943     OPC_TLBR     = 0x01 | OPC_C0,
944     OPC_TLBWI    = 0x02 | OPC_C0,
945     OPC_TLBINV   = 0x03 | OPC_C0,
946     OPC_TLBINVF  = 0x04 | OPC_C0,
947     OPC_TLBWR    = 0x06 | OPC_C0,
948     OPC_TLBP     = 0x08 | OPC_C0,
949     OPC_RFE      = 0x10 | OPC_C0,
950     OPC_ERET     = 0x18 | OPC_C0,
951     OPC_DERET    = 0x1F | OPC_C0,
952     OPC_WAIT     = 0x20 | OPC_C0,
953 };
954 
955 #define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
956 
957 enum {
958     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
959     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
960     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
961     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
962     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
963     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
964     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
965     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
966     OPC_BC2     = (0x08 << 21) | OPC_CP2,
967     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
968     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
969 };
970 
971 #define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
972 
973 enum {
974     OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
975     OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
976     OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
977     OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
978     OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
979     OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
980     OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
981     OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
982 
983     OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
984     OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
985     OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
986     OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
987     OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
988     OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
989     OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
990     OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
991 
992     OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
993     OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
994     OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
995     OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
996     OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
997     OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
998     OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
999     OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1000 
1001     OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1002     OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1003     OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1004     OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1005     OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1006     OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1007     OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1008     OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1009 
1010     OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1011     OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1012     OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1013     OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1014     OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1015     OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1016 
1017     OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1018     OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1019     OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1020     OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1021     OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1022     OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1023 
1024     OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1025     OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1026     OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1027     OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1028     OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1029     OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1030 
1031     OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1032     OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1033     OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1034     OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1035     OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1036     OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1037 
1038     OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1039     OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1040     OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1041     OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1042     OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1043     OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1044 
1045     OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1046     OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1047     OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1048     OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1049     OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1050     OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1051 
1052     OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1053     OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1054     OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1055     OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1056     OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1057     OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1058 
1059     OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1060     OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1061     OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1062     OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1063     OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1064     OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1065 };
1066 
1067 
1068 #define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1069 
1070 enum {
1071     OPC_LWXC1       = 0x00 | OPC_CP3,
1072     OPC_LDXC1       = 0x01 | OPC_CP3,
1073     OPC_LUXC1       = 0x05 | OPC_CP3,
1074     OPC_SWXC1       = 0x08 | OPC_CP3,
1075     OPC_SDXC1       = 0x09 | OPC_CP3,
1076     OPC_SUXC1       = 0x0D | OPC_CP3,
1077     OPC_PREFX       = 0x0F | OPC_CP3,
1078     OPC_ALNV_PS     = 0x1E | OPC_CP3,
1079     OPC_MADD_S      = 0x20 | OPC_CP3,
1080     OPC_MADD_D      = 0x21 | OPC_CP3,
1081     OPC_MADD_PS     = 0x26 | OPC_CP3,
1082     OPC_MSUB_S      = 0x28 | OPC_CP3,
1083     OPC_MSUB_D      = 0x29 | OPC_CP3,
1084     OPC_MSUB_PS     = 0x2E | OPC_CP3,
1085     OPC_NMADD_S     = 0x30 | OPC_CP3,
1086     OPC_NMADD_D     = 0x31 | OPC_CP3,
1087     OPC_NMADD_PS    = 0x36 | OPC_CP3,
1088     OPC_NMSUB_S     = 0x38 | OPC_CP3,
1089     OPC_NMSUB_D     = 0x39 | OPC_CP3,
1090     OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1091 };
1092 
1093 /*
1094  *     MMI (MultiMedia Instruction) encodings
1095  *     ======================================
1096  *
1097  * MMI instructions encoding table keys:
1098  *
1099  *     *   This code is reserved for future use. An attempt to execute it
1100  *         causes a Reserved Instruction exception.
1101  *     %   This code indicates an instruction class. The instruction word
1102  *         must be further decoded by examining additional tables that show
1103  *         the values for other instruction fields.
1104  *     #   This code is reserved for the unsupported instructions DMULT,
1105  *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1106  *         to execute it causes a Reserved Instruction exception.
1107  *
1108  * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1109  *
1110  *  31    26                                        0
1111  * +--------+----------------------------------------+
1112  * | opcode |                                        |
1113  * +--------+----------------------------------------+
1114  *
1115  *   opcode  bits 28..26
1116  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1117  *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1118  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1119  *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
1120  *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
1121  *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
1122  *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
1123  *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
1124  *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
1125  *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
1126  *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
1127  */
1128 
1129 enum {
1130     MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
1131     MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
1132 };
1133 
1134 /*
1135  * MMI instructions with opcode field = MMI:
1136  *
1137  *  31    26                                 5      0
1138  * +--------+-------------------------------+--------+
1139  * |   MMI  |                               |function|
1140  * +--------+-------------------------------+--------+
1141  *
1142  * function  bits 2..0
1143  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1144  *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1145  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1146  *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
1147  *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
1148  *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
1149  *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
1150  *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
1151  *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
1152  *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
1153  *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
1154  */
1155 
1156 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1157 enum {
1158     MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1159     MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1160     MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1161     MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1162     MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
1163     MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1164     MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
1165     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
1166 };
1167 
1168 /* global register indices */
1169 TCGv cpu_gpr[32], cpu_PC;
1170 /*
1171  * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1172  * and the upper halves in cpu_gpr_hi[].
1173  */
1174 TCGv_i64 cpu_gpr_hi[32];
1175 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1176 static TCGv cpu_dspctrl, btarget;
1177 TCGv bcond;
1178 static TCGv cpu_lladdr, cpu_llval;
1179 static TCGv_i32 hflags;
1180 TCGv_i32 fpu_fcr0, fpu_fcr31;
1181 TCGv_i64 fpu_f64[32];
1182 
1183 static const char regnames_HI[][4] = {
1184     "HI0", "HI1", "HI2", "HI3",
1185 };
1186 
1187 static const char regnames_LO[][4] = {
1188     "LO0", "LO1", "LO2", "LO3",
1189 };
1190 
1191 /* General purpose registers moves. */
gen_load_gpr(TCGv t,int reg)1192 void gen_load_gpr(TCGv t, int reg)
1193 {
1194     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1195     if (reg == 0) {
1196         tcg_gen_movi_tl(t, 0);
1197     } else {
1198         tcg_gen_mov_tl(t, cpu_gpr[reg]);
1199     }
1200 }
1201 
gen_store_gpr(TCGv t,int reg)1202 void gen_store_gpr(TCGv t, int reg)
1203 {
1204     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1205     if (reg != 0) {
1206         tcg_gen_mov_tl(cpu_gpr[reg], t);
1207     }
1208 }
1209 
1210 #if defined(TARGET_MIPS64)
gen_load_gpr_hi(TCGv_i64 t,int reg)1211 void gen_load_gpr_hi(TCGv_i64 t, int reg)
1212 {
1213     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1214     if (reg == 0) {
1215         tcg_gen_movi_i64(t, 0);
1216     } else {
1217         tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1218     }
1219 }
1220 
gen_store_gpr_hi(TCGv_i64 t,int reg)1221 void gen_store_gpr_hi(TCGv_i64 t, int reg)
1222 {
1223     assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1224     if (reg != 0) {
1225         tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1226     }
1227 }
1228 #endif /* TARGET_MIPS64 */
1229 
1230 /* Moves to/from shadow registers. */
gen_load_srsgpr(int from,int to)1231 static inline void gen_load_srsgpr(int from, int to)
1232 {
1233     TCGv t0 = tcg_temp_new();
1234 
1235     if (from == 0) {
1236         tcg_gen_movi_tl(t0, 0);
1237     } else {
1238         TCGv_i32 t2 = tcg_temp_new_i32();
1239         TCGv_ptr addr = tcg_temp_new_ptr();
1240 
1241         tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1242         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1243         tcg_gen_andi_i32(t2, t2, 0xf);
1244         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1245         tcg_gen_ext_i32_ptr(addr, t2);
1246         tcg_gen_add_ptr(addr, tcg_env, addr);
1247 
1248         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1249     }
1250     gen_store_gpr(t0, to);
1251 }
1252 
gen_store_srsgpr(int from,int to)1253 static inline void gen_store_srsgpr(int from, int to)
1254 {
1255     if (to != 0) {
1256         TCGv t0 = tcg_temp_new();
1257         TCGv_i32 t2 = tcg_temp_new_i32();
1258         TCGv_ptr addr = tcg_temp_new_ptr();
1259 
1260         gen_load_gpr(t0, from);
1261         tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1262         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1263         tcg_gen_andi_i32(t2, t2, 0xf);
1264         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1265         tcg_gen_ext_i32_ptr(addr, t2);
1266         tcg_gen_add_ptr(addr, tcg_env, addr);
1267 
1268         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1269     }
1270 }
1271 
1272 /* Tests */
gen_save_pc(target_ulong pc)1273 static inline void gen_save_pc(target_ulong pc)
1274 {
1275     tcg_gen_movi_tl(cpu_PC, pc);
1276 }
1277 
save_cpu_state(DisasContext * ctx,int do_save_pc)1278 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1279 {
1280     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1281     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1282         gen_save_pc(ctx->base.pc_next);
1283         ctx->saved_pc = ctx->base.pc_next;
1284     }
1285     if (ctx->hflags != ctx->saved_hflags) {
1286         tcg_gen_movi_i32(hflags, ctx->hflags);
1287         ctx->saved_hflags = ctx->hflags;
1288         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1289         case MIPS_HFLAG_BR:
1290             break;
1291         case MIPS_HFLAG_BC:
1292         case MIPS_HFLAG_BL:
1293         case MIPS_HFLAG_B:
1294             tcg_gen_movi_tl(btarget, ctx->btarget);
1295             break;
1296         }
1297     }
1298 }
1299 
restore_cpu_state(CPUMIPSState * env,DisasContext * ctx)1300 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1301 {
1302     ctx->saved_hflags = ctx->hflags;
1303     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1304     case MIPS_HFLAG_BR:
1305         break;
1306     case MIPS_HFLAG_BC:
1307     case MIPS_HFLAG_BL:
1308     case MIPS_HFLAG_B:
1309         ctx->btarget = env->btarget;
1310         break;
1311     }
1312 }
1313 
generate_exception_err(DisasContext * ctx,int excp,int err)1314 void generate_exception_err(DisasContext *ctx, int excp, int err)
1315 {
1316     save_cpu_state(ctx, 1);
1317     gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp),
1318                                    tcg_constant_i32(err));
1319     ctx->base.is_jmp = DISAS_NORETURN;
1320 }
1321 
generate_exception(DisasContext * ctx,int excp)1322 void generate_exception(DisasContext *ctx, int excp)
1323 {
1324     gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
1325 }
1326 
generate_exception_end(DisasContext * ctx,int excp)1327 void generate_exception_end(DisasContext *ctx, int excp)
1328 {
1329     generate_exception_err(ctx, excp, 0);
1330 }
1331 
generate_exception_break(DisasContext * ctx,int code)1332 void generate_exception_break(DisasContext *ctx, int code)
1333 {
1334 #ifdef CONFIG_USER_ONLY
1335     /* Pass the break code along to cpu_loop. */
1336     tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
1337                    offsetof(CPUMIPSState, error_code));
1338 #endif
1339     generate_exception_end(ctx, EXCP_BREAK);
1340 }
1341 
gen_reserved_instruction(DisasContext * ctx)1342 void gen_reserved_instruction(DisasContext *ctx)
1343 {
1344     generate_exception_end(ctx, EXCP_RI);
1345 }
1346 
1347 /* Floating point register moves. */
gen_load_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)1348 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1349 {
1350     if (ctx->hflags & MIPS_HFLAG_FRE) {
1351         generate_exception(ctx, EXCP_RI);
1352     }
1353     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1354 }
1355 
gen_store_fpr32(DisasContext * ctx,TCGv_i32 t,int reg)1356 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1357 {
1358     TCGv_i64 t64;
1359     if (ctx->hflags & MIPS_HFLAG_FRE) {
1360         generate_exception(ctx, EXCP_RI);
1361     }
1362     t64 = tcg_temp_new_i64();
1363     tcg_gen_extu_i32_i64(t64, t);
1364     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1365 }
1366 
gen_load_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1367 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1368 {
1369     if (ctx->hflags & MIPS_HFLAG_F64) {
1370         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1371     } else {
1372         gen_load_fpr32(ctx, t, reg | 1);
1373     }
1374 }
1375 
gen_store_fpr32h(DisasContext * ctx,TCGv_i32 t,int reg)1376 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1377 {
1378     if (ctx->hflags & MIPS_HFLAG_F64) {
1379         TCGv_i64 t64 = tcg_temp_new_i64();
1380         tcg_gen_extu_i32_i64(t64, t);
1381         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1382     } else {
1383         gen_store_fpr32(ctx, t, reg | 1);
1384     }
1385 }
1386 
gen_load_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1387 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1388 {
1389     if (ctx->hflags & MIPS_HFLAG_F64) {
1390         tcg_gen_mov_i64(t, fpu_f64[reg]);
1391     } else {
1392         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1393     }
1394 }
1395 
gen_store_fpr64(DisasContext * ctx,TCGv_i64 t,int reg)1396 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1397 {
1398     if (ctx->hflags & MIPS_HFLAG_F64) {
1399         tcg_gen_mov_i64(fpu_f64[reg], t);
1400     } else {
1401         TCGv_i64 t0;
1402         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1403         t0 = tcg_temp_new_i64();
1404         tcg_gen_shri_i64(t0, t, 32);
1405         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1406     }
1407 }
1408 
get_fp_bit(int cc)1409 int get_fp_bit(int cc)
1410 {
1411     if (cc) {
1412         return 24 + cc;
1413     } else {
1414         return 23;
1415     }
1416 }
1417 
1418 /* Addresses computation */
gen_op_addr_add(DisasContext * ctx,TCGv ret,TCGv arg0,TCGv arg1)1419 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1420 {
1421     tcg_gen_add_tl(ret, arg0, arg1);
1422 
1423 #if defined(TARGET_MIPS64)
1424     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1425         tcg_gen_ext32s_i64(ret, ret);
1426     }
1427 #endif
1428 }
1429 
gen_op_addr_addi(DisasContext * ctx,TCGv ret,TCGv base,target_long ofs)1430 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs)
1431 {
1432     tcg_gen_addi_tl(ret, base, ofs);
1433 
1434 #if defined(TARGET_MIPS64)
1435     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1436         tcg_gen_ext32s_i64(ret, ret);
1437     }
1438 #endif
1439 }
1440 
1441 /* Addresses computation (translation time) */
addr_add(DisasContext * ctx,target_long base,target_long offset)1442 static target_long addr_add(DisasContext *ctx, target_long base,
1443                             target_long offset)
1444 {
1445     target_long sum = base + offset;
1446 
1447 #if defined(TARGET_MIPS64)
1448     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1449         sum = (int32_t)sum;
1450     }
1451 #endif
1452     return sum;
1453 }
1454 
1455 /* Sign-extract the low 32-bits to a target_long.  */
gen_move_low32(TCGv ret,TCGv_i64 arg)1456 void gen_move_low32(TCGv ret, TCGv_i64 arg)
1457 {
1458 #if defined(TARGET_MIPS64)
1459     tcg_gen_ext32s_i64(ret, arg);
1460 #else
1461     tcg_gen_extrl_i64_i32(ret, arg);
1462 #endif
1463 }
1464 
1465 /* Sign-extract the high 32-bits to a target_long.  */
gen_move_high32(TCGv ret,TCGv_i64 arg)1466 void gen_move_high32(TCGv ret, TCGv_i64 arg)
1467 {
1468 #if defined(TARGET_MIPS64)
1469     tcg_gen_sari_i64(ret, arg, 32);
1470 #else
1471     tcg_gen_extrh_i64_i32(ret, arg);
1472 #endif
1473 }
1474 
check_cp0_enabled(DisasContext * ctx)1475 bool check_cp0_enabled(DisasContext *ctx)
1476 {
1477     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1478         generate_exception_end(ctx, EXCP_CpU);
1479         return false;
1480     }
1481     return true;
1482 }
1483 
check_cp1_enabled(DisasContext * ctx)1484 void check_cp1_enabled(DisasContext *ctx)
1485 {
1486     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1487         generate_exception_err(ctx, EXCP_CpU, 1);
1488     }
1489 }
1490 
1491 /*
1492  * Verify that the processor is running with COP1X instructions enabled.
1493  * This is associated with the nabla symbol in the MIPS32 and MIPS64
1494  * opcode tables.
1495  */
check_cop1x(DisasContext * ctx)1496 void check_cop1x(DisasContext *ctx)
1497 {
1498     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1499         gen_reserved_instruction(ctx);
1500     }
1501 }
1502 
1503 /*
1504  * Verify that the processor is running with 64-bit floating-point
1505  * operations enabled.
1506  */
check_cp1_64bitmode(DisasContext * ctx)1507 void check_cp1_64bitmode(DisasContext *ctx)
1508 {
1509     if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) {
1510         gen_reserved_instruction(ctx);
1511     }
1512 }
1513 
1514 /*
1515  * Verify if floating point register is valid; an operation is not defined
1516  * if bit 0 of any register specification is set and the FR bit in the
1517  * Status register equals zero, since the register numbers specify an
1518  * even-odd pair of adjacent coprocessor general registers. When the FR bit
1519  * in the Status register equals one, both even and odd register numbers
1520  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1521  *
1522  * Multiple 64 bit wide registers can be checked by calling
1523  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1524  */
check_cp1_registers(DisasContext * ctx,int regs)1525 void check_cp1_registers(DisasContext *ctx, int regs)
1526 {
1527     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1528         gen_reserved_instruction(ctx);
1529     }
1530 }
1531 
1532 /*
1533  * Verify that the processor is running with DSP instructions enabled.
1534  * This is enabled by CP0 Status register MX(24) bit.
1535  */
check_dsp(DisasContext * ctx)1536 static inline void check_dsp(DisasContext *ctx)
1537 {
1538     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1539         if (ctx->insn_flags & ASE_DSP) {
1540             generate_exception_end(ctx, EXCP_DSPDIS);
1541         } else {
1542             gen_reserved_instruction(ctx);
1543         }
1544     }
1545 }
1546 
check_dsp_r2(DisasContext * ctx)1547 static inline void check_dsp_r2(DisasContext *ctx)
1548 {
1549     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1550         if (ctx->insn_flags & ASE_DSP) {
1551             generate_exception_end(ctx, EXCP_DSPDIS);
1552         } else {
1553             gen_reserved_instruction(ctx);
1554         }
1555     }
1556 }
1557 
check_dsp_r3(DisasContext * ctx)1558 static inline void check_dsp_r3(DisasContext *ctx)
1559 {
1560     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1561         if (ctx->insn_flags & ASE_DSP) {
1562             generate_exception_end(ctx, EXCP_DSPDIS);
1563         } else {
1564             gen_reserved_instruction(ctx);
1565         }
1566     }
1567 }
1568 
1569 /*
1570  * This code generates a "reserved instruction" exception if the
1571  * CPU does not support the instruction set corresponding to flags.
1572  */
check_insn(DisasContext * ctx,uint64_t flags)1573 void check_insn(DisasContext *ctx, uint64_t flags)
1574 {
1575     if (unlikely(!(ctx->insn_flags & flags))) {
1576         gen_reserved_instruction(ctx);
1577     }
1578 }
1579 
1580 /*
1581  * This code generates a "reserved instruction" exception if the
1582  * CPU has corresponding flag set which indicates that the instruction
1583  * has been removed.
1584  */
check_insn_opc_removed(DisasContext * ctx,uint64_t flags)1585 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1586 {
1587     if (unlikely(ctx->insn_flags & flags)) {
1588         gen_reserved_instruction(ctx);
1589     }
1590 }
1591 
1592 /*
1593  * The Linux kernel traps certain reserved instruction exceptions to
1594  * emulate the corresponding instructions. QEMU is the kernel in user
1595  * mode, so those traps are emulated by accepting the instructions.
1596  *
1597  * A reserved instruction exception is generated for flagged CPUs if
1598  * QEMU runs in system mode.
1599  */
check_insn_opc_user_only(DisasContext * ctx,uint64_t flags)1600 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1601 {
1602 #ifndef CONFIG_USER_ONLY
1603     check_insn_opc_removed(ctx, flags);
1604 #endif
1605 }
1606 
1607 /*
1608  * This code generates a "reserved instruction" exception if the
1609  * CPU does not support 64-bit paired-single (PS) floating point data type.
1610  */
check_ps(DisasContext * ctx)1611 static inline void check_ps(DisasContext *ctx)
1612 {
1613     if (unlikely(!ctx->ps)) {
1614         generate_exception(ctx, EXCP_RI);
1615     }
1616     check_cp1_64bitmode(ctx);
1617 }
1618 
decode_64bit_enabled(DisasContext * ctx)1619 bool decode_64bit_enabled(DisasContext *ctx)
1620 {
1621     return ctx->hflags & MIPS_HFLAG_64;
1622 }
1623 
1624 /*
1625  * This code generates a "reserved instruction" exception if cpu is not
1626  * 64-bit or 64-bit instructions are not enabled.
1627  */
check_mips_64(DisasContext * ctx)1628 void check_mips_64(DisasContext *ctx)
1629 {
1630     if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) {
1631         gen_reserved_instruction(ctx);
1632     }
1633 }
1634 
1635 #ifndef CONFIG_USER_ONLY
check_mvh(DisasContext * ctx)1636 static inline void check_mvh(DisasContext *ctx)
1637 {
1638     if (unlikely(!ctx->mvh)) {
1639         generate_exception(ctx, EXCP_RI);
1640     }
1641 }
1642 #endif
1643 
1644 /*
1645  * This code generates a "reserved instruction" exception if the
1646  * Config5 XNP bit is set.
1647  */
check_xnp(DisasContext * ctx)1648 static inline void check_xnp(DisasContext *ctx)
1649 {
1650     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1651         gen_reserved_instruction(ctx);
1652     }
1653 }
1654 
1655 #ifndef CONFIG_USER_ONLY
1656 /*
1657  * This code generates a "reserved instruction" exception if the
1658  * Config3 PW bit is NOT set.
1659  */
check_pw(DisasContext * ctx)1660 static inline void check_pw(DisasContext *ctx)
1661 {
1662     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1663         gen_reserved_instruction(ctx);
1664     }
1665 }
1666 #endif
1667 
1668 /*
1669  * This code generates a "reserved instruction" exception if the
1670  * Config3 MT bit is NOT set.
1671  */
check_mt(DisasContext * ctx)1672 static inline void check_mt(DisasContext *ctx)
1673 {
1674     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1675         gen_reserved_instruction(ctx);
1676     }
1677 }
1678 
1679 #ifndef CONFIG_USER_ONLY
1680 /*
1681  * This code generates a "coprocessor unusable" exception if CP0 is not
1682  * available, and, if that is not the case, generates a "reserved instruction"
1683  * exception if the Config5 MT bit is NOT set. This is needed for availability
1684  * control of some of MT ASE instructions.
1685  */
check_cp0_mt(DisasContext * ctx)1686 static inline void check_cp0_mt(DisasContext *ctx)
1687 {
1688     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1689         generate_exception_end(ctx, EXCP_CpU);
1690     } else {
1691         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1692             gen_reserved_instruction(ctx);
1693         }
1694     }
1695 }
1696 #endif
1697 
1698 /*
1699  * This code generates a "reserved instruction" exception if the
1700  * Config5 NMS bit is set.
1701  */
check_nms(DisasContext * ctx)1702 static inline void check_nms(DisasContext *ctx)
1703 {
1704     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1705         gen_reserved_instruction(ctx);
1706     }
1707 }
1708 
1709 /*
1710  * This code generates a "reserved instruction" exception if the
1711  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1712  * Config2 TL, and Config5 L2C are unset.
1713  */
check_nms_dl_il_sl_tl_l2c(DisasContext * ctx)1714 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1715 {
1716     if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1717                  !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1718                  !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1719                  !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1720                  !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1721                  !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1722         gen_reserved_instruction(ctx);
1723     }
1724 }
1725 
1726 /*
1727  * This code generates a "reserved instruction" exception if the
1728  * Config5 EVA bit is NOT set.
1729  */
check_eva(DisasContext * ctx)1730 static inline void check_eva(DisasContext *ctx)
1731 {
1732     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1733         gen_reserved_instruction(ctx);
1734     }
1735 }
1736 
1737 
1738 /*
1739  * Define small wrappers for gen_load_fpr* so that we have a uniform
1740  * calling interface for 32 and 64-bit FPRs.  No sense in changing
1741  * all callers for gen_load_fpr32 when we need the CTX parameter for
1742  * this one use.
1743  */
1744 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1745 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1746 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1747 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1748                                                int ft, int fs, int cc)        \
1749 {                                                                             \
1750     TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1751     TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1752     switch (ifmt) {                                                           \
1753     case FMT_PS:                                                              \
1754         check_ps(ctx);                                                        \
1755         break;                                                                \
1756     case FMT_D:                                                               \
1757         if (abs) {                                                            \
1758             check_cop1x(ctx);                                                 \
1759         }                                                                     \
1760         check_cp1_registers(ctx, fs | ft);                                    \
1761         break;                                                                \
1762     case FMT_S:                                                               \
1763         if (abs) {                                                            \
1764             check_cop1x(ctx);                                                 \
1765         }                                                                     \
1766         break;                                                                \
1767     }                                                                         \
1768     gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1769     gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1770     switch (n) {                                                              \
1771     case  0:                                                                  \
1772         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1773     break;                                                                    \
1774     case  1:                                                                  \
1775         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1776     break;                                                                    \
1777     case  2:                                                                  \
1778         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1779     break;                                                                    \
1780     case  3:                                                                  \
1781         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1782     break;                                                                    \
1783     case  4:                                                                  \
1784         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1785     break;                                                                    \
1786     case  5:                                                                  \
1787         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1788     break;                                                                    \
1789     case  6:                                                                  \
1790         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1791     break;                                                                    \
1792     case  7:                                                                  \
1793         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1794     break;                                                                    \
1795     case  8:                                                                  \
1796         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1797     break;                                                                    \
1798     case  9:                                                                  \
1799         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1800     break;                                                                    \
1801     case 10:                                                                  \
1802         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1803     break;                                                                    \
1804     case 11:                                                                  \
1805         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1806     break;                                                                    \
1807     case 12:                                                                  \
1808         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1809     break;                                                                    \
1810     case 13:                                                                  \
1811         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1812     break;                                                                    \
1813     case 14:                                                                  \
1814         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1815     break;                                                                    \
1816     case 15:                                                                  \
1817         gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1818     break;                                                                    \
1819     default:                                                                  \
1820         abort();                                                              \
1821     }                                                                         \
1822 }
1823 
1824 FOP_CONDS(, 0, d, FMT_D, 64)
1825 FOP_CONDS(abs, 1, d, FMT_D, 64)
1826 FOP_CONDS(, 0, s, FMT_S, 32)
1827 FOP_CONDS(abs, 1, s, FMT_S, 32)
1828 FOP_CONDS(, 0, ps, FMT_PS, 64)
1829 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1830 #undef FOP_CONDS
1831 
1832 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1833 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1834                                       int ft, int fs, int fd)           \
1835 {                                                                       \
1836     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1837     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1838     if (ifmt == FMT_D) {                                                \
1839         check_cp1_registers(ctx, fs | ft | fd);                         \
1840     }                                                                   \
1841     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1842     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1843     switch (n) {                                                        \
1844     case  0:                                                            \
1845         gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1);       \
1846         break;                                                          \
1847     case  1:                                                            \
1848         gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1);       \
1849         break;                                                          \
1850     case  2:                                                            \
1851         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1);       \
1852         break;                                                          \
1853     case  3:                                                            \
1854         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1);      \
1855         break;                                                          \
1856     case  4:                                                            \
1857         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1);       \
1858         break;                                                          \
1859     case  5:                                                            \
1860         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1);      \
1861         break;                                                          \
1862     case  6:                                                            \
1863         gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1);       \
1864         break;                                                          \
1865     case  7:                                                            \
1866         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1);      \
1867         break;                                                          \
1868     case  8:                                                            \
1869         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1);      \
1870         break;                                                          \
1871     case  9:                                                            \
1872         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1);      \
1873         break;                                                          \
1874     case 10:                                                            \
1875         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1);      \
1876         break;                                                          \
1877     case 11:                                                            \
1878         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1);     \
1879         break;                                                          \
1880     case 12:                                                            \
1881         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1);      \
1882         break;                                                          \
1883     case 13:                                                            \
1884         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1);     \
1885         break;                                                          \
1886     case 14:                                                            \
1887         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1);      \
1888         break;                                                          \
1889     case 15:                                                            \
1890         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1);     \
1891         break;                                                          \
1892     case 17:                                                            \
1893         gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1);       \
1894         break;                                                          \
1895     case 18:                                                            \
1896         gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1);      \
1897         break;                                                          \
1898     case 19:                                                            \
1899         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1);       \
1900         break;                                                          \
1901     case 25:                                                            \
1902         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1);      \
1903         break;                                                          \
1904     case 26:                                                            \
1905         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1);     \
1906         break;                                                          \
1907     case 27:                                                            \
1908         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1);      \
1909         break;                                                          \
1910     default:                                                            \
1911         abort();                                                        \
1912     }                                                                   \
1913     STORE;                                                              \
1914 }
1915 
1916 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1917 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1918 #undef FOP_CONDNS
1919 #undef gen_ldcmp_fpr32
1920 #undef gen_ldcmp_fpr64
1921 
1922 /* load/store instructions. */
1923 #ifdef CONFIG_USER_ONLY
1924 #define OP_LD_ATOMIC(insn, memop)                                          \
1925 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1926                                 DisasContext *ctx)                         \
1927 {                                                                          \
1928     TCGv t0 = tcg_temp_new();                                              \
1929     tcg_gen_mov_tl(t0, arg1);                                              \
1930     tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop);                    \
1931     tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr));            \
1932     tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval));            \
1933 }
1934 #else
1935 #define OP_LD_ATOMIC(insn, ignored_memop)                                  \
1936 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1937                                 DisasContext *ctx)                         \
1938 {                                                                          \
1939     gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx));      \
1940 }
1941 #endif
1942 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL);
1943 #if defined(TARGET_MIPS64)
1944 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ);
1945 #endif
1946 #undef OP_LD_ATOMIC
1947 
gen_base_offset_addr(DisasContext * ctx,TCGv addr,int base,int offset)1948 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1949 {
1950     if (base == 0) {
1951         tcg_gen_movi_tl(addr, offset);
1952     } else if (offset == 0) {
1953         gen_load_gpr(addr, base);
1954     } else {
1955         tcg_gen_movi_tl(addr, offset);
1956         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1957     }
1958 }
1959 
gen_base_index_addr(DisasContext * ctx,TCGv addr,int base,int index)1960 void gen_base_index_addr(DisasContext *ctx, TCGv addr, int base, int index)
1961 {
1962     if (base == 0) {
1963         gen_load_gpr(addr, index);
1964     } else if (index == 0) {
1965         gen_load_gpr(addr, base);
1966     } else {
1967         gen_op_addr_add(ctx, addr, cpu_gpr[base], cpu_gpr[index]);
1968     }
1969 }
1970 
pc_relative_pc(DisasContext * ctx)1971 static target_ulong pc_relative_pc(DisasContext *ctx)
1972 {
1973     target_ulong pc = ctx->base.pc_next;
1974 
1975     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1976         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1977 
1978         pc -= branch_bytes;
1979     }
1980 
1981     pc &= ~(target_ulong)3;
1982     return pc;
1983 }
1984 
1985 /* LWL or LDL, depending on MemOp. */
gen_lxl(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)1986 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr,
1987                      int mem_idx, MemOp mop)
1988 {
1989     int sizem1 = memop_size(mop) - 1;
1990     TCGv t0 = tcg_temp_new();
1991     TCGv t1 = tcg_temp_new();
1992 
1993     /*
1994      * Do a byte access to possibly trigger a page
1995      * fault with the unaligned address.
1996      */
1997     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
1998     tcg_gen_andi_tl(t1, addr, sizem1);
1999     if (!disas_is_bigendian(ctx)) {
2000         tcg_gen_xori_tl(t1, t1, sizem1);
2001     }
2002     tcg_gen_shli_tl(t1, t1, 3);
2003     tcg_gen_andi_tl(t0, addr, ~sizem1);
2004     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2005     tcg_gen_shl_tl(t0, t0, t1);
2006     tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1);
2007     tcg_gen_andc_tl(t1, reg, t1);
2008     tcg_gen_or_tl(reg, t0, t1);
2009 }
2010 
2011 /* LWR or LDR, depending on MemOp. */
gen_lxr(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)2012 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr,
2013                      int mem_idx, MemOp mop)
2014 {
2015     int size = memop_size(mop);
2016     int sizem1 = size - 1;
2017     TCGv t0 = tcg_temp_new();
2018     TCGv t1 = tcg_temp_new();
2019 
2020     /*
2021      * Do a byte access to possibly trigger a page
2022      * fault with the unaligned address.
2023      */
2024     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2025     tcg_gen_andi_tl(t1, addr, sizem1);
2026     if (disas_is_bigendian(ctx)) {
2027         tcg_gen_xori_tl(t1, t1, sizem1);
2028     }
2029     tcg_gen_shli_tl(t1, t1, 3);
2030     tcg_gen_andi_tl(t0, addr, ~sizem1);
2031     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2032     tcg_gen_shr_tl(t0, t0, t1);
2033     tcg_gen_xori_tl(t1, t1, size * 8 - 1);
2034     tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1);
2035     tcg_gen_and_tl(t1, reg, t1);
2036     tcg_gen_or_tl(reg, t0, t1);
2037 }
2038 
gen_lx(DisasContext * ctx,int rd,int base,int index,MemOp mop)2039 void gen_lx(DisasContext *ctx, int rd, int base, int index, MemOp mop)
2040 {
2041     TCGv t0 = tcg_temp_new();
2042 
2043     gen_base_index_addr(ctx, t0, base, index);
2044     tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | mop);
2045     gen_store_gpr(t0, rd);
2046 }
2047 
2048 /* Load */
gen_ld(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2049 static void gen_ld(DisasContext *ctx, uint32_t opc,
2050                    int rt, int base, int offset)
2051 {
2052     TCGv t0, t1;
2053     int mem_idx = ctx->mem_idx;
2054 
2055     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2056                                       INSN_LOONGSON3A)) {
2057         /*
2058          * Loongson CPU uses a load to zero register for prefetch.
2059          * We emulate it as a NOP. On other CPU we must perform the
2060          * actual memory access.
2061          */
2062         return;
2063     }
2064 
2065     t0 = tcg_temp_new();
2066     gen_base_offset_addr(ctx, t0, base, offset);
2067 
2068     switch (opc) {
2069 #if defined(TARGET_MIPS64)
2070     case OPC_LWU:
2071         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL |
2072                            ctx->default_tcg_memop_mask);
2073         gen_store_gpr(t0, rt);
2074         break;
2075     case OPC_LD:
2076         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2077                            ctx->default_tcg_memop_mask);
2078         gen_store_gpr(t0, rt);
2079         break;
2080     case OPC_LLD:
2081     case R6_OPC_LLD:
2082         op_ld_lld(t0, t0, mem_idx, ctx);
2083         gen_store_gpr(t0, rt);
2084         break;
2085     case OPC_LDL:
2086         t1 = tcg_temp_new();
2087         gen_load_gpr(t1, rt);
2088         gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2089         gen_store_gpr(t1, rt);
2090         break;
2091     case OPC_LDR:
2092         t1 = tcg_temp_new();
2093         gen_load_gpr(t1, rt);
2094         gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2095         gen_store_gpr(t1, rt);
2096         break;
2097     case OPC_LDPC:
2098         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2099         gen_op_addr_add(ctx, t0, t0, t1);
2100         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2101         gen_store_gpr(t0, rt);
2102         break;
2103 #endif
2104     case OPC_LWPC:
2105         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2106         gen_op_addr_add(ctx, t0, t0, t1);
2107         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL);
2108         gen_store_gpr(t0, rt);
2109         break;
2110     case OPC_LWE:
2111         mem_idx = MIPS_HFLAG_UM;
2112         /* fall through */
2113     case OPC_LW:
2114         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL |
2115                            ctx->default_tcg_memop_mask);
2116         gen_store_gpr(t0, rt);
2117         break;
2118     case OPC_LHE:
2119         mem_idx = MIPS_HFLAG_UM;
2120         /* fall through */
2121     case OPC_LH:
2122         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW |
2123                            ctx->default_tcg_memop_mask);
2124         gen_store_gpr(t0, rt);
2125         break;
2126     case OPC_LHUE:
2127         mem_idx = MIPS_HFLAG_UM;
2128         /* fall through */
2129     case OPC_LHU:
2130         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW |
2131                            ctx->default_tcg_memop_mask);
2132         gen_store_gpr(t0, rt);
2133         break;
2134     case OPC_LBE:
2135         mem_idx = MIPS_HFLAG_UM;
2136         /* fall through */
2137     case OPC_LB:
2138         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2139         gen_store_gpr(t0, rt);
2140         break;
2141     case OPC_LBUE:
2142         mem_idx = MIPS_HFLAG_UM;
2143         /* fall through */
2144     case OPC_LBU:
2145         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2146         gen_store_gpr(t0, rt);
2147         break;
2148     case OPC_LWLE:
2149         mem_idx = MIPS_HFLAG_UM;
2150         /* fall through */
2151     case OPC_LWL:
2152         t1 = tcg_temp_new();
2153         gen_load_gpr(t1, rt);
2154         gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2155         tcg_gen_ext32s_tl(t1, t1);
2156         gen_store_gpr(t1, rt);
2157         break;
2158     case OPC_LWRE:
2159         mem_idx = MIPS_HFLAG_UM;
2160         /* fall through */
2161     case OPC_LWR:
2162         t1 = tcg_temp_new();
2163         gen_load_gpr(t1, rt);
2164         gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2165         tcg_gen_ext32s_tl(t1, t1);
2166         gen_store_gpr(t1, rt);
2167         break;
2168     case OPC_LLE:
2169         mem_idx = MIPS_HFLAG_UM;
2170         /* fall through */
2171     case OPC_LL:
2172     case R6_OPC_LL:
2173         op_ld_ll(t0, t0, mem_idx, ctx);
2174         gen_store_gpr(t0, rt);
2175         break;
2176     }
2177 }
2178 
2179 /* Store */
gen_st(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2180 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2181                    int base, int offset)
2182 {
2183     TCGv t0 = tcg_temp_new();
2184     TCGv t1 = tcg_temp_new();
2185     int mem_idx = ctx->mem_idx;
2186 
2187     gen_base_offset_addr(ctx, t0, base, offset);
2188     gen_load_gpr(t1, rt);
2189     switch (opc) {
2190 #if defined(TARGET_MIPS64)
2191     case OPC_SD:
2192         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2193                            ctx->default_tcg_memop_mask);
2194         break;
2195     case OPC_SDL:
2196         gen_helper_0e2i(sdl, t1, t0, mem_idx);
2197         break;
2198     case OPC_SDR:
2199         gen_helper_0e2i(sdr, t1, t0, mem_idx);
2200         break;
2201 #endif
2202     case OPC_SWE:
2203         mem_idx = MIPS_HFLAG_UM;
2204         /* fall through */
2205     case OPC_SW:
2206         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL |
2207                            ctx->default_tcg_memop_mask);
2208         break;
2209     case OPC_SHE:
2210         mem_idx = MIPS_HFLAG_UM;
2211         /* fall through */
2212     case OPC_SH:
2213         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW |
2214                            ctx->default_tcg_memop_mask);
2215         break;
2216     case OPC_SBE:
2217         mem_idx = MIPS_HFLAG_UM;
2218         /* fall through */
2219     case OPC_SB:
2220         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2221         break;
2222     case OPC_SWLE:
2223         mem_idx = MIPS_HFLAG_UM;
2224         /* fall through */
2225     case OPC_SWL:
2226         gen_helper_0e2i(swl, t1, t0, mem_idx);
2227         break;
2228     case OPC_SWRE:
2229         mem_idx = MIPS_HFLAG_UM;
2230         /* fall through */
2231     case OPC_SWR:
2232         gen_helper_0e2i(swr, t1, t0, mem_idx);
2233         break;
2234     }
2235 }
2236 
2237 
2238 /* Store conditional */
gen_st_cond(DisasContext * ctx,int rt,int base,int offset,MemOp tcg_mo,bool eva)2239 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2240                         MemOp tcg_mo, bool eva)
2241 {
2242     TCGv addr, t0, val;
2243     TCGLabel *l1 = gen_new_label();
2244     TCGLabel *done = gen_new_label();
2245 
2246     t0 = tcg_temp_new();
2247     addr = tcg_temp_new();
2248     /* compare the address against that of the preceding LL */
2249     gen_base_offset_addr(ctx, addr, base, offset);
2250     tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2251     gen_store_gpr(tcg_constant_tl(0), rt);
2252     tcg_gen_br(done);
2253 
2254     gen_set_label(l1);
2255     /* generate cmpxchg */
2256     val = tcg_temp_new();
2257     gen_load_gpr(val, rt);
2258     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2259                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2260     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2261     gen_store_gpr(t0, rt);
2262 
2263     gen_set_label(done);
2264 }
2265 
2266 /* Load and store */
gen_flt_ldst(DisasContext * ctx,uint32_t opc,int ft,TCGv t0)2267 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2268                          TCGv t0)
2269 {
2270     /*
2271      * Don't do NOP if destination is zero: we must perform the actual
2272      * memory access.
2273      */
2274     switch (opc) {
2275     case OPC_LWC1:
2276         {
2277             TCGv_i32 fp0 = tcg_temp_new_i32();
2278             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
2279                                 ctx->default_tcg_memop_mask);
2280             gen_store_fpr32(ctx, fp0, ft);
2281         }
2282         break;
2283     case OPC_SWC1:
2284         {
2285             TCGv_i32 fp0 = tcg_temp_new_i32();
2286             gen_load_fpr32(ctx, fp0, ft);
2287             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
2288                                 ctx->default_tcg_memop_mask);
2289         }
2290         break;
2291     case OPC_LDC1:
2292         {
2293             TCGv_i64 fp0 = tcg_temp_new_i64();
2294             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2295                                 ctx->default_tcg_memop_mask);
2296             gen_store_fpr64(ctx, fp0, ft);
2297         }
2298         break;
2299     case OPC_SDC1:
2300         {
2301             TCGv_i64 fp0 = tcg_temp_new_i64();
2302             gen_load_fpr64(ctx, fp0, ft);
2303             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2304                                 ctx->default_tcg_memop_mask);
2305         }
2306         break;
2307     default:
2308         MIPS_INVAL("flt_ldst");
2309         gen_reserved_instruction(ctx);
2310         break;
2311     }
2312 }
2313 
gen_cop1_ldst(DisasContext * ctx,uint32_t op,int rt,int rs,int16_t imm)2314 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2315                           int rs, int16_t imm)
2316 {
2317     TCGv t0 = tcg_temp_new();
2318 
2319     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2320         check_cp1_enabled(ctx);
2321         switch (op) {
2322         case OPC_LDC1:
2323         case OPC_SDC1:
2324             check_insn(ctx, ISA_MIPS2);
2325             /* Fallthrough */
2326         default:
2327             gen_base_offset_addr(ctx, t0, rs, imm);
2328             gen_flt_ldst(ctx, op, rt, t0);
2329         }
2330     } else {
2331         generate_exception_err(ctx, EXCP_CpU, 1);
2332     }
2333 }
2334 
2335 /* Arithmetic with immediate operand */
gen_arith_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int imm)2336 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2337                           int rt, int rs, int imm)
2338 {
2339     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2340 
2341     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2342         /*
2343          * If no destination, treat it as a NOP.
2344          * For addi, we must generate the overflow exception when needed.
2345          */
2346         return;
2347     }
2348     switch (opc) {
2349     case OPC_ADDI:
2350         {
2351             TCGv t0 = tcg_temp_new();
2352             TCGv t1 = tcg_temp_new();
2353             TCGv t2 = tcg_temp_new();
2354             TCGLabel *l1 = gen_new_label();
2355 
2356             gen_load_gpr(t1, rs);
2357             tcg_gen_addi_tl(t0, t1, uimm);
2358             tcg_gen_ext32s_tl(t0, t0);
2359 
2360             tcg_gen_xori_tl(t1, t1, ~uimm);
2361             tcg_gen_xori_tl(t2, t0, uimm);
2362             tcg_gen_and_tl(t1, t1, t2);
2363             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2364             /* operands of same sign, result different sign */
2365             generate_exception(ctx, EXCP_OVERFLOW);
2366             gen_set_label(l1);
2367             tcg_gen_ext32s_tl(t0, t0);
2368             gen_store_gpr(t0, rt);
2369         }
2370         break;
2371     case OPC_ADDIU:
2372         if (rs != 0) {
2373             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2374             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2375         } else {
2376             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2377         }
2378         break;
2379 #if defined(TARGET_MIPS64)
2380     case OPC_DADDI:
2381         {
2382             TCGv t0 = tcg_temp_new();
2383             TCGv t1 = tcg_temp_new();
2384             TCGv t2 = tcg_temp_new();
2385             TCGLabel *l1 = gen_new_label();
2386 
2387             gen_load_gpr(t1, rs);
2388             tcg_gen_addi_tl(t0, t1, uimm);
2389 
2390             tcg_gen_xori_tl(t1, t1, ~uimm);
2391             tcg_gen_xori_tl(t2, t0, uimm);
2392             tcg_gen_and_tl(t1, t1, t2);
2393             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2394             /* operands of same sign, result different sign */
2395             generate_exception(ctx, EXCP_OVERFLOW);
2396             gen_set_label(l1);
2397             gen_store_gpr(t0, rt);
2398         }
2399         break;
2400     case OPC_DADDIU:
2401         if (rs != 0) {
2402             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2403         } else {
2404             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2405         }
2406         break;
2407 #endif
2408     }
2409 }
2410 
2411 /* Logic with immediate operand */
gen_logic_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2412 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2413                           int rt, int rs, int16_t imm)
2414 {
2415     target_ulong uimm;
2416 
2417     if (rt == 0) {
2418         /* If no destination, treat it as a NOP. */
2419         return;
2420     }
2421     uimm = (uint16_t)imm;
2422     switch (opc) {
2423     case OPC_ANDI:
2424         if (likely(rs != 0)) {
2425             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2426         } else {
2427             tcg_gen_movi_tl(cpu_gpr[rt], 0);
2428         }
2429         break;
2430     case OPC_ORI:
2431         if (rs != 0) {
2432             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2433         } else {
2434             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2435         }
2436         break;
2437     case OPC_XORI:
2438         if (likely(rs != 0)) {
2439             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2440         } else {
2441             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2442         }
2443         break;
2444     case OPC_LUI:
2445         if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2446             /* OPC_AUI */
2447             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2448             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2449         } else {
2450             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2451         }
2452         break;
2453 
2454     default:
2455         break;
2456     }
2457 }
2458 
2459 /* Set on less than with immediate operand */
gen_slt_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2460 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2461                         int rt, int rs, int16_t imm)
2462 {
2463     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2464     TCGv t0;
2465 
2466     if (rt == 0) {
2467         /* If no destination, treat it as a NOP. */
2468         return;
2469     }
2470     t0 = tcg_temp_new();
2471     gen_load_gpr(t0, rs);
2472     switch (opc) {
2473     case OPC_SLTI:
2474         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2475         break;
2476     case OPC_SLTIU:
2477         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2478         break;
2479     }
2480 }
2481 
2482 /* Shifts with immediate operand */
gen_shift_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2483 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2484                           int rt, int rs, int16_t imm)
2485 {
2486     target_ulong uimm = ((uint16_t)imm) & 0x1f;
2487     TCGv t0;
2488 
2489     if (rt == 0) {
2490         /* If no destination, treat it as a NOP. */
2491         return;
2492     }
2493 
2494     t0 = tcg_temp_new();
2495     gen_load_gpr(t0, rs);
2496     switch (opc) {
2497     case OPC_SLL:
2498         tcg_gen_shli_tl(t0, t0, uimm);
2499         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2500         break;
2501     case OPC_SRA:
2502         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2503         break;
2504     case OPC_SRL:
2505         if (uimm != 0) {
2506             tcg_gen_ext32u_tl(t0, t0);
2507             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2508         } else {
2509             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2510         }
2511         break;
2512     case OPC_ROTR:
2513         if (uimm != 0) {
2514             TCGv_i32 t1 = tcg_temp_new_i32();
2515 
2516             tcg_gen_trunc_tl_i32(t1, t0);
2517             tcg_gen_rotri_i32(t1, t1, uimm);
2518             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2519         } else {
2520             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2521         }
2522         break;
2523 #if defined(TARGET_MIPS64)
2524     case OPC_DSLL:
2525         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2526         break;
2527     case OPC_DSRA:
2528         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2529         break;
2530     case OPC_DSRL:
2531         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2532         break;
2533     case OPC_DROTR:
2534         if (uimm != 0) {
2535             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2536         } else {
2537             tcg_gen_mov_tl(cpu_gpr[rt], t0);
2538         }
2539         break;
2540     case OPC_DSLL32:
2541         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2542         break;
2543     case OPC_DSRA32:
2544         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2545         break;
2546     case OPC_DSRL32:
2547         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2548         break;
2549     case OPC_DROTR32:
2550         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2551         break;
2552 #endif
2553     }
2554 }
2555 
2556 /* Arithmetic */
gen_arith(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2557 static void gen_arith(DisasContext *ctx, uint32_t opc,
2558                       int rd, int rs, int rt)
2559 {
2560     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2561        && opc != OPC_DADD && opc != OPC_DSUB) {
2562         /*
2563          * If no destination, treat it as a NOP.
2564          * For add & sub, we must generate the overflow exception when needed.
2565          */
2566         return;
2567     }
2568 
2569     switch (opc) {
2570     case OPC_ADD:
2571         {
2572             TCGv t0 = tcg_temp_new();
2573             TCGv t1 = tcg_temp_new();
2574             TCGv t2 = tcg_temp_new();
2575             TCGLabel *l1 = gen_new_label();
2576 
2577             gen_load_gpr(t1, rs);
2578             gen_load_gpr(t2, rt);
2579             tcg_gen_add_tl(t0, t1, t2);
2580             tcg_gen_ext32s_tl(t0, t0);
2581             tcg_gen_xor_tl(t1, t1, t2);
2582             tcg_gen_xor_tl(t2, t0, t2);
2583             tcg_gen_andc_tl(t1, t2, t1);
2584             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2585             /* operands of same sign, result different sign */
2586             generate_exception(ctx, EXCP_OVERFLOW);
2587             gen_set_label(l1);
2588             gen_store_gpr(t0, rd);
2589         }
2590         break;
2591     case OPC_ADDU:
2592         if (rs != 0 && rt != 0) {
2593             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2594             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2595         } else if (rs == 0 && rt != 0) {
2596             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2597         } else if (rs != 0 && rt == 0) {
2598             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2599         } else {
2600             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2601         }
2602         break;
2603     case OPC_SUB:
2604         {
2605             TCGv t0 = tcg_temp_new();
2606             TCGv t1 = tcg_temp_new();
2607             TCGv t2 = tcg_temp_new();
2608             TCGLabel *l1 = gen_new_label();
2609 
2610             gen_load_gpr(t1, rs);
2611             gen_load_gpr(t2, rt);
2612             tcg_gen_sub_tl(t0, t1, t2);
2613             tcg_gen_ext32s_tl(t0, t0);
2614             tcg_gen_xor_tl(t2, t1, t2);
2615             tcg_gen_xor_tl(t1, t0, t1);
2616             tcg_gen_and_tl(t1, t1, t2);
2617             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2618             /*
2619              * operands of different sign, first operand and the result
2620              * of different sign
2621              */
2622             generate_exception(ctx, EXCP_OVERFLOW);
2623             gen_set_label(l1);
2624             gen_store_gpr(t0, rd);
2625         }
2626         break;
2627     case OPC_SUBU:
2628         if (rs != 0 && rt != 0) {
2629             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2630             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2631         } else if (rs == 0 && rt != 0) {
2632             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2633             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2634         } else if (rs != 0 && rt == 0) {
2635             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2636         } else {
2637             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2638         }
2639         break;
2640 #if defined(TARGET_MIPS64)
2641     case OPC_DADD:
2642         {
2643             TCGv t0 = tcg_temp_new();
2644             TCGv t1 = tcg_temp_new();
2645             TCGv t2 = tcg_temp_new();
2646             TCGLabel *l1 = gen_new_label();
2647 
2648             gen_load_gpr(t1, rs);
2649             gen_load_gpr(t2, rt);
2650             tcg_gen_add_tl(t0, t1, t2);
2651             tcg_gen_xor_tl(t1, t1, t2);
2652             tcg_gen_xor_tl(t2, t0, t2);
2653             tcg_gen_andc_tl(t1, t2, t1);
2654             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2655             /* operands of same sign, result different sign */
2656             generate_exception(ctx, EXCP_OVERFLOW);
2657             gen_set_label(l1);
2658             gen_store_gpr(t0, rd);
2659         }
2660         break;
2661     case OPC_DADDU:
2662         if (rs != 0 && rt != 0) {
2663             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2664         } else if (rs == 0 && rt != 0) {
2665             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2666         } else if (rs != 0 && rt == 0) {
2667             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2668         } else {
2669             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2670         }
2671         break;
2672     case OPC_DSUB:
2673         {
2674             TCGv t0 = tcg_temp_new();
2675             TCGv t1 = tcg_temp_new();
2676             TCGv t2 = tcg_temp_new();
2677             TCGLabel *l1 = gen_new_label();
2678 
2679             gen_load_gpr(t1, rs);
2680             gen_load_gpr(t2, rt);
2681             tcg_gen_sub_tl(t0, t1, t2);
2682             tcg_gen_xor_tl(t2, t1, t2);
2683             tcg_gen_xor_tl(t1, t0, t1);
2684             tcg_gen_and_tl(t1, t1, t2);
2685             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2686             /*
2687              * Operands of different sign, first operand and result different
2688              * sign.
2689              */
2690             generate_exception(ctx, EXCP_OVERFLOW);
2691             gen_set_label(l1);
2692             gen_store_gpr(t0, rd);
2693         }
2694         break;
2695     case OPC_DSUBU:
2696         if (rs != 0 && rt != 0) {
2697             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2698         } else if (rs == 0 && rt != 0) {
2699             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2700         } else if (rs != 0 && rt == 0) {
2701             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2702         } else {
2703             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2704         }
2705         break;
2706 #endif
2707     case OPC_MUL:
2708         if (likely(rs != 0 && rt != 0)) {
2709             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2710             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2711         } else {
2712             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2713         }
2714         break;
2715     }
2716 }
2717 
2718 /* Conditional move */
gen_cond_move(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2719 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2720                           int rd, int rs, int rt)
2721 {
2722     TCGv t0, t1, t2;
2723 
2724     if (rd == 0) {
2725         /* If no destination, treat it as a NOP. */
2726         return;
2727     }
2728 
2729     t0 = tcg_temp_new();
2730     gen_load_gpr(t0, rt);
2731     t1 = tcg_constant_tl(0);
2732     t2 = tcg_temp_new();
2733     gen_load_gpr(t2, rs);
2734     switch (opc) {
2735     case OPC_MOVN:
2736         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2737         break;
2738     case OPC_MOVZ:
2739         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2740         break;
2741     case OPC_SELNEZ:
2742         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2743         break;
2744     case OPC_SELEQZ:
2745         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2746         break;
2747     }
2748 }
2749 
2750 /* Logic */
gen_logic(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2751 static void gen_logic(DisasContext *ctx, uint32_t opc,
2752                       int rd, int rs, int rt)
2753 {
2754     if (rd == 0) {
2755         /* If no destination, treat it as a NOP. */
2756         return;
2757     }
2758 
2759     switch (opc) {
2760     case OPC_AND:
2761         if (likely(rs != 0 && rt != 0)) {
2762             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2763         } else {
2764             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2765         }
2766         break;
2767     case OPC_NOR:
2768         if (rs != 0 && rt != 0) {
2769             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2770         } else if (rs == 0 && rt != 0) {
2771             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2772         } else if (rs != 0 && rt == 0) {
2773             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2774         } else {
2775             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2776         }
2777         break;
2778     case OPC_OR:
2779         if (likely(rs != 0 && rt != 0)) {
2780             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2781         } else if (rs == 0 && rt != 0) {
2782             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2783         } else if (rs != 0 && rt == 0) {
2784             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2785         } else {
2786             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2787         }
2788         break;
2789     case OPC_XOR:
2790         if (likely(rs != 0 && rt != 0)) {
2791             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2792         } else if (rs == 0 && rt != 0) {
2793             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2794         } else if (rs != 0 && rt == 0) {
2795             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2796         } else {
2797             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2798         }
2799         break;
2800     }
2801 }
2802 
2803 /* Set on lower than */
gen_slt(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2804 static void gen_slt(DisasContext *ctx, uint32_t opc,
2805                     int rd, int rs, int rt)
2806 {
2807     TCGv t0, t1;
2808 
2809     if (rd == 0) {
2810         /* If no destination, treat it as a NOP. */
2811         return;
2812     }
2813 
2814     t0 = tcg_temp_new();
2815     t1 = tcg_temp_new();
2816     gen_load_gpr(t0, rs);
2817     gen_load_gpr(t1, rt);
2818     switch (opc) {
2819     case OPC_SLT:
2820         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2821         break;
2822     case OPC_SLTU:
2823         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2824         break;
2825     }
2826 }
2827 
2828 /* Shifts */
gen_shift(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2829 static void gen_shift(DisasContext *ctx, uint32_t opc,
2830                       int rd, int rs, int rt)
2831 {
2832     TCGv t0, t1;
2833 
2834     if (rd == 0) {
2835         /*
2836          * If no destination, treat it as a NOP.
2837          * For add & sub, we must generate the overflow exception when needed.
2838          */
2839         return;
2840     }
2841 
2842     t0 = tcg_temp_new();
2843     t1 = tcg_temp_new();
2844     gen_load_gpr(t0, rs);
2845     gen_load_gpr(t1, rt);
2846     switch (opc) {
2847     case OPC_SLLV:
2848         tcg_gen_andi_tl(t0, t0, 0x1f);
2849         tcg_gen_shl_tl(t0, t1, t0);
2850         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2851         break;
2852     case OPC_SRAV:
2853         tcg_gen_andi_tl(t0, t0, 0x1f);
2854         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2855         break;
2856     case OPC_SRLV:
2857         tcg_gen_ext32u_tl(t1, t1);
2858         tcg_gen_andi_tl(t0, t0, 0x1f);
2859         tcg_gen_shr_tl(t0, t1, t0);
2860         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2861         break;
2862     case OPC_ROTRV:
2863         {
2864             TCGv_i32 t2 = tcg_temp_new_i32();
2865             TCGv_i32 t3 = tcg_temp_new_i32();
2866 
2867             tcg_gen_trunc_tl_i32(t2, t0);
2868             tcg_gen_trunc_tl_i32(t3, t1);
2869             tcg_gen_andi_i32(t2, t2, 0x1f);
2870             tcg_gen_rotr_i32(t2, t3, t2);
2871             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2872         }
2873         break;
2874 #if defined(TARGET_MIPS64)
2875     case OPC_DSLLV:
2876         tcg_gen_andi_tl(t0, t0, 0x3f);
2877         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2878         break;
2879     case OPC_DSRAV:
2880         tcg_gen_andi_tl(t0, t0, 0x3f);
2881         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2882         break;
2883     case OPC_DSRLV:
2884         tcg_gen_andi_tl(t0, t0, 0x3f);
2885         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2886         break;
2887     case OPC_DROTRV:
2888         tcg_gen_andi_tl(t0, t0, 0x3f);
2889         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2890         break;
2891 #endif
2892     }
2893 }
2894 
2895 /* Arithmetic on HI/LO registers */
gen_HILO(DisasContext * ctx,uint32_t opc,int acc,int reg)2896 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2897 {
2898     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2899         /* Treat as NOP. */
2900         return;
2901     }
2902 
2903     if (acc != 0) {
2904         check_dsp(ctx);
2905     }
2906 
2907     switch (opc) {
2908     case OPC_MFHI:
2909 #if defined(TARGET_MIPS64)
2910         if (acc != 0) {
2911             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2912         } else
2913 #endif
2914         {
2915             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2916         }
2917         break;
2918     case OPC_MFLO:
2919 #if defined(TARGET_MIPS64)
2920         if (acc != 0) {
2921             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2922         } else
2923 #endif
2924         {
2925             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2926         }
2927         break;
2928     case OPC_MTHI:
2929         if (reg != 0) {
2930 #if defined(TARGET_MIPS64)
2931             if (acc != 0) {
2932                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2933             } else
2934 #endif
2935             {
2936                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2937             }
2938         } else {
2939             tcg_gen_movi_tl(cpu_HI[acc], 0);
2940         }
2941         break;
2942     case OPC_MTLO:
2943         if (reg != 0) {
2944 #if defined(TARGET_MIPS64)
2945             if (acc != 0) {
2946                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2947             } else
2948 #endif
2949             {
2950                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2951             }
2952         } else {
2953             tcg_gen_movi_tl(cpu_LO[acc], 0);
2954         }
2955         break;
2956     }
2957 }
2958 
gen_r6_ld(target_long addr,int reg,int memidx,MemOp memop)2959 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2960                              MemOp memop)
2961 {
2962     TCGv t0 = tcg_temp_new();
2963     tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop);
2964     gen_store_gpr(t0, reg);
2965 }
2966 
gen_pcrel(DisasContext * ctx,int opc,target_ulong pc,int rs)2967 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
2968                              int rs)
2969 {
2970     target_long offset;
2971     target_long addr;
2972 
2973     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
2974     case OPC_ADDIUPC:
2975         if (rs != 0) {
2976             offset = sextract32(ctx->opcode << 2, 0, 21);
2977             addr = addr_add(ctx, pc, offset);
2978             tcg_gen_movi_tl(cpu_gpr[rs], addr);
2979         }
2980         break;
2981     case R6_OPC_LWPC:
2982         offset = sextract32(ctx->opcode << 2, 0, 21);
2983         addr = addr_add(ctx, pc, offset);
2984         gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL);
2985         break;
2986 #if defined(TARGET_MIPS64)
2987     case OPC_LWUPC:
2988         check_mips_64(ctx);
2989         offset = sextract32(ctx->opcode << 2, 0, 21);
2990         addr = addr_add(ctx, pc, offset);
2991         gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL);
2992         break;
2993 #endif
2994     default:
2995         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
2996         case OPC_AUIPC:
2997             if (rs != 0) {
2998                 offset = sextract32(ctx->opcode, 0, 16) << 16;
2999                 addr = addr_add(ctx, pc, offset);
3000                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3001             }
3002             break;
3003         case OPC_ALUIPC:
3004             if (rs != 0) {
3005                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3006                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3007                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3008             }
3009             break;
3010 #if defined(TARGET_MIPS64)
3011         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3012         case R6_OPC_LDPC + (1 << 16):
3013         case R6_OPC_LDPC + (2 << 16):
3014         case R6_OPC_LDPC + (3 << 16):
3015             check_mips_64(ctx);
3016             offset = sextract32(ctx->opcode << 3, 0, 21);
3017             addr = addr_add(ctx, (pc & ~0x7), offset);
3018             gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
3019             break;
3020 #endif
3021         default:
3022             MIPS_INVAL("OPC_PCREL");
3023             gen_reserved_instruction(ctx);
3024             break;
3025         }
3026         break;
3027     }
3028 }
3029 
gen_r6_muldiv(DisasContext * ctx,int opc,int rd,int rs,int rt)3030 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3031 {
3032     TCGv t0, t1;
3033 
3034     if (rd == 0) {
3035         /* Treat as NOP. */
3036         return;
3037     }
3038 
3039     t0 = tcg_temp_new();
3040     t1 = tcg_temp_new();
3041 
3042     gen_load_gpr(t0, rs);
3043     gen_load_gpr(t1, rt);
3044 
3045     switch (opc) {
3046     case R6_OPC_DIV:
3047         {
3048             TCGv t2 = tcg_temp_new();
3049             TCGv t3 = tcg_temp_new();
3050             tcg_gen_ext32s_tl(t0, t0);
3051             tcg_gen_ext32s_tl(t1, t1);
3052             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3053             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3054             tcg_gen_and_tl(t2, t2, t3);
3055             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3056             tcg_gen_or_tl(t2, t2, t3);
3057             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3058             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3059             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3060         }
3061         break;
3062     case R6_OPC_MOD:
3063         {
3064             TCGv t2 = tcg_temp_new();
3065             TCGv t3 = tcg_temp_new();
3066             tcg_gen_ext32s_tl(t0, t0);
3067             tcg_gen_ext32s_tl(t1, t1);
3068             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3069             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3070             tcg_gen_and_tl(t2, t2, t3);
3071             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3072             tcg_gen_or_tl(t2, t2, t3);
3073             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3074             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3075             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3076         }
3077         break;
3078     case R6_OPC_DIVU:
3079         {
3080             tcg_gen_ext32u_tl(t0, t0);
3081             tcg_gen_ext32u_tl(t1, t1);
3082             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3083                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3084             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3085             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3086         }
3087         break;
3088     case R6_OPC_MODU:
3089         {
3090             tcg_gen_ext32u_tl(t0, t0);
3091             tcg_gen_ext32u_tl(t1, t1);
3092             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3093                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3094             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3095             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3096         }
3097         break;
3098     case R6_OPC_MUL:
3099         {
3100             TCGv_i32 t2 = tcg_temp_new_i32();
3101             TCGv_i32 t3 = tcg_temp_new_i32();
3102             tcg_gen_trunc_tl_i32(t2, t0);
3103             tcg_gen_trunc_tl_i32(t3, t1);
3104             tcg_gen_mul_i32(t2, t2, t3);
3105             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3106         }
3107         break;
3108     case R6_OPC_MUH:
3109         {
3110             TCGv_i32 t2 = tcg_temp_new_i32();
3111             TCGv_i32 t3 = tcg_temp_new_i32();
3112             tcg_gen_trunc_tl_i32(t2, t0);
3113             tcg_gen_trunc_tl_i32(t3, t1);
3114             tcg_gen_muls2_i32(t2, t3, t2, t3);
3115             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3116         }
3117         break;
3118     case R6_OPC_MULU:
3119         {
3120             TCGv_i32 t2 = tcg_temp_new_i32();
3121             TCGv_i32 t3 = tcg_temp_new_i32();
3122             tcg_gen_trunc_tl_i32(t2, t0);
3123             tcg_gen_trunc_tl_i32(t3, t1);
3124             tcg_gen_mul_i32(t2, t2, t3);
3125             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3126         }
3127         break;
3128     case R6_OPC_MUHU:
3129         {
3130             TCGv_i32 t2 = tcg_temp_new_i32();
3131             TCGv_i32 t3 = tcg_temp_new_i32();
3132             tcg_gen_trunc_tl_i32(t2, t0);
3133             tcg_gen_trunc_tl_i32(t3, t1);
3134             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3135             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3136         }
3137         break;
3138 #if defined(TARGET_MIPS64)
3139     case R6_OPC_DDIV:
3140         {
3141             TCGv t2 = tcg_temp_new();
3142             TCGv t3 = tcg_temp_new();
3143             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3144             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3145             tcg_gen_and_tl(t2, t2, t3);
3146             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3147             tcg_gen_or_tl(t2, t2, t3);
3148             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3149             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3150         }
3151         break;
3152     case R6_OPC_DMOD:
3153         {
3154             TCGv t2 = tcg_temp_new();
3155             TCGv t3 = tcg_temp_new();
3156             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3157             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3158             tcg_gen_and_tl(t2, t2, t3);
3159             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3160             tcg_gen_or_tl(t2, t2, t3);
3161             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3162             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3163         }
3164         break;
3165     case R6_OPC_DDIVU:
3166         {
3167             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3168                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3169             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3170         }
3171         break;
3172     case R6_OPC_DMODU:
3173         {
3174             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3175                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3176             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3177         }
3178         break;
3179     case R6_OPC_DMUL:
3180         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3181         break;
3182     case R6_OPC_DMUH:
3183         {
3184             TCGv t2 = tcg_temp_new();
3185             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3186         }
3187         break;
3188     case R6_OPC_DMULU:
3189         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3190         break;
3191     case R6_OPC_DMUHU:
3192         {
3193             TCGv t2 = tcg_temp_new();
3194             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3195         }
3196         break;
3197 #endif
3198     default:
3199         MIPS_INVAL("r6 mul/div");
3200         gen_reserved_instruction(ctx);
3201         break;
3202     }
3203 }
3204 
3205 #if defined(TARGET_MIPS64)
gen_div1_tx79(DisasContext * ctx,uint32_t opc,int rs,int rt)3206 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3207 {
3208     TCGv t0, t1;
3209 
3210     t0 = tcg_temp_new();
3211     t1 = tcg_temp_new();
3212 
3213     gen_load_gpr(t0, rs);
3214     gen_load_gpr(t1, rt);
3215 
3216     switch (opc) {
3217     case MMI_OPC_DIV1:
3218         {
3219             TCGv t2 = tcg_temp_new();
3220             TCGv t3 = tcg_temp_new();
3221             tcg_gen_ext32s_tl(t0, t0);
3222             tcg_gen_ext32s_tl(t1, t1);
3223             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3224             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3225             tcg_gen_and_tl(t2, t2, t3);
3226             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3227             tcg_gen_or_tl(t2, t2, t3);
3228             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3229             tcg_gen_div_tl(cpu_LO[1], t0, t1);
3230             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3231             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3232             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3233         }
3234         break;
3235     case MMI_OPC_DIVU1:
3236         {
3237             TCGv t2 = tcg_constant_tl(0);
3238             TCGv t3 = tcg_constant_tl(1);
3239             tcg_gen_ext32u_tl(t0, t0);
3240             tcg_gen_ext32u_tl(t1, t1);
3241             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3242             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3243             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3244             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3245             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3246         }
3247         break;
3248     default:
3249         MIPS_INVAL("div1 TX79");
3250         gen_reserved_instruction(ctx);
3251         break;
3252     }
3253 }
3254 #endif
3255 
gen_muldiv(DisasContext * ctx,uint32_t opc,int acc,int rs,int rt)3256 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3257                        int acc, int rs, int rt)
3258 {
3259     TCGv t0, t1;
3260 
3261     t0 = tcg_temp_new();
3262     t1 = tcg_temp_new();
3263 
3264     gen_load_gpr(t0, rs);
3265     gen_load_gpr(t1, rt);
3266 
3267     if (acc != 0) {
3268         check_dsp(ctx);
3269     }
3270 
3271     switch (opc) {
3272     case OPC_DIV:
3273         {
3274             TCGv t2 = tcg_temp_new();
3275             TCGv t3 = tcg_temp_new();
3276             tcg_gen_ext32s_tl(t0, t0);
3277             tcg_gen_ext32s_tl(t1, t1);
3278             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3279             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3280             tcg_gen_and_tl(t2, t2, t3);
3281             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3282             tcg_gen_or_tl(t2, t2, t3);
3283             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3284             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3285             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3286             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3287             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3288         }
3289         break;
3290     case OPC_DIVU:
3291         {
3292             TCGv t2 = tcg_constant_tl(0);
3293             TCGv t3 = tcg_constant_tl(1);
3294             tcg_gen_ext32u_tl(t0, t0);
3295             tcg_gen_ext32u_tl(t1, t1);
3296             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3297             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3298             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3299             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3300             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3301         }
3302         break;
3303     case OPC_MULT:
3304         {
3305             TCGv_i32 t2 = tcg_temp_new_i32();
3306             TCGv_i32 t3 = tcg_temp_new_i32();
3307             tcg_gen_trunc_tl_i32(t2, t0);
3308             tcg_gen_trunc_tl_i32(t3, t1);
3309             tcg_gen_muls2_i32(t2, t3, t2, t3);
3310             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3311             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3312         }
3313         break;
3314     case OPC_MULTU:
3315         {
3316             TCGv_i32 t2 = tcg_temp_new_i32();
3317             TCGv_i32 t3 = tcg_temp_new_i32();
3318             tcg_gen_trunc_tl_i32(t2, t0);
3319             tcg_gen_trunc_tl_i32(t3, t1);
3320             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3321             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3322             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3323         }
3324         break;
3325 #if defined(TARGET_MIPS64)
3326     case OPC_DDIV:
3327         {
3328             TCGv t2 = tcg_temp_new();
3329             TCGv t3 = tcg_temp_new();
3330             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3331             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3332             tcg_gen_and_tl(t2, t2, t3);
3333             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3334             tcg_gen_or_tl(t2, t2, t3);
3335             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3336             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3337             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3338         }
3339         break;
3340     case OPC_DDIVU:
3341         {
3342             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3343                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3344             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3345             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3346         }
3347         break;
3348     case OPC_DMULT:
3349         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3350         break;
3351     case OPC_DMULTU:
3352         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3353         break;
3354 #endif
3355     case OPC_MADD:
3356         {
3357             TCGv_i64 t2 = tcg_temp_new_i64();
3358             TCGv_i64 t3 = tcg_temp_new_i64();
3359 
3360             tcg_gen_ext_tl_i64(t2, t0);
3361             tcg_gen_ext_tl_i64(t3, t1);
3362             tcg_gen_mul_i64(t2, t2, t3);
3363             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3364             tcg_gen_add_i64(t2, t2, t3);
3365             gen_move_low32(cpu_LO[acc], t2);
3366             gen_move_high32(cpu_HI[acc], t2);
3367         }
3368         break;
3369     case OPC_MADDU:
3370         {
3371             TCGv_i64 t2 = tcg_temp_new_i64();
3372             TCGv_i64 t3 = tcg_temp_new_i64();
3373 
3374             tcg_gen_ext32u_tl(t0, t0);
3375             tcg_gen_ext32u_tl(t1, t1);
3376             tcg_gen_extu_tl_i64(t2, t0);
3377             tcg_gen_extu_tl_i64(t3, t1);
3378             tcg_gen_mul_i64(t2, t2, t3);
3379             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3380             tcg_gen_add_i64(t2, t2, t3);
3381             gen_move_low32(cpu_LO[acc], t2);
3382             gen_move_high32(cpu_HI[acc], t2);
3383         }
3384         break;
3385     case OPC_MSUB:
3386         {
3387             TCGv_i64 t2 = tcg_temp_new_i64();
3388             TCGv_i64 t3 = tcg_temp_new_i64();
3389 
3390             tcg_gen_ext_tl_i64(t2, t0);
3391             tcg_gen_ext_tl_i64(t3, t1);
3392             tcg_gen_mul_i64(t2, t2, t3);
3393             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3394             tcg_gen_sub_i64(t2, t3, t2);
3395             gen_move_low32(cpu_LO[acc], t2);
3396             gen_move_high32(cpu_HI[acc], t2);
3397         }
3398         break;
3399     case OPC_MSUBU:
3400         {
3401             TCGv_i64 t2 = tcg_temp_new_i64();
3402             TCGv_i64 t3 = tcg_temp_new_i64();
3403 
3404             tcg_gen_ext32u_tl(t0, t0);
3405             tcg_gen_ext32u_tl(t1, t1);
3406             tcg_gen_extu_tl_i64(t2, t0);
3407             tcg_gen_extu_tl_i64(t3, t1);
3408             tcg_gen_mul_i64(t2, t2, t3);
3409             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3410             tcg_gen_sub_i64(t2, t3, t2);
3411             gen_move_low32(cpu_LO[acc], t2);
3412             gen_move_high32(cpu_HI[acc], t2);
3413         }
3414         break;
3415     default:
3416         MIPS_INVAL("mul/div");
3417         gen_reserved_instruction(ctx);
3418         break;
3419     }
3420 }
3421 
3422 /*
3423  * These MULT[U] and MADD[U] instructions implemented in for example
3424  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3425  * architectures are special three-operand variants with the syntax
3426  *
3427  *     MULT[U][1] rd, rs, rt
3428  *
3429  * such that
3430  *
3431  *     (rd, LO, HI) <- rs * rt
3432  *
3433  * and
3434  *
3435  *     MADD[U][1] rd, rs, rt
3436  *
3437  * such that
3438  *
3439  *     (rd, LO, HI) <- (LO, HI) + rs * rt
3440  *
3441  * where the low-order 32-bits of the result is placed into both the
3442  * GPR rd and the special register LO. The high-order 32-bits of the
3443  * result is placed into the special register HI.
3444  *
3445  * If the GPR rd is omitted in assembly language, it is taken to be 0,
3446  * which is the zero register that always reads as 0.
3447  */
gen_mul_txx9(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3448 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3449                          int rd, int rs, int rt)
3450 {
3451     TCGv t0 = tcg_temp_new();
3452     TCGv t1 = tcg_temp_new();
3453     int acc = 0;
3454 
3455     gen_load_gpr(t0, rs);
3456     gen_load_gpr(t1, rt);
3457 
3458     switch (opc) {
3459     case MMI_OPC_MULT1:
3460         acc = 1;
3461         /* Fall through */
3462     case OPC_MULT:
3463         {
3464             TCGv_i32 t2 = tcg_temp_new_i32();
3465             TCGv_i32 t3 = tcg_temp_new_i32();
3466             tcg_gen_trunc_tl_i32(t2, t0);
3467             tcg_gen_trunc_tl_i32(t3, t1);
3468             tcg_gen_muls2_i32(t2, t3, t2, t3);
3469             if (rd) {
3470                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3471             }
3472             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3473             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3474         }
3475         break;
3476     case MMI_OPC_MULTU1:
3477         acc = 1;
3478         /* Fall through */
3479     case OPC_MULTU:
3480         {
3481             TCGv_i32 t2 = tcg_temp_new_i32();
3482             TCGv_i32 t3 = tcg_temp_new_i32();
3483             tcg_gen_trunc_tl_i32(t2, t0);
3484             tcg_gen_trunc_tl_i32(t3, t1);
3485             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3486             if (rd) {
3487                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3488             }
3489             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3490             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3491         }
3492         break;
3493     case MMI_OPC_MADD1:
3494         acc = 1;
3495         /* Fall through */
3496     case MMI_OPC_MADD:
3497         {
3498             TCGv_i64 t2 = tcg_temp_new_i64();
3499             TCGv_i64 t3 = tcg_temp_new_i64();
3500 
3501             tcg_gen_ext_tl_i64(t2, t0);
3502             tcg_gen_ext_tl_i64(t3, t1);
3503             tcg_gen_mul_i64(t2, t2, t3);
3504             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3505             tcg_gen_add_i64(t2, t2, t3);
3506             gen_move_low32(cpu_LO[acc], t2);
3507             gen_move_high32(cpu_HI[acc], t2);
3508             if (rd) {
3509                 gen_move_low32(cpu_gpr[rd], t2);
3510             }
3511         }
3512         break;
3513     case MMI_OPC_MADDU1:
3514         acc = 1;
3515         /* Fall through */
3516     case MMI_OPC_MADDU:
3517         {
3518             TCGv_i64 t2 = tcg_temp_new_i64();
3519             TCGv_i64 t3 = tcg_temp_new_i64();
3520 
3521             tcg_gen_ext32u_tl(t0, t0);
3522             tcg_gen_ext32u_tl(t1, t1);
3523             tcg_gen_extu_tl_i64(t2, t0);
3524             tcg_gen_extu_tl_i64(t3, t1);
3525             tcg_gen_mul_i64(t2, t2, t3);
3526             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3527             tcg_gen_add_i64(t2, t2, t3);
3528             gen_move_low32(cpu_LO[acc], t2);
3529             gen_move_high32(cpu_HI[acc], t2);
3530             if (rd) {
3531                 gen_move_low32(cpu_gpr[rd], t2);
3532             }
3533         }
3534         break;
3535     default:
3536         MIPS_INVAL("mul/madd TXx9");
3537         gen_reserved_instruction(ctx);
3538         break;
3539     }
3540 }
3541 
gen_cl(DisasContext * ctx,uint32_t opc,int rd,int rs)3542 static void gen_cl(DisasContext *ctx, uint32_t opc,
3543                    int rd, int rs)
3544 {
3545     TCGv t0;
3546 
3547     if (rd == 0) {
3548         /* Treat as NOP. */
3549         return;
3550     }
3551     t0 = cpu_gpr[rd];
3552     gen_load_gpr(t0, rs);
3553 
3554     switch (opc) {
3555     case OPC_CLO:
3556     case R6_OPC_CLO:
3557 #if defined(TARGET_MIPS64)
3558     case OPC_DCLO:
3559     case R6_OPC_DCLO:
3560 #endif
3561         tcg_gen_not_tl(t0, t0);
3562         break;
3563     }
3564 
3565     switch (opc) {
3566     case OPC_CLO:
3567     case R6_OPC_CLO:
3568     case OPC_CLZ:
3569     case R6_OPC_CLZ:
3570         tcg_gen_ext32u_tl(t0, t0);
3571         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3572         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3573         break;
3574 #if defined(TARGET_MIPS64)
3575     case OPC_DCLO:
3576     case R6_OPC_DCLO:
3577     case OPC_DCLZ:
3578     case R6_OPC_DCLZ:
3579         tcg_gen_clzi_i64(t0, t0, 64);
3580         break;
3581 #endif
3582     }
3583 }
3584 
3585 /* Loongson multimedia instructions */
gen_loongson_multimedia(DisasContext * ctx,int rd,int rs,int rt)3586 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3587 {
3588     uint32_t opc, shift_max;
3589     TCGv_i64 t0, t1;
3590     TCGCond cond;
3591 
3592     opc = MASK_LMMI(ctx->opcode);
3593     check_cp1_enabled(ctx);
3594 
3595     t0 = tcg_temp_new_i64();
3596     t1 = tcg_temp_new_i64();
3597     gen_load_fpr64(ctx, t0, rs);
3598     gen_load_fpr64(ctx, t1, rt);
3599 
3600     switch (opc) {
3601     case OPC_PADDSH:
3602         gen_helper_paddsh(t0, t0, t1);
3603         break;
3604     case OPC_PADDUSH:
3605         gen_helper_paddush(t0, t0, t1);
3606         break;
3607     case OPC_PADDH:
3608         gen_helper_paddh(t0, t0, t1);
3609         break;
3610     case OPC_PADDW:
3611         gen_helper_paddw(t0, t0, t1);
3612         break;
3613     case OPC_PADDSB:
3614         gen_helper_paddsb(t0, t0, t1);
3615         break;
3616     case OPC_PADDUSB:
3617         gen_helper_paddusb(t0, t0, t1);
3618         break;
3619     case OPC_PADDB:
3620         gen_helper_paddb(t0, t0, t1);
3621         break;
3622 
3623     case OPC_PSUBSH:
3624         gen_helper_psubsh(t0, t0, t1);
3625         break;
3626     case OPC_PSUBUSH:
3627         gen_helper_psubush(t0, t0, t1);
3628         break;
3629     case OPC_PSUBH:
3630         gen_helper_psubh(t0, t0, t1);
3631         break;
3632     case OPC_PSUBW:
3633         gen_helper_psubw(t0, t0, t1);
3634         break;
3635     case OPC_PSUBSB:
3636         gen_helper_psubsb(t0, t0, t1);
3637         break;
3638     case OPC_PSUBUSB:
3639         gen_helper_psubusb(t0, t0, t1);
3640         break;
3641     case OPC_PSUBB:
3642         gen_helper_psubb(t0, t0, t1);
3643         break;
3644 
3645     case OPC_PSHUFH:
3646         gen_helper_pshufh(t0, t0, t1);
3647         break;
3648     case OPC_PACKSSWH:
3649         gen_helper_packsswh(t0, t0, t1);
3650         break;
3651     case OPC_PACKSSHB:
3652         gen_helper_packsshb(t0, t0, t1);
3653         break;
3654     case OPC_PACKUSHB:
3655         gen_helper_packushb(t0, t0, t1);
3656         break;
3657 
3658     case OPC_PUNPCKLHW:
3659         gen_helper_punpcklhw(t0, t0, t1);
3660         break;
3661     case OPC_PUNPCKHHW:
3662         gen_helper_punpckhhw(t0, t0, t1);
3663         break;
3664     case OPC_PUNPCKLBH:
3665         gen_helper_punpcklbh(t0, t0, t1);
3666         break;
3667     case OPC_PUNPCKHBH:
3668         gen_helper_punpckhbh(t0, t0, t1);
3669         break;
3670     case OPC_PUNPCKLWD:
3671         gen_helper_punpcklwd(t0, t0, t1);
3672         break;
3673     case OPC_PUNPCKHWD:
3674         gen_helper_punpckhwd(t0, t0, t1);
3675         break;
3676 
3677     case OPC_PAVGH:
3678         gen_helper_pavgh(t0, t0, t1);
3679         break;
3680     case OPC_PAVGB:
3681         gen_helper_pavgb(t0, t0, t1);
3682         break;
3683     case OPC_PMAXSH:
3684         gen_helper_pmaxsh(t0, t0, t1);
3685         break;
3686     case OPC_PMINSH:
3687         gen_helper_pminsh(t0, t0, t1);
3688         break;
3689     case OPC_PMAXUB:
3690         gen_helper_pmaxub(t0, t0, t1);
3691         break;
3692     case OPC_PMINUB:
3693         gen_helper_pminub(t0, t0, t1);
3694         break;
3695 
3696     case OPC_PCMPEQW:
3697         gen_helper_pcmpeqw(t0, t0, t1);
3698         break;
3699     case OPC_PCMPGTW:
3700         gen_helper_pcmpgtw(t0, t0, t1);
3701         break;
3702     case OPC_PCMPEQH:
3703         gen_helper_pcmpeqh(t0, t0, t1);
3704         break;
3705     case OPC_PCMPGTH:
3706         gen_helper_pcmpgth(t0, t0, t1);
3707         break;
3708     case OPC_PCMPEQB:
3709         gen_helper_pcmpeqb(t0, t0, t1);
3710         break;
3711     case OPC_PCMPGTB:
3712         gen_helper_pcmpgtb(t0, t0, t1);
3713         break;
3714 
3715     case OPC_PSLLW:
3716         gen_helper_psllw(t0, t0, t1);
3717         break;
3718     case OPC_PSLLH:
3719         gen_helper_psllh(t0, t0, t1);
3720         break;
3721     case OPC_PSRLW:
3722         gen_helper_psrlw(t0, t0, t1);
3723         break;
3724     case OPC_PSRLH:
3725         gen_helper_psrlh(t0, t0, t1);
3726         break;
3727     case OPC_PSRAW:
3728         gen_helper_psraw(t0, t0, t1);
3729         break;
3730     case OPC_PSRAH:
3731         gen_helper_psrah(t0, t0, t1);
3732         break;
3733 
3734     case OPC_PMULLH:
3735         gen_helper_pmullh(t0, t0, t1);
3736         break;
3737     case OPC_PMULHH:
3738         gen_helper_pmulhh(t0, t0, t1);
3739         break;
3740     case OPC_PMULHUH:
3741         gen_helper_pmulhuh(t0, t0, t1);
3742         break;
3743     case OPC_PMADDHW:
3744         gen_helper_pmaddhw(t0, t0, t1);
3745         break;
3746 
3747     case OPC_PASUBUB:
3748         gen_helper_pasubub(t0, t0, t1);
3749         break;
3750     case OPC_BIADD:
3751         gen_helper_biadd(t0, t0);
3752         break;
3753     case OPC_PMOVMSKB:
3754         gen_helper_pmovmskb(t0, t0);
3755         break;
3756 
3757     case OPC_PADDD:
3758         tcg_gen_add_i64(t0, t0, t1);
3759         break;
3760     case OPC_PSUBD:
3761         tcg_gen_sub_i64(t0, t0, t1);
3762         break;
3763     case OPC_XOR_CP2:
3764         tcg_gen_xor_i64(t0, t0, t1);
3765         break;
3766     case OPC_NOR_CP2:
3767         tcg_gen_nor_i64(t0, t0, t1);
3768         break;
3769     case OPC_AND_CP2:
3770         tcg_gen_and_i64(t0, t0, t1);
3771         break;
3772     case OPC_OR_CP2:
3773         tcg_gen_or_i64(t0, t0, t1);
3774         break;
3775 
3776     case OPC_PANDN:
3777         tcg_gen_andc_i64(t0, t1, t0);
3778         break;
3779 
3780     case OPC_PINSRH_0:
3781         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3782         break;
3783     case OPC_PINSRH_1:
3784         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3785         break;
3786     case OPC_PINSRH_2:
3787         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3788         break;
3789     case OPC_PINSRH_3:
3790         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3791         break;
3792 
3793     case OPC_PEXTRH:
3794         tcg_gen_andi_i64(t1, t1, 3);
3795         tcg_gen_shli_i64(t1, t1, 4);
3796         tcg_gen_shr_i64(t0, t0, t1);
3797         tcg_gen_ext16u_i64(t0, t0);
3798         break;
3799 
3800     case OPC_ADDU_CP2:
3801         tcg_gen_add_i64(t0, t0, t1);
3802         tcg_gen_ext32s_i64(t0, t0);
3803         break;
3804     case OPC_SUBU_CP2:
3805         tcg_gen_sub_i64(t0, t0, t1);
3806         tcg_gen_ext32s_i64(t0, t0);
3807         break;
3808 
3809     case OPC_SLL_CP2:
3810         shift_max = 32;
3811         goto do_shift;
3812     case OPC_SRL_CP2:
3813         shift_max = 32;
3814         goto do_shift;
3815     case OPC_SRA_CP2:
3816         shift_max = 32;
3817         goto do_shift;
3818     case OPC_DSLL_CP2:
3819         shift_max = 64;
3820         goto do_shift;
3821     case OPC_DSRL_CP2:
3822         shift_max = 64;
3823         goto do_shift;
3824     case OPC_DSRA_CP2:
3825         shift_max = 64;
3826         goto do_shift;
3827     do_shift:
3828         /* Make sure shift count isn't TCG undefined behaviour.  */
3829         tcg_gen_andi_i64(t1, t1, shift_max - 1);
3830 
3831         switch (opc) {
3832         case OPC_SLL_CP2:
3833         case OPC_DSLL_CP2:
3834             tcg_gen_shl_i64(t0, t0, t1);
3835             break;
3836         case OPC_SRA_CP2:
3837         case OPC_DSRA_CP2:
3838             /*
3839              * Since SRA is UndefinedResult without sign-extended inputs,
3840              * we can treat SRA and DSRA the same.
3841              */
3842             tcg_gen_sar_i64(t0, t0, t1);
3843             break;
3844         case OPC_SRL_CP2:
3845             /* We want to shift in zeros for SRL; zero-extend first.  */
3846             tcg_gen_ext32u_i64(t0, t0);
3847             /* FALLTHRU */
3848         case OPC_DSRL_CP2:
3849             tcg_gen_shr_i64(t0, t0, t1);
3850             break;
3851         }
3852 
3853         if (shift_max == 32) {
3854             tcg_gen_ext32s_i64(t0, t0);
3855         }
3856 
3857         /* Shifts larger than MAX produce zero.  */
3858         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3859         tcg_gen_neg_i64(t1, t1);
3860         tcg_gen_and_i64(t0, t0, t1);
3861         break;
3862 
3863     case OPC_ADD_CP2:
3864     case OPC_DADD_CP2:
3865         {
3866             TCGv_i64 t2 = tcg_temp_new_i64();
3867             TCGLabel *lab = gen_new_label();
3868 
3869             tcg_gen_mov_i64(t2, t0);
3870             tcg_gen_add_i64(t0, t1, t2);
3871             if (opc == OPC_ADD_CP2) {
3872                 tcg_gen_ext32s_i64(t0, t0);
3873             }
3874             tcg_gen_xor_i64(t1, t1, t2);
3875             tcg_gen_xor_i64(t2, t2, t0);
3876             tcg_gen_andc_i64(t1, t2, t1);
3877             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3878             generate_exception(ctx, EXCP_OVERFLOW);
3879             gen_set_label(lab);
3880             break;
3881         }
3882 
3883     case OPC_SUB_CP2:
3884     case OPC_DSUB_CP2:
3885         {
3886             TCGv_i64 t2 = tcg_temp_new_i64();
3887             TCGLabel *lab = gen_new_label();
3888 
3889             tcg_gen_mov_i64(t2, t0);
3890             tcg_gen_sub_i64(t0, t1, t2);
3891             if (opc == OPC_SUB_CP2) {
3892                 tcg_gen_ext32s_i64(t0, t0);
3893             }
3894             tcg_gen_xor_i64(t1, t1, t2);
3895             tcg_gen_xor_i64(t2, t2, t0);
3896             tcg_gen_and_i64(t1, t1, t2);
3897             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3898             generate_exception(ctx, EXCP_OVERFLOW);
3899             gen_set_label(lab);
3900             break;
3901         }
3902 
3903     case OPC_PMULUW:
3904         tcg_gen_ext32u_i64(t0, t0);
3905         tcg_gen_ext32u_i64(t1, t1);
3906         tcg_gen_mul_i64(t0, t0, t1);
3907         break;
3908 
3909     case OPC_SEQU_CP2:
3910     case OPC_SEQ_CP2:
3911         cond = TCG_COND_EQ;
3912         goto do_cc_cond;
3913         break;
3914     case OPC_SLTU_CP2:
3915         cond = TCG_COND_LTU;
3916         goto do_cc_cond;
3917         break;
3918     case OPC_SLT_CP2:
3919         cond = TCG_COND_LT;
3920         goto do_cc_cond;
3921         break;
3922     case OPC_SLEU_CP2:
3923         cond = TCG_COND_LEU;
3924         goto do_cc_cond;
3925         break;
3926     case OPC_SLE_CP2:
3927         cond = TCG_COND_LE;
3928     do_cc_cond:
3929         {
3930             int cc = (ctx->opcode >> 8) & 0x7;
3931             TCGv_i64 t64 = tcg_temp_new_i64();
3932             TCGv_i32 t32 = tcg_temp_new_i32();
3933 
3934             tcg_gen_setcond_i64(cond, t64, t0, t1);
3935             tcg_gen_extrl_i64_i32(t32, t64);
3936             tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
3937                                 get_fp_bit(cc), 1);
3938         }
3939         return;
3940     default:
3941         MIPS_INVAL("loongson_cp2");
3942         gen_reserved_instruction(ctx);
3943         return;
3944     }
3945 
3946     gen_store_fpr64(ctx, t0, rd);
3947 }
3948 
gen_loongson_lswc2(DisasContext * ctx,int rt,int rs,int rd)3949 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
3950                                int rs, int rd)
3951 {
3952     TCGv t0, t1;
3953     TCGv_i32 fp0;
3954 #if defined(TARGET_MIPS64)
3955     int lsq_rt1 = ctx->opcode & 0x1f;
3956     int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
3957 #endif
3958     int shf_offset = sextract32(ctx->opcode, 6, 8);
3959 
3960     t0 = tcg_temp_new();
3961 
3962     switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
3963 #if defined(TARGET_MIPS64)
3964     case OPC_GSLQ:
3965         t1 = tcg_temp_new();
3966         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3967         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3968                            ctx->default_tcg_memop_mask);
3969         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3970         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3971                            ctx->default_tcg_memop_mask);
3972         gen_store_gpr(t1, rt);
3973         gen_store_gpr(t0, lsq_rt1);
3974         break;
3975     case OPC_GSLQC1:
3976         check_cp1_enabled(ctx);
3977         t1 = tcg_temp_new();
3978         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3979         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3980                            ctx->default_tcg_memop_mask);
3981         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3982         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3983                            ctx->default_tcg_memop_mask);
3984         gen_store_fpr64(ctx, t1, rt);
3985         gen_store_fpr64(ctx, t0, lsq_rt1);
3986         break;
3987     case OPC_GSSQ:
3988         t1 = tcg_temp_new();
3989         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3990         gen_load_gpr(t1, rt);
3991         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3992                            ctx->default_tcg_memop_mask);
3993         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3994         gen_load_gpr(t1, lsq_rt1);
3995         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3996                            ctx->default_tcg_memop_mask);
3997         break;
3998     case OPC_GSSQC1:
3999         check_cp1_enabled(ctx);
4000         t1 = tcg_temp_new();
4001         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4002         gen_load_fpr64(ctx, t1, rt);
4003         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4004                            ctx->default_tcg_memop_mask);
4005         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4006         gen_load_fpr64(ctx, t1, lsq_rt1);
4007         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4008                            ctx->default_tcg_memop_mask);
4009         break;
4010 #endif
4011     case OPC_GSSHFL:
4012         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4013         case OPC_GSLWLC1:
4014             check_cp1_enabled(ctx);
4015             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4016             fp0 = tcg_temp_new_i32();
4017             gen_load_fpr32(ctx, fp0, rt);
4018             t1 = tcg_temp_new();
4019             tcg_gen_ext_i32_tl(t1, fp0);
4020             gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4021             tcg_gen_trunc_tl_i32(fp0, t1);
4022             gen_store_fpr32(ctx, fp0, rt);
4023             break;
4024         case OPC_GSLWRC1:
4025             check_cp1_enabled(ctx);
4026             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4027             fp0 = tcg_temp_new_i32();
4028             gen_load_fpr32(ctx, fp0, rt);
4029             t1 = tcg_temp_new();
4030             tcg_gen_ext_i32_tl(t1, fp0);
4031             gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4032             tcg_gen_trunc_tl_i32(fp0, t1);
4033             gen_store_fpr32(ctx, fp0, rt);
4034             break;
4035 #if defined(TARGET_MIPS64)
4036         case OPC_GSLDLC1:
4037             check_cp1_enabled(ctx);
4038             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4039             t1 = tcg_temp_new();
4040             gen_load_fpr64(ctx, t1, rt);
4041             gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4042             gen_store_fpr64(ctx, t1, rt);
4043             break;
4044         case OPC_GSLDRC1:
4045             check_cp1_enabled(ctx);
4046             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4047             t1 = tcg_temp_new();
4048             gen_load_fpr64(ctx, t1, rt);
4049             gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4050             gen_store_fpr64(ctx, t1, rt);
4051             break;
4052 #endif
4053         default:
4054             MIPS_INVAL("loongson_gsshfl");
4055             gen_reserved_instruction(ctx);
4056             break;
4057         }
4058         break;
4059     case OPC_GSSHFS:
4060         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4061         case OPC_GSSWLC1:
4062             check_cp1_enabled(ctx);
4063             t1 = tcg_temp_new();
4064             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4065             fp0 = tcg_temp_new_i32();
4066             gen_load_fpr32(ctx, fp0, rt);
4067             tcg_gen_ext_i32_tl(t1, fp0);
4068             gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4069             break;
4070         case OPC_GSSWRC1:
4071             check_cp1_enabled(ctx);
4072             t1 = tcg_temp_new();
4073             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4074             fp0 = tcg_temp_new_i32();
4075             gen_load_fpr32(ctx, fp0, rt);
4076             tcg_gen_ext_i32_tl(t1, fp0);
4077             gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4078             break;
4079 #if defined(TARGET_MIPS64)
4080         case OPC_GSSDLC1:
4081             check_cp1_enabled(ctx);
4082             t1 = tcg_temp_new();
4083             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4084             gen_load_fpr64(ctx, t1, rt);
4085             gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4086             break;
4087         case OPC_GSSDRC1:
4088             check_cp1_enabled(ctx);
4089             t1 = tcg_temp_new();
4090             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4091             gen_load_fpr64(ctx, t1, rt);
4092             gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4093             break;
4094 #endif
4095         default:
4096             MIPS_INVAL("loongson_gsshfs");
4097             gen_reserved_instruction(ctx);
4098             break;
4099         }
4100         break;
4101     default:
4102         MIPS_INVAL("loongson_gslsq");
4103         gen_reserved_instruction(ctx);
4104         break;
4105     }
4106 }
4107 
4108 /* Loongson EXT LDC2/SDC2 */
gen_loongson_lsdc2(DisasContext * ctx,int rt,int rs,int rd)4109 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4110                                int rs, int rd)
4111 {
4112     int offset = sextract32(ctx->opcode, 3, 8);
4113     uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4114     TCGv t0, t1;
4115     TCGv_i32 fp0;
4116 
4117     /* Pre-conditions */
4118     switch (opc) {
4119     case OPC_GSLBX:
4120     case OPC_GSLHX:
4121     case OPC_GSLWX:
4122     case OPC_GSLDX:
4123         /* prefetch, implement as NOP */
4124         if (rt == 0) {
4125             return;
4126         }
4127         break;
4128     case OPC_GSSBX:
4129     case OPC_GSSHX:
4130     case OPC_GSSWX:
4131     case OPC_GSSDX:
4132         break;
4133     case OPC_GSLWXC1:
4134 #if defined(TARGET_MIPS64)
4135     case OPC_GSLDXC1:
4136 #endif
4137         check_cp1_enabled(ctx);
4138         /* prefetch, implement as NOP */
4139         if (rt == 0) {
4140             return;
4141         }
4142         break;
4143     case OPC_GSSWXC1:
4144 #if defined(TARGET_MIPS64)
4145     case OPC_GSSDXC1:
4146 #endif
4147         check_cp1_enabled(ctx);
4148         break;
4149     default:
4150         MIPS_INVAL("loongson_lsdc2");
4151         gen_reserved_instruction(ctx);
4152         return;
4153         break;
4154     }
4155 
4156     t0 = tcg_temp_new();
4157 
4158     gen_base_offset_addr(ctx, t0, rs, offset);
4159     gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4160 
4161     switch (opc) {
4162     case OPC_GSLBX:
4163         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4164         gen_store_gpr(t0, rt);
4165         break;
4166     case OPC_GSLHX:
4167         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW |
4168                            ctx->default_tcg_memop_mask);
4169         gen_store_gpr(t0, rt);
4170         break;
4171     case OPC_GSLWX:
4172         gen_base_offset_addr(ctx, t0, rs, offset);
4173         if (rd) {
4174             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4175         }
4176         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4177                            ctx->default_tcg_memop_mask);
4178         gen_store_gpr(t0, rt);
4179         break;
4180 #if defined(TARGET_MIPS64)
4181     case OPC_GSLDX:
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_gpr(t0, rt);
4189         break;
4190 #endif
4191     case OPC_GSLWXC1:
4192         gen_base_offset_addr(ctx, t0, rs, offset);
4193         if (rd) {
4194             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4195         }
4196         fp0 = tcg_temp_new_i32();
4197         tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4198                             ctx->default_tcg_memop_mask);
4199         gen_store_fpr32(ctx, fp0, rt);
4200         break;
4201 #if defined(TARGET_MIPS64)
4202     case OPC_GSLDXC1:
4203         gen_base_offset_addr(ctx, t0, rs, offset);
4204         if (rd) {
4205             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4206         }
4207         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4208                            ctx->default_tcg_memop_mask);
4209         gen_store_fpr64(ctx, t0, rt);
4210         break;
4211 #endif
4212     case OPC_GSSBX:
4213         t1 = tcg_temp_new();
4214         gen_load_gpr(t1, rt);
4215         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4216         break;
4217     case OPC_GSSHX:
4218         t1 = tcg_temp_new();
4219         gen_load_gpr(t1, rt);
4220         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW |
4221                            ctx->default_tcg_memop_mask);
4222         break;
4223     case OPC_GSSWX:
4224         t1 = tcg_temp_new();
4225         gen_load_gpr(t1, rt);
4226         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4227                            ctx->default_tcg_memop_mask);
4228         break;
4229 #if defined(TARGET_MIPS64)
4230     case OPC_GSSDX:
4231         t1 = tcg_temp_new();
4232         gen_load_gpr(t1, rt);
4233         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4234                            ctx->default_tcg_memop_mask);
4235         break;
4236 #endif
4237     case OPC_GSSWXC1:
4238         fp0 = tcg_temp_new_i32();
4239         gen_load_fpr32(ctx, fp0, rt);
4240         tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4241                             ctx->default_tcg_memop_mask);
4242         break;
4243 #if defined(TARGET_MIPS64)
4244     case OPC_GSSDXC1:
4245         t1 = tcg_temp_new();
4246         gen_load_fpr64(ctx, t1, rt);
4247         tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4248                             ctx->default_tcg_memop_mask);
4249         break;
4250 #endif
4251     default:
4252         break;
4253     }
4254 }
4255 
4256 /* Traps */
gen_trap(DisasContext * ctx,uint32_t opc,int rs,int rt,int16_t imm,int code)4257 static void gen_trap(DisasContext *ctx, uint32_t opc,
4258                      int rs, int rt, int16_t imm, int code)
4259 {
4260     int cond;
4261     TCGv t0 = tcg_temp_new();
4262     TCGv t1 = tcg_temp_new();
4263 
4264     cond = 0;
4265     /* Load needed operands */
4266     switch (opc) {
4267     case OPC_TEQ:
4268     case OPC_TGE:
4269     case OPC_TGEU:
4270     case OPC_TLT:
4271     case OPC_TLTU:
4272     case OPC_TNE:
4273         /* Compare two registers */
4274         if (rs != rt) {
4275             gen_load_gpr(t0, rs);
4276             gen_load_gpr(t1, rt);
4277             cond = 1;
4278         }
4279         break;
4280     case OPC_TEQI:
4281     case OPC_TGEI:
4282     case OPC_TGEIU:
4283     case OPC_TLTI:
4284     case OPC_TLTIU:
4285     case OPC_TNEI:
4286         /* Compare register to immediate */
4287         if (rs != 0 || imm != 0) {
4288             gen_load_gpr(t0, rs);
4289             tcg_gen_movi_tl(t1, (int32_t)imm);
4290             cond = 1;
4291         }
4292         break;
4293     }
4294     if (cond == 0) {
4295         switch (opc) {
4296         case OPC_TEQ:   /* rs == rs */
4297         case OPC_TEQI:  /* r0 == 0  */
4298         case OPC_TGE:   /* rs >= rs */
4299         case OPC_TGEI:  /* r0 >= 0  */
4300         case OPC_TGEU:  /* rs >= rs unsigned */
4301         case OPC_TGEIU: /* r0 >= 0  unsigned */
4302             /* Always trap */
4303 #ifdef CONFIG_USER_ONLY
4304             /* Pass the break code along to cpu_loop. */
4305             tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4306                            offsetof(CPUMIPSState, error_code));
4307 #endif
4308             generate_exception_end(ctx, EXCP_TRAP);
4309             break;
4310         case OPC_TLT:   /* rs < rs           */
4311         case OPC_TLTI:  /* r0 < 0            */
4312         case OPC_TLTU:  /* rs < rs unsigned  */
4313         case OPC_TLTIU: /* r0 < 0  unsigned  */
4314         case OPC_TNE:   /* rs != rs          */
4315         case OPC_TNEI:  /* r0 != 0           */
4316             /* Never trap: treat as NOP. */
4317             break;
4318         }
4319     } else {
4320         TCGLabel *l1 = gen_new_label();
4321 
4322         switch (opc) {
4323         case OPC_TEQ:
4324         case OPC_TEQI:
4325             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4326             break;
4327         case OPC_TGE:
4328         case OPC_TGEI:
4329             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4330             break;
4331         case OPC_TGEU:
4332         case OPC_TGEIU:
4333             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4334             break;
4335         case OPC_TLT:
4336         case OPC_TLTI:
4337             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4338             break;
4339         case OPC_TLTU:
4340         case OPC_TLTIU:
4341             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4342             break;
4343         case OPC_TNE:
4344         case OPC_TNEI:
4345             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4346             break;
4347         }
4348 #ifdef CONFIG_USER_ONLY
4349         /* Pass the break code along to cpu_loop. */
4350         tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4351                        offsetof(CPUMIPSState, error_code));
4352 #endif
4353         /* Like save_cpu_state, only don't update saved values. */
4354         if (ctx->base.pc_next != ctx->saved_pc) {
4355             gen_save_pc(ctx->base.pc_next);
4356         }
4357         if (ctx->hflags != ctx->saved_hflags) {
4358             tcg_gen_movi_i32(hflags, ctx->hflags);
4359         }
4360         generate_exception(ctx, EXCP_TRAP);
4361         gen_set_label(l1);
4362     }
4363 }
4364 
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)4365 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4366 {
4367     if (translator_use_goto_tb(&ctx->base, dest)) {
4368         tcg_gen_goto_tb(n);
4369         gen_save_pc(dest);
4370         tcg_gen_exit_tb(ctx->base.tb, n);
4371     } else {
4372         gen_save_pc(dest);
4373         tcg_gen_lookup_and_goto_ptr();
4374     }
4375 }
4376 
4377 /* 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)4378 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4379                                int insn_bytes,
4380                                int rs, int rt, int32_t offset,
4381                                int delayslot_size)
4382 {
4383     target_ulong btgt = -1;
4384     int blink = 0;
4385     int bcond_compute = 0;
4386     TCGv t0 = tcg_temp_new();
4387     TCGv t1 = tcg_temp_new();
4388 
4389     if (ctx->hflags & MIPS_HFLAG_BMASK) {
4390 #ifdef MIPS_DEBUG_DISAS
4391         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
4392                   VADDR_PRIx "\n", ctx->base.pc_next);
4393 #endif
4394         gen_reserved_instruction(ctx);
4395         goto out;
4396     }
4397 
4398     /* Load needed operands */
4399     switch (opc) {
4400     case OPC_BEQ:
4401     case OPC_BEQL:
4402     case OPC_BNE:
4403     case OPC_BNEL:
4404         /* Compare two registers */
4405         if (rs != rt) {
4406             gen_load_gpr(t0, rs);
4407             gen_load_gpr(t1, rt);
4408             bcond_compute = 1;
4409         }
4410         btgt = ctx->base.pc_next + insn_bytes + offset;
4411         break;
4412     case OPC_BGEZ:
4413     case OPC_BGEZAL:
4414     case OPC_BGEZALL:
4415     case OPC_BGEZL:
4416     case OPC_BGTZ:
4417     case OPC_BGTZL:
4418     case OPC_BLEZ:
4419     case OPC_BLEZL:
4420     case OPC_BLTZ:
4421     case OPC_BLTZAL:
4422     case OPC_BLTZALL:
4423     case OPC_BLTZL:
4424         /* Compare to zero */
4425         if (rs != 0) {
4426             gen_load_gpr(t0, rs);
4427             bcond_compute = 1;
4428         }
4429         btgt = ctx->base.pc_next + insn_bytes + offset;
4430         break;
4431     case OPC_BPOSGE32:
4432 #if defined(TARGET_MIPS64)
4433     case OPC_BPOSGE64:
4434         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4435 #else
4436         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4437 #endif
4438         bcond_compute = 1;
4439         btgt = ctx->base.pc_next + insn_bytes + offset;
4440         break;
4441     case OPC_J:
4442     case OPC_JAL:
4443         {
4444             /* Jump to immediate */
4445             int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
4446                                                         : 0xF0000000;
4447             btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
4448                    | (uint32_t)offset;
4449             break;
4450         }
4451     case OPC_JALX:
4452         /* Jump to immediate */
4453         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4454             (uint32_t)offset;
4455         break;
4456     case OPC_JR:
4457     case OPC_JALR:
4458         /* Jump to register */
4459         if (offset != 0 && offset != 16) {
4460             /*
4461              * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4462              * others are reserved.
4463              */
4464             MIPS_INVAL("jump hint");
4465             gen_reserved_instruction(ctx);
4466             goto out;
4467         }
4468         gen_load_gpr(btarget, rs);
4469         break;
4470     default:
4471         MIPS_INVAL("branch/jump");
4472         gen_reserved_instruction(ctx);
4473         goto out;
4474     }
4475     if (bcond_compute == 0) {
4476         /* No condition to be computed */
4477         switch (opc) {
4478         case OPC_BEQ:     /* rx == rx        */
4479         case OPC_BEQL:    /* rx == rx likely */
4480         case OPC_BGEZ:    /* 0 >= 0          */
4481         case OPC_BGEZL:   /* 0 >= 0 likely   */
4482         case OPC_BLEZ:    /* 0 <= 0          */
4483         case OPC_BLEZL:   /* 0 <= 0 likely   */
4484             /* Always take */
4485             ctx->hflags |= MIPS_HFLAG_B;
4486             break;
4487         case OPC_BGEZAL:  /* 0 >= 0          */
4488         case OPC_BGEZALL: /* 0 >= 0 likely   */
4489             /* Always take and link */
4490             blink = 31;
4491             ctx->hflags |= MIPS_HFLAG_B;
4492             break;
4493         case OPC_BNE:     /* rx != rx        */
4494         case OPC_BGTZ:    /* 0 > 0           */
4495         case OPC_BLTZ:    /* 0 < 0           */
4496             /* Treat as NOP. */
4497             goto out;
4498         case OPC_BLTZAL:  /* 0 < 0           */
4499             /*
4500              * Handle as an unconditional branch to get correct delay
4501              * slot checking.
4502              */
4503             blink = 31;
4504             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4505             ctx->hflags |= MIPS_HFLAG_B;
4506             break;
4507         case OPC_BLTZALL: /* 0 < 0 likely */
4508             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4509             /* Skip the instruction in the delay slot */
4510             ctx->base.pc_next += 4;
4511             goto out;
4512         case OPC_BNEL:    /* rx != rx likely */
4513         case OPC_BGTZL:   /* 0 > 0 likely */
4514         case OPC_BLTZL:   /* 0 < 0 likely */
4515             /* Skip the instruction in the delay slot */
4516             ctx->base.pc_next += 4;
4517             goto out;
4518         case OPC_J:
4519             ctx->hflags |= MIPS_HFLAG_B;
4520             break;
4521         case OPC_JALX:
4522             ctx->hflags |= MIPS_HFLAG_BX;
4523             /* Fallthrough */
4524         case OPC_JAL:
4525             blink = 31;
4526             ctx->hflags |= MIPS_HFLAG_B;
4527             break;
4528         case OPC_JR:
4529             ctx->hflags |= MIPS_HFLAG_BR;
4530             break;
4531         case OPC_JALR:
4532             blink = rt;
4533             ctx->hflags |= MIPS_HFLAG_BR;
4534             break;
4535         default:
4536             MIPS_INVAL("branch/jump");
4537             gen_reserved_instruction(ctx);
4538             goto out;
4539         }
4540     } else {
4541         switch (opc) {
4542         case OPC_BEQ:
4543             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4544             goto not_likely;
4545         case OPC_BEQL:
4546             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4547             goto likely;
4548         case OPC_BNE:
4549             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4550             goto not_likely;
4551         case OPC_BNEL:
4552             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4553             goto likely;
4554         case OPC_BGEZ:
4555             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4556             goto not_likely;
4557         case OPC_BGEZL:
4558             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4559             goto likely;
4560         case OPC_BGEZAL:
4561             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4562             blink = 31;
4563             goto not_likely;
4564         case OPC_BGEZALL:
4565             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4566             blink = 31;
4567             goto likely;
4568         case OPC_BGTZ:
4569             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4570             goto not_likely;
4571         case OPC_BGTZL:
4572             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4573             goto likely;
4574         case OPC_BLEZ:
4575             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4576             goto not_likely;
4577         case OPC_BLEZL:
4578             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4579             goto likely;
4580         case OPC_BLTZ:
4581             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4582             goto not_likely;
4583         case OPC_BLTZL:
4584             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4585             goto likely;
4586         case OPC_BPOSGE32:
4587             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4588             goto not_likely;
4589 #if defined(TARGET_MIPS64)
4590         case OPC_BPOSGE64:
4591             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4592             goto not_likely;
4593 #endif
4594         case OPC_BLTZAL:
4595             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4596             blink = 31;
4597         not_likely:
4598             ctx->hflags |= MIPS_HFLAG_BC;
4599             break;
4600         case OPC_BLTZALL:
4601             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4602             blink = 31;
4603         likely:
4604             ctx->hflags |= MIPS_HFLAG_BL;
4605             break;
4606         default:
4607             MIPS_INVAL("conditional branch/jump");
4608             gen_reserved_instruction(ctx);
4609             goto out;
4610         }
4611     }
4612 
4613     ctx->btarget = btgt;
4614 
4615     switch (delayslot_size) {
4616     case 2:
4617         ctx->hflags |= MIPS_HFLAG_BDS16;
4618         break;
4619     case 4:
4620         ctx->hflags |= MIPS_HFLAG_BDS32;
4621         break;
4622     }
4623 
4624     if (blink > 0) {
4625         int post_delay = insn_bytes + delayslot_size;
4626         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4627 
4628         tcg_gen_movi_tl(cpu_gpr[blink],
4629                         ctx->base.pc_next + post_delay + lowbit);
4630     }
4631 
4632  out:
4633     if (insn_bytes == 2) {
4634         ctx->hflags |= MIPS_HFLAG_B16;
4635     }
4636 }
4637 
4638 
4639 /* special3 bitfield operations */
gen_bitops(DisasContext * ctx,uint32_t opc,int rt,int rs,int lsb,int msb)4640 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
4641                        int rs, int lsb, int msb)
4642 {
4643     TCGv t0 = tcg_temp_new();
4644     TCGv t1 = tcg_temp_new();
4645 
4646     gen_load_gpr(t1, rs);
4647     switch (opc) {
4648     case OPC_EXT:
4649         if (lsb + msb > 31) {
4650             goto fail;
4651         }
4652         if (msb != 31) {
4653             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4654         } else {
4655             /*
4656              * The two checks together imply that lsb == 0,
4657              * so this is a simple sign-extension.
4658              */
4659             tcg_gen_ext32s_tl(t0, t1);
4660         }
4661         break;
4662 #if defined(TARGET_MIPS64)
4663     case OPC_DEXTU:
4664         lsb += 32;
4665         goto do_dext;
4666     case OPC_DEXTM:
4667         msb += 32;
4668         goto do_dext;
4669     case OPC_DEXT:
4670     do_dext:
4671         if (lsb + msb > 63) {
4672             goto fail;
4673         }
4674         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4675         break;
4676 #endif
4677     case OPC_INS:
4678         if (lsb > msb) {
4679             goto fail;
4680         }
4681         gen_load_gpr(t0, rt);
4682         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4683         tcg_gen_ext32s_tl(t0, t0);
4684         break;
4685 #if defined(TARGET_MIPS64)
4686     case OPC_DINSU:
4687         lsb += 32;
4688         /* FALLTHRU */
4689     case OPC_DINSM:
4690         msb += 32;
4691         /* FALLTHRU */
4692     case OPC_DINS:
4693         if (lsb > msb) {
4694             goto fail;
4695         }
4696         gen_load_gpr(t0, rt);
4697         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4698         break;
4699 #endif
4700     default:
4701 fail:
4702         MIPS_INVAL("bitops");
4703         gen_reserved_instruction(ctx);
4704         return;
4705     }
4706     gen_store_gpr(t0, rt);
4707 }
4708 
gen_bshfl(DisasContext * ctx,uint32_t op2,int rt,int rd)4709 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
4710 {
4711     TCGv t0;
4712 
4713     if (rd == 0) {
4714         /* If no destination, treat it as a NOP. */
4715         return;
4716     }
4717 
4718     t0 = tcg_temp_new();
4719     gen_load_gpr(t0, rt);
4720     switch (op2) {
4721     case OPC_WSBH:
4722         {
4723             TCGv t1 = tcg_temp_new();
4724             TCGv t2 = tcg_constant_tl(0x00FF00FF);
4725 
4726             tcg_gen_shri_tl(t1, t0, 8);
4727             tcg_gen_and_tl(t1, t1, t2);
4728             tcg_gen_and_tl(t0, t0, t2);
4729             tcg_gen_shli_tl(t0, t0, 8);
4730             tcg_gen_or_tl(t0, t0, t1);
4731             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4732         }
4733         break;
4734     case OPC_SEB:
4735         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4736         break;
4737     case OPC_SEH:
4738         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4739         break;
4740 #if defined(TARGET_MIPS64)
4741     case OPC_DSBH:
4742         {
4743             TCGv t1 = tcg_temp_new();
4744             TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL);
4745 
4746             tcg_gen_shri_tl(t1, t0, 8);
4747             tcg_gen_and_tl(t1, t1, t2);
4748             tcg_gen_and_tl(t0, t0, t2);
4749             tcg_gen_shli_tl(t0, t0, 8);
4750             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4751         }
4752         break;
4753     case OPC_DSHD:
4754         {
4755             TCGv t1 = tcg_temp_new();
4756             TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL);
4757 
4758             tcg_gen_shri_tl(t1, t0, 16);
4759             tcg_gen_and_tl(t1, t1, t2);
4760             tcg_gen_and_tl(t0, t0, t2);
4761             tcg_gen_shli_tl(t0, t0, 16);
4762             tcg_gen_or_tl(t0, t0, t1);
4763             tcg_gen_shri_tl(t1, t0, 32);
4764             tcg_gen_shli_tl(t0, t0, 32);
4765             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4766         }
4767         break;
4768 #endif
4769     default:
4770         MIPS_INVAL("bsfhl");
4771         gen_reserved_instruction(ctx);
4772         return;
4773     }
4774 }
4775 
gen_align_bits(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bits)4776 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
4777                            int rt, int bits)
4778 {
4779     TCGv t0;
4780     if (rd == 0) {
4781         /* Treat as NOP. */
4782         return;
4783     }
4784     t0 = tcg_temp_new();
4785     if (bits == 0 || bits == wordsz) {
4786         if (bits == 0) {
4787             gen_load_gpr(t0, rt);
4788         } else {
4789             gen_load_gpr(t0, rs);
4790         }
4791         switch (wordsz) {
4792         case 32:
4793             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4794             break;
4795 #if defined(TARGET_MIPS64)
4796         case 64:
4797             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4798             break;
4799 #endif
4800         }
4801     } else {
4802         TCGv t1 = tcg_temp_new();
4803         gen_load_gpr(t0, rt);
4804         gen_load_gpr(t1, rs);
4805         switch (wordsz) {
4806         case 32:
4807             {
4808                 TCGv_i64 t2 = tcg_temp_new_i64();
4809                 tcg_gen_concat_tl_i64(t2, t1, t0);
4810                 tcg_gen_shri_i64(t2, t2, 32 - bits);
4811                 gen_move_low32(cpu_gpr[rd], t2);
4812             }
4813             break;
4814 #if defined(TARGET_MIPS64)
4815         case 64:
4816             tcg_gen_shli_tl(t0, t0, bits);
4817             tcg_gen_shri_tl(t1, t1, 64 - bits);
4818             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4819             break;
4820 #endif
4821         }
4822     }
4823 }
4824 
gen_align(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bp)4825 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
4826 {
4827     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
4828 }
4829 
gen_bitswap(DisasContext * ctx,int opc,int rd,int rt)4830 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4831 {
4832     TCGv t0;
4833     if (rd == 0) {
4834         /* Treat as NOP. */
4835         return;
4836     }
4837     t0 = tcg_temp_new();
4838     gen_load_gpr(t0, rt);
4839     switch (opc) {
4840     case OPC_BITSWAP:
4841         gen_helper_bitswap(cpu_gpr[rd], t0);
4842         break;
4843 #if defined(TARGET_MIPS64)
4844     case OPC_DBITSWAP:
4845         gen_helper_dbitswap(cpu_gpr[rd], t0);
4846         break;
4847 #endif
4848     }
4849 }
4850 
4851 #ifndef CONFIG_USER_ONLY
4852 /* CP0 (MMU and control) */
gen_mthc0_entrylo(TCGv arg,target_ulong off)4853 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4854 {
4855     TCGv_i64 t0 = tcg_temp_new_i64();
4856     TCGv_i64 t1 = tcg_temp_new_i64();
4857 
4858     tcg_gen_ext_tl_i64(t0, arg);
4859     tcg_gen_ld_i64(t1, tcg_env, off);
4860 #if defined(TARGET_MIPS64)
4861     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4862 #else
4863     tcg_gen_concat32_i64(t1, t1, t0);
4864 #endif
4865     tcg_gen_st_i64(t1, tcg_env, off);
4866 }
4867 
gen_mthc0_store64(TCGv arg,target_ulong off)4868 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4869 {
4870     TCGv_i64 t0 = tcg_temp_new_i64();
4871     TCGv_i64 t1 = tcg_temp_new_i64();
4872 
4873     tcg_gen_ext_tl_i64(t0, arg);
4874     tcg_gen_ld_i64(t1, tcg_env, off);
4875     tcg_gen_concat32_i64(t1, t1, t0);
4876     tcg_gen_st_i64(t1, tcg_env, off);
4877 }
4878 
gen_mfhc0_entrylo(TCGv arg,target_ulong off)4879 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4880 {
4881     TCGv_i64 t0 = tcg_temp_new_i64();
4882 
4883     tcg_gen_ld_i64(t0, tcg_env, off);
4884 #if defined(TARGET_MIPS64)
4885     tcg_gen_shri_i64(t0, t0, 30);
4886 #else
4887     tcg_gen_shri_i64(t0, t0, 32);
4888 #endif
4889     gen_move_low32(arg, t0);
4890 }
4891 
gen_mfhc0_load64(TCGv arg,target_ulong off,int shift)4892 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4893 {
4894     TCGv_i64 t0 = tcg_temp_new_i64();
4895 
4896     tcg_gen_ld_i64(t0, tcg_env, off);
4897     tcg_gen_shri_i64(t0, t0, 32 + shift);
4898     gen_move_low32(arg, t0);
4899 }
4900 
gen_mfc0_load32(TCGv arg,target_ulong off)4901 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
4902 {
4903     TCGv_i32 t0 = tcg_temp_new_i32();
4904 
4905     tcg_gen_ld_i32(t0, tcg_env, off);
4906     tcg_gen_ext_i32_tl(arg, t0);
4907 }
4908 
gen_mfc0_load64(TCGv arg,target_ulong off)4909 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
4910 {
4911     tcg_gen_ld_tl(arg, tcg_env, off);
4912     tcg_gen_ext32s_tl(arg, arg);
4913 }
4914 
gen_mtc0_store32(TCGv arg,target_ulong off)4915 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
4916 {
4917     TCGv_i32 t0 = tcg_temp_new_i32();
4918 
4919     tcg_gen_trunc_tl_i32(t0, arg);
4920     tcg_gen_st_i32(t0, tcg_env, off);
4921 }
4922 
4923 #define CP0_CHECK(c)                            \
4924     do {                                        \
4925         if (!(c)) {                             \
4926             goto cp0_unimplemented;             \
4927         }                                       \
4928     } while (0)
4929 
gen_mfhc0(DisasContext * ctx,TCGv arg,int reg,int sel)4930 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4931 {
4932     const char *register_name = "invalid";
4933 
4934     switch (reg) {
4935     case CP0_REGISTER_02:
4936         switch (sel) {
4937         case 0:
4938             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4939             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4940             register_name = "EntryLo0";
4941             break;
4942         default:
4943             goto cp0_unimplemented;
4944         }
4945         break;
4946     case CP0_REGISTER_03:
4947         switch (sel) {
4948         case CP0_REG03__ENTRYLO1:
4949             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4950             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4951             register_name = "EntryLo1";
4952             break;
4953         default:
4954             goto cp0_unimplemented;
4955         }
4956         break;
4957     case CP0_REGISTER_17:
4958         switch (sel) {
4959         case CP0_REG17__LLADDR:
4960             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
4961                              ctx->CP0_LLAddr_shift);
4962             register_name = "LLAddr";
4963             break;
4964         case CP0_REG17__MAAR:
4965             CP0_CHECK(ctx->mrp);
4966             gen_helper_mfhc0_maar(arg, tcg_env);
4967             register_name = "MAAR";
4968             break;
4969         default:
4970             goto cp0_unimplemented;
4971         }
4972         break;
4973     case CP0_REGISTER_19:
4974         switch (sel) {
4975         case CP0_REG19__WATCHHI0:
4976         case CP0_REG19__WATCHHI1:
4977         case CP0_REG19__WATCHHI2:
4978         case CP0_REG19__WATCHHI3:
4979         case CP0_REG19__WATCHHI4:
4980         case CP0_REG19__WATCHHI5:
4981         case CP0_REG19__WATCHHI6:
4982         case CP0_REG19__WATCHHI7:
4983             /* upper 32 bits are only available when Config5MI != 0 */
4984             CP0_CHECK(ctx->mi);
4985             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
4986             register_name = "WatchHi";
4987             break;
4988         default:
4989             goto cp0_unimplemented;
4990         }
4991         break;
4992     case CP0_REGISTER_28:
4993         switch (sel) {
4994         case 0:
4995         case 2:
4996         case 4:
4997         case 6:
4998             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4999             register_name = "TagLo";
5000             break;
5001         default:
5002             goto cp0_unimplemented;
5003         }
5004         break;
5005     default:
5006         goto cp0_unimplemented;
5007     }
5008     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5009     return;
5010 
5011 cp0_unimplemented:
5012     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5013                   register_name, reg, sel);
5014     tcg_gen_movi_tl(arg, 0);
5015 }
5016 
gen_mthc0(DisasContext * ctx,TCGv arg,int reg,int sel)5017 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5018 {
5019     const char *register_name = "invalid";
5020     uint64_t mask = ctx->PAMask >> 36;
5021 
5022     switch (reg) {
5023     case CP0_REGISTER_02:
5024         switch (sel) {
5025         case 0:
5026             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5027             tcg_gen_andi_tl(arg, arg, mask);
5028             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5029             register_name = "EntryLo0";
5030             break;
5031         default:
5032             goto cp0_unimplemented;
5033         }
5034         break;
5035     case CP0_REGISTER_03:
5036         switch (sel) {
5037         case CP0_REG03__ENTRYLO1:
5038             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5039             tcg_gen_andi_tl(arg, arg, mask);
5040             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5041             register_name = "EntryLo1";
5042             break;
5043         default:
5044             goto cp0_unimplemented;
5045         }
5046         break;
5047     case CP0_REGISTER_17:
5048         switch (sel) {
5049         case CP0_REG17__LLADDR:
5050             /*
5051              * LLAddr is read-only (the only exception is bit 0 if LLB is
5052              * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5053              * relevant for modern MIPS cores supporting MTHC0, therefore
5054              * treating MTHC0 to LLAddr as NOP.
5055              */
5056             register_name = "LLAddr";
5057             break;
5058         case CP0_REG17__MAAR:
5059             CP0_CHECK(ctx->mrp);
5060             gen_helper_mthc0_maar(tcg_env, arg);
5061             register_name = "MAAR";
5062             break;
5063         default:
5064             goto cp0_unimplemented;
5065         }
5066         break;
5067     case CP0_REGISTER_19:
5068         switch (sel) {
5069         case CP0_REG19__WATCHHI0:
5070         case CP0_REG19__WATCHHI1:
5071         case CP0_REG19__WATCHHI2:
5072         case CP0_REG19__WATCHHI3:
5073         case CP0_REG19__WATCHHI4:
5074         case CP0_REG19__WATCHHI5:
5075         case CP0_REG19__WATCHHI6:
5076         case CP0_REG19__WATCHHI7:
5077             /* upper 32 bits are only available when Config5MI != 0 */
5078             CP0_CHECK(ctx->mi);
5079             gen_helper_0e1i(mthc0_watchhi, arg, sel);
5080             register_name = "WatchHi";
5081             break;
5082         default:
5083             goto cp0_unimplemented;
5084         }
5085         break;
5086     case CP0_REGISTER_28:
5087         switch (sel) {
5088         case 0:
5089         case 2:
5090         case 4:
5091         case 6:
5092             tcg_gen_andi_tl(arg, arg, mask);
5093             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5094             register_name = "TagLo";
5095             break;
5096         default:
5097             goto cp0_unimplemented;
5098         }
5099         break;
5100     default:
5101         goto cp0_unimplemented;
5102     }
5103     trace_mips_translate_c0("mthc0", register_name, reg, sel);
5104     return;
5105 
5106 cp0_unimplemented:
5107     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5108                   register_name, reg, sel);
5109 }
5110 
gen_mfc0_unimplemented(DisasContext * ctx,TCGv arg)5111 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5112 {
5113     if (ctx->insn_flags & ISA_MIPS_R6) {
5114         tcg_gen_movi_tl(arg, 0);
5115     } else {
5116         tcg_gen_movi_tl(arg, ~0);
5117     }
5118 }
5119 
gen_mfc0(DisasContext * ctx,TCGv arg,int reg,int sel)5120 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5121 {
5122     const char *register_name = "invalid";
5123 
5124     if (sel != 0) {
5125         check_insn(ctx, ISA_MIPS_R1);
5126     }
5127 
5128     switch (reg) {
5129     case CP0_REGISTER_00:
5130         switch (sel) {
5131         case CP0_REG00__INDEX:
5132             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5133             register_name = "Index";
5134             break;
5135         case CP0_REG00__MVPCONTROL:
5136             CP0_CHECK(disas_mt_available(ctx));
5137             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
5138             register_name = "MVPControl";
5139             break;
5140         case CP0_REG00__MVPCONF0:
5141             CP0_CHECK(disas_mt_available(ctx));
5142             gen_helper_mfc0_mvpconf0(arg, tcg_env);
5143             register_name = "MVPConf0";
5144             break;
5145         case CP0_REG00__MVPCONF1:
5146             CP0_CHECK(disas_mt_available(ctx));
5147             gen_helper_mfc0_mvpconf1(arg, tcg_env);
5148             register_name = "MVPConf1";
5149             break;
5150         case CP0_REG00__VPCONTROL:
5151             CP0_CHECK(ctx->vp);
5152             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5153             register_name = "VPControl";
5154             break;
5155         default:
5156             goto cp0_unimplemented;
5157         }
5158         break;
5159     case CP0_REGISTER_01:
5160         switch (sel) {
5161         case CP0_REG01__RANDOM:
5162             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5163             gen_helper_mfc0_random(arg, tcg_env);
5164             register_name = "Random";
5165             break;
5166         case CP0_REG01__VPECONTROL:
5167             CP0_CHECK(disas_mt_available(ctx));
5168             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5169             register_name = "VPEControl";
5170             break;
5171         case CP0_REG01__VPECONF0:
5172             CP0_CHECK(disas_mt_available(ctx));
5173             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5174             register_name = "VPEConf0";
5175             break;
5176         case CP0_REG01__VPECONF1:
5177             CP0_CHECK(disas_mt_available(ctx));
5178             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5179             register_name = "VPEConf1";
5180             break;
5181         case CP0_REG01__YQMASK:
5182             CP0_CHECK(disas_mt_available(ctx));
5183             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5184             register_name = "YQMask";
5185             break;
5186         case CP0_REG01__VPESCHEDULE:
5187             CP0_CHECK(disas_mt_available(ctx));
5188             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5189             register_name = "VPESchedule";
5190             break;
5191         case CP0_REG01__VPESCHEFBACK:
5192             CP0_CHECK(disas_mt_available(ctx));
5193             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5194             register_name = "VPEScheFBack";
5195             break;
5196         case CP0_REG01__VPEOPT:
5197             CP0_CHECK(disas_mt_available(ctx));
5198             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5199             register_name = "VPEOpt";
5200             break;
5201         default:
5202             goto cp0_unimplemented;
5203         }
5204         break;
5205     case CP0_REGISTER_02:
5206         switch (sel) {
5207         case CP0_REG02__ENTRYLO0:
5208             {
5209                 TCGv_i64 tmp = tcg_temp_new_i64();
5210                 tcg_gen_ld_i64(tmp, tcg_env,
5211                                offsetof(CPUMIPSState, CP0_EntryLo0));
5212 #if defined(TARGET_MIPS64)
5213                 if (ctx->rxi) {
5214                     /* Move RI/XI fields to bits 31:30 */
5215                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5216                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5217                 }
5218 #endif
5219                 gen_move_low32(arg, tmp);
5220             }
5221             register_name = "EntryLo0";
5222             break;
5223         case CP0_REG02__TCSTATUS:
5224             CP0_CHECK(disas_mt_available(ctx));
5225             gen_helper_mfc0_tcstatus(arg, tcg_env);
5226             register_name = "TCStatus";
5227             break;
5228         case CP0_REG02__TCBIND:
5229             CP0_CHECK(disas_mt_available(ctx));
5230             gen_helper_mfc0_tcbind(arg, tcg_env);
5231             register_name = "TCBind";
5232             break;
5233         case CP0_REG02__TCRESTART:
5234             CP0_CHECK(disas_mt_available(ctx));
5235             gen_helper_mfc0_tcrestart(arg, tcg_env);
5236             register_name = "TCRestart";
5237             break;
5238         case CP0_REG02__TCHALT:
5239             CP0_CHECK(disas_mt_available(ctx));
5240             gen_helper_mfc0_tchalt(arg, tcg_env);
5241             register_name = "TCHalt";
5242             break;
5243         case CP0_REG02__TCCONTEXT:
5244             CP0_CHECK(disas_mt_available(ctx));
5245             gen_helper_mfc0_tccontext(arg, tcg_env);
5246             register_name = "TCContext";
5247             break;
5248         case CP0_REG02__TCSCHEDULE:
5249             CP0_CHECK(disas_mt_available(ctx));
5250             gen_helper_mfc0_tcschedule(arg, tcg_env);
5251             register_name = "TCSchedule";
5252             break;
5253         case CP0_REG02__TCSCHEFBACK:
5254             CP0_CHECK(disas_mt_available(ctx));
5255             gen_helper_mfc0_tcschefback(arg, tcg_env);
5256             register_name = "TCScheFBack";
5257             break;
5258         default:
5259             goto cp0_unimplemented;
5260         }
5261         break;
5262     case CP0_REGISTER_03:
5263         switch (sel) {
5264         case CP0_REG03__ENTRYLO1:
5265             {
5266                 TCGv_i64 tmp = tcg_temp_new_i64();
5267                 tcg_gen_ld_i64(tmp, tcg_env,
5268                                offsetof(CPUMIPSState, CP0_EntryLo1));
5269 #if defined(TARGET_MIPS64)
5270                 if (ctx->rxi) {
5271                     /* Move RI/XI fields to bits 31:30 */
5272                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5273                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5274                 }
5275 #endif
5276                 gen_move_low32(arg, tmp);
5277             }
5278             register_name = "EntryLo1";
5279             break;
5280         case CP0_REG03__GLOBALNUM:
5281             CP0_CHECK(ctx->vp);
5282             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5283             register_name = "GlobalNumber";
5284             break;
5285         default:
5286             goto cp0_unimplemented;
5287         }
5288         break;
5289     case CP0_REGISTER_04:
5290         switch (sel) {
5291         case CP0_REG04__CONTEXT:
5292             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
5293             tcg_gen_ext32s_tl(arg, arg);
5294             register_name = "Context";
5295             break;
5296         case CP0_REG04__CONTEXTCONFIG:
5297             /* SmartMIPS ASE */
5298             /* gen_helper_mfc0_contextconfig(arg); */
5299             register_name = "ContextConfig";
5300             goto cp0_unimplemented;
5301         case CP0_REG04__USERLOCAL:
5302             CP0_CHECK(ctx->ulri);
5303             tcg_gen_ld_tl(arg, tcg_env,
5304                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5305             tcg_gen_ext32s_tl(arg, arg);
5306             register_name = "UserLocal";
5307             break;
5308         case CP0_REG04__MMID:
5309             CP0_CHECK(ctx->mi);
5310             gen_helper_mtc0_memorymapid(tcg_env, arg);
5311             register_name = "MMID";
5312             break;
5313         default:
5314             goto cp0_unimplemented;
5315         }
5316         break;
5317     case CP0_REGISTER_05:
5318         switch (sel) {
5319         case CP0_REG05__PAGEMASK:
5320             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5321             register_name = "PageMask";
5322             break;
5323         case CP0_REG05__PAGEGRAIN:
5324             check_insn(ctx, ISA_MIPS_R2);
5325             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5326             register_name = "PageGrain";
5327             break;
5328         case CP0_REG05__SEGCTL0:
5329             CP0_CHECK(ctx->sc);
5330             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5331             tcg_gen_ext32s_tl(arg, arg);
5332             register_name = "SegCtl0";
5333             break;
5334         case CP0_REG05__SEGCTL1:
5335             CP0_CHECK(ctx->sc);
5336             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5337             tcg_gen_ext32s_tl(arg, arg);
5338             register_name = "SegCtl1";
5339             break;
5340         case CP0_REG05__SEGCTL2:
5341             CP0_CHECK(ctx->sc);
5342             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5343             tcg_gen_ext32s_tl(arg, arg);
5344             register_name = "SegCtl2";
5345             break;
5346         case CP0_REG05__PWBASE:
5347             check_pw(ctx);
5348             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5349             register_name = "PWBase";
5350             break;
5351         case CP0_REG05__PWFIELD:
5352             check_pw(ctx);
5353             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5354             register_name = "PWField";
5355             break;
5356         case CP0_REG05__PWSIZE:
5357             check_pw(ctx);
5358             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5359             register_name = "PWSize";
5360             break;
5361         default:
5362             goto cp0_unimplemented;
5363         }
5364         break;
5365     case CP0_REGISTER_06:
5366         switch (sel) {
5367         case CP0_REG06__WIRED:
5368             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5369             register_name = "Wired";
5370             break;
5371         case CP0_REG06__SRSCONF0:
5372             check_insn(ctx, ISA_MIPS_R2);
5373             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5374             register_name = "SRSConf0";
5375             break;
5376         case CP0_REG06__SRSCONF1:
5377             check_insn(ctx, ISA_MIPS_R2);
5378             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5379             register_name = "SRSConf1";
5380             break;
5381         case CP0_REG06__SRSCONF2:
5382             check_insn(ctx, ISA_MIPS_R2);
5383             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5384             register_name = "SRSConf2";
5385             break;
5386         case CP0_REG06__SRSCONF3:
5387             check_insn(ctx, ISA_MIPS_R2);
5388             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5389             register_name = "SRSConf3";
5390             break;
5391         case CP0_REG06__SRSCONF4:
5392             check_insn(ctx, ISA_MIPS_R2);
5393             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5394             register_name = "SRSConf4";
5395             break;
5396         case CP0_REG06__PWCTL:
5397             check_pw(ctx);
5398             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5399             register_name = "PWCtl";
5400             break;
5401         default:
5402             goto cp0_unimplemented;
5403         }
5404         break;
5405     case CP0_REGISTER_07:
5406         switch (sel) {
5407         case CP0_REG07__HWRENA:
5408             check_insn(ctx, ISA_MIPS_R2);
5409             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5410             register_name = "HWREna";
5411             break;
5412         default:
5413             goto cp0_unimplemented;
5414         }
5415         break;
5416     case CP0_REGISTER_08:
5417         switch (sel) {
5418         case CP0_REG08__BADVADDR:
5419             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5420             tcg_gen_ext32s_tl(arg, arg);
5421             register_name = "BadVAddr";
5422             break;
5423         case CP0_REG08__BADINSTR:
5424             CP0_CHECK(ctx->bi);
5425             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5426             register_name = "BadInstr";
5427             break;
5428         case CP0_REG08__BADINSTRP:
5429             CP0_CHECK(ctx->bp);
5430             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5431             register_name = "BadInstrP";
5432             break;
5433         case CP0_REG08__BADINSTRX:
5434             CP0_CHECK(ctx->bi);
5435             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5436             tcg_gen_andi_tl(arg, arg, ~0xffff);
5437             register_name = "BadInstrX";
5438             break;
5439         default:
5440             goto cp0_unimplemented;
5441         }
5442         break;
5443     case CP0_REGISTER_09:
5444         switch (sel) {
5445         case CP0_REG09__COUNT:
5446             /* Mark as an IO operation because we read the time.  */
5447             translator_io_start(&ctx->base);
5448 
5449             gen_helper_mfc0_count(arg, tcg_env);
5450             /*
5451              * Break the TB to be able to take timer interrupts immediately
5452              * after reading count. DISAS_STOP isn't sufficient, we need to
5453              * ensure we break completely out of translated code.
5454              */
5455             gen_save_pc(ctx->base.pc_next + 4);
5456             ctx->base.is_jmp = DISAS_EXIT;
5457             register_name = "Count";
5458             break;
5459         default:
5460             goto cp0_unimplemented;
5461         }
5462         break;
5463     case CP0_REGISTER_10:
5464         switch (sel) {
5465         case CP0_REG10__ENTRYHI:
5466             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
5467             tcg_gen_ext32s_tl(arg, arg);
5468             register_name = "EntryHi";
5469             break;
5470         default:
5471             goto cp0_unimplemented;
5472         }
5473         break;
5474     case CP0_REGISTER_11:
5475         switch (sel) {
5476         case CP0_REG11__COMPARE:
5477             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5478             register_name = "Compare";
5479             break;
5480         /* 6,7 are implementation dependent */
5481         default:
5482             goto cp0_unimplemented;
5483         }
5484         break;
5485     case CP0_REGISTER_12:
5486         switch (sel) {
5487         case CP0_REG12__STATUS:
5488             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5489             register_name = "Status";
5490             break;
5491         case CP0_REG12__INTCTL:
5492             check_insn(ctx, ISA_MIPS_R2);
5493             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5494             register_name = "IntCtl";
5495             break;
5496         case CP0_REG12__SRSCTL:
5497             check_insn(ctx, ISA_MIPS_R2);
5498             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5499             register_name = "SRSCtl";
5500             break;
5501         case CP0_REG12__SRSMAP:
5502             check_insn(ctx, ISA_MIPS_R2);
5503             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5504             register_name = "SRSMap";
5505             break;
5506         default:
5507             goto cp0_unimplemented;
5508        }
5509         break;
5510     case CP0_REGISTER_13:
5511         switch (sel) {
5512         case CP0_REG13__CAUSE:
5513             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5514             register_name = "Cause";
5515             break;
5516         default:
5517             goto cp0_unimplemented;
5518        }
5519         break;
5520     case CP0_REGISTER_14:
5521         switch (sel) {
5522         case CP0_REG14__EPC:
5523             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
5524             tcg_gen_ext32s_tl(arg, arg);
5525             register_name = "EPC";
5526             break;
5527         default:
5528             goto cp0_unimplemented;
5529         }
5530         break;
5531     case CP0_REGISTER_15:
5532         switch (sel) {
5533         case CP0_REG15__PRID:
5534             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5535             register_name = "PRid";
5536             break;
5537         case CP0_REG15__EBASE:
5538             check_insn(ctx, ISA_MIPS_R2);
5539             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
5540             tcg_gen_ext32s_tl(arg, arg);
5541             register_name = "EBase";
5542             break;
5543         case CP0_REG15__CMGCRBASE:
5544             check_insn(ctx, ISA_MIPS_R2);
5545             CP0_CHECK(ctx->cmgcr);
5546             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5547             tcg_gen_ext32s_tl(arg, arg);
5548             register_name = "CMGCRBase";
5549             break;
5550         default:
5551             goto cp0_unimplemented;
5552        }
5553         break;
5554     case CP0_REGISTER_16:
5555         switch (sel) {
5556         case CP0_REG16__CONFIG:
5557             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5558             register_name = "Config";
5559             break;
5560         case CP0_REG16__CONFIG1:
5561             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5562             register_name = "Config1";
5563             break;
5564         case CP0_REG16__CONFIG2:
5565             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5566             register_name = "Config2";
5567             break;
5568         case CP0_REG16__CONFIG3:
5569             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5570             register_name = "Config3";
5571             break;
5572         case CP0_REG16__CONFIG4:
5573             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5574             register_name = "Config4";
5575             break;
5576         case CP0_REG16__CONFIG5:
5577             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5578             register_name = "Config5";
5579             break;
5580         /* 6,7 are implementation dependent */
5581         case CP0_REG16__CONFIG6:
5582             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5583             register_name = "Config6";
5584             break;
5585         case CP0_REG16__CONFIG7:
5586             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5587             register_name = "Config7";
5588             break;
5589         default:
5590             goto cp0_unimplemented;
5591         }
5592         break;
5593     case CP0_REGISTER_17:
5594         switch (sel) {
5595         case CP0_REG17__LLADDR:
5596             gen_helper_mfc0_lladdr(arg, tcg_env);
5597             register_name = "LLAddr";
5598             break;
5599         case CP0_REG17__MAAR:
5600             CP0_CHECK(ctx->mrp);
5601             gen_helper_mfc0_maar(arg, tcg_env);
5602             register_name = "MAAR";
5603             break;
5604         case CP0_REG17__MAARI:
5605             CP0_CHECK(ctx->mrp);
5606             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5607             register_name = "MAARI";
5608             break;
5609         default:
5610             goto cp0_unimplemented;
5611         }
5612         break;
5613     case CP0_REGISTER_18:
5614         switch (sel) {
5615         case CP0_REG18__WATCHLO0:
5616         case CP0_REG18__WATCHLO1:
5617         case CP0_REG18__WATCHLO2:
5618         case CP0_REG18__WATCHLO3:
5619         case CP0_REG18__WATCHLO4:
5620         case CP0_REG18__WATCHLO5:
5621         case CP0_REG18__WATCHLO6:
5622         case CP0_REG18__WATCHLO7:
5623             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5624             gen_helper_1e0i(mfc0_watchlo, arg, sel);
5625             register_name = "WatchLo";
5626             break;
5627         default:
5628             goto cp0_unimplemented;
5629         }
5630         break;
5631     case CP0_REGISTER_19:
5632         switch (sel) {
5633         case CP0_REG19__WATCHHI0:
5634         case CP0_REG19__WATCHHI1:
5635         case CP0_REG19__WATCHHI2:
5636         case CP0_REG19__WATCHHI3:
5637         case CP0_REG19__WATCHHI4:
5638         case CP0_REG19__WATCHHI5:
5639         case CP0_REG19__WATCHHI6:
5640         case CP0_REG19__WATCHHI7:
5641             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5642             gen_helper_1e0i(mfc0_watchhi, arg, sel);
5643             register_name = "WatchHi";
5644             break;
5645         default:
5646             goto cp0_unimplemented;
5647         }
5648         break;
5649     case CP0_REGISTER_20:
5650         switch (sel) {
5651         case CP0_REG20__XCONTEXT:
5652 #if defined(TARGET_MIPS64)
5653             check_insn(ctx, ISA_MIPS3);
5654             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
5655             tcg_gen_ext32s_tl(arg, arg);
5656             register_name = "XContext";
5657             break;
5658 #endif
5659         default:
5660             goto cp0_unimplemented;
5661         }
5662         break;
5663     case CP0_REGISTER_21:
5664        /* Officially reserved, but sel 0 is used for R1x000 framemask */
5665         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5666         switch (sel) {
5667         case 0:
5668             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5669             register_name = "Framemask";
5670             break;
5671         default:
5672             goto cp0_unimplemented;
5673         }
5674         break;
5675     case CP0_REGISTER_22:
5676         tcg_gen_movi_tl(arg, 0); /* unimplemented */
5677         register_name = "'Diagnostic"; /* implementation dependent */
5678         break;
5679     case CP0_REGISTER_23:
5680         switch (sel) {
5681         case CP0_REG23__DEBUG:
5682             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
5683             register_name = "Debug";
5684             break;
5685         case CP0_REG23__TRACECONTROL:
5686             /* PDtrace support */
5687             /* gen_helper_mfc0_tracecontrol(arg);  */
5688             register_name = "TraceControl";
5689             goto cp0_unimplemented;
5690         case CP0_REG23__TRACECONTROL2:
5691             /* PDtrace support */
5692             /* gen_helper_mfc0_tracecontrol2(arg); */
5693             register_name = "TraceControl2";
5694             goto cp0_unimplemented;
5695         case CP0_REG23__USERTRACEDATA1:
5696             /* PDtrace support */
5697             /* gen_helper_mfc0_usertracedata1(arg);*/
5698             register_name = "UserTraceData1";
5699             goto cp0_unimplemented;
5700         case CP0_REG23__TRACEIBPC:
5701             /* PDtrace support */
5702             /* gen_helper_mfc0_traceibpc(arg);     */
5703             register_name = "TraceIBPC";
5704             goto cp0_unimplemented;
5705         case CP0_REG23__TRACEDBPC:
5706             /* PDtrace support */
5707             /* gen_helper_mfc0_tracedbpc(arg);     */
5708             register_name = "TraceDBPC";
5709             goto cp0_unimplemented;
5710         default:
5711             goto cp0_unimplemented;
5712         }
5713         break;
5714     case CP0_REGISTER_24:
5715         switch (sel) {
5716         case CP0_REG24__DEPC:
5717             /* EJTAG support */
5718             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
5719             tcg_gen_ext32s_tl(arg, arg);
5720             register_name = "DEPC";
5721             break;
5722         default:
5723             goto cp0_unimplemented;
5724         }
5725         break;
5726     case CP0_REGISTER_25:
5727         switch (sel) {
5728         case CP0_REG25__PERFCTL0:
5729             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5730             register_name = "Performance0";
5731             break;
5732         case CP0_REG25__PERFCNT0:
5733             /* gen_helper_mfc0_performance1(arg); */
5734             register_name = "Performance1";
5735             goto cp0_unimplemented;
5736         case CP0_REG25__PERFCTL1:
5737             /* gen_helper_mfc0_performance2(arg); */
5738             register_name = "Performance2";
5739             goto cp0_unimplemented;
5740         case CP0_REG25__PERFCNT1:
5741             /* gen_helper_mfc0_performance3(arg); */
5742             register_name = "Performance3";
5743             goto cp0_unimplemented;
5744         case CP0_REG25__PERFCTL2:
5745             /* gen_helper_mfc0_performance4(arg); */
5746             register_name = "Performance4";
5747             goto cp0_unimplemented;
5748         case CP0_REG25__PERFCNT2:
5749             /* gen_helper_mfc0_performance5(arg); */
5750             register_name = "Performance5";
5751             goto cp0_unimplemented;
5752         case CP0_REG25__PERFCTL3:
5753             /* gen_helper_mfc0_performance6(arg); */
5754             register_name = "Performance6";
5755             goto cp0_unimplemented;
5756         case CP0_REG25__PERFCNT3:
5757             /* gen_helper_mfc0_performance7(arg); */
5758             register_name = "Performance7";
5759             goto cp0_unimplemented;
5760         default:
5761             goto cp0_unimplemented;
5762         }
5763         break;
5764     case CP0_REGISTER_26:
5765         switch (sel) {
5766         case CP0_REG26__ERRCTL:
5767             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5768             register_name = "ErrCtl";
5769             break;
5770         default:
5771             goto cp0_unimplemented;
5772         }
5773         break;
5774     case CP0_REGISTER_27:
5775         switch (sel) {
5776         case CP0_REG27__CACHERR:
5777             tcg_gen_movi_tl(arg, 0); /* unimplemented */
5778             register_name = "CacheErr";
5779             break;
5780         default:
5781             goto cp0_unimplemented;
5782         }
5783         break;
5784     case CP0_REGISTER_28:
5785         switch (sel) {
5786         case CP0_REG28__TAGLO:
5787         case CP0_REG28__TAGLO1:
5788         case CP0_REG28__TAGLO2:
5789         case CP0_REG28__TAGLO3:
5790             {
5791                 TCGv_i64 tmp = tcg_temp_new_i64();
5792                 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo));
5793                 gen_move_low32(arg, tmp);
5794             }
5795             register_name = "TagLo";
5796             break;
5797         case CP0_REG28__DATALO:
5798         case CP0_REG28__DATALO1:
5799         case CP0_REG28__DATALO2:
5800         case CP0_REG28__DATALO3:
5801             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5802             register_name = "DataLo";
5803             break;
5804         default:
5805             goto cp0_unimplemented;
5806         }
5807         break;
5808     case CP0_REGISTER_29:
5809         switch (sel) {
5810         case CP0_REG29__TAGHI:
5811         case CP0_REG29__TAGHI1:
5812         case CP0_REG29__TAGHI2:
5813         case CP0_REG29__TAGHI3:
5814             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5815             register_name = "TagHi";
5816             break;
5817         case CP0_REG29__DATAHI:
5818         case CP0_REG29__DATAHI1:
5819         case CP0_REG29__DATAHI2:
5820         case CP0_REG29__DATAHI3:
5821             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5822             register_name = "DataHi";
5823             break;
5824         default:
5825             goto cp0_unimplemented;
5826         }
5827         break;
5828     case CP0_REGISTER_30:
5829         switch (sel) {
5830         case CP0_REG30__ERROREPC:
5831             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5832             tcg_gen_ext32s_tl(arg, arg);
5833             register_name = "ErrorEPC";
5834             break;
5835         default:
5836             goto cp0_unimplemented;
5837         }
5838         break;
5839     case CP0_REGISTER_31:
5840         switch (sel) {
5841         case CP0_REG31__DESAVE:
5842             /* EJTAG support */
5843             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5844             register_name = "DESAVE";
5845             break;
5846         case CP0_REG31__KSCRATCH1:
5847         case CP0_REG31__KSCRATCH2:
5848         case CP0_REG31__KSCRATCH3:
5849         case CP0_REG31__KSCRATCH4:
5850         case CP0_REG31__KSCRATCH5:
5851         case CP0_REG31__KSCRATCH6:
5852             CP0_CHECK(ctx->kscrexist & (1 << sel));
5853             tcg_gen_ld_tl(arg, tcg_env,
5854                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
5855             tcg_gen_ext32s_tl(arg, arg);
5856             register_name = "KScratch";
5857             break;
5858         default:
5859             goto cp0_unimplemented;
5860         }
5861         break;
5862     default:
5863        goto cp0_unimplemented;
5864     }
5865     trace_mips_translate_c0("mfc0", register_name, reg, sel);
5866     return;
5867 
5868 cp0_unimplemented:
5869     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
5870                   register_name, reg, sel);
5871     gen_mfc0_unimplemented(ctx, arg);
5872 }
5873 
gen_mtc0(DisasContext * ctx,TCGv arg,int reg,int sel)5874 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5875 {
5876     const char *register_name = "invalid";
5877     bool icount;
5878 
5879     if (sel != 0) {
5880         check_insn(ctx, ISA_MIPS_R1);
5881     }
5882 
5883     icount = translator_io_start(&ctx->base);
5884 
5885     switch (reg) {
5886     case CP0_REGISTER_00:
5887         switch (sel) {
5888         case CP0_REG00__INDEX:
5889             gen_helper_mtc0_index(tcg_env, arg);
5890             register_name = "Index";
5891             break;
5892         case CP0_REG00__MVPCONTROL:
5893             CP0_CHECK(disas_mt_available(ctx));
5894             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
5895             register_name = "MVPControl";
5896             break;
5897         case CP0_REG00__MVPCONF0:
5898             CP0_CHECK(disas_mt_available(ctx));
5899             /* ignored */
5900             register_name = "MVPConf0";
5901             break;
5902         case CP0_REG00__MVPCONF1:
5903             CP0_CHECK(disas_mt_available(ctx));
5904             /* ignored */
5905             register_name = "MVPConf1";
5906             break;
5907         case CP0_REG00__VPCONTROL:
5908             CP0_CHECK(ctx->vp);
5909             /* ignored */
5910             register_name = "VPControl";
5911             break;
5912         default:
5913             goto cp0_unimplemented;
5914         }
5915         break;
5916     case CP0_REGISTER_01:
5917         switch (sel) {
5918         case CP0_REG01__RANDOM:
5919             /* ignored */
5920             register_name = "Random";
5921             break;
5922         case CP0_REG01__VPECONTROL:
5923             CP0_CHECK(disas_mt_available(ctx));
5924             gen_helper_mtc0_vpecontrol(tcg_env, arg);
5925             register_name = "VPEControl";
5926             break;
5927         case CP0_REG01__VPECONF0:
5928             CP0_CHECK(disas_mt_available(ctx));
5929             gen_helper_mtc0_vpeconf0(tcg_env, arg);
5930             register_name = "VPEConf0";
5931             break;
5932         case CP0_REG01__VPECONF1:
5933             CP0_CHECK(disas_mt_available(ctx));
5934             gen_helper_mtc0_vpeconf1(tcg_env, arg);
5935             register_name = "VPEConf1";
5936             break;
5937         case CP0_REG01__YQMASK:
5938             CP0_CHECK(disas_mt_available(ctx));
5939             gen_helper_mtc0_yqmask(tcg_env, arg);
5940             register_name = "YQMask";
5941             break;
5942         case CP0_REG01__VPESCHEDULE:
5943             CP0_CHECK(disas_mt_available(ctx));
5944             tcg_gen_st_tl(arg, tcg_env,
5945                           offsetof(CPUMIPSState, CP0_VPESchedule));
5946             register_name = "VPESchedule";
5947             break;
5948         case CP0_REG01__VPESCHEFBACK:
5949             CP0_CHECK(disas_mt_available(ctx));
5950             tcg_gen_st_tl(arg, tcg_env,
5951                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
5952             register_name = "VPEScheFBack";
5953             break;
5954         case CP0_REG01__VPEOPT:
5955             CP0_CHECK(disas_mt_available(ctx));
5956             gen_helper_mtc0_vpeopt(tcg_env, arg);
5957             register_name = "VPEOpt";
5958             break;
5959         default:
5960             goto cp0_unimplemented;
5961         }
5962         break;
5963     case CP0_REGISTER_02:
5964         switch (sel) {
5965         case CP0_REG02__ENTRYLO0:
5966             gen_helper_mtc0_entrylo0(tcg_env, arg);
5967             register_name = "EntryLo0";
5968             break;
5969         case CP0_REG02__TCSTATUS:
5970             CP0_CHECK(disas_mt_available(ctx));
5971             gen_helper_mtc0_tcstatus(tcg_env, arg);
5972             register_name = "TCStatus";
5973             break;
5974         case CP0_REG02__TCBIND:
5975             CP0_CHECK(disas_mt_available(ctx));
5976             gen_helper_mtc0_tcbind(tcg_env, arg);
5977             register_name = "TCBind";
5978             break;
5979         case CP0_REG02__TCRESTART:
5980             CP0_CHECK(disas_mt_available(ctx));
5981             gen_helper_mtc0_tcrestart(tcg_env, arg);
5982             register_name = "TCRestart";
5983             break;
5984         case CP0_REG02__TCHALT:
5985             CP0_CHECK(disas_mt_available(ctx));
5986             gen_helper_mtc0_tchalt(tcg_env, arg);
5987             register_name = "TCHalt";
5988             break;
5989         case CP0_REG02__TCCONTEXT:
5990             CP0_CHECK(disas_mt_available(ctx));
5991             gen_helper_mtc0_tccontext(tcg_env, arg);
5992             register_name = "TCContext";
5993             break;
5994         case CP0_REG02__TCSCHEDULE:
5995             CP0_CHECK(disas_mt_available(ctx));
5996             gen_helper_mtc0_tcschedule(tcg_env, arg);
5997             register_name = "TCSchedule";
5998             break;
5999         case CP0_REG02__TCSCHEFBACK:
6000             CP0_CHECK(disas_mt_available(ctx));
6001             gen_helper_mtc0_tcschefback(tcg_env, arg);
6002             register_name = "TCScheFBack";
6003             break;
6004         default:
6005             goto cp0_unimplemented;
6006         }
6007         break;
6008     case CP0_REGISTER_03:
6009         switch (sel) {
6010         case CP0_REG03__ENTRYLO1:
6011             gen_helper_mtc0_entrylo1(tcg_env, arg);
6012             register_name = "EntryLo1";
6013             break;
6014         case CP0_REG03__GLOBALNUM:
6015             CP0_CHECK(ctx->vp);
6016             /* ignored */
6017             register_name = "GlobalNumber";
6018             break;
6019         default:
6020             goto cp0_unimplemented;
6021         }
6022         break;
6023     case CP0_REGISTER_04:
6024         switch (sel) {
6025         case CP0_REG04__CONTEXT:
6026             gen_helper_mtc0_context(tcg_env, arg);
6027             register_name = "Context";
6028             break;
6029         case CP0_REG04__CONTEXTCONFIG:
6030             /* SmartMIPS ASE */
6031             /* gen_helper_mtc0_contextconfig(arg); */
6032             register_name = "ContextConfig";
6033             goto cp0_unimplemented;
6034         case CP0_REG04__USERLOCAL:
6035             CP0_CHECK(ctx->ulri);
6036             tcg_gen_st_tl(arg, tcg_env,
6037                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6038             register_name = "UserLocal";
6039             break;
6040         case CP0_REG04__MMID:
6041             CP0_CHECK(ctx->mi);
6042             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6043             register_name = "MMID";
6044             break;
6045         default:
6046             goto cp0_unimplemented;
6047         }
6048         break;
6049     case CP0_REGISTER_05:
6050         switch (sel) {
6051         case CP0_REG05__PAGEMASK:
6052             gen_helper_mtc0_pagemask(tcg_env, arg);
6053             register_name = "PageMask";
6054             break;
6055         case CP0_REG05__PAGEGRAIN:
6056             check_insn(ctx, ISA_MIPS_R2);
6057             gen_helper_mtc0_pagegrain(tcg_env, arg);
6058             register_name = "PageGrain";
6059             ctx->base.is_jmp = DISAS_STOP;
6060             break;
6061         case CP0_REG05__SEGCTL0:
6062             CP0_CHECK(ctx->sc);
6063             gen_helper_mtc0_segctl0(tcg_env, arg);
6064             register_name = "SegCtl0";
6065             break;
6066         case CP0_REG05__SEGCTL1:
6067             CP0_CHECK(ctx->sc);
6068             gen_helper_mtc0_segctl1(tcg_env, arg);
6069             register_name = "SegCtl1";
6070             break;
6071         case CP0_REG05__SEGCTL2:
6072             CP0_CHECK(ctx->sc);
6073             gen_helper_mtc0_segctl2(tcg_env, arg);
6074             register_name = "SegCtl2";
6075             break;
6076         case CP0_REG05__PWBASE:
6077             check_pw(ctx);
6078             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6079             register_name = "PWBase";
6080             break;
6081         case CP0_REG05__PWFIELD:
6082             check_pw(ctx);
6083             gen_helper_mtc0_pwfield(tcg_env, arg);
6084             register_name = "PWField";
6085             break;
6086         case CP0_REG05__PWSIZE:
6087             check_pw(ctx);
6088             gen_helper_mtc0_pwsize(tcg_env, arg);
6089             register_name = "PWSize";
6090             break;
6091         default:
6092             goto cp0_unimplemented;
6093         }
6094         break;
6095     case CP0_REGISTER_06:
6096         switch (sel) {
6097         case CP0_REG06__WIRED:
6098             gen_helper_mtc0_wired(tcg_env, arg);
6099             register_name = "Wired";
6100             break;
6101         case CP0_REG06__SRSCONF0:
6102             check_insn(ctx, ISA_MIPS_R2);
6103             gen_helper_mtc0_srsconf0(tcg_env, arg);
6104             register_name = "SRSConf0";
6105             break;
6106         case CP0_REG06__SRSCONF1:
6107             check_insn(ctx, ISA_MIPS_R2);
6108             gen_helper_mtc0_srsconf1(tcg_env, arg);
6109             register_name = "SRSConf1";
6110             break;
6111         case CP0_REG06__SRSCONF2:
6112             check_insn(ctx, ISA_MIPS_R2);
6113             gen_helper_mtc0_srsconf2(tcg_env, arg);
6114             register_name = "SRSConf2";
6115             break;
6116         case CP0_REG06__SRSCONF3:
6117             check_insn(ctx, ISA_MIPS_R2);
6118             gen_helper_mtc0_srsconf3(tcg_env, arg);
6119             register_name = "SRSConf3";
6120             break;
6121         case CP0_REG06__SRSCONF4:
6122             check_insn(ctx, ISA_MIPS_R2);
6123             gen_helper_mtc0_srsconf4(tcg_env, arg);
6124             register_name = "SRSConf4";
6125             break;
6126         case CP0_REG06__PWCTL:
6127             check_pw(ctx);
6128             gen_helper_mtc0_pwctl(tcg_env, arg);
6129             register_name = "PWCtl";
6130             break;
6131         default:
6132             goto cp0_unimplemented;
6133         }
6134         break;
6135     case CP0_REGISTER_07:
6136         switch (sel) {
6137         case CP0_REG07__HWRENA:
6138             check_insn(ctx, ISA_MIPS_R2);
6139             gen_helper_mtc0_hwrena(tcg_env, arg);
6140             ctx->base.is_jmp = DISAS_STOP;
6141             register_name = "HWREna";
6142             break;
6143         default:
6144             goto cp0_unimplemented;
6145         }
6146         break;
6147     case CP0_REGISTER_08:
6148         switch (sel) {
6149         case CP0_REG08__BADVADDR:
6150             /* ignored */
6151             register_name = "BadVAddr";
6152             break;
6153         case CP0_REG08__BADINSTR:
6154             /* ignored */
6155             register_name = "BadInstr";
6156             break;
6157         case CP0_REG08__BADINSTRP:
6158             /* ignored */
6159             register_name = "BadInstrP";
6160             break;
6161         case CP0_REG08__BADINSTRX:
6162             /* ignored */
6163             register_name = "BadInstrX";
6164             break;
6165         default:
6166             goto cp0_unimplemented;
6167         }
6168         break;
6169     case CP0_REGISTER_09:
6170         switch (sel) {
6171         case CP0_REG09__COUNT:
6172             gen_helper_mtc0_count(tcg_env, arg);
6173             register_name = "Count";
6174             break;
6175         default:
6176             goto cp0_unimplemented;
6177         }
6178         break;
6179     case CP0_REGISTER_10:
6180         switch (sel) {
6181         case CP0_REG10__ENTRYHI:
6182             gen_helper_mtc0_entryhi(tcg_env, arg);
6183             register_name = "EntryHi";
6184             break;
6185         default:
6186             goto cp0_unimplemented;
6187         }
6188         break;
6189     case CP0_REGISTER_11:
6190         switch (sel) {
6191         case CP0_REG11__COMPARE:
6192             gen_helper_mtc0_compare(tcg_env, arg);
6193             register_name = "Compare";
6194             break;
6195         /* 6,7 are implementation dependent */
6196         default:
6197             goto cp0_unimplemented;
6198         }
6199         break;
6200     case CP0_REGISTER_12:
6201         switch (sel) {
6202         case CP0_REG12__STATUS:
6203             save_cpu_state(ctx, 1);
6204             gen_helper_mtc0_status(tcg_env, arg);
6205             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6206             gen_save_pc(ctx->base.pc_next + 4);
6207             ctx->base.is_jmp = DISAS_EXIT;
6208             register_name = "Status";
6209             break;
6210         case CP0_REG12__INTCTL:
6211             check_insn(ctx, ISA_MIPS_R2);
6212             gen_helper_mtc0_intctl(tcg_env, arg);
6213             /* Stop translation as we may have switched the execution mode */
6214             ctx->base.is_jmp = DISAS_STOP;
6215             register_name = "IntCtl";
6216             break;
6217         case CP0_REG12__SRSCTL:
6218             check_insn(ctx, ISA_MIPS_R2);
6219             gen_helper_mtc0_srsctl(tcg_env, arg);
6220             /* Stop translation as we may have switched the execution mode */
6221             ctx->base.is_jmp = DISAS_STOP;
6222             register_name = "SRSCtl";
6223             break;
6224         case CP0_REG12__SRSMAP:
6225             check_insn(ctx, ISA_MIPS_R2);
6226             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6227             /* Stop translation as we may have switched the execution mode */
6228             ctx->base.is_jmp = DISAS_STOP;
6229             register_name = "SRSMap";
6230             break;
6231         default:
6232             goto cp0_unimplemented;
6233         }
6234         break;
6235     case CP0_REGISTER_13:
6236         switch (sel) {
6237         case CP0_REG13__CAUSE:
6238             save_cpu_state(ctx, 1);
6239             gen_helper_mtc0_cause(tcg_env, arg);
6240             /*
6241              * Stop translation as we may have triggered an interrupt.
6242              * DISAS_STOP isn't sufficient, we need to ensure we break out of
6243              * translated code to check for pending interrupts.
6244              */
6245             gen_save_pc(ctx->base.pc_next + 4);
6246             ctx->base.is_jmp = DISAS_EXIT;
6247             register_name = "Cause";
6248             break;
6249         default:
6250             goto cp0_unimplemented;
6251         }
6252         break;
6253     case CP0_REGISTER_14:
6254         switch (sel) {
6255         case CP0_REG14__EPC:
6256             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
6257             register_name = "EPC";
6258             break;
6259         default:
6260             goto cp0_unimplemented;
6261         }
6262         break;
6263     case CP0_REGISTER_15:
6264         switch (sel) {
6265         case CP0_REG15__PRID:
6266             /* ignored */
6267             register_name = "PRid";
6268             break;
6269         case CP0_REG15__EBASE:
6270             check_insn(ctx, ISA_MIPS_R2);
6271             gen_helper_mtc0_ebase(tcg_env, arg);
6272             register_name = "EBase";
6273             break;
6274         default:
6275             goto cp0_unimplemented;
6276         }
6277         break;
6278     case CP0_REGISTER_16:
6279         switch (sel) {
6280         case CP0_REG16__CONFIG:
6281             gen_helper_mtc0_config0(tcg_env, arg);
6282             register_name = "Config";
6283             /* Stop translation as we may have switched the execution mode */
6284             ctx->base.is_jmp = DISAS_STOP;
6285             break;
6286         case CP0_REG16__CONFIG1:
6287             /* ignored, read only */
6288             register_name = "Config1";
6289             break;
6290         case CP0_REG16__CONFIG2:
6291             gen_helper_mtc0_config2(tcg_env, arg);
6292             register_name = "Config2";
6293             /* Stop translation as we may have switched the execution mode */
6294             ctx->base.is_jmp = DISAS_STOP;
6295             break;
6296         case CP0_REG16__CONFIG3:
6297             gen_helper_mtc0_config3(tcg_env, arg);
6298             register_name = "Config3";
6299             /* Stop translation as we may have switched the execution mode */
6300             ctx->base.is_jmp = DISAS_STOP;
6301             break;
6302         case CP0_REG16__CONFIG4:
6303             gen_helper_mtc0_config4(tcg_env, arg);
6304             register_name = "Config4";
6305             ctx->base.is_jmp = DISAS_STOP;
6306             break;
6307         case CP0_REG16__CONFIG5:
6308             gen_helper_mtc0_config5(tcg_env, arg);
6309             register_name = "Config5";
6310             /* Stop translation as we may have switched the execution mode */
6311             ctx->base.is_jmp = DISAS_STOP;
6312             break;
6313         /* 6,7 are implementation dependent */
6314         case CP0_REG16__CONFIG6:
6315             /* ignored */
6316             register_name = "Config6";
6317             break;
6318         case CP0_REG16__CONFIG7:
6319             /* ignored */
6320             register_name = "Config7";
6321             break;
6322         default:
6323             register_name = "Invalid config selector";
6324             goto cp0_unimplemented;
6325         }
6326         break;
6327     case CP0_REGISTER_17:
6328         switch (sel) {
6329         case CP0_REG17__LLADDR:
6330             gen_helper_mtc0_lladdr(tcg_env, arg);
6331             register_name = "LLAddr";
6332             break;
6333         case CP0_REG17__MAAR:
6334             CP0_CHECK(ctx->mrp);
6335             gen_helper_mtc0_maar(tcg_env, arg);
6336             register_name = "MAAR";
6337             break;
6338         case CP0_REG17__MAARI:
6339             CP0_CHECK(ctx->mrp);
6340             gen_helper_mtc0_maari(tcg_env, arg);
6341             register_name = "MAARI";
6342             break;
6343         default:
6344             goto cp0_unimplemented;
6345         }
6346         break;
6347     case CP0_REGISTER_18:
6348         switch (sel) {
6349         case CP0_REG18__WATCHLO0:
6350         case CP0_REG18__WATCHLO1:
6351         case CP0_REG18__WATCHLO2:
6352         case CP0_REG18__WATCHLO3:
6353         case CP0_REG18__WATCHLO4:
6354         case CP0_REG18__WATCHLO5:
6355         case CP0_REG18__WATCHLO6:
6356         case CP0_REG18__WATCHLO7:
6357             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6358             gen_helper_0e1i(mtc0_watchlo, arg, sel);
6359             register_name = "WatchLo";
6360             break;
6361         default:
6362             goto cp0_unimplemented;
6363         }
6364         break;
6365     case CP0_REGISTER_19:
6366         switch (sel) {
6367         case CP0_REG19__WATCHHI0:
6368         case CP0_REG19__WATCHHI1:
6369         case CP0_REG19__WATCHHI2:
6370         case CP0_REG19__WATCHHI3:
6371         case CP0_REG19__WATCHHI4:
6372         case CP0_REG19__WATCHHI5:
6373         case CP0_REG19__WATCHHI6:
6374         case CP0_REG19__WATCHHI7:
6375             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6376             gen_helper_0e1i(mtc0_watchhi, arg, sel);
6377             register_name = "WatchHi";
6378             break;
6379         default:
6380             goto cp0_unimplemented;
6381         }
6382         break;
6383     case CP0_REGISTER_20:
6384         switch (sel) {
6385         case CP0_REG20__XCONTEXT:
6386 #if defined(TARGET_MIPS64)
6387             check_insn(ctx, ISA_MIPS3);
6388             gen_helper_mtc0_xcontext(tcg_env, arg);
6389             register_name = "XContext";
6390             break;
6391 #endif
6392         default:
6393             goto cp0_unimplemented;
6394         }
6395         break;
6396     case CP0_REGISTER_21:
6397        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6398         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6399         switch (sel) {
6400         case 0:
6401             gen_helper_mtc0_framemask(tcg_env, arg);
6402             register_name = "Framemask";
6403             break;
6404         default:
6405             goto cp0_unimplemented;
6406         }
6407         break;
6408     case CP0_REGISTER_22:
6409         /* ignored */
6410         register_name = "Diagnostic"; /* implementation dependent */
6411         break;
6412     case CP0_REGISTER_23:
6413         switch (sel) {
6414         case CP0_REG23__DEBUG:
6415             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
6416             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6417             gen_save_pc(ctx->base.pc_next + 4);
6418             ctx->base.is_jmp = DISAS_EXIT;
6419             register_name = "Debug";
6420             break;
6421         case CP0_REG23__TRACECONTROL:
6422             /* PDtrace support */
6423             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
6424             register_name = "TraceControl";
6425             /* Stop translation as we may have switched the execution mode */
6426             ctx->base.is_jmp = DISAS_STOP;
6427             goto cp0_unimplemented;
6428         case CP0_REG23__TRACECONTROL2:
6429             /* PDtrace support */
6430             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
6431             register_name = "TraceControl2";
6432             /* Stop translation as we may have switched the execution mode */
6433             ctx->base.is_jmp = DISAS_STOP;
6434             goto cp0_unimplemented;
6435         case CP0_REG23__USERTRACEDATA1:
6436             /* Stop translation as we may have switched the execution mode */
6437             ctx->base.is_jmp = DISAS_STOP;
6438             /* PDtrace support */
6439             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
6440             register_name = "UserTraceData";
6441             /* Stop translation as we may have switched the execution mode */
6442             ctx->base.is_jmp = DISAS_STOP;
6443             goto cp0_unimplemented;
6444         case CP0_REG23__TRACEIBPC:
6445             /* PDtrace support */
6446             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
6447             /* Stop translation as we may have switched the execution mode */
6448             ctx->base.is_jmp = DISAS_STOP;
6449             register_name = "TraceIBPC";
6450             goto cp0_unimplemented;
6451         case CP0_REG23__TRACEDBPC:
6452             /* PDtrace support */
6453             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
6454             /* Stop translation as we may have switched the execution mode */
6455             ctx->base.is_jmp = DISAS_STOP;
6456             register_name = "TraceDBPC";
6457             goto cp0_unimplemented;
6458         default:
6459             goto cp0_unimplemented;
6460         }
6461         break;
6462     case CP0_REGISTER_24:
6463         switch (sel) {
6464         case CP0_REG24__DEPC:
6465             /* EJTAG support */
6466             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
6467             register_name = "DEPC";
6468             break;
6469         default:
6470             goto cp0_unimplemented;
6471         }
6472         break;
6473     case CP0_REGISTER_25:
6474         switch (sel) {
6475         case CP0_REG25__PERFCTL0:
6476             gen_helper_mtc0_performance0(tcg_env, arg);
6477             register_name = "Performance0";
6478             break;
6479         case CP0_REG25__PERFCNT0:
6480             /* gen_helper_mtc0_performance1(arg); */
6481             register_name = "Performance1";
6482             goto cp0_unimplemented;
6483         case CP0_REG25__PERFCTL1:
6484             /* gen_helper_mtc0_performance2(arg); */
6485             register_name = "Performance2";
6486             goto cp0_unimplemented;
6487         case CP0_REG25__PERFCNT1:
6488             /* gen_helper_mtc0_performance3(arg); */
6489             register_name = "Performance3";
6490             goto cp0_unimplemented;
6491         case CP0_REG25__PERFCTL2:
6492             /* gen_helper_mtc0_performance4(arg); */
6493             register_name = "Performance4";
6494             goto cp0_unimplemented;
6495         case CP0_REG25__PERFCNT2:
6496             /* gen_helper_mtc0_performance5(arg); */
6497             register_name = "Performance5";
6498             goto cp0_unimplemented;
6499         case CP0_REG25__PERFCTL3:
6500             /* gen_helper_mtc0_performance6(arg); */
6501             register_name = "Performance6";
6502             goto cp0_unimplemented;
6503         case CP0_REG25__PERFCNT3:
6504             /* gen_helper_mtc0_performance7(arg); */
6505             register_name = "Performance7";
6506             goto cp0_unimplemented;
6507         default:
6508             goto cp0_unimplemented;
6509         }
6510        break;
6511     case CP0_REGISTER_26:
6512         switch (sel) {
6513         case CP0_REG26__ERRCTL:
6514             gen_helper_mtc0_errctl(tcg_env, arg);
6515             ctx->base.is_jmp = DISAS_STOP;
6516             register_name = "ErrCtl";
6517             break;
6518         default:
6519             goto cp0_unimplemented;
6520         }
6521         break;
6522     case CP0_REGISTER_27:
6523         switch (sel) {
6524         case CP0_REG27__CACHERR:
6525             /* ignored */
6526             register_name = "CacheErr";
6527             break;
6528         default:
6529             goto cp0_unimplemented;
6530         }
6531        break;
6532     case CP0_REGISTER_28:
6533         switch (sel) {
6534         case CP0_REG28__TAGLO:
6535         case CP0_REG28__TAGLO1:
6536         case CP0_REG28__TAGLO2:
6537         case CP0_REG28__TAGLO3:
6538             gen_helper_mtc0_taglo(tcg_env, arg);
6539             register_name = "TagLo";
6540             break;
6541         case CP0_REG28__DATALO:
6542         case CP0_REG28__DATALO1:
6543         case CP0_REG28__DATALO2:
6544         case CP0_REG28__DATALO3:
6545             gen_helper_mtc0_datalo(tcg_env, arg);
6546             register_name = "DataLo";
6547             break;
6548         default:
6549             goto cp0_unimplemented;
6550         }
6551         break;
6552     case CP0_REGISTER_29:
6553         switch (sel) {
6554         case CP0_REG29__TAGHI:
6555         case CP0_REG29__TAGHI1:
6556         case CP0_REG29__TAGHI2:
6557         case CP0_REG29__TAGHI3:
6558             gen_helper_mtc0_taghi(tcg_env, arg);
6559             register_name = "TagHi";
6560             break;
6561         case CP0_REG29__DATAHI:
6562         case CP0_REG29__DATAHI1:
6563         case CP0_REG29__DATAHI2:
6564         case CP0_REG29__DATAHI3:
6565             gen_helper_mtc0_datahi(tcg_env, arg);
6566             register_name = "DataHi";
6567             break;
6568         default:
6569             register_name = "invalid sel";
6570             goto cp0_unimplemented;
6571         }
6572        break;
6573     case CP0_REGISTER_30:
6574         switch (sel) {
6575         case CP0_REG30__ERROREPC:
6576             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6577             register_name = "ErrorEPC";
6578             break;
6579         default:
6580             goto cp0_unimplemented;
6581         }
6582         break;
6583     case CP0_REGISTER_31:
6584         switch (sel) {
6585         case CP0_REG31__DESAVE:
6586             /* EJTAG support */
6587             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6588             register_name = "DESAVE";
6589             break;
6590         case CP0_REG31__KSCRATCH1:
6591         case CP0_REG31__KSCRATCH2:
6592         case CP0_REG31__KSCRATCH3:
6593         case CP0_REG31__KSCRATCH4:
6594         case CP0_REG31__KSCRATCH5:
6595         case CP0_REG31__KSCRATCH6:
6596             CP0_CHECK(ctx->kscrexist & (1 << sel));
6597             tcg_gen_st_tl(arg, tcg_env,
6598                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6599             register_name = "KScratch";
6600             break;
6601         default:
6602             goto cp0_unimplemented;
6603         }
6604         break;
6605     default:
6606        goto cp0_unimplemented;
6607     }
6608     trace_mips_translate_c0("mtc0", register_name, reg, sel);
6609 
6610     /* For simplicity assume that all writes can cause interrupts.  */
6611     if (icount) {
6612         /*
6613          * DISAS_STOP isn't sufficient, we need to ensure we break out of
6614          * translated code to check for pending interrupts.
6615          */
6616         gen_save_pc(ctx->base.pc_next + 4);
6617         ctx->base.is_jmp = DISAS_EXIT;
6618     }
6619     return;
6620 
6621 cp0_unimplemented:
6622     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
6623                   register_name, reg, sel);
6624 }
6625 
6626 #if defined(TARGET_MIPS64)
gen_dmfc0(DisasContext * ctx,TCGv arg,int reg,int sel)6627 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6628 {
6629     const char *register_name = "invalid";
6630 
6631     if (sel != 0) {
6632         check_insn(ctx, ISA_MIPS_R1);
6633     }
6634 
6635     switch (reg) {
6636     case CP0_REGISTER_00:
6637         switch (sel) {
6638         case CP0_REG00__INDEX:
6639             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6640             register_name = "Index";
6641             break;
6642         case CP0_REG00__MVPCONTROL:
6643             CP0_CHECK(disas_mt_available(ctx));
6644             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
6645             register_name = "MVPControl";
6646             break;
6647         case CP0_REG00__MVPCONF0:
6648             CP0_CHECK(disas_mt_available(ctx));
6649             gen_helper_mfc0_mvpconf0(arg, tcg_env);
6650             register_name = "MVPConf0";
6651             break;
6652         case CP0_REG00__MVPCONF1:
6653             CP0_CHECK(disas_mt_available(ctx));
6654             gen_helper_mfc0_mvpconf1(arg, tcg_env);
6655             register_name = "MVPConf1";
6656             break;
6657         case CP0_REG00__VPCONTROL:
6658             CP0_CHECK(ctx->vp);
6659             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6660             register_name = "VPControl";
6661             break;
6662         default:
6663             goto cp0_unimplemented;
6664         }
6665         break;
6666     case CP0_REGISTER_01:
6667         switch (sel) {
6668         case CP0_REG01__RANDOM:
6669             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6670             gen_helper_mfc0_random(arg, tcg_env);
6671             register_name = "Random";
6672             break;
6673         case CP0_REG01__VPECONTROL:
6674             CP0_CHECK(disas_mt_available(ctx));
6675             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6676             register_name = "VPEControl";
6677             break;
6678         case CP0_REG01__VPECONF0:
6679             CP0_CHECK(disas_mt_available(ctx));
6680             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6681             register_name = "VPEConf0";
6682             break;
6683         case CP0_REG01__VPECONF1:
6684             CP0_CHECK(disas_mt_available(ctx));
6685             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6686             register_name = "VPEConf1";
6687             break;
6688         case CP0_REG01__YQMASK:
6689             CP0_CHECK(disas_mt_available(ctx));
6690             tcg_gen_ld_tl(arg, tcg_env,
6691                           offsetof(CPUMIPSState, CP0_YQMask));
6692             register_name = "YQMask";
6693             break;
6694         case CP0_REG01__VPESCHEDULE:
6695             CP0_CHECK(disas_mt_available(ctx));
6696             tcg_gen_ld_tl(arg, tcg_env,
6697                           offsetof(CPUMIPSState, CP0_VPESchedule));
6698             register_name = "VPESchedule";
6699             break;
6700         case CP0_REG01__VPESCHEFBACK:
6701             CP0_CHECK(disas_mt_available(ctx));
6702             tcg_gen_ld_tl(arg, tcg_env,
6703                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6704             register_name = "VPEScheFBack";
6705             break;
6706         case CP0_REG01__VPEOPT:
6707             CP0_CHECK(disas_mt_available(ctx));
6708             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6709             register_name = "VPEOpt";
6710             break;
6711         default:
6712             goto cp0_unimplemented;
6713         }
6714         break;
6715     case CP0_REGISTER_02:
6716         switch (sel) {
6717         case CP0_REG02__ENTRYLO0:
6718             tcg_gen_ld_tl(arg, tcg_env,
6719                           offsetof(CPUMIPSState, CP0_EntryLo0));
6720             register_name = "EntryLo0";
6721             break;
6722         case CP0_REG02__TCSTATUS:
6723             CP0_CHECK(disas_mt_available(ctx));
6724             gen_helper_mfc0_tcstatus(arg, tcg_env);
6725             register_name = "TCStatus";
6726             break;
6727         case CP0_REG02__TCBIND:
6728             CP0_CHECK(disas_mt_available(ctx));
6729             gen_helper_mfc0_tcbind(arg, tcg_env);
6730             register_name = "TCBind";
6731             break;
6732         case CP0_REG02__TCRESTART:
6733             CP0_CHECK(disas_mt_available(ctx));
6734             gen_helper_dmfc0_tcrestart(arg, tcg_env);
6735             register_name = "TCRestart";
6736             break;
6737         case CP0_REG02__TCHALT:
6738             CP0_CHECK(disas_mt_available(ctx));
6739             gen_helper_dmfc0_tchalt(arg, tcg_env);
6740             register_name = "TCHalt";
6741             break;
6742         case CP0_REG02__TCCONTEXT:
6743             CP0_CHECK(disas_mt_available(ctx));
6744             gen_helper_dmfc0_tccontext(arg, tcg_env);
6745             register_name = "TCContext";
6746             break;
6747         case CP0_REG02__TCSCHEDULE:
6748             CP0_CHECK(disas_mt_available(ctx));
6749             gen_helper_dmfc0_tcschedule(arg, tcg_env);
6750             register_name = "TCSchedule";
6751             break;
6752         case CP0_REG02__TCSCHEFBACK:
6753             CP0_CHECK(disas_mt_available(ctx));
6754             gen_helper_dmfc0_tcschefback(arg, tcg_env);
6755             register_name = "TCScheFBack";
6756             break;
6757         default:
6758             goto cp0_unimplemented;
6759         }
6760         break;
6761     case CP0_REGISTER_03:
6762         switch (sel) {
6763         case CP0_REG03__ENTRYLO1:
6764             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6765             register_name = "EntryLo1";
6766             break;
6767         case CP0_REG03__GLOBALNUM:
6768             CP0_CHECK(ctx->vp);
6769             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6770             register_name = "GlobalNumber";
6771             break;
6772         default:
6773             goto cp0_unimplemented;
6774         }
6775         break;
6776     case CP0_REGISTER_04:
6777         switch (sel) {
6778         case CP0_REG04__CONTEXT:
6779             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
6780             register_name = "Context";
6781             break;
6782         case CP0_REG04__CONTEXTCONFIG:
6783             /* SmartMIPS ASE */
6784             /* gen_helper_dmfc0_contextconfig(arg); */
6785             register_name = "ContextConfig";
6786             goto cp0_unimplemented;
6787         case CP0_REG04__USERLOCAL:
6788             CP0_CHECK(ctx->ulri);
6789             tcg_gen_ld_tl(arg, tcg_env,
6790                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6791             register_name = "UserLocal";
6792             break;
6793         case CP0_REG04__MMID:
6794             CP0_CHECK(ctx->mi);
6795             gen_helper_mtc0_memorymapid(tcg_env, arg);
6796             register_name = "MMID";
6797             break;
6798         default:
6799             goto cp0_unimplemented;
6800         }
6801         break;
6802     case CP0_REGISTER_05:
6803         switch (sel) {
6804         case CP0_REG05__PAGEMASK:
6805             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6806             register_name = "PageMask";
6807             break;
6808         case CP0_REG05__PAGEGRAIN:
6809             check_insn(ctx, ISA_MIPS_R2);
6810             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6811             register_name = "PageGrain";
6812             break;
6813         case CP0_REG05__SEGCTL0:
6814             CP0_CHECK(ctx->sc);
6815             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6816             register_name = "SegCtl0";
6817             break;
6818         case CP0_REG05__SEGCTL1:
6819             CP0_CHECK(ctx->sc);
6820             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6821             register_name = "SegCtl1";
6822             break;
6823         case CP0_REG05__SEGCTL2:
6824             CP0_CHECK(ctx->sc);
6825             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6826             register_name = "SegCtl2";
6827             break;
6828         case CP0_REG05__PWBASE:
6829             check_pw(ctx);
6830             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
6831             register_name = "PWBase";
6832             break;
6833         case CP0_REG05__PWFIELD:
6834             check_pw(ctx);
6835             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField));
6836             register_name = "PWField";
6837             break;
6838         case CP0_REG05__PWSIZE:
6839             check_pw(ctx);
6840             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize));
6841             register_name = "PWSize";
6842             break;
6843         default:
6844             goto cp0_unimplemented;
6845         }
6846         break;
6847     case CP0_REGISTER_06:
6848         switch (sel) {
6849         case CP0_REG06__WIRED:
6850             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6851             register_name = "Wired";
6852             break;
6853         case CP0_REG06__SRSCONF0:
6854             check_insn(ctx, ISA_MIPS_R2);
6855             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6856             register_name = "SRSConf0";
6857             break;
6858         case CP0_REG06__SRSCONF1:
6859             check_insn(ctx, ISA_MIPS_R2);
6860             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6861             register_name = "SRSConf1";
6862             break;
6863         case CP0_REG06__SRSCONF2:
6864             check_insn(ctx, ISA_MIPS_R2);
6865             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6866             register_name = "SRSConf2";
6867             break;
6868         case CP0_REG06__SRSCONF3:
6869             check_insn(ctx, ISA_MIPS_R2);
6870             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6871             register_name = "SRSConf3";
6872             break;
6873         case CP0_REG06__SRSCONF4:
6874             check_insn(ctx, ISA_MIPS_R2);
6875             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6876             register_name = "SRSConf4";
6877             break;
6878         case CP0_REG06__PWCTL:
6879             check_pw(ctx);
6880             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6881             register_name = "PWCtl";
6882             break;
6883         default:
6884             goto cp0_unimplemented;
6885         }
6886         break;
6887     case CP0_REGISTER_07:
6888         switch (sel) {
6889         case CP0_REG07__HWRENA:
6890             check_insn(ctx, ISA_MIPS_R2);
6891             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6892             register_name = "HWREna";
6893             break;
6894         default:
6895             goto cp0_unimplemented;
6896         }
6897         break;
6898     case CP0_REGISTER_08:
6899         switch (sel) {
6900         case CP0_REG08__BADVADDR:
6901             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6902             register_name = "BadVAddr";
6903             break;
6904         case CP0_REG08__BADINSTR:
6905             CP0_CHECK(ctx->bi);
6906             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6907             register_name = "BadInstr";
6908             break;
6909         case CP0_REG08__BADINSTRP:
6910             CP0_CHECK(ctx->bp);
6911             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6912             register_name = "BadInstrP";
6913             break;
6914         case CP0_REG08__BADINSTRX:
6915             CP0_CHECK(ctx->bi);
6916             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6917             tcg_gen_andi_tl(arg, arg, ~0xffff);
6918             register_name = "BadInstrX";
6919             break;
6920         default:
6921             goto cp0_unimplemented;
6922         }
6923         break;
6924     case CP0_REGISTER_09:
6925         switch (sel) {
6926         case CP0_REG09__COUNT:
6927             /* Mark as an IO operation because we read the time.  */
6928             translator_io_start(&ctx->base);
6929             gen_helper_mfc0_count(arg, tcg_env);
6930             /*
6931              * Break the TB to be able to take timer interrupts immediately
6932              * after reading count. DISAS_STOP isn't sufficient, we need to
6933              * ensure we break completely out of translated code.
6934              */
6935             gen_save_pc(ctx->base.pc_next + 4);
6936             ctx->base.is_jmp = DISAS_EXIT;
6937             register_name = "Count";
6938             break;
6939         default:
6940             goto cp0_unimplemented;
6941         }
6942         break;
6943     case CP0_REGISTER_10:
6944         switch (sel) {
6945         case CP0_REG10__ENTRYHI:
6946             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
6947             register_name = "EntryHi";
6948             break;
6949         default:
6950             goto cp0_unimplemented;
6951         }
6952         break;
6953     case CP0_REGISTER_11:
6954         switch (sel) {
6955         case CP0_REG11__COMPARE:
6956             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6957             register_name = "Compare";
6958             break;
6959         /* 6,7 are implementation dependent */
6960         default:
6961             goto cp0_unimplemented;
6962         }
6963         break;
6964     case CP0_REGISTER_12:
6965         switch (sel) {
6966         case CP0_REG12__STATUS:
6967             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6968             register_name = "Status";
6969             break;
6970         case CP0_REG12__INTCTL:
6971             check_insn(ctx, ISA_MIPS_R2);
6972             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6973             register_name = "IntCtl";
6974             break;
6975         case CP0_REG12__SRSCTL:
6976             check_insn(ctx, ISA_MIPS_R2);
6977             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6978             register_name = "SRSCtl";
6979             break;
6980         case CP0_REG12__SRSMAP:
6981             check_insn(ctx, ISA_MIPS_R2);
6982             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6983             register_name = "SRSMap";
6984             break;
6985         default:
6986             goto cp0_unimplemented;
6987         }
6988         break;
6989     case CP0_REGISTER_13:
6990         switch (sel) {
6991         case CP0_REG13__CAUSE:
6992             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6993             register_name = "Cause";
6994             break;
6995         default:
6996             goto cp0_unimplemented;
6997         }
6998         break;
6999     case CP0_REGISTER_14:
7000         switch (sel) {
7001         case CP0_REG14__EPC:
7002             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7003             register_name = "EPC";
7004             break;
7005         default:
7006             goto cp0_unimplemented;
7007         }
7008         break;
7009     case CP0_REGISTER_15:
7010         switch (sel) {
7011         case CP0_REG15__PRID:
7012             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7013             register_name = "PRid";
7014             break;
7015         case CP0_REG15__EBASE:
7016             check_insn(ctx, ISA_MIPS_R2);
7017             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
7018             register_name = "EBase";
7019             break;
7020         case CP0_REG15__CMGCRBASE:
7021             check_insn(ctx, ISA_MIPS_R2);
7022             CP0_CHECK(ctx->cmgcr);
7023             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7024             register_name = "CMGCRBase";
7025             break;
7026         default:
7027             goto cp0_unimplemented;
7028         }
7029         break;
7030     case CP0_REGISTER_16:
7031         switch (sel) {
7032         case CP0_REG16__CONFIG:
7033             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7034             register_name = "Config";
7035             break;
7036         case CP0_REG16__CONFIG1:
7037             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7038             register_name = "Config1";
7039             break;
7040         case CP0_REG16__CONFIG2:
7041             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7042             register_name = "Config2";
7043             break;
7044         case CP0_REG16__CONFIG3:
7045             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7046             register_name = "Config3";
7047             break;
7048         case CP0_REG16__CONFIG4:
7049             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7050             register_name = "Config4";
7051             break;
7052         case CP0_REG16__CONFIG5:
7053             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7054             register_name = "Config5";
7055             break;
7056         /* 6,7 are implementation dependent */
7057         case CP0_REG16__CONFIG6:
7058             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7059             register_name = "Config6";
7060             break;
7061         case CP0_REG16__CONFIG7:
7062             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7063             register_name = "Config7";
7064             break;
7065         default:
7066             goto cp0_unimplemented;
7067         }
7068         break;
7069     case CP0_REGISTER_17:
7070         switch (sel) {
7071         case CP0_REG17__LLADDR:
7072             gen_helper_dmfc0_lladdr(arg, tcg_env);
7073             register_name = "LLAddr";
7074             break;
7075         case CP0_REG17__MAAR:
7076             CP0_CHECK(ctx->mrp);
7077             gen_helper_dmfc0_maar(arg, tcg_env);
7078             register_name = "MAAR";
7079             break;
7080         case CP0_REG17__MAARI:
7081             CP0_CHECK(ctx->mrp);
7082             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7083             register_name = "MAARI";
7084             break;
7085         default:
7086             goto cp0_unimplemented;
7087         }
7088         break;
7089     case CP0_REGISTER_18:
7090         switch (sel) {
7091         case CP0_REG18__WATCHLO0:
7092         case CP0_REG18__WATCHLO1:
7093         case CP0_REG18__WATCHLO2:
7094         case CP0_REG18__WATCHLO3:
7095         case CP0_REG18__WATCHLO4:
7096         case CP0_REG18__WATCHLO5:
7097         case CP0_REG18__WATCHLO6:
7098         case CP0_REG18__WATCHLO7:
7099             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7100             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7101             register_name = "WatchLo";
7102             break;
7103         default:
7104             goto cp0_unimplemented;
7105         }
7106         break;
7107     case CP0_REGISTER_19:
7108         switch (sel) {
7109         case CP0_REG19__WATCHHI0:
7110         case CP0_REG19__WATCHHI1:
7111         case CP0_REG19__WATCHHI2:
7112         case CP0_REG19__WATCHHI3:
7113         case CP0_REG19__WATCHHI4:
7114         case CP0_REG19__WATCHHI5:
7115         case CP0_REG19__WATCHHI6:
7116         case CP0_REG19__WATCHHI7:
7117             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7118             gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7119             register_name = "WatchHi";
7120             break;
7121         default:
7122             goto cp0_unimplemented;
7123         }
7124         break;
7125     case CP0_REGISTER_20:
7126         switch (sel) {
7127         case CP0_REG20__XCONTEXT:
7128             check_insn(ctx, ISA_MIPS3);
7129             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
7130             register_name = "XContext";
7131             break;
7132         default:
7133             goto cp0_unimplemented;
7134         }
7135         break;
7136     case CP0_REGISTER_21:
7137         /* Officially reserved, but sel 0 is used for R1x000 framemask */
7138         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7139         switch (sel) {
7140         case 0:
7141             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7142             register_name = "Framemask";
7143             break;
7144         default:
7145             goto cp0_unimplemented;
7146         }
7147         break;
7148     case CP0_REGISTER_22:
7149         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7150         register_name = "'Diagnostic"; /* implementation dependent */
7151         break;
7152     case CP0_REGISTER_23:
7153         switch (sel) {
7154         case CP0_REG23__DEBUG:
7155             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
7156             register_name = "Debug";
7157             break;
7158         case CP0_REG23__TRACECONTROL:
7159             /* PDtrace support */
7160             /* gen_helper_dmfc0_tracecontrol(arg, tcg_env);  */
7161             register_name = "TraceControl";
7162             goto cp0_unimplemented;
7163         case CP0_REG23__TRACECONTROL2:
7164             /* PDtrace support */
7165             /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */
7166             register_name = "TraceControl2";
7167             goto cp0_unimplemented;
7168         case CP0_REG23__USERTRACEDATA1:
7169             /* PDtrace support */
7170             /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/
7171             register_name = "UserTraceData1";
7172             goto cp0_unimplemented;
7173         case CP0_REG23__TRACEIBPC:
7174             /* PDtrace support */
7175             /* gen_helper_dmfc0_traceibpc(arg, tcg_env);     */
7176             register_name = "TraceIBPC";
7177             goto cp0_unimplemented;
7178         case CP0_REG23__TRACEDBPC:
7179             /* PDtrace support */
7180             /* gen_helper_dmfc0_tracedbpc(arg, tcg_env);     */
7181             register_name = "TraceDBPC";
7182             goto cp0_unimplemented;
7183         default:
7184             goto cp0_unimplemented;
7185         }
7186         break;
7187     case CP0_REGISTER_24:
7188         switch (sel) {
7189         case CP0_REG24__DEPC:
7190             /* EJTAG support */
7191             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7192             register_name = "DEPC";
7193             break;
7194         default:
7195             goto cp0_unimplemented;
7196         }
7197         break;
7198     case CP0_REGISTER_25:
7199         switch (sel) {
7200         case CP0_REG25__PERFCTL0:
7201             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7202             register_name = "Performance0";
7203             break;
7204         case CP0_REG25__PERFCNT0:
7205             /* gen_helper_dmfc0_performance1(arg); */
7206             register_name = "Performance1";
7207             goto cp0_unimplemented;
7208         case CP0_REG25__PERFCTL1:
7209             /* gen_helper_dmfc0_performance2(arg); */
7210             register_name = "Performance2";
7211             goto cp0_unimplemented;
7212         case CP0_REG25__PERFCNT1:
7213             /* gen_helper_dmfc0_performance3(arg); */
7214             register_name = "Performance3";
7215             goto cp0_unimplemented;
7216         case CP0_REG25__PERFCTL2:
7217             /* gen_helper_dmfc0_performance4(arg); */
7218             register_name = "Performance4";
7219             goto cp0_unimplemented;
7220         case CP0_REG25__PERFCNT2:
7221             /* gen_helper_dmfc0_performance5(arg); */
7222             register_name = "Performance5";
7223             goto cp0_unimplemented;
7224         case CP0_REG25__PERFCTL3:
7225             /* gen_helper_dmfc0_performance6(arg); */
7226             register_name = "Performance6";
7227             goto cp0_unimplemented;
7228         case CP0_REG25__PERFCNT3:
7229             /* gen_helper_dmfc0_performance7(arg); */
7230             register_name = "Performance7";
7231             goto cp0_unimplemented;
7232         default:
7233             goto cp0_unimplemented;
7234         }
7235         break;
7236     case CP0_REGISTER_26:
7237         switch (sel) {
7238         case CP0_REG26__ERRCTL:
7239             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7240             register_name = "ErrCtl";
7241             break;
7242         default:
7243             goto cp0_unimplemented;
7244         }
7245         break;
7246     case CP0_REGISTER_27:
7247         switch (sel) {
7248         /* ignored */
7249         case CP0_REG27__CACHERR:
7250             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7251             register_name = "CacheErr";
7252             break;
7253         default:
7254             goto cp0_unimplemented;
7255         }
7256         break;
7257     case CP0_REGISTER_28:
7258         switch (sel) {
7259         case CP0_REG28__TAGLO:
7260         case CP0_REG28__TAGLO1:
7261         case CP0_REG28__TAGLO2:
7262         case CP0_REG28__TAGLO3:
7263             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7264             register_name = "TagLo";
7265             break;
7266         case CP0_REG28__DATALO:
7267         case CP0_REG28__DATALO1:
7268         case CP0_REG28__DATALO2:
7269         case CP0_REG28__DATALO3:
7270             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7271             register_name = "DataLo";
7272             break;
7273         default:
7274             goto cp0_unimplemented;
7275         }
7276         break;
7277     case CP0_REGISTER_29:
7278         switch (sel) {
7279         case CP0_REG29__TAGHI:
7280         case CP0_REG29__TAGHI1:
7281         case CP0_REG29__TAGHI2:
7282         case CP0_REG29__TAGHI3:
7283             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7284             register_name = "TagHi";
7285             break;
7286         case CP0_REG29__DATAHI:
7287         case CP0_REG29__DATAHI1:
7288         case CP0_REG29__DATAHI2:
7289         case CP0_REG29__DATAHI3:
7290             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7291             register_name = "DataHi";
7292             break;
7293         default:
7294             goto cp0_unimplemented;
7295         }
7296         break;
7297     case CP0_REGISTER_30:
7298         switch (sel) {
7299         case CP0_REG30__ERROREPC:
7300             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7301             register_name = "ErrorEPC";
7302             break;
7303         default:
7304             goto cp0_unimplemented;
7305         }
7306         break;
7307     case CP0_REGISTER_31:
7308         switch (sel) {
7309         case CP0_REG31__DESAVE:
7310             /* EJTAG support */
7311             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7312             register_name = "DESAVE";
7313             break;
7314         case CP0_REG31__KSCRATCH1:
7315         case CP0_REG31__KSCRATCH2:
7316         case CP0_REG31__KSCRATCH3:
7317         case CP0_REG31__KSCRATCH4:
7318         case CP0_REG31__KSCRATCH5:
7319         case CP0_REG31__KSCRATCH6:
7320             CP0_CHECK(ctx->kscrexist & (1 << sel));
7321             tcg_gen_ld_tl(arg, tcg_env,
7322                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7323             register_name = "KScratch";
7324             break;
7325         default:
7326             goto cp0_unimplemented;
7327         }
7328         break;
7329     default:
7330         goto cp0_unimplemented;
7331     }
7332     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7333     return;
7334 
7335 cp0_unimplemented:
7336     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7337                   register_name, reg, sel);
7338     gen_mfc0_unimplemented(ctx, arg);
7339 }
7340 
gen_dmtc0(DisasContext * ctx,TCGv arg,int reg,int sel)7341 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7342 {
7343     const char *register_name = "invalid";
7344     bool icount;
7345 
7346     if (sel != 0) {
7347         check_insn(ctx, ISA_MIPS_R1);
7348     }
7349 
7350     icount = translator_io_start(&ctx->base);
7351 
7352     switch (reg) {
7353     case CP0_REGISTER_00:
7354         switch (sel) {
7355         case CP0_REG00__INDEX:
7356             gen_helper_mtc0_index(tcg_env, arg);
7357             register_name = "Index";
7358             break;
7359         case CP0_REG00__MVPCONTROL:
7360             CP0_CHECK(disas_mt_available(ctx));
7361             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
7362             register_name = "MVPControl";
7363             break;
7364         case CP0_REG00__MVPCONF0:
7365             CP0_CHECK(disas_mt_available(ctx));
7366             /* ignored */
7367             register_name = "MVPConf0";
7368             break;
7369         case CP0_REG00__MVPCONF1:
7370             CP0_CHECK(disas_mt_available(ctx));
7371             /* ignored */
7372             register_name = "MVPConf1";
7373             break;
7374         case CP0_REG00__VPCONTROL:
7375             CP0_CHECK(ctx->vp);
7376             /* ignored */
7377             register_name = "VPControl";
7378             break;
7379         default:
7380             goto cp0_unimplemented;
7381         }
7382         break;
7383     case CP0_REGISTER_01:
7384         switch (sel) {
7385         case CP0_REG01__RANDOM:
7386             /* ignored */
7387             register_name = "Random";
7388             break;
7389         case CP0_REG01__VPECONTROL:
7390             CP0_CHECK(disas_mt_available(ctx));
7391             gen_helper_mtc0_vpecontrol(tcg_env, arg);
7392             register_name = "VPEControl";
7393             break;
7394         case CP0_REG01__VPECONF0:
7395             CP0_CHECK(disas_mt_available(ctx));
7396             gen_helper_mtc0_vpeconf0(tcg_env, arg);
7397             register_name = "VPEConf0";
7398             break;
7399         case CP0_REG01__VPECONF1:
7400             CP0_CHECK(disas_mt_available(ctx));
7401             gen_helper_mtc0_vpeconf1(tcg_env, arg);
7402             register_name = "VPEConf1";
7403             break;
7404         case CP0_REG01__YQMASK:
7405             CP0_CHECK(disas_mt_available(ctx));
7406             gen_helper_mtc0_yqmask(tcg_env, arg);
7407             register_name = "YQMask";
7408             break;
7409         case CP0_REG01__VPESCHEDULE:
7410             CP0_CHECK(disas_mt_available(ctx));
7411             tcg_gen_st_tl(arg, tcg_env,
7412                           offsetof(CPUMIPSState, CP0_VPESchedule));
7413             register_name = "VPESchedule";
7414             break;
7415         case CP0_REG01__VPESCHEFBACK:
7416             CP0_CHECK(disas_mt_available(ctx));
7417             tcg_gen_st_tl(arg, tcg_env,
7418                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7419             register_name = "VPEScheFBack";
7420             break;
7421         case CP0_REG01__VPEOPT:
7422             CP0_CHECK(disas_mt_available(ctx));
7423             gen_helper_mtc0_vpeopt(tcg_env, arg);
7424             register_name = "VPEOpt";
7425             break;
7426         default:
7427             goto cp0_unimplemented;
7428         }
7429         break;
7430     case CP0_REGISTER_02:
7431         switch (sel) {
7432         case CP0_REG02__ENTRYLO0:
7433             gen_helper_dmtc0_entrylo0(tcg_env, arg);
7434             register_name = "EntryLo0";
7435             break;
7436         case CP0_REG02__TCSTATUS:
7437             CP0_CHECK(disas_mt_available(ctx));
7438             gen_helper_mtc0_tcstatus(tcg_env, arg);
7439             register_name = "TCStatus";
7440             break;
7441         case CP0_REG02__TCBIND:
7442             CP0_CHECK(disas_mt_available(ctx));
7443             gen_helper_mtc0_tcbind(tcg_env, arg);
7444             register_name = "TCBind";
7445             break;
7446         case CP0_REG02__TCRESTART:
7447             CP0_CHECK(disas_mt_available(ctx));
7448             gen_helper_mtc0_tcrestart(tcg_env, arg);
7449             register_name = "TCRestart";
7450             break;
7451         case CP0_REG02__TCHALT:
7452             CP0_CHECK(disas_mt_available(ctx));
7453             gen_helper_mtc0_tchalt(tcg_env, arg);
7454             register_name = "TCHalt";
7455             break;
7456         case CP0_REG02__TCCONTEXT:
7457             CP0_CHECK(disas_mt_available(ctx));
7458             gen_helper_mtc0_tccontext(tcg_env, arg);
7459             register_name = "TCContext";
7460             break;
7461         case CP0_REG02__TCSCHEDULE:
7462             CP0_CHECK(disas_mt_available(ctx));
7463             gen_helper_mtc0_tcschedule(tcg_env, arg);
7464             register_name = "TCSchedule";
7465             break;
7466         case CP0_REG02__TCSCHEFBACK:
7467             CP0_CHECK(disas_mt_available(ctx));
7468             gen_helper_mtc0_tcschefback(tcg_env, arg);
7469             register_name = "TCScheFBack";
7470             break;
7471         default:
7472             goto cp0_unimplemented;
7473         }
7474         break;
7475     case CP0_REGISTER_03:
7476         switch (sel) {
7477         case CP0_REG03__ENTRYLO1:
7478             gen_helper_dmtc0_entrylo1(tcg_env, arg);
7479             register_name = "EntryLo1";
7480             break;
7481         case CP0_REG03__GLOBALNUM:
7482             CP0_CHECK(ctx->vp);
7483             /* ignored */
7484             register_name = "GlobalNumber";
7485             break;
7486         default:
7487             goto cp0_unimplemented;
7488         }
7489         break;
7490     case CP0_REGISTER_04:
7491         switch (sel) {
7492         case CP0_REG04__CONTEXT:
7493             gen_helper_mtc0_context(tcg_env, arg);
7494             register_name = "Context";
7495             break;
7496         case CP0_REG04__CONTEXTCONFIG:
7497             /* SmartMIPS ASE */
7498             /* gen_helper_dmtc0_contextconfig(arg); */
7499             register_name = "ContextConfig";
7500             goto cp0_unimplemented;
7501         case CP0_REG04__USERLOCAL:
7502             CP0_CHECK(ctx->ulri);
7503             tcg_gen_st_tl(arg, tcg_env,
7504                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7505             register_name = "UserLocal";
7506             break;
7507         case CP0_REG04__MMID:
7508             CP0_CHECK(ctx->mi);
7509             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7510             register_name = "MMID";
7511             break;
7512         default:
7513             goto cp0_unimplemented;
7514         }
7515         break;
7516     case CP0_REGISTER_05:
7517         switch (sel) {
7518         case CP0_REG05__PAGEMASK:
7519             gen_helper_mtc0_pagemask(tcg_env, arg);
7520             register_name = "PageMask";
7521             break;
7522         case CP0_REG05__PAGEGRAIN:
7523             check_insn(ctx, ISA_MIPS_R2);
7524             gen_helper_mtc0_pagegrain(tcg_env, arg);
7525             register_name = "PageGrain";
7526             break;
7527         case CP0_REG05__SEGCTL0:
7528             CP0_CHECK(ctx->sc);
7529             gen_helper_mtc0_segctl0(tcg_env, arg);
7530             register_name = "SegCtl0";
7531             break;
7532         case CP0_REG05__SEGCTL1:
7533             CP0_CHECK(ctx->sc);
7534             gen_helper_mtc0_segctl1(tcg_env, arg);
7535             register_name = "SegCtl1";
7536             break;
7537         case CP0_REG05__SEGCTL2:
7538             CP0_CHECK(ctx->sc);
7539             gen_helper_mtc0_segctl2(tcg_env, arg);
7540             register_name = "SegCtl2";
7541             break;
7542         case CP0_REG05__PWBASE:
7543             check_pw(ctx);
7544             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
7545             register_name = "PWBase";
7546             break;
7547         case CP0_REG05__PWFIELD:
7548             check_pw(ctx);
7549             gen_helper_mtc0_pwfield(tcg_env, arg);
7550             register_name = "PWField";
7551             break;
7552         case CP0_REG05__PWSIZE:
7553             check_pw(ctx);
7554             gen_helper_mtc0_pwsize(tcg_env, arg);
7555             register_name = "PWSize";
7556             break;
7557         default:
7558             goto cp0_unimplemented;
7559         }
7560         break;
7561     case CP0_REGISTER_06:
7562         switch (sel) {
7563         case CP0_REG06__WIRED:
7564             gen_helper_mtc0_wired(tcg_env, arg);
7565             register_name = "Wired";
7566             break;
7567         case CP0_REG06__SRSCONF0:
7568             check_insn(ctx, ISA_MIPS_R2);
7569             gen_helper_mtc0_srsconf0(tcg_env, arg);
7570             register_name = "SRSConf0";
7571             break;
7572         case CP0_REG06__SRSCONF1:
7573             check_insn(ctx, ISA_MIPS_R2);
7574             gen_helper_mtc0_srsconf1(tcg_env, arg);
7575             register_name = "SRSConf1";
7576             break;
7577         case CP0_REG06__SRSCONF2:
7578             check_insn(ctx, ISA_MIPS_R2);
7579             gen_helper_mtc0_srsconf2(tcg_env, arg);
7580             register_name = "SRSConf2";
7581             break;
7582         case CP0_REG06__SRSCONF3:
7583             check_insn(ctx, ISA_MIPS_R2);
7584             gen_helper_mtc0_srsconf3(tcg_env, arg);
7585             register_name = "SRSConf3";
7586             break;
7587         case CP0_REG06__SRSCONF4:
7588             check_insn(ctx, ISA_MIPS_R2);
7589             gen_helper_mtc0_srsconf4(tcg_env, arg);
7590             register_name = "SRSConf4";
7591             break;
7592         case CP0_REG06__PWCTL:
7593             check_pw(ctx);
7594             gen_helper_mtc0_pwctl(tcg_env, arg);
7595             register_name = "PWCtl";
7596             break;
7597         default:
7598             goto cp0_unimplemented;
7599         }
7600         break;
7601     case CP0_REGISTER_07:
7602         switch (sel) {
7603         case CP0_REG07__HWRENA:
7604             check_insn(ctx, ISA_MIPS_R2);
7605             gen_helper_mtc0_hwrena(tcg_env, arg);
7606             ctx->base.is_jmp = DISAS_STOP;
7607             register_name = "HWREna";
7608             break;
7609         default:
7610             goto cp0_unimplemented;
7611         }
7612         break;
7613     case CP0_REGISTER_08:
7614         switch (sel) {
7615         case CP0_REG08__BADVADDR:
7616             /* ignored */
7617             register_name = "BadVAddr";
7618             break;
7619         case CP0_REG08__BADINSTR:
7620             /* ignored */
7621             register_name = "BadInstr";
7622             break;
7623         case CP0_REG08__BADINSTRP:
7624             /* ignored */
7625             register_name = "BadInstrP";
7626             break;
7627         case CP0_REG08__BADINSTRX:
7628             /* ignored */
7629             register_name = "BadInstrX";
7630             break;
7631         default:
7632             goto cp0_unimplemented;
7633         }
7634         break;
7635     case CP0_REGISTER_09:
7636         switch (sel) {
7637         case CP0_REG09__COUNT:
7638             gen_helper_mtc0_count(tcg_env, arg);
7639             register_name = "Count";
7640             break;
7641         default:
7642             goto cp0_unimplemented;
7643         }
7644         /* Stop translation as we may have switched the execution mode */
7645         ctx->base.is_jmp = DISAS_STOP;
7646         break;
7647     case CP0_REGISTER_10:
7648         switch (sel) {
7649         case CP0_REG10__ENTRYHI:
7650             gen_helper_mtc0_entryhi(tcg_env, arg);
7651             register_name = "EntryHi";
7652             break;
7653         default:
7654             goto cp0_unimplemented;
7655         }
7656         break;
7657     case CP0_REGISTER_11:
7658         switch (sel) {
7659         case CP0_REG11__COMPARE:
7660             gen_helper_mtc0_compare(tcg_env, arg);
7661             register_name = "Compare";
7662             break;
7663         /* 6,7 are implementation dependent */
7664         default:
7665             goto cp0_unimplemented;
7666         }
7667         /* Stop translation as we may have switched the execution mode */
7668         ctx->base.is_jmp = DISAS_STOP;
7669         break;
7670     case CP0_REGISTER_12:
7671         switch (sel) {
7672         case CP0_REG12__STATUS:
7673             save_cpu_state(ctx, 1);
7674             gen_helper_mtc0_status(tcg_env, arg);
7675             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7676             gen_save_pc(ctx->base.pc_next + 4);
7677             ctx->base.is_jmp = DISAS_EXIT;
7678             register_name = "Status";
7679             break;
7680         case CP0_REG12__INTCTL:
7681             check_insn(ctx, ISA_MIPS_R2);
7682             gen_helper_mtc0_intctl(tcg_env, arg);
7683             /* Stop translation as we may have switched the execution mode */
7684             ctx->base.is_jmp = DISAS_STOP;
7685             register_name = "IntCtl";
7686             break;
7687         case CP0_REG12__SRSCTL:
7688             check_insn(ctx, ISA_MIPS_R2);
7689             gen_helper_mtc0_srsctl(tcg_env, arg);
7690             /* Stop translation as we may have switched the execution mode */
7691             ctx->base.is_jmp = DISAS_STOP;
7692             register_name = "SRSCtl";
7693             break;
7694         case CP0_REG12__SRSMAP:
7695             check_insn(ctx, ISA_MIPS_R2);
7696             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7697             /* Stop translation as we may have switched the execution mode */
7698             ctx->base.is_jmp = DISAS_STOP;
7699             register_name = "SRSMap";
7700             break;
7701         default:
7702             goto cp0_unimplemented;
7703         }
7704         break;
7705     case CP0_REGISTER_13:
7706         switch (sel) {
7707         case CP0_REG13__CAUSE:
7708             save_cpu_state(ctx, 1);
7709             gen_helper_mtc0_cause(tcg_env, arg);
7710             /*
7711              * Stop translation as we may have triggered an interrupt.
7712              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7713              * translated code to check for pending interrupts.
7714              */
7715             gen_save_pc(ctx->base.pc_next + 4);
7716             ctx->base.is_jmp = DISAS_EXIT;
7717             register_name = "Cause";
7718             break;
7719         default:
7720             goto cp0_unimplemented;
7721         }
7722         break;
7723     case CP0_REGISTER_14:
7724         switch (sel) {
7725         case CP0_REG14__EPC:
7726             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7727             register_name = "EPC";
7728             break;
7729         default:
7730             goto cp0_unimplemented;
7731         }
7732         break;
7733     case CP0_REGISTER_15:
7734         switch (sel) {
7735         case CP0_REG15__PRID:
7736             /* ignored */
7737             register_name = "PRid";
7738             break;
7739         case CP0_REG15__EBASE:
7740             check_insn(ctx, ISA_MIPS_R2);
7741             gen_helper_mtc0_ebase(tcg_env, arg);
7742             register_name = "EBase";
7743             break;
7744         default:
7745             goto cp0_unimplemented;
7746         }
7747         break;
7748     case CP0_REGISTER_16:
7749         switch (sel) {
7750         case CP0_REG16__CONFIG:
7751             gen_helper_mtc0_config0(tcg_env, arg);
7752             register_name = "Config";
7753             /* Stop translation as we may have switched the execution mode */
7754             ctx->base.is_jmp = DISAS_STOP;
7755             break;
7756         case CP0_REG16__CONFIG1:
7757             /* ignored, read only */
7758             register_name = "Config1";
7759             break;
7760         case CP0_REG16__CONFIG2:
7761             gen_helper_mtc0_config2(tcg_env, arg);
7762             register_name = "Config2";
7763             /* Stop translation as we may have switched the execution mode */
7764             ctx->base.is_jmp = DISAS_STOP;
7765             break;
7766         case CP0_REG16__CONFIG3:
7767             gen_helper_mtc0_config3(tcg_env, arg);
7768             register_name = "Config3";
7769             /* Stop translation as we may have switched the execution mode */
7770             ctx->base.is_jmp = DISAS_STOP;
7771             break;
7772         case CP0_REG16__CONFIG4:
7773             /* currently ignored */
7774             register_name = "Config4";
7775             break;
7776         case CP0_REG16__CONFIG5:
7777             gen_helper_mtc0_config5(tcg_env, arg);
7778             register_name = "Config5";
7779             /* Stop translation as we may have switched the execution mode */
7780             ctx->base.is_jmp = DISAS_STOP;
7781             break;
7782         /* 6,7 are implementation dependent */
7783         default:
7784             register_name = "Invalid config selector";
7785             goto cp0_unimplemented;
7786         }
7787         break;
7788     case CP0_REGISTER_17:
7789         switch (sel) {
7790         case CP0_REG17__LLADDR:
7791             gen_helper_mtc0_lladdr(tcg_env, arg);
7792             register_name = "LLAddr";
7793             break;
7794         case CP0_REG17__MAAR:
7795             CP0_CHECK(ctx->mrp);
7796             gen_helper_mtc0_maar(tcg_env, arg);
7797             register_name = "MAAR";
7798             break;
7799         case CP0_REG17__MAARI:
7800             CP0_CHECK(ctx->mrp);
7801             gen_helper_mtc0_maari(tcg_env, arg);
7802             register_name = "MAARI";
7803             break;
7804         default:
7805             goto cp0_unimplemented;
7806         }
7807         break;
7808     case CP0_REGISTER_18:
7809         switch (sel) {
7810         case CP0_REG18__WATCHLO0:
7811         case CP0_REG18__WATCHLO1:
7812         case CP0_REG18__WATCHLO2:
7813         case CP0_REG18__WATCHLO3:
7814         case CP0_REG18__WATCHLO4:
7815         case CP0_REG18__WATCHLO5:
7816         case CP0_REG18__WATCHLO6:
7817         case CP0_REG18__WATCHLO7:
7818             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7819             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7820             register_name = "WatchLo";
7821             break;
7822         default:
7823             goto cp0_unimplemented;
7824         }
7825         break;
7826     case CP0_REGISTER_19:
7827         switch (sel) {
7828         case CP0_REG19__WATCHHI0:
7829         case CP0_REG19__WATCHHI1:
7830         case CP0_REG19__WATCHHI2:
7831         case CP0_REG19__WATCHHI3:
7832         case CP0_REG19__WATCHHI4:
7833         case CP0_REG19__WATCHHI5:
7834         case CP0_REG19__WATCHHI6:
7835         case CP0_REG19__WATCHHI7:
7836             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7837             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7838             register_name = "WatchHi";
7839             break;
7840         default:
7841             goto cp0_unimplemented;
7842         }
7843         break;
7844     case CP0_REGISTER_20:
7845         switch (sel) {
7846         case CP0_REG20__XCONTEXT:
7847             check_insn(ctx, ISA_MIPS3);
7848             gen_helper_mtc0_xcontext(tcg_env, arg);
7849             register_name = "XContext";
7850             break;
7851         default:
7852             goto cp0_unimplemented;
7853         }
7854         break;
7855     case CP0_REGISTER_21:
7856        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7857         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7858         switch (sel) {
7859         case 0:
7860             gen_helper_mtc0_framemask(tcg_env, arg);
7861             register_name = "Framemask";
7862             break;
7863         default:
7864             goto cp0_unimplemented;
7865         }
7866         break;
7867     case CP0_REGISTER_22:
7868         /* ignored */
7869         register_name = "Diagnostic"; /* implementation dependent */
7870         break;
7871     case CP0_REGISTER_23:
7872         switch (sel) {
7873         case CP0_REG23__DEBUG:
7874             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
7875             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7876             gen_save_pc(ctx->base.pc_next + 4);
7877             ctx->base.is_jmp = DISAS_EXIT;
7878             register_name = "Debug";
7879             break;
7880         case CP0_REG23__TRACECONTROL:
7881             /* PDtrace support */
7882             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
7883             /* Stop translation as we may have switched the execution mode */
7884             ctx->base.is_jmp = DISAS_STOP;
7885             register_name = "TraceControl";
7886             goto cp0_unimplemented;
7887         case CP0_REG23__TRACECONTROL2:
7888             /* PDtrace support */
7889             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
7890             /* Stop translation as we may have switched the execution mode */
7891             ctx->base.is_jmp = DISAS_STOP;
7892             register_name = "TraceControl2";
7893             goto cp0_unimplemented;
7894         case CP0_REG23__USERTRACEDATA1:
7895             /* PDtrace support */
7896             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
7897             /* Stop translation as we may have switched the execution mode */
7898             ctx->base.is_jmp = DISAS_STOP;
7899             register_name = "UserTraceData1";
7900             goto cp0_unimplemented;
7901         case CP0_REG23__TRACEIBPC:
7902             /* PDtrace support */
7903             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
7904             /* Stop translation as we may have switched the execution mode */
7905             ctx->base.is_jmp = DISAS_STOP;
7906             register_name = "TraceIBPC";
7907             goto cp0_unimplemented;
7908         case CP0_REG23__TRACEDBPC:
7909             /* PDtrace support */
7910             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
7911             /* Stop translation as we may have switched the execution mode */
7912             ctx->base.is_jmp = DISAS_STOP;
7913             register_name = "TraceDBPC";
7914             goto cp0_unimplemented;
7915         default:
7916             goto cp0_unimplemented;
7917         }
7918         break;
7919     case CP0_REGISTER_24:
7920         switch (sel) {
7921         case CP0_REG24__DEPC:
7922             /* EJTAG support */
7923             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7924             register_name = "DEPC";
7925             break;
7926         default:
7927             goto cp0_unimplemented;
7928         }
7929         break;
7930     case CP0_REGISTER_25:
7931         switch (sel) {
7932         case CP0_REG25__PERFCTL0:
7933             gen_helper_mtc0_performance0(tcg_env, arg);
7934             register_name = "Performance0";
7935             break;
7936         case CP0_REG25__PERFCNT0:
7937             /* gen_helper_mtc0_performance1(tcg_env, arg); */
7938             register_name = "Performance1";
7939             goto cp0_unimplemented;
7940         case CP0_REG25__PERFCTL1:
7941             /* gen_helper_mtc0_performance2(tcg_env, arg); */
7942             register_name = "Performance2";
7943             goto cp0_unimplemented;
7944         case CP0_REG25__PERFCNT1:
7945             /* gen_helper_mtc0_performance3(tcg_env, arg); */
7946             register_name = "Performance3";
7947             goto cp0_unimplemented;
7948         case CP0_REG25__PERFCTL2:
7949             /* gen_helper_mtc0_performance4(tcg_env, arg); */
7950             register_name = "Performance4";
7951             goto cp0_unimplemented;
7952         case CP0_REG25__PERFCNT2:
7953             /* gen_helper_mtc0_performance5(tcg_env, arg); */
7954             register_name = "Performance5";
7955             goto cp0_unimplemented;
7956         case CP0_REG25__PERFCTL3:
7957             /* gen_helper_mtc0_performance6(tcg_env, arg); */
7958             register_name = "Performance6";
7959             goto cp0_unimplemented;
7960         case CP0_REG25__PERFCNT3:
7961             /* gen_helper_mtc0_performance7(tcg_env, arg); */
7962             register_name = "Performance7";
7963             goto cp0_unimplemented;
7964         default:
7965             goto cp0_unimplemented;
7966         }
7967         break;
7968     case CP0_REGISTER_26:
7969         switch (sel) {
7970         case CP0_REG26__ERRCTL:
7971             gen_helper_mtc0_errctl(tcg_env, arg);
7972             ctx->base.is_jmp = DISAS_STOP;
7973             register_name = "ErrCtl";
7974             break;
7975         default:
7976             goto cp0_unimplemented;
7977         }
7978         break;
7979     case CP0_REGISTER_27:
7980         switch (sel) {
7981         case CP0_REG27__CACHERR:
7982             /* ignored */
7983             register_name = "CacheErr";
7984             break;
7985         default:
7986             goto cp0_unimplemented;
7987         }
7988         break;
7989     case CP0_REGISTER_28:
7990         switch (sel) {
7991         case CP0_REG28__TAGLO:
7992         case CP0_REG28__TAGLO1:
7993         case CP0_REG28__TAGLO2:
7994         case CP0_REG28__TAGLO3:
7995             gen_helper_mtc0_taglo(tcg_env, arg);
7996             register_name = "TagLo";
7997             break;
7998         case CP0_REG28__DATALO:
7999         case CP0_REG28__DATALO1:
8000         case CP0_REG28__DATALO2:
8001         case CP0_REG28__DATALO3:
8002             gen_helper_mtc0_datalo(tcg_env, arg);
8003             register_name = "DataLo";
8004             break;
8005         default:
8006             goto cp0_unimplemented;
8007         }
8008         break;
8009     case CP0_REGISTER_29:
8010         switch (sel) {
8011         case CP0_REG29__TAGHI:
8012         case CP0_REG29__TAGHI1:
8013         case CP0_REG29__TAGHI2:
8014         case CP0_REG29__TAGHI3:
8015             gen_helper_mtc0_taghi(tcg_env, arg);
8016             register_name = "TagHi";
8017             break;
8018         case CP0_REG29__DATAHI:
8019         case CP0_REG29__DATAHI1:
8020         case CP0_REG29__DATAHI2:
8021         case CP0_REG29__DATAHI3:
8022             gen_helper_mtc0_datahi(tcg_env, arg);
8023             register_name = "DataHi";
8024             break;
8025         default:
8026             register_name = "invalid sel";
8027             goto cp0_unimplemented;
8028         }
8029         break;
8030     case CP0_REGISTER_30:
8031         switch (sel) {
8032         case CP0_REG30__ERROREPC:
8033             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8034             register_name = "ErrorEPC";
8035             break;
8036         default:
8037             goto cp0_unimplemented;
8038         }
8039         break;
8040     case CP0_REGISTER_31:
8041         switch (sel) {
8042         case CP0_REG31__DESAVE:
8043             /* EJTAG support */
8044             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8045             register_name = "DESAVE";
8046             break;
8047         case CP0_REG31__KSCRATCH1:
8048         case CP0_REG31__KSCRATCH2:
8049         case CP0_REG31__KSCRATCH3:
8050         case CP0_REG31__KSCRATCH4:
8051         case CP0_REG31__KSCRATCH5:
8052         case CP0_REG31__KSCRATCH6:
8053             CP0_CHECK(ctx->kscrexist & (1 << sel));
8054             tcg_gen_st_tl(arg, tcg_env,
8055                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8056             register_name = "KScratch";
8057             break;
8058         default:
8059             goto cp0_unimplemented;
8060         }
8061         break;
8062     default:
8063         goto cp0_unimplemented;
8064     }
8065     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8066 
8067     /* For simplicity assume that all writes can cause interrupts.  */
8068     if (icount) {
8069         /*
8070          * DISAS_STOP isn't sufficient, we need to ensure we break out of
8071          * translated code to check for pending interrupts.
8072          */
8073         gen_save_pc(ctx->base.pc_next + 4);
8074         ctx->base.is_jmp = DISAS_EXIT;
8075     }
8076     return;
8077 
8078 cp0_unimplemented:
8079     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8080                   register_name, reg, sel);
8081 }
8082 #endif /* TARGET_MIPS64 */
8083 
gen_mftr(CPUMIPSState * env,DisasContext * ctx,int rt,int rd,int u,int sel,int h)8084 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8085                      int u, int sel, int h)
8086 {
8087     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8088     TCGv t0 = tcg_temp_new();
8089 
8090     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8091         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8092          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8093         tcg_gen_movi_tl(t0, -1);
8094     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8095                (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8096         tcg_gen_movi_tl(t0, -1);
8097     } else if (u == 0) {
8098         switch (rt) {
8099         case 1:
8100             switch (sel) {
8101             case 1:
8102                 gen_helper_mftc0_vpecontrol(t0, tcg_env);
8103                 break;
8104             case 2:
8105                 gen_helper_mftc0_vpeconf0(t0, tcg_env);
8106                 break;
8107             default:
8108                 goto die;
8109                 break;
8110             }
8111             break;
8112         case 2:
8113             switch (sel) {
8114             case 1:
8115                 gen_helper_mftc0_tcstatus(t0, tcg_env);
8116                 break;
8117             case 2:
8118                 gen_helper_mftc0_tcbind(t0, tcg_env);
8119                 break;
8120             case 3:
8121                 gen_helper_mftc0_tcrestart(t0, tcg_env);
8122                 break;
8123             case 4:
8124                 gen_helper_mftc0_tchalt(t0, tcg_env);
8125                 break;
8126             case 5:
8127                 gen_helper_mftc0_tccontext(t0, tcg_env);
8128                 break;
8129             case 6:
8130                 gen_helper_mftc0_tcschedule(t0, tcg_env);
8131                 break;
8132             case 7:
8133                 gen_helper_mftc0_tcschefback(t0, tcg_env);
8134                 break;
8135             default:
8136                 gen_mfc0(ctx, t0, rt, sel);
8137                 break;
8138             }
8139             break;
8140         case 10:
8141             switch (sel) {
8142             case 0:
8143                 gen_helper_mftc0_entryhi(t0, tcg_env);
8144                 break;
8145             default:
8146                 gen_mfc0(ctx, t0, rt, sel);
8147                 break;
8148             }
8149             break;
8150         case 12:
8151             switch (sel) {
8152             case 0:
8153                 gen_helper_mftc0_status(t0, tcg_env);
8154                 break;
8155             default:
8156                 gen_mfc0(ctx, t0, rt, sel);
8157                 break;
8158             }
8159             break;
8160         case 13:
8161             switch (sel) {
8162             case 0:
8163                 gen_helper_mftc0_cause(t0, tcg_env);
8164                 break;
8165             default:
8166                 goto die;
8167                 break;
8168             }
8169             break;
8170         case 14:
8171             switch (sel) {
8172             case 0:
8173                 gen_helper_mftc0_epc(t0, tcg_env);
8174                 break;
8175             default:
8176                 goto die;
8177                 break;
8178             }
8179             break;
8180         case 15:
8181             switch (sel) {
8182             case 1:
8183                 gen_helper_mftc0_ebase(t0, tcg_env);
8184                 break;
8185             default:
8186                 goto die;
8187                 break;
8188             }
8189             break;
8190         case 16:
8191             switch (sel) {
8192             case 0:
8193             case 1:
8194             case 2:
8195             case 3:
8196             case 4:
8197             case 5:
8198             case 6:
8199             case 7:
8200                 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel));
8201                 break;
8202             default:
8203                 goto die;
8204                 break;
8205             }
8206             break;
8207         case 23:
8208             switch (sel) {
8209             case 0:
8210                 gen_helper_mftc0_debug(t0, tcg_env);
8211                 break;
8212             default:
8213                 gen_mfc0(ctx, t0, rt, sel);
8214                 break;
8215             }
8216             break;
8217         default:
8218             gen_mfc0(ctx, t0, rt, sel);
8219         }
8220     } else {
8221         switch (sel) {
8222         /* GPR registers. */
8223         case 0:
8224             gen_helper_1e0i(mftgpr, t0, rt);
8225             break;
8226         /* Auxiliary CPU registers */
8227         case 1:
8228             switch (rt) {
8229             case 0:
8230                 gen_helper_1e0i(mftlo, t0, 0);
8231                 break;
8232             case 1:
8233                 gen_helper_1e0i(mfthi, t0, 0);
8234                 break;
8235             case 2:
8236                 gen_helper_1e0i(mftacx, t0, 0);
8237                 break;
8238             case 4:
8239                 gen_helper_1e0i(mftlo, t0, 1);
8240                 break;
8241             case 5:
8242                 gen_helper_1e0i(mfthi, t0, 1);
8243                 break;
8244             case 6:
8245                 gen_helper_1e0i(mftacx, t0, 1);
8246                 break;
8247             case 8:
8248                 gen_helper_1e0i(mftlo, t0, 2);
8249                 break;
8250             case 9:
8251                 gen_helper_1e0i(mfthi, t0, 2);
8252                 break;
8253             case 10:
8254                 gen_helper_1e0i(mftacx, t0, 2);
8255                 break;
8256             case 12:
8257                 gen_helper_1e0i(mftlo, t0, 3);
8258                 break;
8259             case 13:
8260                 gen_helper_1e0i(mfthi, t0, 3);
8261                 break;
8262             case 14:
8263                 gen_helper_1e0i(mftacx, t0, 3);
8264                 break;
8265             case 16:
8266                 gen_helper_mftdsp(t0, tcg_env);
8267                 break;
8268             default:
8269                 goto die;
8270             }
8271             break;
8272         /* Floating point (COP1). */
8273         case 2:
8274             /* XXX: For now we support only a single FPU context. */
8275             if (h == 0) {
8276                 TCGv_i32 fp0 = tcg_temp_new_i32();
8277 
8278                 gen_load_fpr32(ctx, fp0, rt);
8279                 tcg_gen_ext_i32_tl(t0, fp0);
8280             } else {
8281                 TCGv_i32 fp0 = tcg_temp_new_i32();
8282 
8283                 gen_load_fpr32h(ctx, fp0, rt);
8284                 tcg_gen_ext_i32_tl(t0, fp0);
8285             }
8286             break;
8287         case 3:
8288             /* XXX: For now we support only a single FPU context. */
8289             gen_helper_1e0i(cfc1, t0, rt);
8290             break;
8291         /* COP2: Not implemented. */
8292         case 4:
8293         case 5:
8294             /* fall through */
8295         default:
8296             goto die;
8297         }
8298     }
8299     trace_mips_translate_tr("mftr", rt, u, sel, h);
8300     gen_store_gpr(t0, rd);
8301     return;
8302 
8303 die:
8304     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8305     gen_reserved_instruction(ctx);
8306 }
8307 
gen_mttr(CPUMIPSState * env,DisasContext * ctx,int rd,int rt,int u,int sel,int h)8308 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8309                      int u, int sel, int h)
8310 {
8311     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8312     TCGv t0 = tcg_temp_new();
8313 
8314     gen_load_gpr(t0, rt);
8315     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8316         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8317          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8318         /* NOP */
8319         ;
8320     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8321              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8322         /* NOP */
8323         ;
8324     } else if (u == 0) {
8325         switch (rd) {
8326         case 1:
8327             switch (sel) {
8328             case 1:
8329                 gen_helper_mttc0_vpecontrol(tcg_env, t0);
8330                 break;
8331             case 2:
8332                 gen_helper_mttc0_vpeconf0(tcg_env, t0);
8333                 break;
8334             default:
8335                 goto die;
8336                 break;
8337             }
8338             break;
8339         case 2:
8340             switch (sel) {
8341             case 1:
8342                 gen_helper_mttc0_tcstatus(tcg_env, t0);
8343                 break;
8344             case 2:
8345                 gen_helper_mttc0_tcbind(tcg_env, t0);
8346                 break;
8347             case 3:
8348                 gen_helper_mttc0_tcrestart(tcg_env, t0);
8349                 break;
8350             case 4:
8351                 gen_helper_mttc0_tchalt(tcg_env, t0);
8352                 break;
8353             case 5:
8354                 gen_helper_mttc0_tccontext(tcg_env, t0);
8355                 break;
8356             case 6:
8357                 gen_helper_mttc0_tcschedule(tcg_env, t0);
8358                 break;
8359             case 7:
8360                 gen_helper_mttc0_tcschefback(tcg_env, t0);
8361                 break;
8362             default:
8363                 gen_mtc0(ctx, t0, rd, sel);
8364                 break;
8365             }
8366             break;
8367         case 10:
8368             switch (sel) {
8369             case 0:
8370                 gen_helper_mttc0_entryhi(tcg_env, t0);
8371                 break;
8372             default:
8373                 gen_mtc0(ctx, t0, rd, sel);
8374                 break;
8375             }
8376             break;
8377         case 12:
8378             switch (sel) {
8379             case 0:
8380                 gen_helper_mttc0_status(tcg_env, t0);
8381                 break;
8382             default:
8383                 gen_mtc0(ctx, t0, rd, sel);
8384                 break;
8385             }
8386             break;
8387         case 13:
8388             switch (sel) {
8389             case 0:
8390                 gen_helper_mttc0_cause(tcg_env, t0);
8391                 break;
8392             default:
8393                 goto die;
8394                 break;
8395             }
8396             break;
8397         case 15:
8398             switch (sel) {
8399             case 1:
8400                 gen_helper_mttc0_ebase(tcg_env, t0);
8401                 break;
8402             default:
8403                 goto die;
8404                 break;
8405             }
8406             break;
8407         case 23:
8408             switch (sel) {
8409             case 0:
8410                 gen_helper_mttc0_debug(tcg_env, t0);
8411                 break;
8412             default:
8413                 gen_mtc0(ctx, t0, rd, sel);
8414                 break;
8415             }
8416             break;
8417         default:
8418             gen_mtc0(ctx, t0, rd, sel);
8419         }
8420     } else {
8421         switch (sel) {
8422         /* GPR registers. */
8423         case 0:
8424             gen_helper_0e1i(mttgpr, t0, rd);
8425             break;
8426         /* Auxiliary CPU registers */
8427         case 1:
8428             switch (rd) {
8429             case 0:
8430                 gen_helper_0e1i(mttlo, t0, 0);
8431                 break;
8432             case 1:
8433                 gen_helper_0e1i(mtthi, t0, 0);
8434                 break;
8435             case 2:
8436                 gen_helper_0e1i(mttacx, t0, 0);
8437                 break;
8438             case 4:
8439                 gen_helper_0e1i(mttlo, t0, 1);
8440                 break;
8441             case 5:
8442                 gen_helper_0e1i(mtthi, t0, 1);
8443                 break;
8444             case 6:
8445                 gen_helper_0e1i(mttacx, t0, 1);
8446                 break;
8447             case 8:
8448                 gen_helper_0e1i(mttlo, t0, 2);
8449                 break;
8450             case 9:
8451                 gen_helper_0e1i(mtthi, t0, 2);
8452                 break;
8453             case 10:
8454                 gen_helper_0e1i(mttacx, t0, 2);
8455                 break;
8456             case 12:
8457                 gen_helper_0e1i(mttlo, t0, 3);
8458                 break;
8459             case 13:
8460                 gen_helper_0e1i(mtthi, t0, 3);
8461                 break;
8462             case 14:
8463                 gen_helper_0e1i(mttacx, t0, 3);
8464                 break;
8465             case 16:
8466                 gen_helper_mttdsp(tcg_env, t0);
8467                 break;
8468             default:
8469                 goto die;
8470             }
8471             break;
8472         /* Floating point (COP1). */
8473         case 2:
8474             /* XXX: For now we support only a single FPU context. */
8475             if (h == 0) {
8476                 TCGv_i32 fp0 = tcg_temp_new_i32();
8477 
8478                 tcg_gen_trunc_tl_i32(fp0, t0);
8479                 gen_store_fpr32(ctx, fp0, rd);
8480             } else {
8481                 TCGv_i32 fp0 = tcg_temp_new_i32();
8482 
8483                 tcg_gen_trunc_tl_i32(fp0, t0);
8484                 gen_store_fpr32h(ctx, fp0, rd);
8485             }
8486             break;
8487         case 3:
8488             /* XXX: For now we support only a single FPU context. */
8489             gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
8490             /* Stop translation as we may have changed hflags */
8491             ctx->base.is_jmp = DISAS_STOP;
8492             break;
8493         /* COP2: Not implemented. */
8494         case 4:
8495         case 5:
8496             /* fall through */
8497         default:
8498             goto die;
8499         }
8500     }
8501     trace_mips_translate_tr("mttr", rd, u, sel, h);
8502     return;
8503 
8504 die:
8505     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8506     gen_reserved_instruction(ctx);
8507 }
8508 
gen_cp0(CPUMIPSState * env,DisasContext * ctx,uint32_t opc,int rt,int rd)8509 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
8510                     int rt, int rd)
8511 {
8512     const char *opn = "ldst";
8513 
8514     check_cp0_enabled(ctx);
8515     switch (opc) {
8516     case OPC_MFC0:
8517         if (rt == 0) {
8518             /* Treat as NOP. */
8519             return;
8520         }
8521         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8522         opn = "mfc0";
8523         break;
8524     case OPC_MTC0:
8525         {
8526             TCGv t0 = tcg_temp_new();
8527 
8528             gen_load_gpr(t0, rt);
8529             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8530         }
8531         opn = "mtc0";
8532         break;
8533 #if defined(TARGET_MIPS64)
8534     case OPC_DMFC0:
8535         check_insn(ctx, ISA_MIPS3);
8536         if (rt == 0) {
8537             /* Treat as NOP. */
8538             return;
8539         }
8540         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8541         opn = "dmfc0";
8542         break;
8543     case OPC_DMTC0:
8544         check_insn(ctx, ISA_MIPS3);
8545         {
8546             TCGv t0 = tcg_temp_new();
8547 
8548             gen_load_gpr(t0, rt);
8549             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8550         }
8551         opn = "dmtc0";
8552         break;
8553 #endif
8554     case OPC_MFHC0:
8555         check_mvh(ctx);
8556         if (rt == 0) {
8557             /* Treat as NOP. */
8558             return;
8559         }
8560         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8561         opn = "mfhc0";
8562         break;
8563     case OPC_MTHC0:
8564         check_mvh(ctx);
8565         {
8566             TCGv t0 = tcg_temp_new();
8567             gen_load_gpr(t0, rt);
8568             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8569         }
8570         opn = "mthc0";
8571         break;
8572     case OPC_MFTR:
8573         check_cp0_enabled(ctx);
8574         if (rd == 0) {
8575             /* Treat as NOP. */
8576             return;
8577         }
8578         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8579                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8580         opn = "mftr";
8581         break;
8582     case OPC_MTTR:
8583         check_cp0_enabled(ctx);
8584         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8585                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8586         opn = "mttr";
8587         break;
8588     case OPC_TLBWI:
8589         opn = "tlbwi";
8590         if (!env->tlb->helper_tlbwi) {
8591             goto die;
8592         }
8593         gen_helper_tlbwi(tcg_env);
8594         break;
8595     case OPC_TLBINV:
8596         opn = "tlbinv";
8597         if (ctx->ie >= 2) {
8598             if (!env->tlb->helper_tlbinv) {
8599                 goto die;
8600             }
8601             gen_helper_tlbinv(tcg_env);
8602         } /* treat as nop if TLBINV not supported */
8603         break;
8604     case OPC_TLBINVF:
8605         opn = "tlbinvf";
8606         if (ctx->ie >= 2) {
8607             if (!env->tlb->helper_tlbinvf) {
8608                 goto die;
8609             }
8610             gen_helper_tlbinvf(tcg_env);
8611         } /* treat as nop if TLBINV not supported */
8612         break;
8613     case OPC_TLBWR:
8614         opn = "tlbwr";
8615         if (!env->tlb->helper_tlbwr) {
8616             goto die;
8617         }
8618         gen_helper_tlbwr(tcg_env);
8619         break;
8620     case OPC_TLBP:
8621         opn = "tlbp";
8622         if (!env->tlb->helper_tlbp) {
8623             goto die;
8624         }
8625         gen_helper_tlbp(tcg_env);
8626         break;
8627     case OPC_TLBR:
8628         opn = "tlbr";
8629         if (!env->tlb->helper_tlbr) {
8630             goto die;
8631         }
8632         gen_helper_tlbr(tcg_env);
8633         break;
8634     case OPC_ERET: /* OPC_ERETNC */
8635         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8636             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8637             goto die;
8638         } else {
8639             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8640             if (ctx->opcode & (1 << bit_shift)) {
8641                 /* OPC_ERETNC */
8642                 opn = "eretnc";
8643                 check_insn(ctx, ISA_MIPS_R5);
8644                 gen_helper_eretnc(tcg_env);
8645             } else {
8646                 /* OPC_ERET */
8647                 opn = "eret";
8648                 check_insn(ctx, ISA_MIPS2);
8649                 gen_helper_eret(tcg_env);
8650             }
8651             ctx->base.is_jmp = DISAS_EXIT;
8652         }
8653         break;
8654     case OPC_DERET:
8655         opn = "deret";
8656         check_insn(ctx, ISA_MIPS_R1);
8657         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8658             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8659             goto die;
8660         }
8661         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8662             MIPS_INVAL(opn);
8663             gen_reserved_instruction(ctx);
8664         } else {
8665             gen_helper_deret(tcg_env);
8666             ctx->base.is_jmp = DISAS_EXIT;
8667         }
8668         break;
8669     case OPC_WAIT:
8670         opn = "wait";
8671         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
8672         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8673             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8674             goto die;
8675         }
8676         /* If we get an exception, we want to restart at next instruction */
8677         ctx->base.pc_next += 4;
8678         save_cpu_state(ctx, 1);
8679         ctx->base.pc_next -= 4;
8680         gen_helper_wait(tcg_env);
8681         ctx->base.is_jmp = DISAS_NORETURN;
8682         break;
8683     default:
8684  die:
8685         MIPS_INVAL(opn);
8686         gen_reserved_instruction(ctx);
8687         return;
8688     }
8689     (void)opn; /* avoid a compiler warning */
8690 }
8691 #endif /* !CONFIG_USER_ONLY */
8692 
8693 /* CP1 Branches (before delay slot) */
gen_compute_branch1(DisasContext * ctx,uint32_t op,int32_t cc,int32_t offset)8694 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8695                                 int32_t cc, int32_t offset)
8696 {
8697     target_ulong btarget;
8698     TCGv_i32 t0 = tcg_temp_new_i32();
8699 
8700     if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8701         gen_reserved_instruction(ctx);
8702         return;
8703     }
8704 
8705     if (cc != 0) {
8706         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
8707     }
8708 
8709     btarget = ctx->base.pc_next + 4 + offset;
8710 
8711     switch (op) {
8712     case OPC_BC1F:
8713         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8714         tcg_gen_not_i32(t0, t0);
8715         tcg_gen_andi_i32(t0, t0, 1);
8716         tcg_gen_extu_i32_tl(bcond, t0);
8717         goto not_likely;
8718     case OPC_BC1FL:
8719         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8720         tcg_gen_not_i32(t0, t0);
8721         tcg_gen_andi_i32(t0, t0, 1);
8722         tcg_gen_extu_i32_tl(bcond, t0);
8723         goto likely;
8724     case OPC_BC1T:
8725         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8726         tcg_gen_andi_i32(t0, t0, 1);
8727         tcg_gen_extu_i32_tl(bcond, t0);
8728         goto not_likely;
8729     case OPC_BC1TL:
8730         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8731         tcg_gen_andi_i32(t0, t0, 1);
8732         tcg_gen_extu_i32_tl(bcond, t0);
8733     likely:
8734         ctx->hflags |= MIPS_HFLAG_BL;
8735         break;
8736     case OPC_BC1FANY2:
8737         {
8738             TCGv_i32 t1 = tcg_temp_new_i32();
8739             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8740             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8741             tcg_gen_nand_i32(t0, t0, t1);
8742             tcg_gen_andi_i32(t0, t0, 1);
8743             tcg_gen_extu_i32_tl(bcond, t0);
8744         }
8745         goto not_likely;
8746     case OPC_BC1TANY2:
8747         {
8748             TCGv_i32 t1 = tcg_temp_new_i32();
8749             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8750             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8751             tcg_gen_or_i32(t0, t0, t1);
8752             tcg_gen_andi_i32(t0, t0, 1);
8753             tcg_gen_extu_i32_tl(bcond, t0);
8754         }
8755         goto not_likely;
8756     case OPC_BC1FANY4:
8757         {
8758             TCGv_i32 t1 = tcg_temp_new_i32();
8759             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8760             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8761             tcg_gen_and_i32(t0, t0, t1);
8762             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8763             tcg_gen_and_i32(t0, t0, t1);
8764             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8765             tcg_gen_nand_i32(t0, t0, t1);
8766             tcg_gen_andi_i32(t0, t0, 1);
8767             tcg_gen_extu_i32_tl(bcond, t0);
8768         }
8769         goto not_likely;
8770     case OPC_BC1TANY4:
8771         {
8772             TCGv_i32 t1 = tcg_temp_new_i32();
8773             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8774             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8775             tcg_gen_or_i32(t0, t0, t1);
8776             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8777             tcg_gen_or_i32(t0, t0, t1);
8778             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8779             tcg_gen_or_i32(t0, t0, t1);
8780             tcg_gen_andi_i32(t0, t0, 1);
8781             tcg_gen_extu_i32_tl(bcond, t0);
8782         }
8783     not_likely:
8784         ctx->hflags |= MIPS_HFLAG_BC;
8785         break;
8786     default:
8787         MIPS_INVAL("cp1 cond branch");
8788         gen_reserved_instruction(ctx);
8789         return;
8790     }
8791     ctx->btarget = btarget;
8792     ctx->hflags |= MIPS_HFLAG_BDS32;
8793 }
8794 
8795 /* R6 CP1 Branches */
gen_compute_branch1_r6(DisasContext * ctx,uint32_t op,int32_t ft,int32_t offset,int delayslot_size)8796 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8797                                    int32_t ft, int32_t offset,
8798                                    int delayslot_size)
8799 {
8800     target_ulong btarget;
8801     TCGv_i64 t0 = tcg_temp_new_i64();
8802 
8803     if (ctx->hflags & MIPS_HFLAG_BMASK) {
8804 #ifdef MIPS_DEBUG_DISAS
8805         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
8806                   VADDR_PRIx "\n", ctx->base.pc_next);
8807 #endif
8808         gen_reserved_instruction(ctx);
8809         return;
8810     }
8811 
8812     gen_load_fpr64(ctx, t0, ft);
8813     tcg_gen_andi_i64(t0, t0, 1);
8814 
8815     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
8816 
8817     switch (op) {
8818     case OPC_BC1EQZ:
8819         tcg_gen_xori_i64(t0, t0, 1);
8820         ctx->hflags |= MIPS_HFLAG_BC;
8821         break;
8822     case OPC_BC1NEZ:
8823         /* t0 already set */
8824         ctx->hflags |= MIPS_HFLAG_BC;
8825         break;
8826     default:
8827         MIPS_INVAL("cp1 cond branch");
8828         gen_reserved_instruction(ctx);
8829         return;
8830     }
8831 
8832     tcg_gen_trunc_i64_tl(bcond, t0);
8833 
8834     ctx->btarget = btarget;
8835 
8836     switch (delayslot_size) {
8837     case 2:
8838         ctx->hflags |= MIPS_HFLAG_BDS16;
8839         break;
8840     case 4:
8841         ctx->hflags |= MIPS_HFLAG_BDS32;
8842         break;
8843     }
8844 }
8845 
8846 /* Coprocessor 1 (FPU) */
8847 
8848 #define FOP(func, fmt) (((fmt) << 21) | (func))
8849 
8850 enum fopcode {
8851     OPC_ADD_S = FOP(0, FMT_S),
8852     OPC_SUB_S = FOP(1, FMT_S),
8853     OPC_MUL_S = FOP(2, FMT_S),
8854     OPC_DIV_S = FOP(3, FMT_S),
8855     OPC_SQRT_S = FOP(4, FMT_S),
8856     OPC_ABS_S = FOP(5, FMT_S),
8857     OPC_MOV_S = FOP(6, FMT_S),
8858     OPC_NEG_S = FOP(7, FMT_S),
8859     OPC_ROUND_L_S = FOP(8, FMT_S),
8860     OPC_TRUNC_L_S = FOP(9, FMT_S),
8861     OPC_CEIL_L_S = FOP(10, FMT_S),
8862     OPC_FLOOR_L_S = FOP(11, FMT_S),
8863     OPC_ROUND_W_S = FOP(12, FMT_S),
8864     OPC_TRUNC_W_S = FOP(13, FMT_S),
8865     OPC_CEIL_W_S = FOP(14, FMT_S),
8866     OPC_FLOOR_W_S = FOP(15, FMT_S),
8867     OPC_SEL_S = FOP(16, FMT_S),
8868     OPC_MOVCF_S = FOP(17, FMT_S),
8869     OPC_MOVZ_S = FOP(18, FMT_S),
8870     OPC_MOVN_S = FOP(19, FMT_S),
8871     OPC_SELEQZ_S = FOP(20, FMT_S),
8872     OPC_RECIP_S = FOP(21, FMT_S),
8873     OPC_RSQRT_S = FOP(22, FMT_S),
8874     OPC_SELNEZ_S = FOP(23, FMT_S),
8875     OPC_MADDF_S = FOP(24, FMT_S),
8876     OPC_MSUBF_S = FOP(25, FMT_S),
8877     OPC_RINT_S = FOP(26, FMT_S),
8878     OPC_CLASS_S = FOP(27, FMT_S),
8879     OPC_MIN_S = FOP(28, FMT_S),
8880     OPC_RECIP2_S = FOP(28, FMT_S),
8881     OPC_MINA_S = FOP(29, FMT_S),
8882     OPC_RECIP1_S = FOP(29, FMT_S),
8883     OPC_MAX_S = FOP(30, FMT_S),
8884     OPC_RSQRT1_S = FOP(30, FMT_S),
8885     OPC_MAXA_S = FOP(31, FMT_S),
8886     OPC_RSQRT2_S = FOP(31, FMT_S),
8887     OPC_CVT_D_S = FOP(33, FMT_S),
8888     OPC_CVT_W_S = FOP(36, FMT_S),
8889     OPC_CVT_L_S = FOP(37, FMT_S),
8890     OPC_CVT_PS_S = FOP(38, FMT_S),
8891     OPC_CMP_F_S = FOP(48, FMT_S),
8892     OPC_CMP_UN_S = FOP(49, FMT_S),
8893     OPC_CMP_EQ_S = FOP(50, FMT_S),
8894     OPC_CMP_UEQ_S = FOP(51, FMT_S),
8895     OPC_CMP_OLT_S = FOP(52, FMT_S),
8896     OPC_CMP_ULT_S = FOP(53, FMT_S),
8897     OPC_CMP_OLE_S = FOP(54, FMT_S),
8898     OPC_CMP_ULE_S = FOP(55, FMT_S),
8899     OPC_CMP_SF_S = FOP(56, FMT_S),
8900     OPC_CMP_NGLE_S = FOP(57, FMT_S),
8901     OPC_CMP_SEQ_S = FOP(58, FMT_S),
8902     OPC_CMP_NGL_S = FOP(59, FMT_S),
8903     OPC_CMP_LT_S = FOP(60, FMT_S),
8904     OPC_CMP_NGE_S = FOP(61, FMT_S),
8905     OPC_CMP_LE_S = FOP(62, FMT_S),
8906     OPC_CMP_NGT_S = FOP(63, FMT_S),
8907 
8908     OPC_ADD_D = FOP(0, FMT_D),
8909     OPC_SUB_D = FOP(1, FMT_D),
8910     OPC_MUL_D = FOP(2, FMT_D),
8911     OPC_DIV_D = FOP(3, FMT_D),
8912     OPC_SQRT_D = FOP(4, FMT_D),
8913     OPC_ABS_D = FOP(5, FMT_D),
8914     OPC_MOV_D = FOP(6, FMT_D),
8915     OPC_NEG_D = FOP(7, FMT_D),
8916     OPC_ROUND_L_D = FOP(8, FMT_D),
8917     OPC_TRUNC_L_D = FOP(9, FMT_D),
8918     OPC_CEIL_L_D = FOP(10, FMT_D),
8919     OPC_FLOOR_L_D = FOP(11, FMT_D),
8920     OPC_ROUND_W_D = FOP(12, FMT_D),
8921     OPC_TRUNC_W_D = FOP(13, FMT_D),
8922     OPC_CEIL_W_D = FOP(14, FMT_D),
8923     OPC_FLOOR_W_D = FOP(15, FMT_D),
8924     OPC_SEL_D = FOP(16, FMT_D),
8925     OPC_MOVCF_D = FOP(17, FMT_D),
8926     OPC_MOVZ_D = FOP(18, FMT_D),
8927     OPC_MOVN_D = FOP(19, FMT_D),
8928     OPC_SELEQZ_D = FOP(20, FMT_D),
8929     OPC_RECIP_D = FOP(21, FMT_D),
8930     OPC_RSQRT_D = FOP(22, FMT_D),
8931     OPC_SELNEZ_D = FOP(23, FMT_D),
8932     OPC_MADDF_D = FOP(24, FMT_D),
8933     OPC_MSUBF_D = FOP(25, FMT_D),
8934     OPC_RINT_D = FOP(26, FMT_D),
8935     OPC_CLASS_D = FOP(27, FMT_D),
8936     OPC_MIN_D = FOP(28, FMT_D),
8937     OPC_RECIP2_D = FOP(28, FMT_D),
8938     OPC_MINA_D = FOP(29, FMT_D),
8939     OPC_RECIP1_D = FOP(29, FMT_D),
8940     OPC_MAX_D = FOP(30, FMT_D),
8941     OPC_RSQRT1_D = FOP(30, FMT_D),
8942     OPC_MAXA_D = FOP(31, FMT_D),
8943     OPC_RSQRT2_D = FOP(31, FMT_D),
8944     OPC_CVT_S_D = FOP(32, FMT_D),
8945     OPC_CVT_W_D = FOP(36, FMT_D),
8946     OPC_CVT_L_D = FOP(37, FMT_D),
8947     OPC_CMP_F_D = FOP(48, FMT_D),
8948     OPC_CMP_UN_D = FOP(49, FMT_D),
8949     OPC_CMP_EQ_D = FOP(50, FMT_D),
8950     OPC_CMP_UEQ_D = FOP(51, FMT_D),
8951     OPC_CMP_OLT_D = FOP(52, FMT_D),
8952     OPC_CMP_ULT_D = FOP(53, FMT_D),
8953     OPC_CMP_OLE_D = FOP(54, FMT_D),
8954     OPC_CMP_ULE_D = FOP(55, FMT_D),
8955     OPC_CMP_SF_D = FOP(56, FMT_D),
8956     OPC_CMP_NGLE_D = FOP(57, FMT_D),
8957     OPC_CMP_SEQ_D = FOP(58, FMT_D),
8958     OPC_CMP_NGL_D = FOP(59, FMT_D),
8959     OPC_CMP_LT_D = FOP(60, FMT_D),
8960     OPC_CMP_NGE_D = FOP(61, FMT_D),
8961     OPC_CMP_LE_D = FOP(62, FMT_D),
8962     OPC_CMP_NGT_D = FOP(63, FMT_D),
8963 
8964     OPC_CVT_S_W = FOP(32, FMT_W),
8965     OPC_CVT_D_W = FOP(33, FMT_W),
8966     OPC_CVT_S_L = FOP(32, FMT_L),
8967     OPC_CVT_D_L = FOP(33, FMT_L),
8968     OPC_CVT_PS_PW = FOP(38, FMT_W),
8969 
8970     OPC_ADD_PS = FOP(0, FMT_PS),
8971     OPC_SUB_PS = FOP(1, FMT_PS),
8972     OPC_MUL_PS = FOP(2, FMT_PS),
8973     OPC_DIV_PS = FOP(3, FMT_PS),
8974     OPC_ABS_PS = FOP(5, FMT_PS),
8975     OPC_MOV_PS = FOP(6, FMT_PS),
8976     OPC_NEG_PS = FOP(7, FMT_PS),
8977     OPC_MOVCF_PS = FOP(17, FMT_PS),
8978     OPC_MOVZ_PS = FOP(18, FMT_PS),
8979     OPC_MOVN_PS = FOP(19, FMT_PS),
8980     OPC_ADDR_PS = FOP(24, FMT_PS),
8981     OPC_MULR_PS = FOP(26, FMT_PS),
8982     OPC_RECIP2_PS = FOP(28, FMT_PS),
8983     OPC_RECIP1_PS = FOP(29, FMT_PS),
8984     OPC_RSQRT1_PS = FOP(30, FMT_PS),
8985     OPC_RSQRT2_PS = FOP(31, FMT_PS),
8986 
8987     OPC_CVT_S_PU = FOP(32, FMT_PS),
8988     OPC_CVT_PW_PS = FOP(36, FMT_PS),
8989     OPC_CVT_S_PL = FOP(40, FMT_PS),
8990     OPC_PLL_PS = FOP(44, FMT_PS),
8991     OPC_PLU_PS = FOP(45, FMT_PS),
8992     OPC_PUL_PS = FOP(46, FMT_PS),
8993     OPC_PUU_PS = FOP(47, FMT_PS),
8994     OPC_CMP_F_PS = FOP(48, FMT_PS),
8995     OPC_CMP_UN_PS = FOP(49, FMT_PS),
8996     OPC_CMP_EQ_PS = FOP(50, FMT_PS),
8997     OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
8998     OPC_CMP_OLT_PS = FOP(52, FMT_PS),
8999     OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9000     OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9001     OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9002     OPC_CMP_SF_PS = FOP(56, FMT_PS),
9003     OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9004     OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9005     OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9006     OPC_CMP_LT_PS = FOP(60, FMT_PS),
9007     OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9008     OPC_CMP_LE_PS = FOP(62, FMT_PS),
9009     OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9010 };
9011 
9012 enum r6_f_cmp_op {
9013     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9014     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9015     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9016     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9017     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9018     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9019     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9020     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9021     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9022     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9023     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9024     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9025     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9026     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9027     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9028     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9029     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9030     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9031     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9032     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9033     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9034     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9035 
9036     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9037     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9038     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9039     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9040     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9041     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9042     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9043     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9044     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9045     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9046     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9047     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9048     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9049     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9050     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9051     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9052     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9053     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9054     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9055     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9056     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9057     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9058 };
9059 
gen_cp1(DisasContext * ctx,uint32_t opc,int rt,int fs)9060 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9061 {
9062     TCGv t0 = tcg_temp_new();
9063 
9064     switch (opc) {
9065     case OPC_MFC1:
9066         {
9067             TCGv_i32 fp0 = tcg_temp_new_i32();
9068 
9069             gen_load_fpr32(ctx, fp0, fs);
9070             tcg_gen_ext_i32_tl(t0, fp0);
9071         }
9072         gen_store_gpr(t0, rt);
9073         break;
9074     case OPC_MTC1:
9075         gen_load_gpr(t0, rt);
9076         {
9077             TCGv_i32 fp0 = tcg_temp_new_i32();
9078 
9079             tcg_gen_trunc_tl_i32(fp0, t0);
9080             gen_store_fpr32(ctx, fp0, fs);
9081         }
9082         break;
9083     case OPC_CFC1:
9084         gen_helper_1e0i(cfc1, t0, fs);
9085         gen_store_gpr(t0, rt);
9086         break;
9087     case OPC_CTC1:
9088         gen_load_gpr(t0, rt);
9089         save_cpu_state(ctx, 0);
9090         gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9091         /* Stop translation as we may have changed hflags */
9092         ctx->base.is_jmp = DISAS_STOP;
9093         break;
9094 #if defined(TARGET_MIPS64)
9095     case OPC_DMFC1:
9096         gen_load_fpr64(ctx, t0, fs);
9097         gen_store_gpr(t0, rt);
9098         break;
9099     case OPC_DMTC1:
9100         gen_load_gpr(t0, rt);
9101         gen_store_fpr64(ctx, t0, fs);
9102         break;
9103 #endif
9104     case OPC_MFHC1:
9105         {
9106             TCGv_i32 fp0 = tcg_temp_new_i32();
9107 
9108             gen_load_fpr32h(ctx, fp0, fs);
9109             tcg_gen_ext_i32_tl(t0, fp0);
9110         }
9111         gen_store_gpr(t0, rt);
9112         break;
9113     case OPC_MTHC1:
9114         gen_load_gpr(t0, rt);
9115         {
9116             TCGv_i32 fp0 = tcg_temp_new_i32();
9117 
9118             tcg_gen_trunc_tl_i32(fp0, t0);
9119             gen_store_fpr32h(ctx, fp0, fs);
9120         }
9121         break;
9122     default:
9123         MIPS_INVAL("cp1 move");
9124         gen_reserved_instruction(ctx);
9125         return;
9126     }
9127 }
9128 
gen_movci(DisasContext * ctx,int rd,int rs,int cc,int tf)9129 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9130 {
9131     TCGLabel *l1;
9132     TCGCond cond;
9133     TCGv_i32 t0;
9134 
9135     if (rd == 0) {
9136         /* Treat as NOP. */
9137         return;
9138     }
9139 
9140     if (tf) {
9141         cond = TCG_COND_EQ;
9142     } else {
9143         cond = TCG_COND_NE;
9144     }
9145 
9146     l1 = gen_new_label();
9147     t0 = tcg_temp_new_i32();
9148     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9149     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9150     gen_load_gpr(cpu_gpr[rd], rs);
9151     gen_set_label(l1);
9152 }
9153 
gen_movcf_s(DisasContext * ctx,int fs,int fd,int cc,int tf)9154 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9155                                int tf)
9156 {
9157     int cond;
9158     TCGv_i32 t0 = tcg_temp_new_i32();
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     gen_load_fpr32(ctx, t0, fs);
9170     gen_store_fpr32(ctx, t0, fd);
9171     gen_set_label(l1);
9172 }
9173 
gen_movcf_d(DisasContext * ctx,int fs,int fd,int cc,int tf)9174 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9175                                int tf)
9176 {
9177     int cond;
9178     TCGv_i32 t0 = tcg_temp_new_i32();
9179     TCGv_i64 fp0;
9180     TCGLabel *l1 = gen_new_label();
9181 
9182     if (tf) {
9183         cond = TCG_COND_EQ;
9184     } else {
9185         cond = TCG_COND_NE;
9186     }
9187 
9188     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9189     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9190     fp0 = tcg_temp_new_i64();
9191     gen_load_fpr64(ctx, fp0, fs);
9192     gen_store_fpr64(ctx, fp0, fd);
9193     gen_set_label(l1);
9194 }
9195 
gen_movcf_ps(DisasContext * ctx,int fs,int fd,int cc,int tf)9196 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9197                                 int cc, int tf)
9198 {
9199     int cond;
9200     TCGv_i32 t0 = tcg_temp_new_i32();
9201     TCGLabel *l1 = gen_new_label();
9202     TCGLabel *l2 = gen_new_label();
9203 
9204     if (tf) {
9205         cond = TCG_COND_EQ;
9206     } else {
9207         cond = TCG_COND_NE;
9208     }
9209 
9210     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9211     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9212     gen_load_fpr32(ctx, t0, fs);
9213     gen_store_fpr32(ctx, t0, fd);
9214     gen_set_label(l1);
9215 
9216     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9217     tcg_gen_brcondi_i32(cond, t0, 0, l2);
9218     gen_load_fpr32h(ctx, t0, fs);
9219     gen_store_fpr32h(ctx, t0, fd);
9220     gen_set_label(l2);
9221 }
9222 
gen_sel_s(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9223 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9224                       int fs)
9225 {
9226     TCGv_i32 t1 = tcg_constant_i32(0);
9227     TCGv_i32 fp0 = tcg_temp_new_i32();
9228     TCGv_i32 fp1 = tcg_temp_new_i32();
9229     TCGv_i32 fp2 = tcg_temp_new_i32();
9230     gen_load_fpr32(ctx, fp0, fd);
9231     gen_load_fpr32(ctx, fp1, ft);
9232     gen_load_fpr32(ctx, fp2, fs);
9233 
9234     switch (op1) {
9235     case OPC_SEL_S:
9236         tcg_gen_andi_i32(fp0, fp0, 1);
9237         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9238         break;
9239     case OPC_SELEQZ_S:
9240         tcg_gen_andi_i32(fp1, fp1, 1);
9241         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9242         break;
9243     case OPC_SELNEZ_S:
9244         tcg_gen_andi_i32(fp1, fp1, 1);
9245         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9246         break;
9247     default:
9248         MIPS_INVAL("gen_sel_s");
9249         gen_reserved_instruction(ctx);
9250         break;
9251     }
9252 
9253     gen_store_fpr32(ctx, fp0, fd);
9254 }
9255 
gen_sel_d(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9256 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9257                       int fs)
9258 {
9259     TCGv_i64 t1 = tcg_constant_i64(0);
9260     TCGv_i64 fp0 = tcg_temp_new_i64();
9261     TCGv_i64 fp1 = tcg_temp_new_i64();
9262     TCGv_i64 fp2 = tcg_temp_new_i64();
9263     gen_load_fpr64(ctx, fp0, fd);
9264     gen_load_fpr64(ctx, fp1, ft);
9265     gen_load_fpr64(ctx, fp2, fs);
9266 
9267     switch (op1) {
9268     case OPC_SEL_D:
9269         tcg_gen_andi_i64(fp0, fp0, 1);
9270         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9271         break;
9272     case OPC_SELEQZ_D:
9273         tcg_gen_andi_i64(fp1, fp1, 1);
9274         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9275         break;
9276     case OPC_SELNEZ_D:
9277         tcg_gen_andi_i64(fp1, fp1, 1);
9278         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9279         break;
9280     default:
9281         MIPS_INVAL("gen_sel_d");
9282         gen_reserved_instruction(ctx);
9283         break;
9284     }
9285 
9286     gen_store_fpr64(ctx, fp0, fd);
9287 }
9288 
gen_farith(DisasContext * ctx,enum fopcode op1,int ft,int fs,int fd,int cc)9289 static void gen_farith(DisasContext *ctx, enum fopcode op1,
9290                        int ft, int fs, int fd, int cc)
9291 {
9292     uint32_t func = ctx->opcode & 0x3f;
9293     switch (op1) {
9294     case OPC_ADD_S:
9295         {
9296             TCGv_i32 fp0 = tcg_temp_new_i32();
9297             TCGv_i32 fp1 = tcg_temp_new_i32();
9298 
9299             gen_load_fpr32(ctx, fp0, fs);
9300             gen_load_fpr32(ctx, fp1, ft);
9301             gen_helper_float_add_s(fp0, tcg_env, fp0, fp1);
9302             gen_store_fpr32(ctx, fp0, fd);
9303         }
9304         break;
9305     case OPC_SUB_S:
9306         {
9307             TCGv_i32 fp0 = tcg_temp_new_i32();
9308             TCGv_i32 fp1 = tcg_temp_new_i32();
9309 
9310             gen_load_fpr32(ctx, fp0, fs);
9311             gen_load_fpr32(ctx, fp1, ft);
9312             gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1);
9313             gen_store_fpr32(ctx, fp0, fd);
9314         }
9315         break;
9316     case OPC_MUL_S:
9317         {
9318             TCGv_i32 fp0 = tcg_temp_new_i32();
9319             TCGv_i32 fp1 = tcg_temp_new_i32();
9320 
9321             gen_load_fpr32(ctx, fp0, fs);
9322             gen_load_fpr32(ctx, fp1, ft);
9323             gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1);
9324             gen_store_fpr32(ctx, fp0, fd);
9325         }
9326         break;
9327     case OPC_DIV_S:
9328         {
9329             TCGv_i32 fp0 = tcg_temp_new_i32();
9330             TCGv_i32 fp1 = tcg_temp_new_i32();
9331 
9332             gen_load_fpr32(ctx, fp0, fs);
9333             gen_load_fpr32(ctx, fp1, ft);
9334             gen_helper_float_div_s(fp0, tcg_env, fp0, fp1);
9335             gen_store_fpr32(ctx, fp0, fd);
9336         }
9337         break;
9338     case OPC_SQRT_S:
9339         {
9340             TCGv_i32 fp0 = tcg_temp_new_i32();
9341 
9342             gen_load_fpr32(ctx, fp0, fs);
9343             gen_helper_float_sqrt_s(fp0, tcg_env, fp0);
9344             gen_store_fpr32(ctx, fp0, fd);
9345         }
9346         break;
9347     case OPC_ABS_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_andi_i32(fp0, fp0, 0x7fffffffUL);
9354             } else {
9355                 gen_helper_float_abs_s(fp0, fp0);
9356             }
9357             gen_store_fpr32(ctx, fp0, fd);
9358         }
9359         break;
9360     case OPC_MOV_S:
9361         {
9362             TCGv_i32 fp0 = tcg_temp_new_i32();
9363 
9364             gen_load_fpr32(ctx, fp0, fs);
9365             gen_store_fpr32(ctx, fp0, fd);
9366         }
9367         break;
9368     case OPC_NEG_S:
9369         {
9370             TCGv_i32 fp0 = tcg_temp_new_i32();
9371 
9372             gen_load_fpr32(ctx, fp0, fs);
9373             if (ctx->abs2008) {
9374                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9375             } else {
9376                 gen_helper_float_chs_s(fp0, fp0);
9377             }
9378             gen_store_fpr32(ctx, fp0, fd);
9379         }
9380         break;
9381     case OPC_ROUND_L_S:
9382         check_cp1_64bitmode(ctx);
9383         {
9384             TCGv_i32 fp32 = tcg_temp_new_i32();
9385             TCGv_i64 fp64 = tcg_temp_new_i64();
9386 
9387             gen_load_fpr32(ctx, fp32, fs);
9388             if (ctx->nan2008) {
9389                 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32);
9390             } else {
9391                 gen_helper_float_round_l_s(fp64, tcg_env, fp32);
9392             }
9393             gen_store_fpr64(ctx, fp64, fd);
9394         }
9395         break;
9396     case OPC_TRUNC_L_S:
9397         check_cp1_64bitmode(ctx);
9398         {
9399             TCGv_i32 fp32 = tcg_temp_new_i32();
9400             TCGv_i64 fp64 = tcg_temp_new_i64();
9401 
9402             gen_load_fpr32(ctx, fp32, fs);
9403             if (ctx->nan2008) {
9404                 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32);
9405             } else {
9406                 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32);
9407             }
9408             gen_store_fpr64(ctx, fp64, fd);
9409         }
9410         break;
9411     case OPC_CEIL_L_S:
9412         check_cp1_64bitmode(ctx);
9413         {
9414             TCGv_i32 fp32 = tcg_temp_new_i32();
9415             TCGv_i64 fp64 = tcg_temp_new_i64();
9416 
9417             gen_load_fpr32(ctx, fp32, fs);
9418             if (ctx->nan2008) {
9419                 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32);
9420             } else {
9421                 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32);
9422             }
9423             gen_store_fpr64(ctx, fp64, fd);
9424         }
9425         break;
9426     case OPC_FLOOR_L_S:
9427         check_cp1_64bitmode(ctx);
9428         {
9429             TCGv_i32 fp32 = tcg_temp_new_i32();
9430             TCGv_i64 fp64 = tcg_temp_new_i64();
9431 
9432             gen_load_fpr32(ctx, fp32, fs);
9433             if (ctx->nan2008) {
9434                 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32);
9435             } else {
9436                 gen_helper_float_floor_l_s(fp64, tcg_env, fp32);
9437             }
9438             gen_store_fpr64(ctx, fp64, fd);
9439         }
9440         break;
9441     case OPC_ROUND_W_S:
9442         {
9443             TCGv_i32 fp0 = tcg_temp_new_i32();
9444 
9445             gen_load_fpr32(ctx, fp0, fs);
9446             if (ctx->nan2008) {
9447                 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0);
9448             } else {
9449                 gen_helper_float_round_w_s(fp0, tcg_env, fp0);
9450             }
9451             gen_store_fpr32(ctx, fp0, fd);
9452         }
9453         break;
9454     case OPC_TRUNC_W_S:
9455         {
9456             TCGv_i32 fp0 = tcg_temp_new_i32();
9457 
9458             gen_load_fpr32(ctx, fp0, fs);
9459             if (ctx->nan2008) {
9460                 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0);
9461             } else {
9462                 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0);
9463             }
9464             gen_store_fpr32(ctx, fp0, fd);
9465         }
9466         break;
9467     case OPC_CEIL_W_S:
9468         {
9469             TCGv_i32 fp0 = tcg_temp_new_i32();
9470 
9471             gen_load_fpr32(ctx, fp0, fs);
9472             if (ctx->nan2008) {
9473                 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0);
9474             } else {
9475                 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0);
9476             }
9477             gen_store_fpr32(ctx, fp0, fd);
9478         }
9479         break;
9480     case OPC_FLOOR_W_S:
9481         {
9482             TCGv_i32 fp0 = tcg_temp_new_i32();
9483 
9484             gen_load_fpr32(ctx, fp0, fs);
9485             if (ctx->nan2008) {
9486                 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0);
9487             } else {
9488                 gen_helper_float_floor_w_s(fp0, tcg_env, fp0);
9489             }
9490             gen_store_fpr32(ctx, fp0, fd);
9491         }
9492         break;
9493     case OPC_SEL_S:
9494         check_insn(ctx, ISA_MIPS_R6);
9495         gen_sel_s(ctx, op1, fd, ft, fs);
9496         break;
9497     case OPC_SELEQZ_S:
9498         check_insn(ctx, ISA_MIPS_R6);
9499         gen_sel_s(ctx, op1, fd, ft, fs);
9500         break;
9501     case OPC_SELNEZ_S:
9502         check_insn(ctx, ISA_MIPS_R6);
9503         gen_sel_s(ctx, op1, fd, ft, fs);
9504         break;
9505     case OPC_MOVCF_S:
9506         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9507         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9508         break;
9509     case OPC_MOVZ_S:
9510         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9511         {
9512             TCGLabel *l1 = gen_new_label();
9513             TCGv_i32 fp0;
9514 
9515             if (ft != 0) {
9516                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9517             }
9518             fp0 = tcg_temp_new_i32();
9519             gen_load_fpr32(ctx, fp0, fs);
9520             gen_store_fpr32(ctx, fp0, fd);
9521             gen_set_label(l1);
9522         }
9523         break;
9524     case OPC_MOVN_S:
9525         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9526         {
9527             TCGLabel *l1 = gen_new_label();
9528             TCGv_i32 fp0;
9529 
9530             if (ft != 0) {
9531                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9532                 fp0 = tcg_temp_new_i32();
9533                 gen_load_fpr32(ctx, fp0, fs);
9534                 gen_store_fpr32(ctx, fp0, fd);
9535                 gen_set_label(l1);
9536             }
9537         }
9538         break;
9539     case OPC_RECIP_S:
9540         {
9541             TCGv_i32 fp0 = tcg_temp_new_i32();
9542 
9543             gen_load_fpr32(ctx, fp0, fs);
9544             gen_helper_float_recip_s(fp0, tcg_env, fp0);
9545             gen_store_fpr32(ctx, fp0, fd);
9546         }
9547         break;
9548     case OPC_RSQRT_S:
9549         {
9550             TCGv_i32 fp0 = tcg_temp_new_i32();
9551 
9552             gen_load_fpr32(ctx, fp0, fs);
9553             gen_helper_float_rsqrt_s(fp0, tcg_env, fp0);
9554             gen_store_fpr32(ctx, fp0, fd);
9555         }
9556         break;
9557     case OPC_MADDF_S:
9558         check_insn(ctx, ISA_MIPS_R6);
9559         {
9560             TCGv_i32 fp0 = tcg_temp_new_i32();
9561             TCGv_i32 fp1 = tcg_temp_new_i32();
9562             TCGv_i32 fp2 = tcg_temp_new_i32();
9563             gen_load_fpr32(ctx, fp0, fs);
9564             gen_load_fpr32(ctx, fp1, ft);
9565             gen_load_fpr32(ctx, fp2, fd);
9566             gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2);
9567             gen_store_fpr32(ctx, fp2, fd);
9568         }
9569         break;
9570     case OPC_MSUBF_S:
9571         check_insn(ctx, ISA_MIPS_R6);
9572         {
9573             TCGv_i32 fp0 = tcg_temp_new_i32();
9574             TCGv_i32 fp1 = tcg_temp_new_i32();
9575             TCGv_i32 fp2 = tcg_temp_new_i32();
9576             gen_load_fpr32(ctx, fp0, fs);
9577             gen_load_fpr32(ctx, fp1, ft);
9578             gen_load_fpr32(ctx, fp2, fd);
9579             gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2);
9580             gen_store_fpr32(ctx, fp2, fd);
9581         }
9582         break;
9583     case OPC_RINT_S:
9584         check_insn(ctx, ISA_MIPS_R6);
9585         {
9586             TCGv_i32 fp0 = tcg_temp_new_i32();
9587             gen_load_fpr32(ctx, fp0, fs);
9588             gen_helper_float_rint_s(fp0, tcg_env, fp0);
9589             gen_store_fpr32(ctx, fp0, fd);
9590         }
9591         break;
9592     case OPC_CLASS_S:
9593         check_insn(ctx, ISA_MIPS_R6);
9594         {
9595             TCGv_i32 fp0 = tcg_temp_new_i32();
9596             gen_load_fpr32(ctx, fp0, fs);
9597             gen_helper_float_class_s(fp0, tcg_env, fp0);
9598             gen_store_fpr32(ctx, fp0, fd);
9599         }
9600         break;
9601     case OPC_MIN_S: /* OPC_RECIP2_S */
9602         if (ctx->insn_flags & ISA_MIPS_R6) {
9603             /* OPC_MIN_S */
9604             TCGv_i32 fp0 = tcg_temp_new_i32();
9605             TCGv_i32 fp1 = tcg_temp_new_i32();
9606             TCGv_i32 fp2 = tcg_temp_new_i32();
9607             gen_load_fpr32(ctx, fp0, fs);
9608             gen_load_fpr32(ctx, fp1, ft);
9609             gen_helper_float_min_s(fp2, tcg_env, fp0, fp1);
9610             gen_store_fpr32(ctx, fp2, fd);
9611         } else {
9612             /* OPC_RECIP2_S */
9613             check_cp1_64bitmode(ctx);
9614             {
9615                 TCGv_i32 fp0 = tcg_temp_new_i32();
9616                 TCGv_i32 fp1 = tcg_temp_new_i32();
9617 
9618                 gen_load_fpr32(ctx, fp0, fs);
9619                 gen_load_fpr32(ctx, fp1, ft);
9620                 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1);
9621                 gen_store_fpr32(ctx, fp0, fd);
9622             }
9623         }
9624         break;
9625     case OPC_MINA_S: /* OPC_RECIP1_S */
9626         if (ctx->insn_flags & ISA_MIPS_R6) {
9627             /* OPC_MINA_S */
9628             TCGv_i32 fp0 = tcg_temp_new_i32();
9629             TCGv_i32 fp1 = tcg_temp_new_i32();
9630             TCGv_i32 fp2 = tcg_temp_new_i32();
9631             gen_load_fpr32(ctx, fp0, fs);
9632             gen_load_fpr32(ctx, fp1, ft);
9633             gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1);
9634             gen_store_fpr32(ctx, fp2, fd);
9635         } else {
9636             /* OPC_RECIP1_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_recip1_s(fp0, tcg_env, fp0);
9643                 gen_store_fpr32(ctx, fp0, fd);
9644             }
9645         }
9646         break;
9647     case OPC_MAX_S: /* OPC_RSQRT1_S */
9648         if (ctx->insn_flags & ISA_MIPS_R6) {
9649             /* OPC_MAX_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_max_s(fp1, tcg_env, fp0, fp1);
9655             gen_store_fpr32(ctx, fp1, fd);
9656         } else {
9657             /* OPC_RSQRT1_S */
9658             check_cp1_64bitmode(ctx);
9659             {
9660                 TCGv_i32 fp0 = tcg_temp_new_i32();
9661 
9662                 gen_load_fpr32(ctx, fp0, fs);
9663                 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0);
9664                 gen_store_fpr32(ctx, fp0, fd);
9665             }
9666         }
9667         break;
9668     case OPC_MAXA_S: /* OPC_RSQRT2_S */
9669         if (ctx->insn_flags & ISA_MIPS_R6) {
9670             /* OPC_MAXA_S */
9671             TCGv_i32 fp0 = tcg_temp_new_i32();
9672             TCGv_i32 fp1 = tcg_temp_new_i32();
9673             gen_load_fpr32(ctx, fp0, fs);
9674             gen_load_fpr32(ctx, fp1, ft);
9675             gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1);
9676             gen_store_fpr32(ctx, fp1, fd);
9677         } else {
9678             /* OPC_RSQRT2_S */
9679             check_cp1_64bitmode(ctx);
9680             {
9681                 TCGv_i32 fp0 = tcg_temp_new_i32();
9682                 TCGv_i32 fp1 = tcg_temp_new_i32();
9683 
9684                 gen_load_fpr32(ctx, fp0, fs);
9685                 gen_load_fpr32(ctx, fp1, ft);
9686                 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1);
9687                 gen_store_fpr32(ctx, fp0, fd);
9688             }
9689         }
9690         break;
9691     case OPC_CVT_D_S:
9692         check_cp1_registers(ctx, fd);
9693         {
9694             TCGv_i32 fp32 = tcg_temp_new_i32();
9695             TCGv_i64 fp64 = tcg_temp_new_i64();
9696 
9697             gen_load_fpr32(ctx, fp32, fs);
9698             gen_helper_float_cvtd_s(fp64, tcg_env, fp32);
9699             gen_store_fpr64(ctx, fp64, fd);
9700         }
9701         break;
9702     case OPC_CVT_W_S:
9703         {
9704             TCGv_i32 fp0 = tcg_temp_new_i32();
9705 
9706             gen_load_fpr32(ctx, fp0, fs);
9707             if (ctx->nan2008) {
9708                 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0);
9709             } else {
9710                 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0);
9711             }
9712             gen_store_fpr32(ctx, fp0, fd);
9713         }
9714         break;
9715     case OPC_CVT_L_S:
9716         check_cp1_64bitmode(ctx);
9717         {
9718             TCGv_i32 fp32 = tcg_temp_new_i32();
9719             TCGv_i64 fp64 = tcg_temp_new_i64();
9720 
9721             gen_load_fpr32(ctx, fp32, fs);
9722             if (ctx->nan2008) {
9723                 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32);
9724             } else {
9725                 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32);
9726             }
9727             gen_store_fpr64(ctx, fp64, fd);
9728         }
9729         break;
9730     case OPC_CVT_PS_S:
9731         check_ps(ctx);
9732         {
9733             TCGv_i64 fp64 = tcg_temp_new_i64();
9734             TCGv_i32 fp32_0 = tcg_temp_new_i32();
9735             TCGv_i32 fp32_1 = tcg_temp_new_i32();
9736 
9737             gen_load_fpr32(ctx, fp32_0, fs);
9738             gen_load_fpr32(ctx, fp32_1, ft);
9739             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9740             gen_store_fpr64(ctx, fp64, fd);
9741         }
9742         break;
9743     case OPC_CMP_F_S:
9744     case OPC_CMP_UN_S:
9745     case OPC_CMP_EQ_S:
9746     case OPC_CMP_UEQ_S:
9747     case OPC_CMP_OLT_S:
9748     case OPC_CMP_ULT_S:
9749     case OPC_CMP_OLE_S:
9750     case OPC_CMP_ULE_S:
9751     case OPC_CMP_SF_S:
9752     case OPC_CMP_NGLE_S:
9753     case OPC_CMP_SEQ_S:
9754     case OPC_CMP_NGL_S:
9755     case OPC_CMP_LT_S:
9756     case OPC_CMP_NGE_S:
9757     case OPC_CMP_LE_S:
9758     case OPC_CMP_NGT_S:
9759         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9760         if (ctx->opcode & (1 << 6)) {
9761             gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
9762         } else {
9763             gen_cmp_s(ctx, func - 48, ft, fs, cc);
9764         }
9765         break;
9766     case OPC_ADD_D:
9767         check_cp1_registers(ctx, fs | ft | fd);
9768         {
9769             TCGv_i64 fp0 = tcg_temp_new_i64();
9770             TCGv_i64 fp1 = tcg_temp_new_i64();
9771 
9772             gen_load_fpr64(ctx, fp0, fs);
9773             gen_load_fpr64(ctx, fp1, ft);
9774             gen_helper_float_add_d(fp0, tcg_env, fp0, fp1);
9775             gen_store_fpr64(ctx, fp0, fd);
9776         }
9777         break;
9778     case OPC_SUB_D:
9779         check_cp1_registers(ctx, fs | ft | fd);
9780         {
9781             TCGv_i64 fp0 = tcg_temp_new_i64();
9782             TCGv_i64 fp1 = tcg_temp_new_i64();
9783 
9784             gen_load_fpr64(ctx, fp0, fs);
9785             gen_load_fpr64(ctx, fp1, ft);
9786             gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1);
9787             gen_store_fpr64(ctx, fp0, fd);
9788         }
9789         break;
9790     case OPC_MUL_D:
9791         check_cp1_registers(ctx, fs | ft | fd);
9792         {
9793             TCGv_i64 fp0 = tcg_temp_new_i64();
9794             TCGv_i64 fp1 = tcg_temp_new_i64();
9795 
9796             gen_load_fpr64(ctx, fp0, fs);
9797             gen_load_fpr64(ctx, fp1, ft);
9798             gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1);
9799             gen_store_fpr64(ctx, fp0, fd);
9800         }
9801         break;
9802     case OPC_DIV_D:
9803         check_cp1_registers(ctx, fs | ft | fd);
9804         {
9805             TCGv_i64 fp0 = tcg_temp_new_i64();
9806             TCGv_i64 fp1 = tcg_temp_new_i64();
9807 
9808             gen_load_fpr64(ctx, fp0, fs);
9809             gen_load_fpr64(ctx, fp1, ft);
9810             gen_helper_float_div_d(fp0, tcg_env, fp0, fp1);
9811             gen_store_fpr64(ctx, fp0, fd);
9812         }
9813         break;
9814     case OPC_SQRT_D:
9815         check_cp1_registers(ctx, fs | fd);
9816         {
9817             TCGv_i64 fp0 = tcg_temp_new_i64();
9818 
9819             gen_load_fpr64(ctx, fp0, fs);
9820             gen_helper_float_sqrt_d(fp0, tcg_env, fp0);
9821             gen_store_fpr64(ctx, fp0, fd);
9822         }
9823         break;
9824     case OPC_ABS_D:
9825         check_cp1_registers(ctx, fs | fd);
9826         {
9827             TCGv_i64 fp0 = tcg_temp_new_i64();
9828 
9829             gen_load_fpr64(ctx, fp0, fs);
9830             if (ctx->abs2008) {
9831                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9832             } else {
9833                 gen_helper_float_abs_d(fp0, fp0);
9834             }
9835             gen_store_fpr64(ctx, fp0, fd);
9836         }
9837         break;
9838     case OPC_MOV_D:
9839         check_cp1_registers(ctx, fs | fd);
9840         {
9841             TCGv_i64 fp0 = tcg_temp_new_i64();
9842 
9843             gen_load_fpr64(ctx, fp0, fs);
9844             gen_store_fpr64(ctx, fp0, fd);
9845         }
9846         break;
9847     case OPC_NEG_D:
9848         check_cp1_registers(ctx, fs | fd);
9849         {
9850             TCGv_i64 fp0 = tcg_temp_new_i64();
9851 
9852             gen_load_fpr64(ctx, fp0, fs);
9853             if (ctx->abs2008) {
9854                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9855             } else {
9856                 gen_helper_float_chs_d(fp0, fp0);
9857             }
9858             gen_store_fpr64(ctx, fp0, fd);
9859         }
9860         break;
9861     case OPC_ROUND_L_D:
9862         check_cp1_64bitmode(ctx);
9863         {
9864             TCGv_i64 fp0 = tcg_temp_new_i64();
9865 
9866             gen_load_fpr64(ctx, fp0, fs);
9867             if (ctx->nan2008) {
9868                 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0);
9869             } else {
9870                 gen_helper_float_round_l_d(fp0, tcg_env, fp0);
9871             }
9872             gen_store_fpr64(ctx, fp0, fd);
9873         }
9874         break;
9875     case OPC_TRUNC_L_D:
9876         check_cp1_64bitmode(ctx);
9877         {
9878             TCGv_i64 fp0 = tcg_temp_new_i64();
9879 
9880             gen_load_fpr64(ctx, fp0, fs);
9881             if (ctx->nan2008) {
9882                 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0);
9883             } else {
9884                 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0);
9885             }
9886             gen_store_fpr64(ctx, fp0, fd);
9887         }
9888         break;
9889     case OPC_CEIL_L_D:
9890         check_cp1_64bitmode(ctx);
9891         {
9892             TCGv_i64 fp0 = tcg_temp_new_i64();
9893 
9894             gen_load_fpr64(ctx, fp0, fs);
9895             if (ctx->nan2008) {
9896                 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0);
9897             } else {
9898                 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0);
9899             }
9900             gen_store_fpr64(ctx, fp0, fd);
9901         }
9902         break;
9903     case OPC_FLOOR_L_D:
9904         check_cp1_64bitmode(ctx);
9905         {
9906             TCGv_i64 fp0 = tcg_temp_new_i64();
9907 
9908             gen_load_fpr64(ctx, fp0, fs);
9909             if (ctx->nan2008) {
9910                 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0);
9911             } else {
9912                 gen_helper_float_floor_l_d(fp0, tcg_env, fp0);
9913             }
9914             gen_store_fpr64(ctx, fp0, fd);
9915         }
9916         break;
9917     case OPC_ROUND_W_D:
9918         check_cp1_registers(ctx, fs);
9919         {
9920             TCGv_i32 fp32 = tcg_temp_new_i32();
9921             TCGv_i64 fp64 = tcg_temp_new_i64();
9922 
9923             gen_load_fpr64(ctx, fp64, fs);
9924             if (ctx->nan2008) {
9925                 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64);
9926             } else {
9927                 gen_helper_float_round_w_d(fp32, tcg_env, fp64);
9928             }
9929             gen_store_fpr32(ctx, fp32, fd);
9930         }
9931         break;
9932     case OPC_TRUNC_W_D:
9933         check_cp1_registers(ctx, fs);
9934         {
9935             TCGv_i32 fp32 = tcg_temp_new_i32();
9936             TCGv_i64 fp64 = tcg_temp_new_i64();
9937 
9938             gen_load_fpr64(ctx, fp64, fs);
9939             if (ctx->nan2008) {
9940                 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64);
9941             } else {
9942                 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64);
9943             }
9944             gen_store_fpr32(ctx, fp32, fd);
9945         }
9946         break;
9947     case OPC_CEIL_W_D:
9948         check_cp1_registers(ctx, fs);
9949         {
9950             TCGv_i32 fp32 = tcg_temp_new_i32();
9951             TCGv_i64 fp64 = tcg_temp_new_i64();
9952 
9953             gen_load_fpr64(ctx, fp64, fs);
9954             if (ctx->nan2008) {
9955                 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64);
9956             } else {
9957                 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64);
9958             }
9959             gen_store_fpr32(ctx, fp32, fd);
9960         }
9961         break;
9962     case OPC_FLOOR_W_D:
9963         check_cp1_registers(ctx, fs);
9964         {
9965             TCGv_i32 fp32 = tcg_temp_new_i32();
9966             TCGv_i64 fp64 = tcg_temp_new_i64();
9967 
9968             gen_load_fpr64(ctx, fp64, fs);
9969             if (ctx->nan2008) {
9970                 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64);
9971             } else {
9972                 gen_helper_float_floor_w_d(fp32, tcg_env, fp64);
9973             }
9974             gen_store_fpr32(ctx, fp32, fd);
9975         }
9976         break;
9977     case OPC_SEL_D:
9978         check_insn(ctx, ISA_MIPS_R6);
9979         gen_sel_d(ctx, op1, fd, ft, fs);
9980         break;
9981     case OPC_SELEQZ_D:
9982         check_insn(ctx, ISA_MIPS_R6);
9983         gen_sel_d(ctx, op1, fd, ft, fs);
9984         break;
9985     case OPC_SELNEZ_D:
9986         check_insn(ctx, ISA_MIPS_R6);
9987         gen_sel_d(ctx, op1, fd, ft, fs);
9988         break;
9989     case OPC_MOVCF_D:
9990         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9991         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9992         break;
9993     case OPC_MOVZ_D:
9994         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9995         {
9996             TCGLabel *l1 = gen_new_label();
9997             TCGv_i64 fp0;
9998 
9999             if (ft != 0) {
10000                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10001             }
10002             fp0 = tcg_temp_new_i64();
10003             gen_load_fpr64(ctx, fp0, fs);
10004             gen_store_fpr64(ctx, fp0, fd);
10005             gen_set_label(l1);
10006         }
10007         break;
10008     case OPC_MOVN_D:
10009         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10010         {
10011             TCGLabel *l1 = gen_new_label();
10012             TCGv_i64 fp0;
10013 
10014             if (ft != 0) {
10015                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10016                 fp0 = tcg_temp_new_i64();
10017                 gen_load_fpr64(ctx, fp0, fs);
10018                 gen_store_fpr64(ctx, fp0, fd);
10019                 gen_set_label(l1);
10020             }
10021         }
10022         break;
10023     case OPC_RECIP_D:
10024         check_cp1_registers(ctx, fs | fd);
10025         {
10026             TCGv_i64 fp0 = tcg_temp_new_i64();
10027 
10028             gen_load_fpr64(ctx, fp0, fs);
10029             gen_helper_float_recip_d(fp0, tcg_env, fp0);
10030             gen_store_fpr64(ctx, fp0, fd);
10031         }
10032         break;
10033     case OPC_RSQRT_D:
10034         check_cp1_registers(ctx, fs | fd);
10035         {
10036             TCGv_i64 fp0 = tcg_temp_new_i64();
10037 
10038             gen_load_fpr64(ctx, fp0, fs);
10039             gen_helper_float_rsqrt_d(fp0, tcg_env, fp0);
10040             gen_store_fpr64(ctx, fp0, fd);
10041         }
10042         break;
10043     case OPC_MADDF_D:
10044         check_insn(ctx, ISA_MIPS_R6);
10045         {
10046             TCGv_i64 fp0 = tcg_temp_new_i64();
10047             TCGv_i64 fp1 = tcg_temp_new_i64();
10048             TCGv_i64 fp2 = tcg_temp_new_i64();
10049             gen_load_fpr64(ctx, fp0, fs);
10050             gen_load_fpr64(ctx, fp1, ft);
10051             gen_load_fpr64(ctx, fp2, fd);
10052             gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2);
10053             gen_store_fpr64(ctx, fp2, fd);
10054         }
10055         break;
10056     case OPC_MSUBF_D:
10057         check_insn(ctx, ISA_MIPS_R6);
10058         {
10059             TCGv_i64 fp0 = tcg_temp_new_i64();
10060             TCGv_i64 fp1 = tcg_temp_new_i64();
10061             TCGv_i64 fp2 = tcg_temp_new_i64();
10062             gen_load_fpr64(ctx, fp0, fs);
10063             gen_load_fpr64(ctx, fp1, ft);
10064             gen_load_fpr64(ctx, fp2, fd);
10065             gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2);
10066             gen_store_fpr64(ctx, fp2, fd);
10067         }
10068         break;
10069     case OPC_RINT_D:
10070         check_insn(ctx, ISA_MIPS_R6);
10071         {
10072             TCGv_i64 fp0 = tcg_temp_new_i64();
10073             gen_load_fpr64(ctx, fp0, fs);
10074             gen_helper_float_rint_d(fp0, tcg_env, fp0);
10075             gen_store_fpr64(ctx, fp0, fd);
10076         }
10077         break;
10078     case OPC_CLASS_D:
10079         check_insn(ctx, ISA_MIPS_R6);
10080         {
10081             TCGv_i64 fp0 = tcg_temp_new_i64();
10082             gen_load_fpr64(ctx, fp0, fs);
10083             gen_helper_float_class_d(fp0, tcg_env, fp0);
10084             gen_store_fpr64(ctx, fp0, fd);
10085         }
10086         break;
10087     case OPC_MIN_D: /* OPC_RECIP2_D */
10088         if (ctx->insn_flags & ISA_MIPS_R6) {
10089             /* OPC_MIN_D */
10090             TCGv_i64 fp0 = tcg_temp_new_i64();
10091             TCGv_i64 fp1 = tcg_temp_new_i64();
10092             gen_load_fpr64(ctx, fp0, fs);
10093             gen_load_fpr64(ctx, fp1, ft);
10094             gen_helper_float_min_d(fp1, tcg_env, fp0, fp1);
10095             gen_store_fpr64(ctx, fp1, fd);
10096         } else {
10097             /* OPC_RECIP2_D */
10098             check_cp1_64bitmode(ctx);
10099             {
10100                 TCGv_i64 fp0 = tcg_temp_new_i64();
10101                 TCGv_i64 fp1 = tcg_temp_new_i64();
10102 
10103                 gen_load_fpr64(ctx, fp0, fs);
10104                 gen_load_fpr64(ctx, fp1, ft);
10105                 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1);
10106                 gen_store_fpr64(ctx, fp0, fd);
10107             }
10108         }
10109         break;
10110     case OPC_MINA_D: /* OPC_RECIP1_D */
10111         if (ctx->insn_flags & ISA_MIPS_R6) {
10112             /* OPC_MINA_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_mina_d(fp1, tcg_env, fp0, fp1);
10118             gen_store_fpr64(ctx, fp1, fd);
10119         } else {
10120             /* OPC_RECIP1_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_recip1_d(fp0, tcg_env, fp0);
10127                 gen_store_fpr64(ctx, fp0, fd);
10128             }
10129         }
10130         break;
10131     case OPC_MAX_D: /*  OPC_RSQRT1_D */
10132         if (ctx->insn_flags & ISA_MIPS_R6) {
10133             /* OPC_MAX_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_max_d(fp1, tcg_env, fp0, fp1);
10139             gen_store_fpr64(ctx, fp1, fd);
10140         } else {
10141             /* OPC_RSQRT1_D */
10142             check_cp1_64bitmode(ctx);
10143             {
10144                 TCGv_i64 fp0 = tcg_temp_new_i64();
10145 
10146                 gen_load_fpr64(ctx, fp0, fs);
10147                 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0);
10148                 gen_store_fpr64(ctx, fp0, fd);
10149             }
10150         }
10151         break;
10152     case OPC_MAXA_D: /* OPC_RSQRT2_D */
10153         if (ctx->insn_flags & ISA_MIPS_R6) {
10154             /* OPC_MAXA_D */
10155             TCGv_i64 fp0 = tcg_temp_new_i64();
10156             TCGv_i64 fp1 = tcg_temp_new_i64();
10157             gen_load_fpr64(ctx, fp0, fs);
10158             gen_load_fpr64(ctx, fp1, ft);
10159             gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1);
10160             gen_store_fpr64(ctx, fp1, fd);
10161         } else {
10162             /* OPC_RSQRT2_D */
10163             check_cp1_64bitmode(ctx);
10164             {
10165                 TCGv_i64 fp0 = tcg_temp_new_i64();
10166                 TCGv_i64 fp1 = tcg_temp_new_i64();
10167 
10168                 gen_load_fpr64(ctx, fp0, fs);
10169                 gen_load_fpr64(ctx, fp1, ft);
10170                 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1);
10171                 gen_store_fpr64(ctx, fp0, fd);
10172             }
10173         }
10174         break;
10175     case OPC_CMP_F_D:
10176     case OPC_CMP_UN_D:
10177     case OPC_CMP_EQ_D:
10178     case OPC_CMP_UEQ_D:
10179     case OPC_CMP_OLT_D:
10180     case OPC_CMP_ULT_D:
10181     case OPC_CMP_OLE_D:
10182     case OPC_CMP_ULE_D:
10183     case OPC_CMP_SF_D:
10184     case OPC_CMP_NGLE_D:
10185     case OPC_CMP_SEQ_D:
10186     case OPC_CMP_NGL_D:
10187     case OPC_CMP_LT_D:
10188     case OPC_CMP_NGE_D:
10189     case OPC_CMP_LE_D:
10190     case OPC_CMP_NGT_D:
10191         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10192         if (ctx->opcode & (1 << 6)) {
10193             gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10194         } else {
10195             gen_cmp_d(ctx, func - 48, ft, fs, cc);
10196         }
10197         break;
10198     case OPC_CVT_S_D:
10199         check_cp1_registers(ctx, fs);
10200         {
10201             TCGv_i32 fp32 = tcg_temp_new_i32();
10202             TCGv_i64 fp64 = tcg_temp_new_i64();
10203 
10204             gen_load_fpr64(ctx, fp64, fs);
10205             gen_helper_float_cvts_d(fp32, tcg_env, fp64);
10206             gen_store_fpr32(ctx, fp32, fd);
10207         }
10208         break;
10209     case OPC_CVT_W_D:
10210         check_cp1_registers(ctx, fs);
10211         {
10212             TCGv_i32 fp32 = tcg_temp_new_i32();
10213             TCGv_i64 fp64 = tcg_temp_new_i64();
10214 
10215             gen_load_fpr64(ctx, fp64, fs);
10216             if (ctx->nan2008) {
10217                 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64);
10218             } else {
10219                 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64);
10220             }
10221             gen_store_fpr32(ctx, fp32, fd);
10222         }
10223         break;
10224     case OPC_CVT_L_D:
10225         check_cp1_64bitmode(ctx);
10226         {
10227             TCGv_i64 fp0 = tcg_temp_new_i64();
10228 
10229             gen_load_fpr64(ctx, fp0, fs);
10230             if (ctx->nan2008) {
10231                 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0);
10232             } else {
10233                 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0);
10234             }
10235             gen_store_fpr64(ctx, fp0, fd);
10236         }
10237         break;
10238     case OPC_CVT_S_W:
10239         {
10240             TCGv_i32 fp0 = tcg_temp_new_i32();
10241 
10242             gen_load_fpr32(ctx, fp0, fs);
10243             gen_helper_float_cvts_w(fp0, tcg_env, fp0);
10244             gen_store_fpr32(ctx, fp0, fd);
10245         }
10246         break;
10247     case OPC_CVT_D_W:
10248         check_cp1_registers(ctx, fd);
10249         {
10250             TCGv_i32 fp32 = tcg_temp_new_i32();
10251             TCGv_i64 fp64 = tcg_temp_new_i64();
10252 
10253             gen_load_fpr32(ctx, fp32, fs);
10254             gen_helper_float_cvtd_w(fp64, tcg_env, fp32);
10255             gen_store_fpr64(ctx, fp64, fd);
10256         }
10257         break;
10258     case OPC_CVT_S_L:
10259         check_cp1_64bitmode(ctx);
10260         {
10261             TCGv_i32 fp32 = tcg_temp_new_i32();
10262             TCGv_i64 fp64 = tcg_temp_new_i64();
10263 
10264             gen_load_fpr64(ctx, fp64, fs);
10265             gen_helper_float_cvts_l(fp32, tcg_env, fp64);
10266             gen_store_fpr32(ctx, fp32, fd);
10267         }
10268         break;
10269     case OPC_CVT_D_L:
10270         check_cp1_64bitmode(ctx);
10271         {
10272             TCGv_i64 fp0 = tcg_temp_new_i64();
10273 
10274             gen_load_fpr64(ctx, fp0, fs);
10275             gen_helper_float_cvtd_l(fp0, tcg_env, fp0);
10276             gen_store_fpr64(ctx, fp0, fd);
10277         }
10278         break;
10279     case OPC_CVT_PS_PW:
10280         check_ps(ctx);
10281         {
10282             TCGv_i64 fp0 = tcg_temp_new_i64();
10283 
10284             gen_load_fpr64(ctx, fp0, fs);
10285             gen_helper_float_cvtps_pw(fp0, tcg_env, fp0);
10286             gen_store_fpr64(ctx, fp0, fd);
10287         }
10288         break;
10289     case OPC_ADD_PS:
10290         check_ps(ctx);
10291         {
10292             TCGv_i64 fp0 = tcg_temp_new_i64();
10293             TCGv_i64 fp1 = tcg_temp_new_i64();
10294 
10295             gen_load_fpr64(ctx, fp0, fs);
10296             gen_load_fpr64(ctx, fp1, ft);
10297             gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1);
10298             gen_store_fpr64(ctx, fp0, fd);
10299         }
10300         break;
10301     case OPC_SUB_PS:
10302         check_ps(ctx);
10303         {
10304             TCGv_i64 fp0 = tcg_temp_new_i64();
10305             TCGv_i64 fp1 = tcg_temp_new_i64();
10306 
10307             gen_load_fpr64(ctx, fp0, fs);
10308             gen_load_fpr64(ctx, fp1, ft);
10309             gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1);
10310             gen_store_fpr64(ctx, fp0, fd);
10311         }
10312         break;
10313     case OPC_MUL_PS:
10314         check_ps(ctx);
10315         {
10316             TCGv_i64 fp0 = tcg_temp_new_i64();
10317             TCGv_i64 fp1 = tcg_temp_new_i64();
10318 
10319             gen_load_fpr64(ctx, fp0, fs);
10320             gen_load_fpr64(ctx, fp1, ft);
10321             gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1);
10322             gen_store_fpr64(ctx, fp0, fd);
10323         }
10324         break;
10325     case OPC_ABS_PS:
10326         check_ps(ctx);
10327         {
10328             TCGv_i64 fp0 = tcg_temp_new_i64();
10329 
10330             gen_load_fpr64(ctx, fp0, fs);
10331             gen_helper_float_abs_ps(fp0, fp0);
10332             gen_store_fpr64(ctx, fp0, fd);
10333         }
10334         break;
10335     case OPC_MOV_PS:
10336         check_ps(ctx);
10337         {
10338             TCGv_i64 fp0 = tcg_temp_new_i64();
10339 
10340             gen_load_fpr64(ctx, fp0, fs);
10341             gen_store_fpr64(ctx, fp0, fd);
10342         }
10343         break;
10344     case OPC_NEG_PS:
10345         check_ps(ctx);
10346         {
10347             TCGv_i64 fp0 = tcg_temp_new_i64();
10348 
10349             gen_load_fpr64(ctx, fp0, fs);
10350             gen_helper_float_chs_ps(fp0, fp0);
10351             gen_store_fpr64(ctx, fp0, fd);
10352         }
10353         break;
10354     case OPC_MOVCF_PS:
10355         check_ps(ctx);
10356         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10357         break;
10358     case OPC_MOVZ_PS:
10359         check_ps(ctx);
10360         {
10361             TCGLabel *l1 = gen_new_label();
10362             TCGv_i64 fp0;
10363 
10364             if (ft != 0) {
10365                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10366             }
10367             fp0 = tcg_temp_new_i64();
10368             gen_load_fpr64(ctx, fp0, fs);
10369             gen_store_fpr64(ctx, fp0, fd);
10370             gen_set_label(l1);
10371         }
10372         break;
10373     case OPC_MOVN_PS:
10374         check_ps(ctx);
10375         {
10376             TCGLabel *l1 = gen_new_label();
10377             TCGv_i64 fp0;
10378 
10379             if (ft != 0) {
10380                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10381                 fp0 = tcg_temp_new_i64();
10382                 gen_load_fpr64(ctx, fp0, fs);
10383                 gen_store_fpr64(ctx, fp0, fd);
10384                 gen_set_label(l1);
10385             }
10386         }
10387         break;
10388     case OPC_ADDR_PS:
10389         check_ps(ctx);
10390         {
10391             TCGv_i64 fp0 = tcg_temp_new_i64();
10392             TCGv_i64 fp1 = tcg_temp_new_i64();
10393 
10394             gen_load_fpr64(ctx, fp0, ft);
10395             gen_load_fpr64(ctx, fp1, fs);
10396             gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1);
10397             gen_store_fpr64(ctx, fp0, fd);
10398         }
10399         break;
10400     case OPC_MULR_PS:
10401         check_ps(ctx);
10402         {
10403             TCGv_i64 fp0 = tcg_temp_new_i64();
10404             TCGv_i64 fp1 = tcg_temp_new_i64();
10405 
10406             gen_load_fpr64(ctx, fp0, ft);
10407             gen_load_fpr64(ctx, fp1, fs);
10408             gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1);
10409             gen_store_fpr64(ctx, fp0, fd);
10410         }
10411         break;
10412     case OPC_RECIP2_PS:
10413         check_ps(ctx);
10414         {
10415             TCGv_i64 fp0 = tcg_temp_new_i64();
10416             TCGv_i64 fp1 = tcg_temp_new_i64();
10417 
10418             gen_load_fpr64(ctx, fp0, fs);
10419             gen_load_fpr64(ctx, fp1, ft);
10420             gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1);
10421             gen_store_fpr64(ctx, fp0, fd);
10422         }
10423         break;
10424     case OPC_RECIP1_PS:
10425         check_ps(ctx);
10426         {
10427             TCGv_i64 fp0 = tcg_temp_new_i64();
10428 
10429             gen_load_fpr64(ctx, fp0, fs);
10430             gen_helper_float_recip1_ps(fp0, tcg_env, fp0);
10431             gen_store_fpr64(ctx, fp0, fd);
10432         }
10433         break;
10434     case OPC_RSQRT1_PS:
10435         check_ps(ctx);
10436         {
10437             TCGv_i64 fp0 = tcg_temp_new_i64();
10438 
10439             gen_load_fpr64(ctx, fp0, fs);
10440             gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0);
10441             gen_store_fpr64(ctx, fp0, fd);
10442         }
10443         break;
10444     case OPC_RSQRT2_PS:
10445         check_ps(ctx);
10446         {
10447             TCGv_i64 fp0 = tcg_temp_new_i64();
10448             TCGv_i64 fp1 = tcg_temp_new_i64();
10449 
10450             gen_load_fpr64(ctx, fp0, fs);
10451             gen_load_fpr64(ctx, fp1, ft);
10452             gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1);
10453             gen_store_fpr64(ctx, fp0, fd);
10454         }
10455         break;
10456     case OPC_CVT_S_PU:
10457         check_cp1_64bitmode(ctx);
10458         {
10459             TCGv_i32 fp0 = tcg_temp_new_i32();
10460 
10461             gen_load_fpr32h(ctx, fp0, fs);
10462             gen_helper_float_cvts_pu(fp0, tcg_env, fp0);
10463             gen_store_fpr32(ctx, fp0, fd);
10464         }
10465         break;
10466     case OPC_CVT_PW_PS:
10467         check_ps(ctx);
10468         {
10469             TCGv_i64 fp0 = tcg_temp_new_i64();
10470 
10471             gen_load_fpr64(ctx, fp0, fs);
10472             gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0);
10473             gen_store_fpr64(ctx, fp0, fd);
10474         }
10475         break;
10476     case OPC_CVT_S_PL:
10477         check_cp1_64bitmode(ctx);
10478         {
10479             TCGv_i32 fp0 = tcg_temp_new_i32();
10480 
10481             gen_load_fpr32(ctx, fp0, fs);
10482             gen_helper_float_cvts_pl(fp0, tcg_env, fp0);
10483             gen_store_fpr32(ctx, fp0, fd);
10484         }
10485         break;
10486     case OPC_PLL_PS:
10487         check_ps(ctx);
10488         {
10489             TCGv_i32 fp0 = tcg_temp_new_i32();
10490             TCGv_i32 fp1 = tcg_temp_new_i32();
10491 
10492             gen_load_fpr32(ctx, fp0, fs);
10493             gen_load_fpr32(ctx, fp1, ft);
10494             gen_store_fpr32h(ctx, fp0, fd);
10495             gen_store_fpr32(ctx, fp1, fd);
10496         }
10497         break;
10498     case OPC_PLU_PS:
10499         check_ps(ctx);
10500         {
10501             TCGv_i32 fp0 = tcg_temp_new_i32();
10502             TCGv_i32 fp1 = tcg_temp_new_i32();
10503 
10504             gen_load_fpr32(ctx, fp0, fs);
10505             gen_load_fpr32h(ctx, fp1, ft);
10506             gen_store_fpr32(ctx, fp1, fd);
10507             gen_store_fpr32h(ctx, fp0, fd);
10508         }
10509         break;
10510     case OPC_PUL_PS:
10511         check_ps(ctx);
10512         {
10513             TCGv_i32 fp0 = tcg_temp_new_i32();
10514             TCGv_i32 fp1 = tcg_temp_new_i32();
10515 
10516             gen_load_fpr32h(ctx, fp0, fs);
10517             gen_load_fpr32(ctx, fp1, ft);
10518             gen_store_fpr32(ctx, fp1, fd);
10519             gen_store_fpr32h(ctx, fp0, fd);
10520         }
10521         break;
10522     case OPC_PUU_PS:
10523         check_ps(ctx);
10524         {
10525             TCGv_i32 fp0 = tcg_temp_new_i32();
10526             TCGv_i32 fp1 = tcg_temp_new_i32();
10527 
10528             gen_load_fpr32h(ctx, fp0, fs);
10529             gen_load_fpr32h(ctx, fp1, ft);
10530             gen_store_fpr32(ctx, fp1, fd);
10531             gen_store_fpr32h(ctx, fp0, fd);
10532         }
10533         break;
10534     case OPC_CMP_F_PS:
10535     case OPC_CMP_UN_PS:
10536     case OPC_CMP_EQ_PS:
10537     case OPC_CMP_UEQ_PS:
10538     case OPC_CMP_OLT_PS:
10539     case OPC_CMP_ULT_PS:
10540     case OPC_CMP_OLE_PS:
10541     case OPC_CMP_ULE_PS:
10542     case OPC_CMP_SF_PS:
10543     case OPC_CMP_NGLE_PS:
10544     case OPC_CMP_SEQ_PS:
10545     case OPC_CMP_NGL_PS:
10546     case OPC_CMP_LT_PS:
10547     case OPC_CMP_NGE_PS:
10548     case OPC_CMP_LE_PS:
10549     case OPC_CMP_NGT_PS:
10550         if (ctx->opcode & (1 << 6)) {
10551             gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
10552         } else {
10553             gen_cmp_ps(ctx, func - 48, ft, fs, cc);
10554         }
10555         break;
10556     default:
10557         MIPS_INVAL("farith");
10558         gen_reserved_instruction(ctx);
10559         return;
10560     }
10561 }
10562 
10563 /* Coprocessor 3 (FPU) */
gen_flt3_ldst(DisasContext * ctx,uint32_t opc,int fd,int fs,int base,int index)10564 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
10565                           int fd, int fs, int base, int index)
10566 {
10567     TCGv t0 = tcg_temp_new();
10568 
10569     gen_base_index_addr(ctx, t0, base, index);
10570     /*
10571      * Don't do NOP if destination is zero: we must perform the actual
10572      * memory access.
10573      */
10574     switch (opc) {
10575     case OPC_LWXC1:
10576         check_cop1x(ctx);
10577         {
10578             TCGv_i32 fp0 = tcg_temp_new_i32();
10579 
10580             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
10581             tcg_gen_trunc_tl_i32(fp0, t0);
10582             gen_store_fpr32(ctx, fp0, fd);
10583         }
10584         break;
10585     case OPC_LDXC1:
10586         check_cop1x(ctx);
10587         check_cp1_registers(ctx, fd);
10588         {
10589             TCGv_i64 fp0 = tcg_temp_new_i64();
10590             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10591             gen_store_fpr64(ctx, fp0, fd);
10592         }
10593         break;
10594     case OPC_LUXC1:
10595         check_cp1_64bitmode(ctx);
10596         tcg_gen_andi_tl(t0, t0, ~0x7);
10597         {
10598             TCGv_i64 fp0 = tcg_temp_new_i64();
10599 
10600             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10601             gen_store_fpr64(ctx, fp0, fd);
10602         }
10603         break;
10604     case OPC_SWXC1:
10605         check_cop1x(ctx);
10606         {
10607             TCGv_i32 fp0 = tcg_temp_new_i32();
10608             gen_load_fpr32(ctx, fp0, fs);
10609             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
10610         }
10611         break;
10612     case OPC_SDXC1:
10613         check_cop1x(ctx);
10614         check_cp1_registers(ctx, fs);
10615         {
10616             TCGv_i64 fp0 = tcg_temp_new_i64();
10617             gen_load_fpr64(ctx, fp0, fs);
10618             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10619         }
10620         break;
10621     case OPC_SUXC1:
10622         check_cp1_64bitmode(ctx);
10623         tcg_gen_andi_tl(t0, t0, ~0x7);
10624         {
10625             TCGv_i64 fp0 = tcg_temp_new_i64();
10626             gen_load_fpr64(ctx, fp0, fs);
10627             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10628         }
10629         break;
10630     }
10631 }
10632 
gen_flt3_arith(DisasContext * ctx,uint32_t opc,int fd,int fr,int fs,int ft)10633 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
10634                            int fd, int fr, int fs, int ft)
10635 {
10636     switch (opc) {
10637     case OPC_ALNV_PS:
10638         check_ps(ctx);
10639         {
10640             TCGv t0 = tcg_temp_new();
10641             TCGv_i32 fp = tcg_temp_new_i32();
10642             TCGv_i32 fph = tcg_temp_new_i32();
10643             TCGLabel *l1 = gen_new_label();
10644             TCGLabel *l2 = gen_new_label();
10645 
10646             gen_load_gpr(t0, fr);
10647             tcg_gen_andi_tl(t0, t0, 0x7);
10648 
10649             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10650             gen_load_fpr32(ctx, fp, fs);
10651             gen_load_fpr32h(ctx, fph, fs);
10652             gen_store_fpr32(ctx, fp, fd);
10653             gen_store_fpr32h(ctx, fph, fd);
10654             tcg_gen_br(l2);
10655             gen_set_label(l1);
10656             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10657             if (disas_is_bigendian(ctx)) {
10658                 gen_load_fpr32(ctx, fp, fs);
10659                 gen_load_fpr32h(ctx, fph, ft);
10660                 gen_store_fpr32h(ctx, fp, fd);
10661                 gen_store_fpr32(ctx, fph, fd);
10662             } else {
10663                 gen_load_fpr32h(ctx, fph, fs);
10664                 gen_load_fpr32(ctx, fp, ft);
10665                 gen_store_fpr32(ctx, fph, fd);
10666                 gen_store_fpr32h(ctx, fp, fd);
10667             }
10668             gen_set_label(l2);
10669         }
10670         break;
10671     case OPC_MADD_S:
10672         check_cop1x(ctx);
10673         {
10674             TCGv_i32 fp0 = tcg_temp_new_i32();
10675             TCGv_i32 fp1 = tcg_temp_new_i32();
10676             TCGv_i32 fp2 = tcg_temp_new_i32();
10677 
10678             gen_load_fpr32(ctx, fp0, fs);
10679             gen_load_fpr32(ctx, fp1, ft);
10680             gen_load_fpr32(ctx, fp2, fr);
10681             gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2);
10682             gen_store_fpr32(ctx, fp2, fd);
10683         }
10684         break;
10685     case OPC_MADD_D:
10686         check_cop1x(ctx);
10687         check_cp1_registers(ctx, fd | fs | ft | fr);
10688         {
10689             TCGv_i64 fp0 = tcg_temp_new_i64();
10690             TCGv_i64 fp1 = tcg_temp_new_i64();
10691             TCGv_i64 fp2 = tcg_temp_new_i64();
10692 
10693             gen_load_fpr64(ctx, fp0, fs);
10694             gen_load_fpr64(ctx, fp1, ft);
10695             gen_load_fpr64(ctx, fp2, fr);
10696             gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2);
10697             gen_store_fpr64(ctx, fp2, fd);
10698         }
10699         break;
10700     case OPC_MADD_PS:
10701         check_ps(ctx);
10702         {
10703             TCGv_i64 fp0 = tcg_temp_new_i64();
10704             TCGv_i64 fp1 = tcg_temp_new_i64();
10705             TCGv_i64 fp2 = tcg_temp_new_i64();
10706 
10707             gen_load_fpr64(ctx, fp0, fs);
10708             gen_load_fpr64(ctx, fp1, ft);
10709             gen_load_fpr64(ctx, fp2, fr);
10710             gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2);
10711             gen_store_fpr64(ctx, fp2, fd);
10712         }
10713         break;
10714     case OPC_MSUB_S:
10715         check_cop1x(ctx);
10716         {
10717             TCGv_i32 fp0 = tcg_temp_new_i32();
10718             TCGv_i32 fp1 = tcg_temp_new_i32();
10719             TCGv_i32 fp2 = tcg_temp_new_i32();
10720 
10721             gen_load_fpr32(ctx, fp0, fs);
10722             gen_load_fpr32(ctx, fp1, ft);
10723             gen_load_fpr32(ctx, fp2, fr);
10724             gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2);
10725             gen_store_fpr32(ctx, fp2, fd);
10726         }
10727         break;
10728     case OPC_MSUB_D:
10729         check_cop1x(ctx);
10730         check_cp1_registers(ctx, fd | fs | ft | fr);
10731         {
10732             TCGv_i64 fp0 = tcg_temp_new_i64();
10733             TCGv_i64 fp1 = tcg_temp_new_i64();
10734             TCGv_i64 fp2 = tcg_temp_new_i64();
10735 
10736             gen_load_fpr64(ctx, fp0, fs);
10737             gen_load_fpr64(ctx, fp1, ft);
10738             gen_load_fpr64(ctx, fp2, fr);
10739             gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2);
10740             gen_store_fpr64(ctx, fp2, fd);
10741         }
10742         break;
10743     case OPC_MSUB_PS:
10744         check_ps(ctx);
10745         {
10746             TCGv_i64 fp0 = tcg_temp_new_i64();
10747             TCGv_i64 fp1 = tcg_temp_new_i64();
10748             TCGv_i64 fp2 = tcg_temp_new_i64();
10749 
10750             gen_load_fpr64(ctx, fp0, fs);
10751             gen_load_fpr64(ctx, fp1, ft);
10752             gen_load_fpr64(ctx, fp2, fr);
10753             gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2);
10754             gen_store_fpr64(ctx, fp2, fd);
10755         }
10756         break;
10757     case OPC_NMADD_S:
10758         check_cop1x(ctx);
10759         {
10760             TCGv_i32 fp0 = tcg_temp_new_i32();
10761             TCGv_i32 fp1 = tcg_temp_new_i32();
10762             TCGv_i32 fp2 = tcg_temp_new_i32();
10763 
10764             gen_load_fpr32(ctx, fp0, fs);
10765             gen_load_fpr32(ctx, fp1, ft);
10766             gen_load_fpr32(ctx, fp2, fr);
10767             gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2);
10768             gen_store_fpr32(ctx, fp2, fd);
10769         }
10770         break;
10771     case OPC_NMADD_D:
10772         check_cop1x(ctx);
10773         check_cp1_registers(ctx, fd | fs | ft | fr);
10774         {
10775             TCGv_i64 fp0 = tcg_temp_new_i64();
10776             TCGv_i64 fp1 = tcg_temp_new_i64();
10777             TCGv_i64 fp2 = tcg_temp_new_i64();
10778 
10779             gen_load_fpr64(ctx, fp0, fs);
10780             gen_load_fpr64(ctx, fp1, ft);
10781             gen_load_fpr64(ctx, fp2, fr);
10782             gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2);
10783             gen_store_fpr64(ctx, fp2, fd);
10784         }
10785         break;
10786     case OPC_NMADD_PS:
10787         check_ps(ctx);
10788         {
10789             TCGv_i64 fp0 = tcg_temp_new_i64();
10790             TCGv_i64 fp1 = tcg_temp_new_i64();
10791             TCGv_i64 fp2 = tcg_temp_new_i64();
10792 
10793             gen_load_fpr64(ctx, fp0, fs);
10794             gen_load_fpr64(ctx, fp1, ft);
10795             gen_load_fpr64(ctx, fp2, fr);
10796             gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2);
10797             gen_store_fpr64(ctx, fp2, fd);
10798         }
10799         break;
10800     case OPC_NMSUB_S:
10801         check_cop1x(ctx);
10802         {
10803             TCGv_i32 fp0 = tcg_temp_new_i32();
10804             TCGv_i32 fp1 = tcg_temp_new_i32();
10805             TCGv_i32 fp2 = tcg_temp_new_i32();
10806 
10807             gen_load_fpr32(ctx, fp0, fs);
10808             gen_load_fpr32(ctx, fp1, ft);
10809             gen_load_fpr32(ctx, fp2, fr);
10810             gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2);
10811             gen_store_fpr32(ctx, fp2, fd);
10812         }
10813         break;
10814     case OPC_NMSUB_D:
10815         check_cop1x(ctx);
10816         check_cp1_registers(ctx, fd | fs | ft | fr);
10817         {
10818             TCGv_i64 fp0 = tcg_temp_new_i64();
10819             TCGv_i64 fp1 = tcg_temp_new_i64();
10820             TCGv_i64 fp2 = tcg_temp_new_i64();
10821 
10822             gen_load_fpr64(ctx, fp0, fs);
10823             gen_load_fpr64(ctx, fp1, ft);
10824             gen_load_fpr64(ctx, fp2, fr);
10825             gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2);
10826             gen_store_fpr64(ctx, fp2, fd);
10827         }
10828         break;
10829     case OPC_NMSUB_PS:
10830         check_ps(ctx);
10831         {
10832             TCGv_i64 fp0 = tcg_temp_new_i64();
10833             TCGv_i64 fp1 = tcg_temp_new_i64();
10834             TCGv_i64 fp2 = tcg_temp_new_i64();
10835 
10836             gen_load_fpr64(ctx, fp0, fs);
10837             gen_load_fpr64(ctx, fp1, ft);
10838             gen_load_fpr64(ctx, fp2, fr);
10839             gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2);
10840             gen_store_fpr64(ctx, fp2, fd);
10841         }
10842         break;
10843     default:
10844         MIPS_INVAL("flt3_arith");
10845         gen_reserved_instruction(ctx);
10846         return;
10847     }
10848 }
10849 
gen_rdhwr(DisasContext * ctx,int rt,int rd,int sel)10850 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10851 {
10852     TCGv t0;
10853 
10854 #if !defined(CONFIG_USER_ONLY)
10855     /*
10856      * The Linux kernel will emulate rdhwr if it's not supported natively.
10857      * Therefore only check the ISA in system mode.
10858      */
10859     check_insn(ctx, ISA_MIPS_R2);
10860 #endif
10861     t0 = tcg_temp_new();
10862 
10863     switch (rd) {
10864     case 0:
10865         gen_helper_rdhwr_cpunum(t0, tcg_env);
10866         gen_store_gpr(t0, rt);
10867         break;
10868     case 1:
10869         gen_helper_rdhwr_synci_step(t0, tcg_env);
10870         gen_store_gpr(t0, rt);
10871         break;
10872     case 2:
10873         translator_io_start(&ctx->base);
10874         gen_helper_rdhwr_cc(t0, tcg_env);
10875         gen_store_gpr(t0, rt);
10876         /*
10877          * Break the TB to be able to take timer interrupts immediately
10878          * after reading count. DISAS_STOP isn't sufficient, we need to ensure
10879          * we break completely out of translated code.
10880          */
10881         gen_save_pc(ctx->base.pc_next + 4);
10882         ctx->base.is_jmp = DISAS_EXIT;
10883         break;
10884     case 3:
10885         gen_helper_rdhwr_ccres(t0, tcg_env);
10886         gen_store_gpr(t0, rt);
10887         break;
10888     case 4:
10889         check_insn(ctx, ISA_MIPS_R6);
10890         if (sel != 0) {
10891             /*
10892              * Performance counter registers are not implemented other than
10893              * control register 0.
10894              */
10895             generate_exception(ctx, EXCP_RI);
10896         }
10897         gen_helper_rdhwr_performance(t0, tcg_env);
10898         gen_store_gpr(t0, rt);
10899         break;
10900     case 5:
10901         check_insn(ctx, ISA_MIPS_R6);
10902         gen_helper_rdhwr_xnp(t0, tcg_env);
10903         gen_store_gpr(t0, rt);
10904         break;
10905     case 29:
10906 #if defined(CONFIG_USER_ONLY)
10907         tcg_gen_ld_tl(t0, tcg_env,
10908                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10909         gen_store_gpr(t0, rt);
10910         break;
10911 #else
10912         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10913             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10914             tcg_gen_ld_tl(t0, tcg_env,
10915                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10916             gen_store_gpr(t0, rt);
10917         } else {
10918             gen_reserved_instruction(ctx);
10919         }
10920         break;
10921 #endif
10922     default:            /* Invalid */
10923         MIPS_INVAL("rdhwr");
10924         gen_reserved_instruction(ctx);
10925         break;
10926     }
10927 }
10928 
clear_branch_hflags(DisasContext * ctx)10929 static inline void clear_branch_hflags(DisasContext *ctx)
10930 {
10931     ctx->hflags &= ~MIPS_HFLAG_BMASK;
10932     if (ctx->base.is_jmp == DISAS_NEXT) {
10933         save_cpu_state(ctx, 0);
10934     } else {
10935         /*
10936          * It is not safe to save ctx->hflags as hflags may be changed
10937          * in execution time by the instruction in delay / forbidden slot.
10938          */
10939         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10940     }
10941 }
10942 
gen_branch(DisasContext * ctx,int insn_bytes)10943 static void gen_branch(DisasContext *ctx, int insn_bytes)
10944 {
10945     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10946         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10947         /* Branches completion */
10948         clear_branch_hflags(ctx);
10949         ctx->base.is_jmp = DISAS_NORETURN;
10950         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10951         case MIPS_HFLAG_FBNSLOT:
10952             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
10953             break;
10954         case MIPS_HFLAG_B:
10955             /* unconditional branch */
10956             if (proc_hflags & MIPS_HFLAG_BX) {
10957                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10958             }
10959             gen_goto_tb(ctx, 0, ctx->btarget);
10960             break;
10961         case MIPS_HFLAG_BL:
10962             /* blikely taken case */
10963             gen_goto_tb(ctx, 0, ctx->btarget);
10964             break;
10965         case MIPS_HFLAG_BC:
10966             /* Conditional branch */
10967             {
10968                 TCGLabel *l1 = gen_new_label();
10969 
10970                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10971                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
10972                 gen_set_label(l1);
10973                 gen_goto_tb(ctx, 0, ctx->btarget);
10974             }
10975             break;
10976         case MIPS_HFLAG_BR:
10977             /* unconditional branch to register */
10978             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10979                 TCGv t0 = tcg_temp_new();
10980                 TCGv_i32 t1 = tcg_temp_new_i32();
10981 
10982                 tcg_gen_andi_tl(t0, btarget, 0x1);
10983                 tcg_gen_trunc_tl_i32(t1, t0);
10984                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10985                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10986                 tcg_gen_or_i32(hflags, hflags, t1);
10987 
10988                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10989             } else {
10990                 tcg_gen_mov_tl(cpu_PC, btarget);
10991             }
10992             tcg_gen_lookup_and_goto_ptr();
10993             break;
10994         default:
10995             LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
10996             gen_reserved_instruction(ctx);
10997         }
10998     }
10999 }
11000 
11001 /* Compact Branches */
gen_compute_compact_branch(DisasContext * ctx,uint32_t opc,int rs,int rt,int32_t offset)11002 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11003                                        int rs, int rt, int32_t offset)
11004 {
11005     int bcond_compute = 0;
11006     TCGv t0 = tcg_temp_new();
11007     TCGv t1 = tcg_temp_new();
11008     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11009 
11010     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11011 #ifdef MIPS_DEBUG_DISAS
11012         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
11013                   VADDR_PRIx "\n", ctx->base.pc_next);
11014 #endif
11015         gen_reserved_instruction(ctx);
11016         return;
11017     }
11018 
11019     /* Load needed operands and calculate btarget */
11020     switch (opc) {
11021     /* compact branch */
11022     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11023     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11024         gen_load_gpr(t0, rs);
11025         gen_load_gpr(t1, rt);
11026         bcond_compute = 1;
11027         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11028         if (rs <= rt && rs == 0) {
11029             /* OPC_BEQZALC, OPC_BNEZALC */
11030             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11031         }
11032         break;
11033     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11034     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11035         gen_load_gpr(t0, rs);
11036         gen_load_gpr(t1, rt);
11037         bcond_compute = 1;
11038         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11039         break;
11040     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11041     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11042         if (rs == 0 || rs == rt) {
11043             /* OPC_BLEZALC, OPC_BGEZALC */
11044             /* OPC_BGTZALC, OPC_BLTZALC */
11045             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11046         }
11047         gen_load_gpr(t0, rs);
11048         gen_load_gpr(t1, rt);
11049         bcond_compute = 1;
11050         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11051         break;
11052     case OPC_BC:
11053     case OPC_BALC:
11054         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11055         break;
11056     case OPC_BEQZC:
11057     case OPC_BNEZC:
11058         if (rs != 0) {
11059             /* OPC_BEQZC, OPC_BNEZC */
11060             gen_load_gpr(t0, rs);
11061             bcond_compute = 1;
11062             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11063         } else {
11064             /* OPC_JIC, OPC_JIALC */
11065             TCGv tbase = tcg_temp_new();
11066 
11067             gen_load_gpr(tbase, rt);
11068             gen_op_addr_addi(ctx, btarget, tbase, offset);
11069         }
11070         break;
11071     default:
11072         MIPS_INVAL("Compact branch/jump");
11073         gen_reserved_instruction(ctx);
11074         return;
11075     }
11076 
11077     if (bcond_compute == 0) {
11078         /* Unconditional compact branch */
11079         switch (opc) {
11080         case OPC_JIALC:
11081             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11082             /* Fallthrough */
11083         case OPC_JIC:
11084             ctx->hflags |= MIPS_HFLAG_BR;
11085             break;
11086         case OPC_BALC:
11087             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11088             /* Fallthrough */
11089         case OPC_BC:
11090             ctx->hflags |= MIPS_HFLAG_B;
11091             break;
11092         default:
11093             MIPS_INVAL("Compact branch/jump");
11094             gen_reserved_instruction(ctx);
11095             return;
11096         }
11097 
11098         /* Generating branch here as compact branches don't have delay slot */
11099         gen_branch(ctx, 4);
11100     } else {
11101         /* Conditional compact branch */
11102         TCGLabel *fs = gen_new_label();
11103         save_cpu_state(ctx, 0);
11104 
11105         switch (opc) {
11106         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11107             if (rs == 0 && rt != 0) {
11108                 /* OPC_BLEZALC */
11109                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11110             } else if (rs != 0 && rt != 0 && rs == rt) {
11111                 /* OPC_BGEZALC */
11112                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11113             } else {
11114                 /* OPC_BGEUC */
11115                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11116             }
11117             break;
11118         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11119             if (rs == 0 && rt != 0) {
11120                 /* OPC_BGTZALC */
11121                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11122             } else if (rs != 0 && rt != 0 && rs == rt) {
11123                 /* OPC_BLTZALC */
11124                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11125             } else {
11126                 /* OPC_BLTUC */
11127                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11128             }
11129             break;
11130         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11131             if (rs == 0 && rt != 0) {
11132                 /* OPC_BLEZC */
11133                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11134             } else if (rs != 0 && rt != 0 && rs == rt) {
11135                 /* OPC_BGEZC */
11136                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11137             } else {
11138                 /* OPC_BGEC */
11139                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11140             }
11141             break;
11142         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11143             if (rs == 0 && rt != 0) {
11144                 /* OPC_BGTZC */
11145                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11146             } else if (rs != 0 && rt != 0 && rs == rt) {
11147                 /* OPC_BLTZC */
11148                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11149             } else {
11150                 /* OPC_BLTC */
11151                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11152             }
11153             break;
11154         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11155         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11156             if (rs >= rt) {
11157                 /* OPC_BOVC, OPC_BNVC */
11158                 TCGv t2 = tcg_temp_new();
11159                 TCGv t3 = tcg_temp_new();
11160                 TCGv t4 = tcg_temp_new();
11161                 TCGv input_overflow = tcg_temp_new();
11162 
11163                 gen_load_gpr(t0, rs);
11164                 gen_load_gpr(t1, rt);
11165                 tcg_gen_ext32s_tl(t2, t0);
11166                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11167                 tcg_gen_ext32s_tl(t3, t1);
11168                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11169                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11170 
11171                 tcg_gen_add_tl(t4, t2, t3);
11172                 tcg_gen_ext32s_tl(t4, t4);
11173                 tcg_gen_xor_tl(t2, t2, t3);
11174                 tcg_gen_xor_tl(t3, t4, t3);
11175                 tcg_gen_andc_tl(t2, t3, t2);
11176                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11177                 tcg_gen_or_tl(t4, t4, input_overflow);
11178                 if (opc == OPC_BOVC) {
11179                     /* OPC_BOVC */
11180                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11181                 } else {
11182                     /* OPC_BNVC */
11183                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11184                 }
11185             } else if (rs < rt && rs == 0) {
11186                 /* OPC_BEQZALC, OPC_BNEZALC */
11187                 if (opc == OPC_BEQZALC) {
11188                     /* OPC_BEQZALC */
11189                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11190                 } else {
11191                     /* OPC_BNEZALC */
11192                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11193                 }
11194             } else {
11195                 /* OPC_BEQC, OPC_BNEC */
11196                 if (opc == OPC_BEQC) {
11197                     /* OPC_BEQC */
11198                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11199                 } else {
11200                     /* OPC_BNEC */
11201                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11202                 }
11203             }
11204             break;
11205         case OPC_BEQZC:
11206             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11207             break;
11208         case OPC_BNEZC:
11209             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11210             break;
11211         default:
11212             MIPS_INVAL("Compact conditional branch/jump");
11213             gen_reserved_instruction(ctx);
11214             return;
11215         }
11216 
11217         /* Generating branch here as compact branches don't have delay slot */
11218         gen_goto_tb(ctx, 1, ctx->btarget);
11219         gen_set_label(fs);
11220 
11221         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11222     }
11223 }
11224 
gen_addiupc(DisasContext * ctx,int rx,int imm,int is_64_bit,int extended)11225 void gen_addiupc(DisasContext *ctx, int rx, int imm,
11226                  int is_64_bit, int extended)
11227 {
11228     target_ulong npc;
11229 
11230     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11231         gen_reserved_instruction(ctx);
11232         return;
11233     }
11234 
11235     npc = pc_relative_pc(ctx) + imm;
11236     if (!is_64_bit) {
11237         npc = (int32_t)npc;
11238     }
11239     tcg_gen_movi_tl(cpu_gpr[rx], npc);
11240 }
11241 
gen_cache_operation(DisasContext * ctx,uint32_t op,int base,int16_t offset)11242 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11243                                 int16_t offset)
11244 {
11245     TCGv_i32 t0 = tcg_constant_i32(op);
11246     TCGv t1 = tcg_temp_new();
11247     gen_base_offset_addr(ctx, t1, base, offset);
11248     gen_helper_cache(tcg_env, t1, t0);
11249 }
11250 
is_uhi(DisasContext * ctx,int sdbbp_code)11251 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
11252 {
11253 #ifdef CONFIG_USER_ONLY
11254     return false;
11255 #else
11256     bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
11257     return semihosting_enabled(is_user) && sdbbp_code == 1;
11258 #endif
11259 }
11260 
gen_ldxs(DisasContext * ctx,int base,int index,int rd)11261 void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
11262 {
11263     TCGv t0 = tcg_temp_new();
11264     TCGv t1 = tcg_temp_new();
11265 
11266     gen_load_gpr(t0, base);
11267 
11268     if (index != 0) {
11269         gen_load_gpr(t1, index);
11270         tcg_gen_shli_tl(t1, t1, 2);
11271         gen_op_addr_add(ctx, t0, t1, t0);
11272     }
11273 
11274     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
11275     gen_store_gpr(t1, rd);
11276 }
11277 
gen_sync(int stype)11278 static void gen_sync(int stype)
11279 {
11280     TCGBar tcg_mo = TCG_BAR_SC;
11281 
11282     switch (stype) {
11283     case 0x4: /* SYNC_WMB */
11284         tcg_mo |= TCG_MO_ST_ST;
11285         break;
11286     case 0x10: /* SYNC_MB */
11287         tcg_mo |= TCG_MO_ALL;
11288         break;
11289     case 0x11: /* SYNC_ACQUIRE */
11290         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
11291         break;
11292     case 0x12: /* SYNC_RELEASE */
11293         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
11294         break;
11295     case 0x13: /* SYNC_RMB */
11296         tcg_mo |= TCG_MO_LD_LD;
11297         break;
11298     default:
11299         tcg_mo |= TCG_MO_ALL;
11300         break;
11301     }
11302 
11303     tcg_gen_mb(tcg_mo);
11304 }
11305 
11306 /* ISA extensions (ASEs) */
11307 
11308 /* MIPS16 extension to MIPS32 */
11309 #include "mips16e_translate.c.inc"
11310 
11311 /* microMIPS extension to MIPS32/MIPS64 */
11312 
11313 /*
11314  * Values for microMIPS fmt field.  Variable-width, depending on which
11315  * formats the instruction supports.
11316  */
11317 enum {
11318     FMT_SD_S = 0,
11319     FMT_SD_D = 1,
11320 
11321     FMT_SDPS_S = 0,
11322     FMT_SDPS_D = 1,
11323     FMT_SDPS_PS = 2,
11324 
11325     FMT_SWL_S = 0,
11326     FMT_SWL_W = 1,
11327     FMT_SWL_L = 2,
11328 
11329     FMT_DWL_D = 0,
11330     FMT_DWL_W = 1,
11331     FMT_DWL_L = 2
11332 };
11333 
11334 #include "micromips_translate.c.inc"
11335 
11336 #include "nanomips_translate.c.inc"
11337 
11338 /* MIPSDSP functions. */
11339 
gen_mipsdsp_arith(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2)11340 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
11341                               int ret, int v1, int v2)
11342 {
11343     TCGv v1_t;
11344     TCGv v2_t;
11345 
11346     if (ret == 0) {
11347         /* Treat as NOP. */
11348         return;
11349     }
11350 
11351     v1_t = tcg_temp_new();
11352     v2_t = tcg_temp_new();
11353 
11354     gen_load_gpr(v1_t, v1);
11355     gen_load_gpr(v2_t, v2);
11356 
11357     switch (op1) {
11358     case OPC_ADDUH_QB_DSP:
11359         check_dsp_r2(ctx);
11360         switch (op2) {
11361         case OPC_ADDUH_QB:
11362             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
11363             break;
11364         case OPC_ADDUH_R_QB:
11365             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11366             break;
11367         case OPC_ADDQH_PH:
11368             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
11369             break;
11370         case OPC_ADDQH_R_PH:
11371             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11372             break;
11373         case OPC_ADDQH_W:
11374             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
11375             break;
11376         case OPC_ADDQH_R_W:
11377             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11378             break;
11379         case OPC_SUBUH_QB:
11380             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
11381             break;
11382         case OPC_SUBUH_R_QB:
11383             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11384             break;
11385         case OPC_SUBQH_PH:
11386             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
11387             break;
11388         case OPC_SUBQH_R_PH:
11389             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11390             break;
11391         case OPC_SUBQH_W:
11392             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
11393             break;
11394         case OPC_SUBQH_R_W:
11395             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11396             break;
11397         }
11398         break;
11399     case OPC_ABSQ_S_PH_DSP:
11400         switch (op2) {
11401         case OPC_ABSQ_S_QB:
11402             check_dsp_r2(ctx);
11403             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env);
11404             break;
11405         case OPC_ABSQ_S_PH:
11406             check_dsp(ctx);
11407             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env);
11408             break;
11409         case OPC_ABSQ_S_W:
11410             check_dsp(ctx);
11411             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env);
11412             break;
11413         case OPC_PRECEQ_W_PHL:
11414             check_dsp(ctx);
11415             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
11416             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11417             break;
11418         case OPC_PRECEQ_W_PHR:
11419             check_dsp(ctx);
11420             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
11421             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
11422             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11423             break;
11424         case OPC_PRECEQU_PH_QBL:
11425             check_dsp(ctx);
11426             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
11427             break;
11428         case OPC_PRECEQU_PH_QBR:
11429             check_dsp(ctx);
11430             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
11431             break;
11432         case OPC_PRECEQU_PH_QBLA:
11433             check_dsp(ctx);
11434             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
11435             break;
11436         case OPC_PRECEQU_PH_QBRA:
11437             check_dsp(ctx);
11438             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
11439             break;
11440         case OPC_PRECEU_PH_QBL:
11441             check_dsp(ctx);
11442             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
11443             break;
11444         case OPC_PRECEU_PH_QBR:
11445             check_dsp(ctx);
11446             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
11447             break;
11448         case OPC_PRECEU_PH_QBLA:
11449             check_dsp(ctx);
11450             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
11451             break;
11452         case OPC_PRECEU_PH_QBRA:
11453             check_dsp(ctx);
11454             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
11455             break;
11456         }
11457         break;
11458     case OPC_ADDU_QB_DSP:
11459         switch (op2) {
11460         case OPC_ADDQ_PH:
11461             check_dsp(ctx);
11462             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11463             break;
11464         case OPC_ADDQ_S_PH:
11465             check_dsp(ctx);
11466             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11467             break;
11468         case OPC_ADDQ_S_W:
11469             check_dsp(ctx);
11470             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11471             break;
11472         case OPC_ADDU_QB:
11473             check_dsp(ctx);
11474             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11475             break;
11476         case OPC_ADDU_S_QB:
11477             check_dsp(ctx);
11478             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11479             break;
11480         case OPC_ADDU_PH:
11481             check_dsp_r2(ctx);
11482             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11483             break;
11484         case OPC_ADDU_S_PH:
11485             check_dsp_r2(ctx);
11486             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11487             break;
11488         case OPC_SUBQ_PH:
11489             check_dsp(ctx);
11490             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11491             break;
11492         case OPC_SUBQ_S_PH:
11493             check_dsp(ctx);
11494             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11495             break;
11496         case OPC_SUBQ_S_W:
11497             check_dsp(ctx);
11498             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11499             break;
11500         case OPC_SUBU_QB:
11501             check_dsp(ctx);
11502             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11503             break;
11504         case OPC_SUBU_S_QB:
11505             check_dsp(ctx);
11506             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11507             break;
11508         case OPC_SUBU_PH:
11509             check_dsp_r2(ctx);
11510             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11511             break;
11512         case OPC_SUBU_S_PH:
11513             check_dsp_r2(ctx);
11514             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11515             break;
11516         case OPC_ADDSC:
11517             check_dsp(ctx);
11518             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11519             break;
11520         case OPC_ADDWC:
11521             check_dsp(ctx);
11522             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11523             break;
11524         case OPC_MODSUB:
11525             check_dsp(ctx);
11526             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
11527             break;
11528         case OPC_RADDU_W_QB:
11529             check_dsp(ctx);
11530             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
11531             break;
11532         }
11533         break;
11534     case OPC_CMPU_EQ_QB_DSP:
11535         switch (op2) {
11536         case OPC_PRECR_QB_PH:
11537             check_dsp_r2(ctx);
11538             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11539             break;
11540         case OPC_PRECRQ_QB_PH:
11541             check_dsp(ctx);
11542             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11543             break;
11544         case OPC_PRECR_SRA_PH_W:
11545             check_dsp_r2(ctx);
11546             {
11547                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11548                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
11549                                           cpu_gpr[ret]);
11550                 break;
11551             }
11552         case OPC_PRECR_SRA_R_PH_W:
11553             check_dsp_r2(ctx);
11554             {
11555                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11556                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
11557                                             cpu_gpr[ret]);
11558                 break;
11559             }
11560         case OPC_PRECRQ_PH_W:
11561             check_dsp(ctx);
11562             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
11563             break;
11564         case OPC_PRECRQ_RS_PH_W:
11565             check_dsp(ctx);
11566             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11567             break;
11568         case OPC_PRECRQU_S_QB_PH:
11569             check_dsp(ctx);
11570             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11571             break;
11572         }
11573         break;
11574 #ifdef TARGET_MIPS64
11575     case OPC_ABSQ_S_QH_DSP:
11576         switch (op2) {
11577         case OPC_PRECEQ_L_PWL:
11578             check_dsp(ctx);
11579             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
11580             break;
11581         case OPC_PRECEQ_L_PWR:
11582             check_dsp(ctx);
11583             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
11584             break;
11585         case OPC_PRECEQ_PW_QHL:
11586             check_dsp(ctx);
11587             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
11588             break;
11589         case OPC_PRECEQ_PW_QHR:
11590             check_dsp(ctx);
11591             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
11592             break;
11593         case OPC_PRECEQ_PW_QHLA:
11594             check_dsp(ctx);
11595             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
11596             break;
11597         case OPC_PRECEQ_PW_QHRA:
11598             check_dsp(ctx);
11599             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
11600             break;
11601         case OPC_PRECEQU_QH_OBL:
11602             check_dsp(ctx);
11603             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
11604             break;
11605         case OPC_PRECEQU_QH_OBR:
11606             check_dsp(ctx);
11607             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
11608             break;
11609         case OPC_PRECEQU_QH_OBLA:
11610             check_dsp(ctx);
11611             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
11612             break;
11613         case OPC_PRECEQU_QH_OBRA:
11614             check_dsp(ctx);
11615             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
11616             break;
11617         case OPC_PRECEU_QH_OBL:
11618             check_dsp(ctx);
11619             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
11620             break;
11621         case OPC_PRECEU_QH_OBR:
11622             check_dsp(ctx);
11623             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
11624             break;
11625         case OPC_PRECEU_QH_OBLA:
11626             check_dsp(ctx);
11627             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
11628             break;
11629         case OPC_PRECEU_QH_OBRA:
11630             check_dsp(ctx);
11631             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
11632             break;
11633         case OPC_ABSQ_S_OB:
11634             check_dsp_r2(ctx);
11635             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env);
11636             break;
11637         case OPC_ABSQ_S_PW:
11638             check_dsp(ctx);
11639             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env);
11640             break;
11641         case OPC_ABSQ_S_QH:
11642             check_dsp(ctx);
11643             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env);
11644             break;
11645         }
11646         break;
11647     case OPC_ADDU_OB_DSP:
11648         switch (op2) {
11649         case OPC_RADDU_L_OB:
11650             check_dsp(ctx);
11651             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
11652             break;
11653         case OPC_SUBQ_PW:
11654             check_dsp(ctx);
11655             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11656             break;
11657         case OPC_SUBQ_S_PW:
11658             check_dsp(ctx);
11659             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11660             break;
11661         case OPC_SUBQ_QH:
11662             check_dsp(ctx);
11663             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11664             break;
11665         case OPC_SUBQ_S_QH:
11666             check_dsp(ctx);
11667             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11668             break;
11669         case OPC_SUBU_OB:
11670             check_dsp(ctx);
11671             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11672             break;
11673         case OPC_SUBU_S_OB:
11674             check_dsp(ctx);
11675             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11676             break;
11677         case OPC_SUBU_QH:
11678             check_dsp_r2(ctx);
11679             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11680             break;
11681         case OPC_SUBU_S_QH:
11682             check_dsp_r2(ctx);
11683             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11684             break;
11685         case OPC_SUBUH_OB:
11686             check_dsp_r2(ctx);
11687             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
11688             break;
11689         case OPC_SUBUH_R_OB:
11690             check_dsp_r2(ctx);
11691             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11692             break;
11693         case OPC_ADDQ_PW:
11694             check_dsp(ctx);
11695             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11696             break;
11697         case OPC_ADDQ_S_PW:
11698             check_dsp(ctx);
11699             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11700             break;
11701         case OPC_ADDQ_QH:
11702             check_dsp(ctx);
11703             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11704             break;
11705         case OPC_ADDQ_S_QH:
11706             check_dsp(ctx);
11707             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11708             break;
11709         case OPC_ADDU_OB:
11710             check_dsp(ctx);
11711             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11712             break;
11713         case OPC_ADDU_S_OB:
11714             check_dsp(ctx);
11715             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11716             break;
11717         case OPC_ADDU_QH:
11718             check_dsp_r2(ctx);
11719             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11720             break;
11721         case OPC_ADDU_S_QH:
11722             check_dsp_r2(ctx);
11723             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11724             break;
11725         case OPC_ADDUH_OB:
11726             check_dsp_r2(ctx);
11727             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
11728             break;
11729         case OPC_ADDUH_R_OB:
11730             check_dsp_r2(ctx);
11731             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11732             break;
11733         }
11734         break;
11735     case OPC_CMPU_EQ_OB_DSP:
11736         switch (op2) {
11737         case OPC_PRECR_OB_QH:
11738             check_dsp_r2(ctx);
11739             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
11740             break;
11741         case OPC_PRECR_SRA_QH_PW:
11742             check_dsp_r2(ctx);
11743             {
11744                 TCGv_i32 ret_t = tcg_constant_i32(ret);
11745                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
11746                 break;
11747             }
11748         case OPC_PRECR_SRA_R_QH_PW:
11749             check_dsp_r2(ctx);
11750             {
11751                 TCGv_i32 sa_v = tcg_constant_i32(ret);
11752                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
11753                 break;
11754             }
11755         case OPC_PRECRQ_OB_QH:
11756             check_dsp(ctx);
11757             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
11758             break;
11759         case OPC_PRECRQ_PW_L:
11760             check_dsp(ctx);
11761             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
11762             break;
11763         case OPC_PRECRQ_QH_PW:
11764             check_dsp(ctx);
11765             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
11766             break;
11767         case OPC_PRECRQ_RS_QH_PW:
11768             check_dsp(ctx);
11769             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11770             break;
11771         case OPC_PRECRQU_S_OB_QH:
11772             check_dsp(ctx);
11773             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11774             break;
11775         }
11776         break;
11777 #endif
11778     }
11779 }
11780 
gen_mipsdsp_shift(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)11781 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
11782                               int ret, int v1, int v2)
11783 {
11784     uint32_t op2;
11785     TCGv t0;
11786     TCGv v1_t;
11787     TCGv v2_t;
11788 
11789     if (ret == 0) {
11790         /* Treat as NOP. */
11791         return;
11792     }
11793 
11794     t0 = tcg_temp_new();
11795     v1_t = tcg_temp_new();
11796     v2_t = tcg_temp_new();
11797 
11798     tcg_gen_movi_tl(t0, v1);
11799     gen_load_gpr(v1_t, v1);
11800     gen_load_gpr(v2_t, v2);
11801 
11802     switch (opc) {
11803     case OPC_SHLL_QB_DSP:
11804         {
11805             op2 = MASK_SHLL_QB(ctx->opcode);
11806             switch (op2) {
11807             case OPC_SHLL_QB:
11808                 check_dsp(ctx);
11809                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env);
11810                 break;
11811             case OPC_SHLLV_QB:
11812                 check_dsp(ctx);
11813                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11814                 break;
11815             case OPC_SHLL_PH:
11816                 check_dsp(ctx);
11817                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
11818                 break;
11819             case OPC_SHLLV_PH:
11820                 check_dsp(ctx);
11821                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11822                 break;
11823             case OPC_SHLL_S_PH:
11824                 check_dsp(ctx);
11825                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
11826                 break;
11827             case OPC_SHLLV_S_PH:
11828                 check_dsp(ctx);
11829                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11830                 break;
11831             case OPC_SHLL_S_W:
11832                 check_dsp(ctx);
11833                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env);
11834                 break;
11835             case OPC_SHLLV_S_W:
11836                 check_dsp(ctx);
11837                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11838                 break;
11839             case OPC_SHRL_QB:
11840                 check_dsp(ctx);
11841                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
11842                 break;
11843             case OPC_SHRLV_QB:
11844                 check_dsp(ctx);
11845                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
11846                 break;
11847             case OPC_SHRL_PH:
11848                 check_dsp_r2(ctx);
11849                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
11850                 break;
11851             case OPC_SHRLV_PH:
11852                 check_dsp_r2(ctx);
11853                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
11854                 break;
11855             case OPC_SHRA_QB:
11856                 check_dsp_r2(ctx);
11857                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
11858                 break;
11859             case OPC_SHRA_R_QB:
11860                 check_dsp_r2(ctx);
11861                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
11862                 break;
11863             case OPC_SHRAV_QB:
11864                 check_dsp_r2(ctx);
11865                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
11866                 break;
11867             case OPC_SHRAV_R_QB:
11868                 check_dsp_r2(ctx);
11869                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
11870                 break;
11871             case OPC_SHRA_PH:
11872                 check_dsp(ctx);
11873                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
11874                 break;
11875             case OPC_SHRA_R_PH:
11876                 check_dsp(ctx);
11877                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
11878                 break;
11879             case OPC_SHRAV_PH:
11880                 check_dsp(ctx);
11881                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
11882                 break;
11883             case OPC_SHRAV_R_PH:
11884                 check_dsp(ctx);
11885                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
11886                 break;
11887             case OPC_SHRA_R_W:
11888                 check_dsp(ctx);
11889                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
11890                 break;
11891             case OPC_SHRAV_R_W:
11892                 check_dsp(ctx);
11893                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
11894                 break;
11895             default:            /* Invalid */
11896                 MIPS_INVAL("MASK SHLL.QB");
11897                 gen_reserved_instruction(ctx);
11898                 break;
11899             }
11900             break;
11901         }
11902 #ifdef TARGET_MIPS64
11903     case OPC_SHLL_OB_DSP:
11904         op2 = MASK_SHLL_OB(ctx->opcode);
11905         switch (op2) {
11906         case OPC_SHLL_PW:
11907             check_dsp(ctx);
11908             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
11909             break;
11910         case OPC_SHLLV_PW:
11911             check_dsp(ctx);
11912             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11913             break;
11914         case OPC_SHLL_S_PW:
11915             check_dsp(ctx);
11916             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
11917             break;
11918         case OPC_SHLLV_S_PW:
11919             check_dsp(ctx);
11920             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11921             break;
11922         case OPC_SHLL_OB:
11923             check_dsp(ctx);
11924             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env);
11925             break;
11926         case OPC_SHLLV_OB:
11927             check_dsp(ctx);
11928             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11929             break;
11930         case OPC_SHLL_QH:
11931             check_dsp(ctx);
11932             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
11933             break;
11934         case OPC_SHLLV_QH:
11935             check_dsp(ctx);
11936             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11937             break;
11938         case OPC_SHLL_S_QH:
11939             check_dsp(ctx);
11940             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
11941             break;
11942         case OPC_SHLLV_S_QH:
11943             check_dsp(ctx);
11944             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11945             break;
11946         case OPC_SHRA_OB:
11947             check_dsp_r2(ctx);
11948             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
11949             break;
11950         case OPC_SHRAV_OB:
11951             check_dsp_r2(ctx);
11952             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
11953             break;
11954         case OPC_SHRA_R_OB:
11955             check_dsp_r2(ctx);
11956             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
11957             break;
11958         case OPC_SHRAV_R_OB:
11959             check_dsp_r2(ctx);
11960             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
11961             break;
11962         case OPC_SHRA_PW:
11963             check_dsp(ctx);
11964             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
11965             break;
11966         case OPC_SHRAV_PW:
11967             check_dsp(ctx);
11968             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
11969             break;
11970         case OPC_SHRA_R_PW:
11971             check_dsp(ctx);
11972             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
11973             break;
11974         case OPC_SHRAV_R_PW:
11975             check_dsp(ctx);
11976             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
11977             break;
11978         case OPC_SHRA_QH:
11979             check_dsp(ctx);
11980             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
11981             break;
11982         case OPC_SHRAV_QH:
11983             check_dsp(ctx);
11984             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
11985             break;
11986         case OPC_SHRA_R_QH:
11987             check_dsp(ctx);
11988             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
11989             break;
11990         case OPC_SHRAV_R_QH:
11991             check_dsp(ctx);
11992             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
11993             break;
11994         case OPC_SHRL_OB:
11995             check_dsp(ctx);
11996             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
11997             break;
11998         case OPC_SHRLV_OB:
11999             check_dsp(ctx);
12000             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12001             break;
12002         case OPC_SHRL_QH:
12003             check_dsp_r2(ctx);
12004             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12005             break;
12006         case OPC_SHRLV_QH:
12007             check_dsp_r2(ctx);
12008             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12009             break;
12010         default:            /* Invalid */
12011             MIPS_INVAL("MASK SHLL.OB");
12012             gen_reserved_instruction(ctx);
12013             break;
12014         }
12015         break;
12016 #endif
12017     }
12018 }
12019 
gen_mipsdsp_multiply(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12020 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12021                                  int ret, int v1, int v2, int check_ret)
12022 {
12023     TCGv_i32 t0;
12024     TCGv v1_t;
12025     TCGv v2_t;
12026 
12027     if ((ret == 0) && (check_ret == 1)) {
12028         /* Treat as NOP. */
12029         return;
12030     }
12031 
12032     t0 = tcg_temp_new_i32();
12033     v1_t = tcg_temp_new();
12034     v2_t = tcg_temp_new();
12035 
12036     tcg_gen_movi_i32(t0, ret);
12037     gen_load_gpr(v1_t, v1);
12038     gen_load_gpr(v2_t, v2);
12039 
12040     switch (op1) {
12041     case OPC_MUL_PH_DSP:
12042         check_dsp_r2(ctx);
12043         switch (op2) {
12044         case  OPC_MUL_PH:
12045             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12046             break;
12047         case  OPC_MUL_S_PH:
12048             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12049             break;
12050         case OPC_MULQ_S_W:
12051             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12052             break;
12053         case OPC_MULQ_RS_W:
12054             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12055             break;
12056         }
12057         break;
12058     case OPC_DPA_W_PH_DSP:
12059         switch (op2) {
12060         case OPC_DPAU_H_QBL:
12061             check_dsp(ctx);
12062             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env);
12063             break;
12064         case OPC_DPAU_H_QBR:
12065             check_dsp(ctx);
12066             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env);
12067             break;
12068         case OPC_DPSU_H_QBL:
12069             check_dsp(ctx);
12070             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env);
12071             break;
12072         case OPC_DPSU_H_QBR:
12073             check_dsp(ctx);
12074             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env);
12075             break;
12076         case OPC_DPA_W_PH:
12077             check_dsp_r2(ctx);
12078             gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env);
12079             break;
12080         case OPC_DPAX_W_PH:
12081             check_dsp_r2(ctx);
12082             gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env);
12083             break;
12084         case OPC_DPAQ_S_W_PH:
12085             check_dsp(ctx);
12086             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12087             break;
12088         case OPC_DPAQX_S_W_PH:
12089             check_dsp_r2(ctx);
12090             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12091             break;
12092         case OPC_DPAQX_SA_W_PH:
12093             check_dsp_r2(ctx);
12094             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12095             break;
12096         case OPC_DPS_W_PH:
12097             check_dsp_r2(ctx);
12098             gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env);
12099             break;
12100         case OPC_DPSX_W_PH:
12101             check_dsp_r2(ctx);
12102             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env);
12103             break;
12104         case OPC_DPSQ_S_W_PH:
12105             check_dsp(ctx);
12106             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12107             break;
12108         case OPC_DPSQX_S_W_PH:
12109             check_dsp_r2(ctx);
12110             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12111             break;
12112         case OPC_DPSQX_SA_W_PH:
12113             check_dsp_r2(ctx);
12114             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12115             break;
12116         case OPC_MULSAQ_S_W_PH:
12117             check_dsp(ctx);
12118             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12119             break;
12120         case OPC_DPAQ_SA_L_W:
12121             check_dsp(ctx);
12122             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12123             break;
12124         case OPC_DPSQ_SA_L_W:
12125             check_dsp(ctx);
12126             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12127             break;
12128         case OPC_MAQ_S_W_PHL:
12129             check_dsp(ctx);
12130             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env);
12131             break;
12132         case OPC_MAQ_S_W_PHR:
12133             check_dsp(ctx);
12134             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env);
12135             break;
12136         case OPC_MAQ_SA_W_PHL:
12137             check_dsp(ctx);
12138             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env);
12139             break;
12140         case OPC_MAQ_SA_W_PHR:
12141             check_dsp(ctx);
12142             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env);
12143             break;
12144         case OPC_MULSA_W_PH:
12145             check_dsp_r2(ctx);
12146             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env);
12147             break;
12148         }
12149         break;
12150 #ifdef TARGET_MIPS64
12151     case OPC_DPAQ_W_QH_DSP:
12152         {
12153             int ac = ret & 0x03;
12154             tcg_gen_movi_i32(t0, ac);
12155 
12156             switch (op2) {
12157             case OPC_DMADD:
12158                 check_dsp(ctx);
12159                 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env);
12160                 break;
12161             case OPC_DMADDU:
12162                 check_dsp(ctx);
12163                 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env);
12164                 break;
12165             case OPC_DMSUB:
12166                 check_dsp(ctx);
12167                 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env);
12168                 break;
12169             case OPC_DMSUBU:
12170                 check_dsp(ctx);
12171                 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env);
12172                 break;
12173             case OPC_DPA_W_QH:
12174                 check_dsp_r2(ctx);
12175                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env);
12176                 break;
12177             case OPC_DPAQ_S_W_QH:
12178                 check_dsp(ctx);
12179                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12180                 break;
12181             case OPC_DPAQ_SA_L_PW:
12182                 check_dsp(ctx);
12183                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12184                 break;
12185             case OPC_DPAU_H_OBL:
12186                 check_dsp(ctx);
12187                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env);
12188                 break;
12189             case OPC_DPAU_H_OBR:
12190                 check_dsp(ctx);
12191                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env);
12192                 break;
12193             case OPC_DPS_W_QH:
12194                 check_dsp_r2(ctx);
12195                 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env);
12196                 break;
12197             case OPC_DPSQ_S_W_QH:
12198                 check_dsp(ctx);
12199                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12200                 break;
12201             case OPC_DPSQ_SA_L_PW:
12202                 check_dsp(ctx);
12203                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12204                 break;
12205             case OPC_DPSU_H_OBL:
12206                 check_dsp(ctx);
12207                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env);
12208                 break;
12209             case OPC_DPSU_H_OBR:
12210                 check_dsp(ctx);
12211                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env);
12212                 break;
12213             case OPC_MAQ_S_L_PWL:
12214                 check_dsp(ctx);
12215                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env);
12216                 break;
12217             case OPC_MAQ_S_L_PWR:
12218                 check_dsp(ctx);
12219                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env);
12220                 break;
12221             case OPC_MAQ_S_W_QHLL:
12222                 check_dsp(ctx);
12223                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env);
12224                 break;
12225             case OPC_MAQ_SA_W_QHLL:
12226                 check_dsp(ctx);
12227                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env);
12228                 break;
12229             case OPC_MAQ_S_W_QHLR:
12230                 check_dsp(ctx);
12231                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env);
12232                 break;
12233             case OPC_MAQ_SA_W_QHLR:
12234                 check_dsp(ctx);
12235                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env);
12236                 break;
12237             case OPC_MAQ_S_W_QHRL:
12238                 check_dsp(ctx);
12239                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env);
12240                 break;
12241             case OPC_MAQ_SA_W_QHRL:
12242                 check_dsp(ctx);
12243                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env);
12244                 break;
12245             case OPC_MAQ_S_W_QHRR:
12246                 check_dsp(ctx);
12247                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env);
12248                 break;
12249             case OPC_MAQ_SA_W_QHRR:
12250                 check_dsp(ctx);
12251                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env);
12252                 break;
12253             case OPC_MULSAQ_S_L_PW:
12254                 check_dsp(ctx);
12255                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env);
12256                 break;
12257             case OPC_MULSAQ_S_W_QH:
12258                 check_dsp(ctx);
12259                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12260                 break;
12261             }
12262         }
12263         break;
12264 #endif
12265     case OPC_ADDU_QB_DSP:
12266         switch (op2) {
12267         case OPC_MULEU_S_PH_QBL:
12268             check_dsp(ctx);
12269             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12270             break;
12271         case OPC_MULEU_S_PH_QBR:
12272             check_dsp(ctx);
12273             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12274             break;
12275         case OPC_MULQ_RS_PH:
12276             check_dsp(ctx);
12277             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12278             break;
12279         case OPC_MULEQ_S_W_PHL:
12280             check_dsp(ctx);
12281             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12282             break;
12283         case OPC_MULEQ_S_W_PHR:
12284             check_dsp(ctx);
12285             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12286             break;
12287         case OPC_MULQ_S_PH:
12288             check_dsp_r2(ctx);
12289             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12290             break;
12291         }
12292         break;
12293 #ifdef TARGET_MIPS64
12294     case OPC_ADDU_OB_DSP:
12295         switch (op2) {
12296         case OPC_MULEQ_S_PW_QHL:
12297             check_dsp(ctx);
12298             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12299             break;
12300         case OPC_MULEQ_S_PW_QHR:
12301             check_dsp(ctx);
12302             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12303             break;
12304         case OPC_MULEU_S_QH_OBL:
12305             check_dsp(ctx);
12306             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12307             break;
12308         case OPC_MULEU_S_QH_OBR:
12309             check_dsp(ctx);
12310             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12311             break;
12312         case OPC_MULQ_RS_QH:
12313             check_dsp(ctx);
12314             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12315             break;
12316         }
12317         break;
12318 #endif
12319     }
12320 }
12321 
gen_mipsdsp_bitinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int val)12322 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12323                                 int ret, int val)
12324 {
12325     int16_t imm;
12326     TCGv t0;
12327     TCGv val_t;
12328 
12329     if (ret == 0) {
12330         /* Treat as NOP. */
12331         return;
12332     }
12333 
12334     t0 = tcg_temp_new();
12335     val_t = tcg_temp_new();
12336     gen_load_gpr(val_t, val);
12337 
12338     switch (op1) {
12339     case OPC_ABSQ_S_PH_DSP:
12340         switch (op2) {
12341         case OPC_BITREV:
12342             check_dsp(ctx);
12343             gen_helper_bitrev(cpu_gpr[ret], val_t);
12344             break;
12345         case OPC_REPL_QB:
12346             check_dsp(ctx);
12347             {
12348                 target_long result;
12349                 imm = (ctx->opcode >> 16) & 0xFF;
12350                 result = (uint32_t)imm << 24 |
12351                          (uint32_t)imm << 16 |
12352                          (uint32_t)imm << 8  |
12353                          (uint32_t)imm;
12354                 result = (int32_t)result;
12355                 tcg_gen_movi_tl(cpu_gpr[ret], result);
12356             }
12357             break;
12358         case OPC_REPLV_QB:
12359             check_dsp(ctx);
12360             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12361             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12362             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12363             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12364             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12365             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12366             break;
12367         case OPC_REPL_PH:
12368             check_dsp(ctx);
12369             {
12370                 imm = (ctx->opcode >> 16) & 0x03FF;
12371                 imm = (int16_t)(imm << 6) >> 6;
12372                 tcg_gen_movi_tl(cpu_gpr[ret], \
12373                                 (target_long)((int32_t)imm << 16 | \
12374                                 (uint16_t)imm));
12375             }
12376             break;
12377         case OPC_REPLV_PH:
12378             check_dsp(ctx);
12379             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12380             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12381             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12382             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12383             break;
12384         }
12385         break;
12386 #ifdef TARGET_MIPS64
12387     case OPC_ABSQ_S_QH_DSP:
12388         switch (op2) {
12389         case OPC_REPL_OB:
12390             check_dsp(ctx);
12391             {
12392                 target_long temp;
12393 
12394                 imm = (ctx->opcode >> 16) & 0xFF;
12395                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
12396                 temp = (temp << 16) | temp;
12397                 temp = (temp << 32) | temp;
12398                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12399                 break;
12400             }
12401         case OPC_REPL_PW:
12402             check_dsp(ctx);
12403             {
12404                 target_long temp;
12405 
12406                 imm = (ctx->opcode >> 16) & 0x03FF;
12407                 imm = (int16_t)(imm << 6) >> 6;
12408                 temp = ((target_long)imm << 32) \
12409                        | ((target_long)imm & 0xFFFFFFFF);
12410                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12411                 break;
12412             }
12413         case OPC_REPL_QH:
12414             check_dsp(ctx);
12415             {
12416                 target_long temp;
12417 
12418                 imm = (ctx->opcode >> 16) & 0x03FF;
12419                 imm = (int16_t)(imm << 6) >> 6;
12420 
12421                 temp = ((uint64_t)(uint16_t)imm << 48) |
12422                        ((uint64_t)(uint16_t)imm << 32) |
12423                        ((uint64_t)(uint16_t)imm << 16) |
12424                        (uint64_t)(uint16_t)imm;
12425                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12426                 break;
12427             }
12428         case OPC_REPLV_OB:
12429             check_dsp(ctx);
12430             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12431             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12432             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12433             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12434             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12435             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12436             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12437             break;
12438         case OPC_REPLV_PW:
12439             check_dsp(ctx);
12440             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
12441             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12442             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12443             break;
12444         case OPC_REPLV_QH:
12445             check_dsp(ctx);
12446             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12447             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12448             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12449             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12450             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12451             break;
12452         }
12453         break;
12454 #endif
12455     }
12456 }
12457 
gen_mipsdsp_add_cmp_pick(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12458 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
12459                                      uint32_t op1, uint32_t op2,
12460                                      int ret, int v1, int v2, int check_ret)
12461 {
12462     TCGv t1;
12463     TCGv v1_t;
12464     TCGv v2_t;
12465 
12466     if ((ret == 0) && (check_ret == 1)) {
12467         /* Treat as NOP. */
12468         return;
12469     }
12470 
12471     t1 = tcg_temp_new();
12472     v1_t = tcg_temp_new();
12473     v2_t = tcg_temp_new();
12474 
12475     gen_load_gpr(v1_t, v1);
12476     gen_load_gpr(v2_t, v2);
12477 
12478     switch (op1) {
12479     case OPC_CMPU_EQ_QB_DSP:
12480         switch (op2) {
12481         case OPC_CMPU_EQ_QB:
12482             check_dsp(ctx);
12483             gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env);
12484             break;
12485         case OPC_CMPU_LT_QB:
12486             check_dsp(ctx);
12487             gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env);
12488             break;
12489         case OPC_CMPU_LE_QB:
12490             check_dsp(ctx);
12491             gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env);
12492             break;
12493         case OPC_CMPGU_EQ_QB:
12494             check_dsp(ctx);
12495             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
12496             break;
12497         case OPC_CMPGU_LT_QB:
12498             check_dsp(ctx);
12499             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
12500             break;
12501         case OPC_CMPGU_LE_QB:
12502             check_dsp(ctx);
12503             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
12504             break;
12505         case OPC_CMPGDU_EQ_QB:
12506             check_dsp_r2(ctx);
12507             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
12508             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12509             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12510             tcg_gen_shli_tl(t1, t1, 24);
12511             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12512             break;
12513         case OPC_CMPGDU_LT_QB:
12514             check_dsp_r2(ctx);
12515             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
12516             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12517             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12518             tcg_gen_shli_tl(t1, t1, 24);
12519             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12520             break;
12521         case OPC_CMPGDU_LE_QB:
12522             check_dsp_r2(ctx);
12523             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
12524             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12525             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12526             tcg_gen_shli_tl(t1, t1, 24);
12527             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12528             break;
12529         case OPC_CMP_EQ_PH:
12530             check_dsp(ctx);
12531             gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env);
12532             break;
12533         case OPC_CMP_LT_PH:
12534             check_dsp(ctx);
12535             gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env);
12536             break;
12537         case OPC_CMP_LE_PH:
12538             check_dsp(ctx);
12539             gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env);
12540             break;
12541         case OPC_PICK_QB:
12542             check_dsp(ctx);
12543             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12544             break;
12545         case OPC_PICK_PH:
12546             check_dsp(ctx);
12547             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12548             break;
12549         case OPC_PACKRL_PH:
12550             check_dsp(ctx);
12551             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
12552             break;
12553         }
12554         break;
12555 #ifdef TARGET_MIPS64
12556     case OPC_CMPU_EQ_OB_DSP:
12557         switch (op2) {
12558         case OPC_CMP_EQ_PW:
12559             check_dsp(ctx);
12560             gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env);
12561             break;
12562         case OPC_CMP_LT_PW:
12563             check_dsp(ctx);
12564             gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env);
12565             break;
12566         case OPC_CMP_LE_PW:
12567             check_dsp(ctx);
12568             gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env);
12569             break;
12570         case OPC_CMP_EQ_QH:
12571             check_dsp(ctx);
12572             gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env);
12573             break;
12574         case OPC_CMP_LT_QH:
12575             check_dsp(ctx);
12576             gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env);
12577             break;
12578         case OPC_CMP_LE_QH:
12579             check_dsp(ctx);
12580             gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env);
12581             break;
12582         case OPC_CMPGDU_EQ_OB:
12583             check_dsp_r2(ctx);
12584             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12585             break;
12586         case OPC_CMPGDU_LT_OB:
12587             check_dsp_r2(ctx);
12588             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12589             break;
12590         case OPC_CMPGDU_LE_OB:
12591             check_dsp_r2(ctx);
12592             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12593             break;
12594         case OPC_CMPGU_EQ_OB:
12595             check_dsp(ctx);
12596             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
12597             break;
12598         case OPC_CMPGU_LT_OB:
12599             check_dsp(ctx);
12600             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
12601             break;
12602         case OPC_CMPGU_LE_OB:
12603             check_dsp(ctx);
12604             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
12605             break;
12606         case OPC_CMPU_EQ_OB:
12607             check_dsp(ctx);
12608             gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env);
12609             break;
12610         case OPC_CMPU_LT_OB:
12611             check_dsp(ctx);
12612             gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env);
12613             break;
12614         case OPC_CMPU_LE_OB:
12615             check_dsp(ctx);
12616             gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env);
12617             break;
12618         case OPC_PACKRL_PW:
12619             check_dsp(ctx);
12620             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
12621             break;
12622         case OPC_PICK_OB:
12623             check_dsp(ctx);
12624             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12625             break;
12626         case OPC_PICK_PW:
12627             check_dsp(ctx);
12628             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12629             break;
12630         case OPC_PICK_QH:
12631             check_dsp(ctx);
12632             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12633             break;
12634         }
12635         break;
12636 #endif
12637     }
12638 }
12639 
gen_mipsdsp_append(CPUMIPSState * env,DisasContext * ctx,uint32_t op1,int rt,int rs,int sa)12640 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
12641                                uint32_t op1, int rt, int rs, int sa)
12642 {
12643     TCGv t0;
12644 
12645     check_dsp_r2(ctx);
12646 
12647     if (rt == 0) {
12648         /* Treat as NOP. */
12649         return;
12650     }
12651 
12652     t0 = tcg_temp_new();
12653     gen_load_gpr(t0, rs);
12654 
12655     switch (op1) {
12656     case OPC_APPEND_DSP:
12657         switch (MASK_APPEND(ctx->opcode)) {
12658         case OPC_APPEND:
12659             if (sa != 0) {
12660                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
12661             }
12662             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12663             break;
12664         case OPC_PREPEND:
12665             if (sa != 0) {
12666                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
12667                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12668                 tcg_gen_shli_tl(t0, t0, 32 - sa);
12669                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12670             }
12671             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12672             break;
12673         case OPC_BALIGN:
12674             sa &= 3;
12675             if (sa != 0 && sa != 2) {
12676                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12677                 tcg_gen_ext32u_tl(t0, t0);
12678                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
12679                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12680             }
12681             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12682             break;
12683         default:            /* Invalid */
12684             MIPS_INVAL("MASK APPEND");
12685             gen_reserved_instruction(ctx);
12686             break;
12687         }
12688         break;
12689 #ifdef TARGET_MIPS64
12690     case OPC_DAPPEND_DSP:
12691         switch (MASK_DAPPEND(ctx->opcode)) {
12692         case OPC_DAPPEND:
12693             if (sa != 0) {
12694                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
12695             }
12696             break;
12697         case OPC_PREPENDD:
12698             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
12699             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
12700             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
12701             break;
12702         case OPC_PREPENDW:
12703             if (sa != 0) {
12704                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12705                 tcg_gen_shli_tl(t0, t0, 64 - sa);
12706                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12707             }
12708             break;
12709         case OPC_DBALIGN:
12710             sa &= 7;
12711             if (sa != 0 && sa != 2 && sa != 4) {
12712                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12713                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
12714                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12715             }
12716             break;
12717         default:            /* Invalid */
12718             MIPS_INVAL("MASK DAPPEND");
12719             gen_reserved_instruction(ctx);
12720             break;
12721         }
12722         break;
12723 #endif
12724     }
12725 }
12726 
gen_mipsdsp_accinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12727 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12728                                 int ret, int v1, int v2, int check_ret)
12729 
12730 {
12731     TCGv t0;
12732     TCGv t1;
12733     TCGv v1_t;
12734     int16_t imm;
12735 
12736     if ((ret == 0) && (check_ret == 1)) {
12737         /* Treat as NOP. */
12738         return;
12739     }
12740 
12741     t0 = tcg_temp_new();
12742     t1 = tcg_temp_new();
12743     v1_t = tcg_temp_new();
12744 
12745     gen_load_gpr(v1_t, v1);
12746 
12747     switch (op1) {
12748     case OPC_EXTR_W_DSP:
12749         check_dsp(ctx);
12750         switch (op2) {
12751         case OPC_EXTR_W:
12752             tcg_gen_movi_tl(t0, v2);
12753             tcg_gen_movi_tl(t1, v1);
12754             gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env);
12755             break;
12756         case OPC_EXTR_R_W:
12757             tcg_gen_movi_tl(t0, v2);
12758             tcg_gen_movi_tl(t1, v1);
12759             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
12760             break;
12761         case OPC_EXTR_RS_W:
12762             tcg_gen_movi_tl(t0, v2);
12763             tcg_gen_movi_tl(t1, v1);
12764             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
12765             break;
12766         case OPC_EXTR_S_H:
12767             tcg_gen_movi_tl(t0, v2);
12768             tcg_gen_movi_tl(t1, v1);
12769             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
12770             break;
12771         case OPC_EXTRV_S_H:
12772             tcg_gen_movi_tl(t0, v2);
12773             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
12774             break;
12775         case OPC_EXTRV_W:
12776             tcg_gen_movi_tl(t0, v2);
12777             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12778             break;
12779         case OPC_EXTRV_R_W:
12780             tcg_gen_movi_tl(t0, v2);
12781             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12782             break;
12783         case OPC_EXTRV_RS_W:
12784             tcg_gen_movi_tl(t0, v2);
12785             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12786             break;
12787         case OPC_EXTP:
12788             tcg_gen_movi_tl(t0, v2);
12789             tcg_gen_movi_tl(t1, v1);
12790             gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env);
12791             break;
12792         case OPC_EXTPV:
12793             tcg_gen_movi_tl(t0, v2);
12794             gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env);
12795             break;
12796         case OPC_EXTPDP:
12797             tcg_gen_movi_tl(t0, v2);
12798             tcg_gen_movi_tl(t1, v1);
12799             gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env);
12800             break;
12801         case OPC_EXTPDPV:
12802             tcg_gen_movi_tl(t0, v2);
12803             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
12804             break;
12805         case OPC_SHILO:
12806             imm = (ctx->opcode >> 20) & 0x3F;
12807             tcg_gen_movi_tl(t0, ret);
12808             tcg_gen_movi_tl(t1, imm);
12809             gen_helper_shilo(t0, t1, tcg_env);
12810             break;
12811         case OPC_SHILOV:
12812             tcg_gen_movi_tl(t0, ret);
12813             gen_helper_shilo(t0, v1_t, tcg_env);
12814             break;
12815         case OPC_MTHLIP:
12816             tcg_gen_movi_tl(t0, ret);
12817             gen_helper_mthlip(t0, v1_t, tcg_env);
12818             break;
12819         case OPC_WRDSP:
12820             imm = (ctx->opcode >> 11) & 0x3FF;
12821             tcg_gen_movi_tl(t0, imm);
12822             gen_helper_wrdsp(v1_t, t0, tcg_env);
12823             break;
12824         case OPC_RDDSP:
12825             imm = (ctx->opcode >> 16) & 0x03FF;
12826             tcg_gen_movi_tl(t0, imm);
12827             gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env);
12828             break;
12829         }
12830         break;
12831 #ifdef TARGET_MIPS64
12832     case OPC_DEXTR_W_DSP:
12833         check_dsp(ctx);
12834         switch (op2) {
12835         case OPC_DMTHLIP:
12836             tcg_gen_movi_tl(t0, ret);
12837             gen_helper_dmthlip(v1_t, t0, tcg_env);
12838             break;
12839         case OPC_DSHILO:
12840             {
12841                 int shift = (ctx->opcode >> 19) & 0x7F;
12842                 int ac = (ctx->opcode >> 11) & 0x03;
12843                 tcg_gen_movi_tl(t0, shift);
12844                 tcg_gen_movi_tl(t1, ac);
12845                 gen_helper_dshilo(t0, t1, tcg_env);
12846                 break;
12847             }
12848         case OPC_DSHILOV:
12849             {
12850                 int ac = (ctx->opcode >> 11) & 0x03;
12851                 tcg_gen_movi_tl(t0, ac);
12852                 gen_helper_dshilo(v1_t, t0, tcg_env);
12853                 break;
12854             }
12855         case OPC_DEXTP:
12856             tcg_gen_movi_tl(t0, v2);
12857             tcg_gen_movi_tl(t1, v1);
12858 
12859             gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env);
12860             break;
12861         case OPC_DEXTPV:
12862             tcg_gen_movi_tl(t0, v2);
12863             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env);
12864             break;
12865         case OPC_DEXTPDP:
12866             tcg_gen_movi_tl(t0, v2);
12867             tcg_gen_movi_tl(t1, v1);
12868             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env);
12869             break;
12870         case OPC_DEXTPDPV:
12871             tcg_gen_movi_tl(t0, v2);
12872             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
12873             break;
12874         case OPC_DEXTR_L:
12875             tcg_gen_movi_tl(t0, v2);
12876             tcg_gen_movi_tl(t1, v1);
12877             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env);
12878             break;
12879         case OPC_DEXTR_R_L:
12880             tcg_gen_movi_tl(t0, v2);
12881             tcg_gen_movi_tl(t1, v1);
12882             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env);
12883             break;
12884         case OPC_DEXTR_RS_L:
12885             tcg_gen_movi_tl(t0, v2);
12886             tcg_gen_movi_tl(t1, v1);
12887             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env);
12888             break;
12889         case OPC_DEXTR_W:
12890             tcg_gen_movi_tl(t0, v2);
12891             tcg_gen_movi_tl(t1, v1);
12892             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env);
12893             break;
12894         case OPC_DEXTR_R_W:
12895             tcg_gen_movi_tl(t0, v2);
12896             tcg_gen_movi_tl(t1, v1);
12897             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
12898             break;
12899         case OPC_DEXTR_RS_W:
12900             tcg_gen_movi_tl(t0, v2);
12901             tcg_gen_movi_tl(t1, v1);
12902             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
12903             break;
12904         case OPC_DEXTR_S_H:
12905             tcg_gen_movi_tl(t0, v2);
12906             tcg_gen_movi_tl(t1, v1);
12907             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
12908             break;
12909         case OPC_DEXTRV_S_H:
12910             tcg_gen_movi_tl(t0, v2);
12911             gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
12912             break;
12913         case OPC_DEXTRV_L:
12914             tcg_gen_movi_tl(t0, v2);
12915             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12916             break;
12917         case OPC_DEXTRV_R_L:
12918             tcg_gen_movi_tl(t0, v2);
12919             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12920             break;
12921         case OPC_DEXTRV_RS_L:
12922             tcg_gen_movi_tl(t0, v2);
12923             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12924             break;
12925         case OPC_DEXTRV_W:
12926             tcg_gen_movi_tl(t0, v2);
12927             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12928             break;
12929         case OPC_DEXTRV_R_W:
12930             tcg_gen_movi_tl(t0, v2);
12931             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12932             break;
12933         case OPC_DEXTRV_RS_W:
12934             tcg_gen_movi_tl(t0, v2);
12935             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12936             break;
12937         }
12938         break;
12939 #endif
12940     }
12941 }
12942 
12943 /* End MIPSDSP functions. */
12944 
decode_opc_special_r6(CPUMIPSState * env,DisasContext * ctx)12945 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
12946 {
12947     int rs, rt, rd, sa;
12948     uint32_t op1, op2;
12949 
12950     rs = (ctx->opcode >> 21) & 0x1f;
12951     rt = (ctx->opcode >> 16) & 0x1f;
12952     rd = (ctx->opcode >> 11) & 0x1f;
12953     sa = (ctx->opcode >> 6) & 0x1f;
12954 
12955     op1 = MASK_SPECIAL(ctx->opcode);
12956     switch (op1) {
12957     case OPC_MULT:
12958     case OPC_MULTU:
12959     case OPC_DIV:
12960     case OPC_DIVU:
12961         op2 = MASK_R6_MULDIV(ctx->opcode);
12962         switch (op2) {
12963         case R6_OPC_MUL:
12964         case R6_OPC_MUH:
12965         case R6_OPC_MULU:
12966         case R6_OPC_MUHU:
12967         case R6_OPC_DIV:
12968         case R6_OPC_MOD:
12969         case R6_OPC_DIVU:
12970         case R6_OPC_MODU:
12971             gen_r6_muldiv(ctx, op2, rd, rs, rt);
12972             break;
12973         default:
12974             MIPS_INVAL("special_r6 muldiv");
12975             gen_reserved_instruction(ctx);
12976             break;
12977         }
12978         break;
12979     case OPC_SELEQZ:
12980     case OPC_SELNEZ:
12981         gen_cond_move(ctx, op1, rd, rs, rt);
12982         break;
12983     case R6_OPC_CLO:
12984     case R6_OPC_CLZ:
12985         if (rt == 0 && sa == 1) {
12986             /*
12987              * Major opcode and function field is shared with preR6 MFHI/MTHI.
12988              * We need additionally to check other fields.
12989              */
12990             gen_cl(ctx, op1, rd, rs);
12991         } else {
12992             gen_reserved_instruction(ctx);
12993         }
12994         break;
12995     case R6_OPC_SDBBP:
12996         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
12997             ctx->base.is_jmp = DISAS_SEMIHOST;
12998         } else {
12999             if (ctx->hflags & MIPS_HFLAG_SBRI) {
13000                 gen_reserved_instruction(ctx);
13001             } else {
13002                 generate_exception_end(ctx, EXCP_DBp);
13003             }
13004         }
13005         break;
13006 #if defined(TARGET_MIPS64)
13007     case R6_OPC_DCLO:
13008     case R6_OPC_DCLZ:
13009         if (rt == 0 && sa == 1) {
13010             /*
13011              * Major opcode and function field is shared with preR6 MFHI/MTHI.
13012              * We need additionally to check other fields.
13013              */
13014             check_mips_64(ctx);
13015             gen_cl(ctx, op1, rd, rs);
13016         } else {
13017             gen_reserved_instruction(ctx);
13018         }
13019         break;
13020     case OPC_DMULT:
13021     case OPC_DMULTU:
13022     case OPC_DDIV:
13023     case OPC_DDIVU:
13024 
13025         op2 = MASK_R6_MULDIV(ctx->opcode);
13026         switch (op2) {
13027         case R6_OPC_DMUL:
13028         case R6_OPC_DMUH:
13029         case R6_OPC_DMULU:
13030         case R6_OPC_DMUHU:
13031         case R6_OPC_DDIV:
13032         case R6_OPC_DMOD:
13033         case R6_OPC_DDIVU:
13034         case R6_OPC_DMODU:
13035             check_mips_64(ctx);
13036             gen_r6_muldiv(ctx, op2, rd, rs, rt);
13037             break;
13038         default:
13039             MIPS_INVAL("special_r6 muldiv");
13040             gen_reserved_instruction(ctx);
13041             break;
13042         }
13043         break;
13044 #endif
13045     default:            /* Invalid */
13046         MIPS_INVAL("special_r6");
13047         gen_reserved_instruction(ctx);
13048         break;
13049     }
13050 }
13051 
decode_opc_special_tx79(CPUMIPSState * env,DisasContext * ctx)13052 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13053 {
13054     int rs = extract32(ctx->opcode, 21, 5);
13055     int rt = extract32(ctx->opcode, 16, 5);
13056     int rd = extract32(ctx->opcode, 11, 5);
13057     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13058 
13059     switch (op1) {
13060     case OPC_MOVN:         /* Conditional move */
13061     case OPC_MOVZ:
13062         gen_cond_move(ctx, op1, rd, rs, rt);
13063         break;
13064     case OPC_MFHI:          /* Move from HI/LO */
13065     case OPC_MFLO:
13066         gen_HILO(ctx, op1, 0, rd);
13067         break;
13068     case OPC_MTHI:
13069     case OPC_MTLO:          /* Move to HI/LO */
13070         gen_HILO(ctx, op1, 0, rs);
13071         break;
13072     case OPC_MULT:
13073     case OPC_MULTU:
13074         gen_mul_txx9(ctx, op1, rd, rs, rt);
13075         break;
13076     case OPC_DIV:
13077     case OPC_DIVU:
13078         gen_muldiv(ctx, op1, 0, rs, rt);
13079         break;
13080 #if defined(TARGET_MIPS64)
13081     case OPC_DMULT:
13082     case OPC_DMULTU:
13083     case OPC_DDIV:
13084     case OPC_DDIVU:
13085         check_insn_opc_user_only(ctx, INSN_R5900);
13086         gen_muldiv(ctx, op1, 0, rs, rt);
13087         break;
13088 #endif
13089     case OPC_JR:
13090         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13091         break;
13092     default:            /* Invalid */
13093         MIPS_INVAL("special_tx79");
13094         gen_reserved_instruction(ctx);
13095         break;
13096     }
13097 }
13098 
decode_opc_special_legacy(CPUMIPSState * env,DisasContext * ctx)13099 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13100 {
13101     int rs, rt, rd;
13102     uint32_t op1;
13103 
13104     rs = (ctx->opcode >> 21) & 0x1f;
13105     rt = (ctx->opcode >> 16) & 0x1f;
13106     rd = (ctx->opcode >> 11) & 0x1f;
13107 
13108     op1 = MASK_SPECIAL(ctx->opcode);
13109     switch (op1) {
13110     case OPC_MOVN:         /* Conditional move */
13111     case OPC_MOVZ:
13112         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
13113                    INSN_LOONGSON2E | INSN_LOONGSON2F);
13114         gen_cond_move(ctx, op1, rd, rs, rt);
13115         break;
13116     case OPC_MFHI:          /* Move from HI/LO */
13117     case OPC_MFLO:
13118         gen_HILO(ctx, op1, rs & 3, rd);
13119         break;
13120     case OPC_MTHI:
13121     case OPC_MTLO:          /* Move to HI/LO */
13122         gen_HILO(ctx, op1, rd & 3, rs);
13123         break;
13124     case OPC_MOVCI:
13125         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
13126         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13127             check_cp1_enabled(ctx);
13128             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
13129                       (ctx->opcode >> 16) & 1);
13130         } else {
13131             generate_exception_err(ctx, EXCP_CpU, 1);
13132         }
13133         break;
13134     case OPC_MULT:
13135     case OPC_MULTU:
13136         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13137         break;
13138     case OPC_DIV:
13139     case OPC_DIVU:
13140         gen_muldiv(ctx, op1, 0, rs, rt);
13141         break;
13142 #if defined(TARGET_MIPS64)
13143     case OPC_DMULT:
13144     case OPC_DMULTU:
13145     case OPC_DDIV:
13146     case OPC_DDIVU:
13147         check_insn(ctx, ISA_MIPS3);
13148         check_mips_64(ctx);
13149         gen_muldiv(ctx, op1, 0, rs, rt);
13150         break;
13151 #endif
13152     case OPC_JR:
13153         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13154         break;
13155     case OPC_SPIM:
13156 #ifdef MIPS_STRICT_STANDARD
13157         MIPS_INVAL("SPIM");
13158         gen_reserved_instruction(ctx);
13159 #else
13160         /* Implemented as RI exception for now. */
13161         MIPS_INVAL("spim (unofficial)");
13162         gen_reserved_instruction(ctx);
13163 #endif
13164         break;
13165     default:            /* Invalid */
13166         MIPS_INVAL("special_legacy");
13167         gen_reserved_instruction(ctx);
13168         break;
13169     }
13170 }
13171 
decode_opc_special(CPUMIPSState * env,DisasContext * ctx)13172 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
13173 {
13174     int rs, rt, rd, sa;
13175     uint32_t op1;
13176 
13177     rs = (ctx->opcode >> 21) & 0x1f;
13178     rt = (ctx->opcode >> 16) & 0x1f;
13179     rd = (ctx->opcode >> 11) & 0x1f;
13180     sa = (ctx->opcode >> 6) & 0x1f;
13181 
13182     op1 = MASK_SPECIAL(ctx->opcode);
13183     switch (op1) {
13184     case OPC_SLL:          /* Shift with immediate */
13185         if (sa == 5 && rd == 0 &&
13186             rs == 0 && rt == 0) { /* PAUSE */
13187             if ((ctx->insn_flags & ISA_MIPS_R6) &&
13188                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
13189                 gen_reserved_instruction(ctx);
13190                 break;
13191             }
13192         }
13193         /* Fallthrough */
13194     case OPC_SRA:
13195         gen_shift_imm(ctx, op1, rd, rt, sa);
13196         break;
13197     case OPC_SRL:
13198         switch ((ctx->opcode >> 21) & 0x1f) {
13199         case 1:
13200             /* rotr is decoded as srl on non-R2 CPUs */
13201             if (ctx->insn_flags & ISA_MIPS_R2) {
13202                 op1 = OPC_ROTR;
13203             }
13204             /* Fallthrough */
13205         case 0:
13206             gen_shift_imm(ctx, op1, rd, rt, sa);
13207             break;
13208         default:
13209             gen_reserved_instruction(ctx);
13210             break;
13211         }
13212         break;
13213     case OPC_ADD:
13214     case OPC_ADDU:
13215     case OPC_SUB:
13216     case OPC_SUBU:
13217         gen_arith(ctx, op1, rd, rs, rt);
13218         break;
13219     case OPC_SLLV:         /* Shifts */
13220     case OPC_SRAV:
13221         gen_shift(ctx, op1, rd, rs, rt);
13222         break;
13223     case OPC_SRLV:
13224         switch ((ctx->opcode >> 6) & 0x1f) {
13225         case 1:
13226             /* rotrv is decoded as srlv on non-R2 CPUs */
13227             if (ctx->insn_flags & ISA_MIPS_R2) {
13228                 op1 = OPC_ROTRV;
13229             }
13230             /* Fallthrough */
13231         case 0:
13232             gen_shift(ctx, op1, rd, rs, rt);
13233             break;
13234         default:
13235             gen_reserved_instruction(ctx);
13236             break;
13237         }
13238         break;
13239     case OPC_SLT:          /* Set on less than */
13240     case OPC_SLTU:
13241         gen_slt(ctx, op1, rd, rs, rt);
13242         break;
13243     case OPC_AND:          /* Logic*/
13244     case OPC_OR:
13245     case OPC_NOR:
13246     case OPC_XOR:
13247         gen_logic(ctx, op1, rd, rs, rt);
13248         break;
13249     case OPC_JALR:
13250         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
13251         break;
13252     case OPC_TGE: /* Traps */
13253     case OPC_TGEU:
13254     case OPC_TLT:
13255     case OPC_TLTU:
13256     case OPC_TEQ:
13257     case OPC_TNE:
13258         check_insn(ctx, ISA_MIPS2);
13259         gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
13260         break;
13261     case OPC_PMON:
13262         /* Pmon entry point, also R4010 selsl */
13263 #ifdef MIPS_STRICT_STANDARD
13264         MIPS_INVAL("PMON / selsl");
13265         gen_reserved_instruction(ctx);
13266 #else
13267         gen_helper_pmon(tcg_env, tcg_constant_i32(sa));
13268 #endif
13269         break;
13270     case OPC_SYSCALL:
13271         generate_exception_end(ctx, EXCP_SYSCALL);
13272         break;
13273     case OPC_BREAK:
13274         generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
13275         break;
13276     case OPC_SYNC:
13277         check_insn(ctx, ISA_MIPS2);
13278         gen_sync(extract32(ctx->opcode, 6, 5));
13279         break;
13280 
13281 #if defined(TARGET_MIPS64)
13282         /* MIPS64 specific opcodes */
13283     case OPC_DSLL:
13284     case OPC_DSRA:
13285     case OPC_DSLL32:
13286     case OPC_DSRA32:
13287         check_insn(ctx, ISA_MIPS3);
13288         check_mips_64(ctx);
13289         gen_shift_imm(ctx, op1, rd, rt, sa);
13290         break;
13291     case OPC_DSRL:
13292         switch ((ctx->opcode >> 21) & 0x1f) {
13293         case 1:
13294             /* drotr is decoded as dsrl on non-R2 CPUs */
13295             if (ctx->insn_flags & ISA_MIPS_R2) {
13296                 op1 = OPC_DROTR;
13297             }
13298             /* Fallthrough */
13299         case 0:
13300             check_insn(ctx, ISA_MIPS3);
13301             check_mips_64(ctx);
13302             gen_shift_imm(ctx, op1, rd, rt, sa);
13303             break;
13304         default:
13305             gen_reserved_instruction(ctx);
13306             break;
13307         }
13308         break;
13309     case OPC_DSRL32:
13310         switch ((ctx->opcode >> 21) & 0x1f) {
13311         case 1:
13312             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
13313             if (ctx->insn_flags & ISA_MIPS_R2) {
13314                 op1 = OPC_DROTR32;
13315             }
13316             /* Fallthrough */
13317         case 0:
13318             check_insn(ctx, ISA_MIPS3);
13319             check_mips_64(ctx);
13320             gen_shift_imm(ctx, op1, rd, rt, sa);
13321             break;
13322         default:
13323             gen_reserved_instruction(ctx);
13324             break;
13325         }
13326         break;
13327     case OPC_DADD:
13328     case OPC_DADDU:
13329     case OPC_DSUB:
13330     case OPC_DSUBU:
13331         check_insn(ctx, ISA_MIPS3);
13332         check_mips_64(ctx);
13333         gen_arith(ctx, op1, rd, rs, rt);
13334         break;
13335     case OPC_DSLLV:
13336     case OPC_DSRAV:
13337         check_insn(ctx, ISA_MIPS3);
13338         check_mips_64(ctx);
13339         gen_shift(ctx, op1, rd, rs, rt);
13340         break;
13341     case OPC_DSRLV:
13342         switch ((ctx->opcode >> 6) & 0x1f) {
13343         case 1:
13344             /* drotrv is decoded as dsrlv on non-R2 CPUs */
13345             if (ctx->insn_flags & ISA_MIPS_R2) {
13346                 op1 = OPC_DROTRV;
13347             }
13348             /* Fallthrough */
13349         case 0:
13350             check_insn(ctx, ISA_MIPS3);
13351             check_mips_64(ctx);
13352             gen_shift(ctx, op1, rd, rs, rt);
13353             break;
13354         default:
13355             gen_reserved_instruction(ctx);
13356             break;
13357         }
13358         break;
13359 #endif
13360     default:
13361         if (ctx->insn_flags & ISA_MIPS_R6) {
13362             decode_opc_special_r6(env, ctx);
13363         } else if (ctx->insn_flags & INSN_R5900) {
13364             decode_opc_special_tx79(env, ctx);
13365         } else {
13366             decode_opc_special_legacy(env, ctx);
13367         }
13368     }
13369 }
13370 
13371 
decode_opc_special2_legacy(CPUMIPSState * env,DisasContext * ctx)13372 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
13373 {
13374     int rs, rt, rd;
13375     uint32_t op1;
13376 
13377     rs = (ctx->opcode >> 21) & 0x1f;
13378     rt = (ctx->opcode >> 16) & 0x1f;
13379     rd = (ctx->opcode >> 11) & 0x1f;
13380 
13381     op1 = MASK_SPECIAL2(ctx->opcode);
13382     switch (op1) {
13383     case OPC_MADD: /* Multiply and add/sub */
13384     case OPC_MADDU:
13385     case OPC_MSUB:
13386     case OPC_MSUBU:
13387         check_insn(ctx, ISA_MIPS_R1);
13388         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13389         break;
13390     case OPC_MUL:
13391         gen_arith(ctx, op1, rd, rs, rt);
13392         break;
13393     case OPC_CLO:
13394     case OPC_CLZ:
13395         check_insn(ctx, ISA_MIPS_R1);
13396         gen_cl(ctx, op1, rd, rs);
13397         break;
13398     case OPC_SDBBP:
13399         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13400             ctx->base.is_jmp = DISAS_SEMIHOST;
13401         } else {
13402             /*
13403              * XXX: not clear which exception should be raised
13404              *      when in debug mode...
13405              */
13406             check_insn(ctx, ISA_MIPS_R1);
13407             generate_exception_end(ctx, EXCP_DBp);
13408         }
13409         break;
13410 #if defined(TARGET_MIPS64)
13411     case OPC_DCLO:
13412     case OPC_DCLZ:
13413         check_insn(ctx, ISA_MIPS_R1);
13414         check_mips_64(ctx);
13415         gen_cl(ctx, op1, rd, rs);
13416         break;
13417 #endif
13418     default:            /* Invalid */
13419         MIPS_INVAL("special2_legacy");
13420         gen_reserved_instruction(ctx);
13421         break;
13422     }
13423 }
13424 
gen_crc32(DisasContext * ctx,int rd,int rs,int rt,int sz,int crc32c)13425 void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz,
13426                int crc32c)
13427 {
13428     TCGv t0;
13429     TCGv t1;
13430     TCGv_i32 tsz = tcg_constant_i32(1 << sz);
13431     if (rd == 0) {
13432         /* Treat as NOP. */
13433         return;
13434     }
13435     t0 = tcg_temp_new();
13436     t1 = tcg_temp_new();
13437 
13438     gen_load_gpr(t0, rt);
13439     gen_load_gpr(t1, rs);
13440 
13441     if (crc32c) {
13442         gen_helper_crc32c(cpu_gpr[rd], t0, t1, tsz);
13443     } else {
13444         gen_helper_crc32(cpu_gpr[rd], t0, t1, tsz);
13445     }
13446 }
13447 
decode_opc_special3_r6(CPUMIPSState * env,DisasContext * ctx)13448 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
13449 {
13450     int rs, rt, rd, sa;
13451     uint32_t op1, op2;
13452     int16_t imm;
13453 
13454     rs = (ctx->opcode >> 21) & 0x1f;
13455     rt = (ctx->opcode >> 16) & 0x1f;
13456     rd = (ctx->opcode >> 11) & 0x1f;
13457     sa = (ctx->opcode >> 6) & 0x1f;
13458     imm = (int16_t)ctx->opcode >> 7;
13459 
13460     op1 = MASK_SPECIAL3(ctx->opcode);
13461     switch (op1) {
13462     case R6_OPC_PREF:
13463         if (rt >= 24) {
13464             /* hint codes 24-31 are reserved and signal RI */
13465             gen_reserved_instruction(ctx);
13466         }
13467         /* Treat as NOP. */
13468         break;
13469     case R6_OPC_CACHE:
13470         check_cp0_enabled(ctx);
13471         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13472             gen_cache_operation(ctx, rt, rs, imm);
13473         }
13474         break;
13475     case R6_OPC_SC:
13476         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false);
13477         break;
13478     case R6_OPC_LL:
13479         gen_ld(ctx, op1, rt, rs, imm);
13480         break;
13481     case OPC_BSHFL:
13482         {
13483             if (rd == 0) {
13484                 /* Treat as NOP. */
13485                 break;
13486             }
13487             op2 = MASK_BSHFL(ctx->opcode);
13488             switch (op2) {
13489             case OPC_ALIGN:
13490             case OPC_ALIGN_1:
13491             case OPC_ALIGN_2:
13492             case OPC_ALIGN_3:
13493                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
13494                 break;
13495             case OPC_BITSWAP:
13496                 gen_bitswap(ctx, op2, rd, rt);
13497                 break;
13498             }
13499         }
13500         break;
13501 #ifndef CONFIG_USER_ONLY
13502     case OPC_GINV:
13503         if (unlikely(ctx->gi <= 1)) {
13504             gen_reserved_instruction(ctx);
13505         }
13506         check_cp0_enabled(ctx);
13507         switch ((ctx->opcode >> 6) & 3) {
13508         case 0:    /* GINVI */
13509             /* Treat as NOP. */
13510             break;
13511         case 2:    /* GINVT */
13512             gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
13513             break;
13514         default:
13515             gen_reserved_instruction(ctx);
13516             break;
13517         }
13518         break;
13519 #endif
13520 #if defined(TARGET_MIPS64)
13521     case R6_OPC_SCD:
13522         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false);
13523         break;
13524     case R6_OPC_LLD:
13525         gen_ld(ctx, op1, rt, rs, imm);
13526         break;
13527     case OPC_DBSHFL:
13528         check_mips_64(ctx);
13529         {
13530             if (rd == 0) {
13531                 /* Treat as NOP. */
13532                 break;
13533             }
13534             op2 = MASK_DBSHFL(ctx->opcode);
13535             switch (op2) {
13536             case OPC_DALIGN:
13537             case OPC_DALIGN_1:
13538             case OPC_DALIGN_2:
13539             case OPC_DALIGN_3:
13540             case OPC_DALIGN_4:
13541             case OPC_DALIGN_5:
13542             case OPC_DALIGN_6:
13543             case OPC_DALIGN_7:
13544                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
13545                 break;
13546             case OPC_DBITSWAP:
13547                 gen_bitswap(ctx, op2, rd, rt);
13548                 break;
13549             }
13550 
13551         }
13552         break;
13553 #endif
13554     default:            /* Invalid */
13555         MIPS_INVAL("special3_r6");
13556         gen_reserved_instruction(ctx);
13557         break;
13558     }
13559 }
13560 
decode_opc_special3_legacy(CPUMIPSState * env,DisasContext * ctx)13561 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
13562 {
13563     int rs, rt, rd;
13564     uint32_t op1, op2;
13565 
13566     rs = (ctx->opcode >> 21) & 0x1f;
13567     rt = (ctx->opcode >> 16) & 0x1f;
13568     rd = (ctx->opcode >> 11) & 0x1f;
13569 
13570     op1 = MASK_SPECIAL3(ctx->opcode);
13571     switch (op1) {
13572     case OPC_MUL_PH_DSP:
13573         /*
13574          * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13575          * the same mask and op1.
13576          */
13577         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) {
13578             op2 = MASK_ADDUH_QB(ctx->opcode);
13579             switch (op2) {
13580             case OPC_ADDUH_QB:
13581             case OPC_ADDUH_R_QB:
13582             case OPC_ADDQH_PH:
13583             case OPC_ADDQH_R_PH:
13584             case OPC_ADDQH_W:
13585             case OPC_ADDQH_R_W:
13586             case OPC_SUBUH_QB:
13587             case OPC_SUBUH_R_QB:
13588             case OPC_SUBQH_PH:
13589             case OPC_SUBQH_R_PH:
13590             case OPC_SUBQH_W:
13591             case OPC_SUBQH_R_W:
13592                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13593                 break;
13594             case OPC_MUL_PH:
13595             case OPC_MUL_S_PH:
13596             case OPC_MULQ_S_W:
13597             case OPC_MULQ_RS_W:
13598                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13599                 break;
13600             default:
13601                 MIPS_INVAL("MASK ADDUH.QB");
13602                 gen_reserved_instruction(ctx);
13603                 break;
13604             }
13605         } else {
13606             gen_reserved_instruction(ctx);
13607         }
13608         break;
13609     case OPC_LX_DSP:
13610         check_dsp(ctx);
13611         op2 = MASK_LX(ctx->opcode);
13612         switch (op2) {
13613 #if defined(TARGET_MIPS64)
13614         case OPC_LDX:
13615             gen_lx(ctx, rd, rs, rt, MO_UQ);
13616             break;
13617 #endif
13618         case OPC_LBUX:
13619             gen_lx(ctx, rd, rs, rt, MO_UB);
13620             break;
13621         case OPC_LHX:
13622             gen_lx(ctx, rd, rs, rt, MO_SW);
13623             break;
13624         case OPC_LWX:
13625             gen_lx(ctx, rd, rs, rt, MO_SL);
13626             break;
13627         default:            /* Invalid */
13628             MIPS_INVAL("MASK LX");
13629             gen_reserved_instruction(ctx);
13630             break;
13631         }
13632         break;
13633     case OPC_ABSQ_S_PH_DSP:
13634         op2 = MASK_ABSQ_S_PH(ctx->opcode);
13635         switch (op2) {
13636         case OPC_ABSQ_S_QB:
13637         case OPC_ABSQ_S_PH:
13638         case OPC_ABSQ_S_W:
13639         case OPC_PRECEQ_W_PHL:
13640         case OPC_PRECEQ_W_PHR:
13641         case OPC_PRECEQU_PH_QBL:
13642         case OPC_PRECEQU_PH_QBR:
13643         case OPC_PRECEQU_PH_QBLA:
13644         case OPC_PRECEQU_PH_QBRA:
13645         case OPC_PRECEU_PH_QBL:
13646         case OPC_PRECEU_PH_QBR:
13647         case OPC_PRECEU_PH_QBLA:
13648         case OPC_PRECEU_PH_QBRA:
13649             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13650             break;
13651         case OPC_BITREV:
13652         case OPC_REPL_QB:
13653         case OPC_REPLV_QB:
13654         case OPC_REPL_PH:
13655         case OPC_REPLV_PH:
13656             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13657             break;
13658         default:
13659             MIPS_INVAL("MASK ABSQ_S.PH");
13660             gen_reserved_instruction(ctx);
13661             break;
13662         }
13663         break;
13664     case OPC_ADDU_QB_DSP:
13665         op2 = MASK_ADDU_QB(ctx->opcode);
13666         switch (op2) {
13667         case OPC_ADDQ_PH:
13668         case OPC_ADDQ_S_PH:
13669         case OPC_ADDQ_S_W:
13670         case OPC_ADDU_QB:
13671         case OPC_ADDU_S_QB:
13672         case OPC_ADDU_PH:
13673         case OPC_ADDU_S_PH:
13674         case OPC_SUBQ_PH:
13675         case OPC_SUBQ_S_PH:
13676         case OPC_SUBQ_S_W:
13677         case OPC_SUBU_QB:
13678         case OPC_SUBU_S_QB:
13679         case OPC_SUBU_PH:
13680         case OPC_SUBU_S_PH:
13681         case OPC_ADDSC:
13682         case OPC_ADDWC:
13683         case OPC_MODSUB:
13684         case OPC_RADDU_W_QB:
13685             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13686             break;
13687         case OPC_MULEU_S_PH_QBL:
13688         case OPC_MULEU_S_PH_QBR:
13689         case OPC_MULQ_RS_PH:
13690         case OPC_MULEQ_S_W_PHL:
13691         case OPC_MULEQ_S_W_PHR:
13692         case OPC_MULQ_S_PH:
13693             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13694             break;
13695         default:            /* Invalid */
13696             MIPS_INVAL("MASK ADDU.QB");
13697             gen_reserved_instruction(ctx);
13698             break;
13699 
13700         }
13701         break;
13702     case OPC_CMPU_EQ_QB_DSP:
13703         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
13704         switch (op2) {
13705         case OPC_PRECR_SRA_PH_W:
13706         case OPC_PRECR_SRA_R_PH_W:
13707             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
13708             break;
13709         case OPC_PRECR_QB_PH:
13710         case OPC_PRECRQ_QB_PH:
13711         case OPC_PRECRQ_PH_W:
13712         case OPC_PRECRQ_RS_PH_W:
13713         case OPC_PRECRQU_S_QB_PH:
13714             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13715             break;
13716         case OPC_CMPU_EQ_QB:
13717         case OPC_CMPU_LT_QB:
13718         case OPC_CMPU_LE_QB:
13719         case OPC_CMP_EQ_PH:
13720         case OPC_CMP_LT_PH:
13721         case OPC_CMP_LE_PH:
13722             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
13723             break;
13724         case OPC_CMPGU_EQ_QB:
13725         case OPC_CMPGU_LT_QB:
13726         case OPC_CMPGU_LE_QB:
13727         case OPC_CMPGDU_EQ_QB:
13728         case OPC_CMPGDU_LT_QB:
13729         case OPC_CMPGDU_LE_QB:
13730         case OPC_PICK_QB:
13731         case OPC_PICK_PH:
13732         case OPC_PACKRL_PH:
13733             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
13734             break;
13735         default:            /* Invalid */
13736             MIPS_INVAL("MASK CMPU.EQ.QB");
13737             gen_reserved_instruction(ctx);
13738             break;
13739         }
13740         break;
13741     case OPC_SHLL_QB_DSP:
13742         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
13743         break;
13744     case OPC_DPA_W_PH_DSP:
13745         op2 = MASK_DPA_W_PH(ctx->opcode);
13746         switch (op2) {
13747         case OPC_DPAU_H_QBL:
13748         case OPC_DPAU_H_QBR:
13749         case OPC_DPSU_H_QBL:
13750         case OPC_DPSU_H_QBR:
13751         case OPC_DPA_W_PH:
13752         case OPC_DPAX_W_PH:
13753         case OPC_DPAQ_S_W_PH:
13754         case OPC_DPAQX_S_W_PH:
13755         case OPC_DPAQX_SA_W_PH:
13756         case OPC_DPS_W_PH:
13757         case OPC_DPSX_W_PH:
13758         case OPC_DPSQ_S_W_PH:
13759         case OPC_DPSQX_S_W_PH:
13760         case OPC_DPSQX_SA_W_PH:
13761         case OPC_MULSAQ_S_W_PH:
13762         case OPC_DPAQ_SA_L_W:
13763         case OPC_DPSQ_SA_L_W:
13764         case OPC_MAQ_S_W_PHL:
13765         case OPC_MAQ_S_W_PHR:
13766         case OPC_MAQ_SA_W_PHL:
13767         case OPC_MAQ_SA_W_PHR:
13768         case OPC_MULSA_W_PH:
13769             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
13770             break;
13771         default:            /* Invalid */
13772             MIPS_INVAL("MASK DPAW.PH");
13773             gen_reserved_instruction(ctx);
13774             break;
13775         }
13776         break;
13777     case OPC_INSV_DSP:
13778         op2 = MASK_INSV(ctx->opcode);
13779         switch (op2) {
13780         case OPC_INSV:
13781             check_dsp(ctx);
13782             {
13783                 TCGv t0, t1;
13784 
13785                 if (rt == 0) {
13786                     break;
13787                 }
13788 
13789                 t0 = tcg_temp_new();
13790                 t1 = tcg_temp_new();
13791 
13792                 gen_load_gpr(t0, rt);
13793                 gen_load_gpr(t1, rs);
13794 
13795                 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0);
13796                 break;
13797             }
13798         default:            /* Invalid */
13799             MIPS_INVAL("MASK INSV");
13800             gen_reserved_instruction(ctx);
13801             break;
13802         }
13803         break;
13804     case OPC_APPEND_DSP:
13805         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
13806         break;
13807     case OPC_EXTR_W_DSP:
13808         op2 = MASK_EXTR_W(ctx->opcode);
13809         switch (op2) {
13810         case OPC_EXTR_W:
13811         case OPC_EXTR_R_W:
13812         case OPC_EXTR_RS_W:
13813         case OPC_EXTR_S_H:
13814         case OPC_EXTRV_S_H:
13815         case OPC_EXTRV_W:
13816         case OPC_EXTRV_R_W:
13817         case OPC_EXTRV_RS_W:
13818         case OPC_EXTP:
13819         case OPC_EXTPV:
13820         case OPC_EXTPDP:
13821         case OPC_EXTPDPV:
13822             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
13823             break;
13824         case OPC_RDDSP:
13825             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
13826             break;
13827         case OPC_SHILO:
13828         case OPC_SHILOV:
13829         case OPC_MTHLIP:
13830         case OPC_WRDSP:
13831             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
13832             break;
13833         default:            /* Invalid */
13834             MIPS_INVAL("MASK EXTR.W");
13835             gen_reserved_instruction(ctx);
13836             break;
13837         }
13838         break;
13839 #if defined(TARGET_MIPS64)
13840     case OPC_ABSQ_S_QH_DSP:
13841         op2 = MASK_ABSQ_S_QH(ctx->opcode);
13842         switch (op2) {
13843         case OPC_PRECEQ_L_PWL:
13844         case OPC_PRECEQ_L_PWR:
13845         case OPC_PRECEQ_PW_QHL:
13846         case OPC_PRECEQ_PW_QHR:
13847         case OPC_PRECEQ_PW_QHLA:
13848         case OPC_PRECEQ_PW_QHRA:
13849         case OPC_PRECEQU_QH_OBL:
13850         case OPC_PRECEQU_QH_OBR:
13851         case OPC_PRECEQU_QH_OBLA:
13852         case OPC_PRECEQU_QH_OBRA:
13853         case OPC_PRECEU_QH_OBL:
13854         case OPC_PRECEU_QH_OBR:
13855         case OPC_PRECEU_QH_OBLA:
13856         case OPC_PRECEU_QH_OBRA:
13857         case OPC_ABSQ_S_OB:
13858         case OPC_ABSQ_S_PW:
13859         case OPC_ABSQ_S_QH:
13860             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13861             break;
13862         case OPC_REPL_OB:
13863         case OPC_REPL_PW:
13864         case OPC_REPL_QH:
13865         case OPC_REPLV_OB:
13866         case OPC_REPLV_PW:
13867         case OPC_REPLV_QH:
13868             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13869             break;
13870         default:            /* Invalid */
13871             MIPS_INVAL("MASK ABSQ_S.QH");
13872             gen_reserved_instruction(ctx);
13873             break;
13874         }
13875         break;
13876     case OPC_ADDU_OB_DSP:
13877         op2 = MASK_ADDU_OB(ctx->opcode);
13878         switch (op2) {
13879         case OPC_RADDU_L_OB:
13880         case OPC_SUBQ_PW:
13881         case OPC_SUBQ_S_PW:
13882         case OPC_SUBQ_QH:
13883         case OPC_SUBQ_S_QH:
13884         case OPC_SUBU_OB:
13885         case OPC_SUBU_S_OB:
13886         case OPC_SUBU_QH:
13887         case OPC_SUBU_S_QH:
13888         case OPC_SUBUH_OB:
13889         case OPC_SUBUH_R_OB:
13890         case OPC_ADDQ_PW:
13891         case OPC_ADDQ_S_PW:
13892         case OPC_ADDQ_QH:
13893         case OPC_ADDQ_S_QH:
13894         case OPC_ADDU_OB:
13895         case OPC_ADDU_S_OB:
13896         case OPC_ADDU_QH:
13897         case OPC_ADDU_S_QH:
13898         case OPC_ADDUH_OB:
13899         case OPC_ADDUH_R_OB:
13900             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13901             break;
13902         case OPC_MULEQ_S_PW_QHL:
13903         case OPC_MULEQ_S_PW_QHR:
13904         case OPC_MULEU_S_QH_OBL:
13905         case OPC_MULEU_S_QH_OBR:
13906         case OPC_MULQ_RS_QH:
13907             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13908             break;
13909         default:            /* Invalid */
13910             MIPS_INVAL("MASK ADDU.OB");
13911             gen_reserved_instruction(ctx);
13912             break;
13913         }
13914         break;
13915     case OPC_CMPU_EQ_OB_DSP:
13916         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
13917         switch (op2) {
13918         case OPC_PRECR_SRA_QH_PW:
13919         case OPC_PRECR_SRA_R_QH_PW:
13920             /* Return value is rt. */
13921             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
13922             break;
13923         case OPC_PRECR_OB_QH:
13924         case OPC_PRECRQ_OB_QH:
13925         case OPC_PRECRQ_PW_L:
13926         case OPC_PRECRQ_QH_PW:
13927         case OPC_PRECRQ_RS_QH_PW:
13928         case OPC_PRECRQU_S_OB_QH:
13929             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13930             break;
13931         case OPC_CMPU_EQ_OB:
13932         case OPC_CMPU_LT_OB:
13933         case OPC_CMPU_LE_OB:
13934         case OPC_CMP_EQ_QH:
13935         case OPC_CMP_LT_QH:
13936         case OPC_CMP_LE_QH:
13937         case OPC_CMP_EQ_PW:
13938         case OPC_CMP_LT_PW:
13939         case OPC_CMP_LE_PW:
13940             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
13941             break;
13942         case OPC_CMPGDU_EQ_OB:
13943         case OPC_CMPGDU_LT_OB:
13944         case OPC_CMPGDU_LE_OB:
13945         case OPC_CMPGU_EQ_OB:
13946         case OPC_CMPGU_LT_OB:
13947         case OPC_CMPGU_LE_OB:
13948         case OPC_PACKRL_PW:
13949         case OPC_PICK_OB:
13950         case OPC_PICK_PW:
13951         case OPC_PICK_QH:
13952             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
13953             break;
13954         default:            /* Invalid */
13955             MIPS_INVAL("MASK CMPU_EQ.OB");
13956             gen_reserved_instruction(ctx);
13957             break;
13958         }
13959         break;
13960     case OPC_DAPPEND_DSP:
13961         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
13962         break;
13963     case OPC_DEXTR_W_DSP:
13964         op2 = MASK_DEXTR_W(ctx->opcode);
13965         switch (op2) {
13966         case OPC_DEXTP:
13967         case OPC_DEXTPDP:
13968         case OPC_DEXTPDPV:
13969         case OPC_DEXTPV:
13970         case OPC_DEXTR_L:
13971         case OPC_DEXTR_R_L:
13972         case OPC_DEXTR_RS_L:
13973         case OPC_DEXTR_W:
13974         case OPC_DEXTR_R_W:
13975         case OPC_DEXTR_RS_W:
13976         case OPC_DEXTR_S_H:
13977         case OPC_DEXTRV_L:
13978         case OPC_DEXTRV_R_L:
13979         case OPC_DEXTRV_RS_L:
13980         case OPC_DEXTRV_S_H:
13981         case OPC_DEXTRV_W:
13982         case OPC_DEXTRV_R_W:
13983         case OPC_DEXTRV_RS_W:
13984             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
13985             break;
13986         case OPC_DMTHLIP:
13987         case OPC_DSHILO:
13988         case OPC_DSHILOV:
13989             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
13990             break;
13991         default:            /* Invalid */
13992             MIPS_INVAL("MASK EXTR.W");
13993             gen_reserved_instruction(ctx);
13994             break;
13995         }
13996         break;
13997     case OPC_DPAQ_W_QH_DSP:
13998         op2 = MASK_DPAQ_W_QH(ctx->opcode);
13999         switch (op2) {
14000         case OPC_DPAU_H_OBL:
14001         case OPC_DPAU_H_OBR:
14002         case OPC_DPSU_H_OBL:
14003         case OPC_DPSU_H_OBR:
14004         case OPC_DPA_W_QH:
14005         case OPC_DPAQ_S_W_QH:
14006         case OPC_DPS_W_QH:
14007         case OPC_DPSQ_S_W_QH:
14008         case OPC_MULSAQ_S_W_QH:
14009         case OPC_DPAQ_SA_L_PW:
14010         case OPC_DPSQ_SA_L_PW:
14011         case OPC_MULSAQ_S_L_PW:
14012             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14013             break;
14014         case OPC_MAQ_S_W_QHLL:
14015         case OPC_MAQ_S_W_QHLR:
14016         case OPC_MAQ_S_W_QHRL:
14017         case OPC_MAQ_S_W_QHRR:
14018         case OPC_MAQ_SA_W_QHLL:
14019         case OPC_MAQ_SA_W_QHLR:
14020         case OPC_MAQ_SA_W_QHRL:
14021         case OPC_MAQ_SA_W_QHRR:
14022         case OPC_MAQ_S_L_PWL:
14023         case OPC_MAQ_S_L_PWR:
14024         case OPC_DMADD:
14025         case OPC_DMADDU:
14026         case OPC_DMSUB:
14027         case OPC_DMSUBU:
14028             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14029             break;
14030         default:            /* Invalid */
14031             MIPS_INVAL("MASK DPAQ.W.QH");
14032             gen_reserved_instruction(ctx);
14033             break;
14034         }
14035         break;
14036     case OPC_DINSV_DSP:
14037         op2 = MASK_INSV(ctx->opcode);
14038         switch (op2) {
14039         case OPC_DINSV:
14040         {
14041             TCGv t0, t1;
14042 
14043             check_dsp(ctx);
14044 
14045             if (rt == 0) {
14046                 break;
14047             }
14048 
14049             t0 = tcg_temp_new();
14050             t1 = tcg_temp_new();
14051 
14052             gen_load_gpr(t0, rt);
14053             gen_load_gpr(t1, rs);
14054 
14055             gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0);
14056             break;
14057         }
14058         default:            /* Invalid */
14059             MIPS_INVAL("MASK DINSV");
14060             gen_reserved_instruction(ctx);
14061             break;
14062         }
14063         break;
14064     case OPC_SHLL_OB_DSP:
14065         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14066         break;
14067 #endif
14068     default:            /* Invalid */
14069         MIPS_INVAL("special3_legacy");
14070         gen_reserved_instruction(ctx);
14071         break;
14072     }
14073 }
14074 
14075 
14076 #if defined(TARGET_MIPS64)
14077 
decode_mmi(CPUMIPSState * env,DisasContext * ctx)14078 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14079 {
14080     uint32_t opc = MASK_MMI(ctx->opcode);
14081     int rs = extract32(ctx->opcode, 21, 5);
14082     int rt = extract32(ctx->opcode, 16, 5);
14083     int rd = extract32(ctx->opcode, 11, 5);
14084 
14085     switch (opc) {
14086     case MMI_OPC_MULT1:
14087     case MMI_OPC_MULTU1:
14088     case MMI_OPC_MADD:
14089     case MMI_OPC_MADDU:
14090     case MMI_OPC_MADD1:
14091     case MMI_OPC_MADDU1:
14092         gen_mul_txx9(ctx, opc, rd, rs, rt);
14093         break;
14094     case MMI_OPC_DIV1:
14095     case MMI_OPC_DIVU1:
14096         gen_div1_tx79(ctx, opc, rs, rt);
14097         break;
14098     default:
14099         MIPS_INVAL("TX79 MMI class");
14100         gen_reserved_instruction(ctx);
14101         break;
14102     }
14103 }
14104 
gen_mmi_sq(DisasContext * ctx,int base,int rt,int offset)14105 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
14106 {
14107     gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
14108 }
14109 
14110 /*
14111  * The TX79-specific instruction Store Quadword
14112  *
14113  * +--------+-------+-------+------------------------+
14114  * | 011111 |  base |   rt  |           offset       | SQ
14115  * +--------+-------+-------+------------------------+
14116  *      6       5       5                 16
14117  *
14118  * has the same opcode as the Read Hardware Register instruction
14119  *
14120  * +--------+-------+-------+-------+-------+--------+
14121  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
14122  * +--------+-------+-------+-------+-------+--------+
14123  *      6       5       5       5       5        6
14124  *
14125  * that is required, trapped and emulated by the Linux kernel. However, all
14126  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
14127  * offset is odd. Therefore all valid SQ instructions can execute normally.
14128  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
14129  * between SQ and RDHWR, as the Linux kernel does.
14130  */
decode_mmi_sq(CPUMIPSState * env,DisasContext * ctx)14131 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
14132 {
14133     int base = extract32(ctx->opcode, 21, 5);
14134     int rt = extract32(ctx->opcode, 16, 5);
14135     int offset = extract32(ctx->opcode, 0, 16);
14136 
14137 #ifdef CONFIG_USER_ONLY
14138     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
14139     uint32_t op2 = extract32(ctx->opcode, 6, 5);
14140 
14141     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
14142         int rd = extract32(ctx->opcode, 11, 5);
14143 
14144         gen_rdhwr(ctx, rt, rd, 0);
14145         return;
14146     }
14147 #endif
14148 
14149     gen_mmi_sq(ctx, base, rt, offset);
14150 }
14151 
14152 #endif
14153 
decode_opc_special3(CPUMIPSState * env,DisasContext * ctx)14154 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
14155 {
14156     int rs, rt, rd, sa;
14157     uint32_t op1, op2;
14158     int16_t imm;
14159 
14160     rs = (ctx->opcode >> 21) & 0x1f;
14161     rt = (ctx->opcode >> 16) & 0x1f;
14162     rd = (ctx->opcode >> 11) & 0x1f;
14163     sa = (ctx->opcode >> 6) & 0x1f;
14164     imm = sextract32(ctx->opcode, 7, 9);
14165 
14166     op1 = MASK_SPECIAL3(ctx->opcode);
14167 
14168     /*
14169      * EVA loads and stores overlap Loongson 2E instructions decoded by
14170      * decode_opc_special3_legacy(), so be careful to allow their decoding when
14171      * EVA is absent.
14172      */
14173     if (ctx->eva) {
14174         switch (op1) {
14175         case OPC_LWLE:
14176         case OPC_LWRE:
14177         case OPC_LBUE:
14178         case OPC_LHUE:
14179         case OPC_LBE:
14180         case OPC_LHE:
14181         case OPC_LLE:
14182         case OPC_LWE:
14183             check_cp0_enabled(ctx);
14184             gen_ld(ctx, op1, rt, rs, imm);
14185             return;
14186         case OPC_SWLE:
14187         case OPC_SWRE:
14188         case OPC_SBE:
14189         case OPC_SHE:
14190         case OPC_SWE:
14191             check_cp0_enabled(ctx);
14192             gen_st(ctx, op1, rt, rs, imm);
14193             return;
14194         case OPC_SCE:
14195             check_cp0_enabled(ctx);
14196             gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true);
14197             return;
14198         case OPC_CACHEE:
14199             check_eva(ctx);
14200             check_cp0_enabled(ctx);
14201             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14202                 gen_cache_operation(ctx, rt, rs, imm);
14203             }
14204             return;
14205         case OPC_PREFE:
14206             check_cp0_enabled(ctx);
14207             /* Treat as NOP. */
14208             return;
14209         }
14210     }
14211 
14212     switch (op1) {
14213     case OPC_EXT:
14214     case OPC_INS:
14215         check_insn(ctx, ISA_MIPS_R2);
14216         gen_bitops(ctx, op1, rt, rs, sa, rd);
14217         break;
14218     case OPC_BSHFL:
14219         op2 = MASK_BSHFL(ctx->opcode);
14220         switch (op2) {
14221         case OPC_ALIGN:
14222         case OPC_ALIGN_1:
14223         case OPC_ALIGN_2:
14224         case OPC_ALIGN_3:
14225         case OPC_BITSWAP:
14226             check_insn(ctx, ISA_MIPS_R6);
14227             decode_opc_special3_r6(env, ctx);
14228             break;
14229         default:
14230             check_insn(ctx, ISA_MIPS_R2);
14231             gen_bshfl(ctx, op2, rt, rd);
14232             break;
14233         }
14234         break;
14235 #if defined(TARGET_MIPS64)
14236     case OPC_DEXTM:
14237     case OPC_DEXTU:
14238     case OPC_DEXT:
14239     case OPC_DINSM:
14240     case OPC_DINSU:
14241     case OPC_DINS:
14242         check_insn(ctx, ISA_MIPS_R2);
14243         check_mips_64(ctx);
14244         gen_bitops(ctx, op1, rt, rs, sa, rd);
14245         break;
14246     case OPC_DBSHFL:
14247         op2 = MASK_DBSHFL(ctx->opcode);
14248         switch (op2) {
14249         case OPC_DALIGN:
14250         case OPC_DALIGN_1:
14251         case OPC_DALIGN_2:
14252         case OPC_DALIGN_3:
14253         case OPC_DALIGN_4:
14254         case OPC_DALIGN_5:
14255         case OPC_DALIGN_6:
14256         case OPC_DALIGN_7:
14257         case OPC_DBITSWAP:
14258             check_insn(ctx, ISA_MIPS_R6);
14259             decode_opc_special3_r6(env, ctx);
14260             break;
14261         default:
14262             check_insn(ctx, ISA_MIPS_R2);
14263             check_mips_64(ctx);
14264             op2 = MASK_DBSHFL(ctx->opcode);
14265             gen_bshfl(ctx, op2, rt, rd);
14266             break;
14267         }
14268         break;
14269 #endif
14270     case OPC_RDHWR:
14271         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
14272         break;
14273     case OPC_FORK:
14274         check_mt(ctx);
14275         {
14276             TCGv t0 = tcg_temp_new();
14277             TCGv t1 = tcg_temp_new();
14278 
14279             gen_load_gpr(t0, rt);
14280             gen_load_gpr(t1, rs);
14281             gen_helper_fork(t0, t1);
14282         }
14283         break;
14284     case OPC_YIELD:
14285         check_mt(ctx);
14286         {
14287             TCGv t0 = tcg_temp_new();
14288 
14289             gen_load_gpr(t0, rs);
14290             gen_helper_yield(t0, tcg_env, t0);
14291             gen_store_gpr(t0, rd);
14292         }
14293         break;
14294     default:
14295         if (ctx->insn_flags & ISA_MIPS_R6) {
14296             decode_opc_special3_r6(env, ctx);
14297         } else {
14298             decode_opc_special3_legacy(env, ctx);
14299         }
14300     }
14301 }
14302 
decode_opc_legacy(CPUMIPSState * env,DisasContext * ctx)14303 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
14304 {
14305     int32_t offset;
14306     int rs, rt, rd, sa;
14307     uint32_t op, op1;
14308     int16_t imm;
14309 
14310     op = MASK_OP_MAJOR(ctx->opcode);
14311     rs = (ctx->opcode >> 21) & 0x1f;
14312     rt = (ctx->opcode >> 16) & 0x1f;
14313     rd = (ctx->opcode >> 11) & 0x1f;
14314     sa = (ctx->opcode >> 6) & 0x1f;
14315     imm = (int16_t)ctx->opcode;
14316     switch (op) {
14317     case OPC_SPECIAL:
14318         decode_opc_special(env, ctx);
14319         break;
14320     case OPC_SPECIAL2:
14321 #if defined(TARGET_MIPS64)
14322         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
14323             decode_mmi(env, ctx);
14324             break;
14325         }
14326 #endif
14327         if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
14328             if (decode_ase_mxu(ctx, ctx->opcode)) {
14329                 break;
14330             }
14331         }
14332         decode_opc_special2_legacy(env, ctx);
14333         break;
14334     case OPC_SPECIAL3:
14335 #if defined(TARGET_MIPS64)
14336         if (ctx->insn_flags & INSN_R5900) {
14337             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
14338         } else {
14339             decode_opc_special3(env, ctx);
14340         }
14341 #else
14342         decode_opc_special3(env, ctx);
14343 #endif
14344         break;
14345     case OPC_REGIMM:
14346         op1 = MASK_REGIMM(ctx->opcode);
14347         switch (op1) {
14348         case OPC_BLTZL: /* REGIMM branches */
14349         case OPC_BGEZL:
14350         case OPC_BLTZALL:
14351         case OPC_BGEZALL:
14352             check_insn(ctx, ISA_MIPS2);
14353             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14354             /* Fallthrough */
14355         case OPC_BLTZ:
14356         case OPC_BGEZ:
14357             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14358             break;
14359         case OPC_BLTZAL:
14360         case OPC_BGEZAL:
14361             if (ctx->insn_flags & ISA_MIPS_R6) {
14362                 if (rs == 0) {
14363                     /* OPC_NAL, OPC_BAL */
14364                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
14365                 } else {
14366                     gen_reserved_instruction(ctx);
14367                 }
14368             } else {
14369                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14370             }
14371             break;
14372         case OPC_TGEI: /* REGIMM traps */
14373         case OPC_TGEIU:
14374         case OPC_TLTI:
14375         case OPC_TLTIU:
14376         case OPC_TEQI:
14377         case OPC_TNEI:
14378             check_insn(ctx, ISA_MIPS2);
14379             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14380             gen_trap(ctx, op1, rs, -1, imm, 0);
14381             break;
14382         case OPC_SIGRIE:
14383             check_insn(ctx, ISA_MIPS_R6);
14384             gen_reserved_instruction(ctx);
14385             break;
14386         case OPC_SYNCI:
14387             check_insn(ctx, ISA_MIPS_R2);
14388             /*
14389              * Break the TB to be able to sync copied instructions
14390              * immediately.
14391              */
14392             ctx->base.is_jmp = DISAS_STOP;
14393             break;
14394         case OPC_BPOSGE32:    /* MIPS DSP branch */
14395 #if defined(TARGET_MIPS64)
14396         case OPC_BPOSGE64:
14397 #endif
14398             check_dsp(ctx);
14399             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
14400             break;
14401 #if defined(TARGET_MIPS64)
14402         case OPC_DAHI:
14403             check_insn(ctx, ISA_MIPS_R6);
14404             check_mips_64(ctx);
14405             if (rs != 0) {
14406                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
14407             }
14408             break;
14409         case OPC_DATI:
14410             check_insn(ctx, ISA_MIPS_R6);
14411             check_mips_64(ctx);
14412             if (rs != 0) {
14413                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
14414             }
14415             break;
14416 #endif
14417         default:            /* Invalid */
14418             MIPS_INVAL("regimm");
14419             gen_reserved_instruction(ctx);
14420             break;
14421         }
14422         break;
14423     case OPC_CP0:
14424         check_cp0_enabled(ctx);
14425         op1 = MASK_CP0(ctx->opcode);
14426         switch (op1) {
14427         case OPC_MFC0:
14428         case OPC_MTC0:
14429         case OPC_MFTR:
14430         case OPC_MTTR:
14431         case OPC_MFHC0:
14432         case OPC_MTHC0:
14433 #if defined(TARGET_MIPS64)
14434         case OPC_DMFC0:
14435         case OPC_DMTC0:
14436 #endif
14437 #ifndef CONFIG_USER_ONLY
14438             gen_cp0(env, ctx, op1, rt, rd);
14439 #endif /* !CONFIG_USER_ONLY */
14440             break;
14441         case OPC_C0:
14442         case OPC_C0_1:
14443         case OPC_C0_2:
14444         case OPC_C0_3:
14445         case OPC_C0_4:
14446         case OPC_C0_5:
14447         case OPC_C0_6:
14448         case OPC_C0_7:
14449         case OPC_C0_8:
14450         case OPC_C0_9:
14451         case OPC_C0_A:
14452         case OPC_C0_B:
14453         case OPC_C0_C:
14454         case OPC_C0_D:
14455         case OPC_C0_E:
14456         case OPC_C0_F:
14457 #ifndef CONFIG_USER_ONLY
14458             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
14459 #endif /* !CONFIG_USER_ONLY */
14460             break;
14461         case OPC_MFMC0:
14462 #ifndef CONFIG_USER_ONLY
14463             {
14464                 uint32_t op2;
14465                 TCGv t0 = tcg_temp_new();
14466 
14467                 op2 = MASK_MFMC0(ctx->opcode);
14468                 switch (op2) {
14469                 case OPC_DMT:
14470                     check_cp0_mt(ctx);
14471                     gen_helper_dmt(t0);
14472                     gen_store_gpr(t0, rt);
14473                     break;
14474                 case OPC_EMT:
14475                     check_cp0_mt(ctx);
14476                     gen_helper_emt(t0);
14477                     gen_store_gpr(t0, rt);
14478                     break;
14479                 case OPC_DVPE:
14480                     check_cp0_mt(ctx);
14481                     gen_helper_dvpe(t0, tcg_env);
14482                     gen_store_gpr(t0, rt);
14483                     break;
14484                 case OPC_EVPE:
14485                     check_cp0_mt(ctx);
14486                     gen_helper_evpe(t0, tcg_env);
14487                     gen_store_gpr(t0, rt);
14488                     break;
14489                 case OPC_DVP:
14490                     check_insn(ctx, ISA_MIPS_R6);
14491                     if (ctx->vp) {
14492                         gen_helper_dvp(t0, tcg_env);
14493                         gen_store_gpr(t0, rt);
14494                     }
14495                     break;
14496                 case OPC_EVP:
14497                     check_insn(ctx, ISA_MIPS_R6);
14498                     if (ctx->vp) {
14499                         gen_helper_evp(t0, tcg_env);
14500                         gen_store_gpr(t0, rt);
14501                     }
14502                     break;
14503                 case OPC_DI:
14504                     check_insn(ctx, ISA_MIPS_R2);
14505                     save_cpu_state(ctx, 1);
14506                     gen_helper_di(t0, tcg_env);
14507                     gen_store_gpr(t0, rt);
14508                     /*
14509                      * Stop translation as we may have switched
14510                      * the execution mode.
14511                      */
14512                     ctx->base.is_jmp = DISAS_STOP;
14513                     break;
14514                 case OPC_EI:
14515                     check_insn(ctx, ISA_MIPS_R2);
14516                     save_cpu_state(ctx, 1);
14517                     gen_helper_ei(t0, tcg_env);
14518                     gen_store_gpr(t0, rt);
14519                     /*
14520                      * DISAS_STOP isn't sufficient, we need to ensure we break
14521                      * out of translated code to check for pending interrupts.
14522                      */
14523                     gen_save_pc(ctx->base.pc_next + 4);
14524                     ctx->base.is_jmp = DISAS_EXIT;
14525                     break;
14526                 default:            /* Invalid */
14527                     MIPS_INVAL("mfmc0");
14528                     gen_reserved_instruction(ctx);
14529                     break;
14530                 }
14531             }
14532 #endif /* !CONFIG_USER_ONLY */
14533             break;
14534         case OPC_RDPGPR:
14535             check_insn(ctx, ISA_MIPS_R2);
14536             gen_load_srsgpr(rt, rd);
14537             break;
14538         case OPC_WRPGPR:
14539             check_insn(ctx, ISA_MIPS_R2);
14540             gen_store_srsgpr(rt, rd);
14541             break;
14542         default:
14543             MIPS_INVAL("cp0");
14544             gen_reserved_instruction(ctx);
14545             break;
14546         }
14547         break;
14548     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
14549         if (ctx->insn_flags & ISA_MIPS_R6) {
14550             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
14551             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14552         } else {
14553             /* OPC_ADDI */
14554             /* Arithmetic with immediate opcode */
14555             gen_arith_imm(ctx, op, rt, rs, imm);
14556         }
14557         break;
14558     case OPC_ADDIU:
14559          gen_arith_imm(ctx, op, rt, rs, imm);
14560          break;
14561     case OPC_SLTI: /* Set on less than with immediate opcode */
14562     case OPC_SLTIU:
14563          gen_slt_imm(ctx, op, rt, rs, imm);
14564          break;
14565     case OPC_ANDI: /* Arithmetic with immediate opcode */
14566     case OPC_LUI: /* OPC_AUI */
14567     case OPC_ORI:
14568     case OPC_XORI:
14569          gen_logic_imm(ctx, op, rt, rs, imm);
14570          break;
14571     case OPC_J: /* Jump */
14572     case OPC_JAL:
14573          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14574          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14575          break;
14576     /* Branch */
14577     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
14578         if (ctx->insn_flags & ISA_MIPS_R6) {
14579             if (rt == 0) {
14580                 gen_reserved_instruction(ctx);
14581                 break;
14582             }
14583             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
14584             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14585         } else {
14586             /* OPC_BLEZL */
14587             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14588         }
14589         break;
14590     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
14591         if (ctx->insn_flags & ISA_MIPS_R6) {
14592             if (rt == 0) {
14593                 gen_reserved_instruction(ctx);
14594                 break;
14595             }
14596             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
14597             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14598         } else {
14599             /* OPC_BGTZL */
14600             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14601         }
14602         break;
14603     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
14604         if (rt == 0) {
14605             /* OPC_BLEZ */
14606             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14607         } else {
14608             check_insn(ctx, ISA_MIPS_R6);
14609             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
14610             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14611         }
14612         break;
14613     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
14614         if (rt == 0) {
14615             /* OPC_BGTZ */
14616             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14617         } else {
14618             check_insn(ctx, ISA_MIPS_R6);
14619             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
14620             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14621         }
14622         break;
14623     case OPC_BEQL:
14624     case OPC_BNEL:
14625         check_insn(ctx, ISA_MIPS2);
14626          check_insn_opc_removed(ctx, ISA_MIPS_R6);
14627         /* Fallthrough */
14628     case OPC_BEQ:
14629     case OPC_BNE:
14630          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14631          break;
14632     case OPC_LL: /* Load and stores */
14633         check_insn(ctx, ISA_MIPS2);
14634         if (ctx->insn_flags & INSN_R5900) {
14635             check_insn_opc_user_only(ctx, INSN_R5900);
14636         }
14637         /* Fallthrough */
14638     case OPC_LWL:
14639     case OPC_LWR:
14640     case OPC_LB:
14641     case OPC_LH:
14642     case OPC_LW:
14643     case OPC_LWPC:
14644     case OPC_LBU:
14645     case OPC_LHU:
14646          gen_ld(ctx, op, rt, rs, imm);
14647          break;
14648     case OPC_SWL:
14649     case OPC_SWR:
14650     case OPC_SB:
14651     case OPC_SH:
14652     case OPC_SW:
14653          gen_st(ctx, op, rt, rs, imm);
14654          break;
14655     case OPC_SC:
14656         check_insn(ctx, ISA_MIPS2);
14657         if (ctx->insn_flags & INSN_R5900) {
14658             check_insn_opc_user_only(ctx, INSN_R5900);
14659         }
14660         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false);
14661         break;
14662     case OPC_CACHE:
14663         check_cp0_enabled(ctx);
14664         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
14665         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14666             gen_cache_operation(ctx, rt, rs, imm);
14667         }
14668         /* Treat as NOP. */
14669         break;
14670     case OPC_PREF:
14671         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
14672         /* Treat as NOP. */
14673         break;
14674 
14675     /* Floating point (COP1). */
14676     case OPC_LWC1:
14677     case OPC_LDC1:
14678     case OPC_SWC1:
14679     case OPC_SDC1:
14680         gen_cop1_ldst(ctx, op, rt, rs, imm);
14681         break;
14682 
14683     case OPC_CP1:
14684         op1 = MASK_CP1(ctx->opcode);
14685 
14686         switch (op1) {
14687         case OPC_MFHC1:
14688         case OPC_MTHC1:
14689             check_cp1_enabled(ctx);
14690             check_insn(ctx, ISA_MIPS_R2);
14691             /* fall through */
14692         case OPC_MFC1:
14693         case OPC_CFC1:
14694         case OPC_MTC1:
14695         case OPC_CTC1:
14696             check_cp1_enabled(ctx);
14697             gen_cp1(ctx, op1, rt, rd);
14698             break;
14699 #if defined(TARGET_MIPS64)
14700         case OPC_DMFC1:
14701         case OPC_DMTC1:
14702             check_cp1_enabled(ctx);
14703             check_insn(ctx, ISA_MIPS3);
14704             check_mips_64(ctx);
14705             gen_cp1(ctx, op1, rt, rd);
14706             break;
14707 #endif
14708         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
14709             check_cp1_enabled(ctx);
14710             if (ctx->insn_flags & ISA_MIPS_R6) {
14711                 /* OPC_BC1EQZ */
14712                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14713                                        rt, imm << 2, 4);
14714             } else {
14715                 /* OPC_BC1ANY2 */
14716                 check_cop1x(ctx);
14717                 if (!ase_3d_available(env)) {
14718                     return false;
14719                 }
14720                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14721                                     (rt >> 2) & 0x7, imm << 2);
14722             }
14723             break;
14724         case OPC_BC1NEZ:
14725             check_cp1_enabled(ctx);
14726             check_insn(ctx, ISA_MIPS_R6);
14727             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14728                                    rt, imm << 2, 4);
14729             break;
14730         case OPC_BC1ANY4:
14731             check_cp1_enabled(ctx);
14732             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14733             check_cop1x(ctx);
14734             if (!ase_3d_available(env)) {
14735                 return false;
14736             }
14737             /* fall through */
14738         case OPC_BC1:
14739             check_cp1_enabled(ctx);
14740             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14741             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14742                                 (rt >> 2) & 0x7, imm << 2);
14743             break;
14744         case OPC_PS_FMT:
14745             check_ps(ctx);
14746             /* fall through */
14747         case OPC_S_FMT:
14748         case OPC_D_FMT:
14749             check_cp1_enabled(ctx);
14750             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
14751                        (imm >> 8) & 0x7);
14752             break;
14753         case OPC_W_FMT:
14754         case OPC_L_FMT:
14755         {
14756             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
14757             check_cp1_enabled(ctx);
14758             if (ctx->insn_flags & ISA_MIPS_R6) {
14759                 switch (r6_op) {
14760                 case R6_OPC_CMP_AF_S:
14761                 case R6_OPC_CMP_UN_S:
14762                 case R6_OPC_CMP_EQ_S:
14763                 case R6_OPC_CMP_UEQ_S:
14764                 case R6_OPC_CMP_LT_S:
14765                 case R6_OPC_CMP_ULT_S:
14766                 case R6_OPC_CMP_LE_S:
14767                 case R6_OPC_CMP_ULE_S:
14768                 case R6_OPC_CMP_SAF_S:
14769                 case R6_OPC_CMP_SUN_S:
14770                 case R6_OPC_CMP_SEQ_S:
14771                 case R6_OPC_CMP_SEUQ_S:
14772                 case R6_OPC_CMP_SLT_S:
14773                 case R6_OPC_CMP_SULT_S:
14774                 case R6_OPC_CMP_SLE_S:
14775                 case R6_OPC_CMP_SULE_S:
14776                 case R6_OPC_CMP_OR_S:
14777                 case R6_OPC_CMP_UNE_S:
14778                 case R6_OPC_CMP_NE_S:
14779                 case R6_OPC_CMP_SOR_S:
14780                 case R6_OPC_CMP_SUNE_S:
14781                 case R6_OPC_CMP_SNE_S:
14782                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
14783                     break;
14784                 case R6_OPC_CMP_AF_D:
14785                 case R6_OPC_CMP_UN_D:
14786                 case R6_OPC_CMP_EQ_D:
14787                 case R6_OPC_CMP_UEQ_D:
14788                 case R6_OPC_CMP_LT_D:
14789                 case R6_OPC_CMP_ULT_D:
14790                 case R6_OPC_CMP_LE_D:
14791                 case R6_OPC_CMP_ULE_D:
14792                 case R6_OPC_CMP_SAF_D:
14793                 case R6_OPC_CMP_SUN_D:
14794                 case R6_OPC_CMP_SEQ_D:
14795                 case R6_OPC_CMP_SEUQ_D:
14796                 case R6_OPC_CMP_SLT_D:
14797                 case R6_OPC_CMP_SULT_D:
14798                 case R6_OPC_CMP_SLE_D:
14799                 case R6_OPC_CMP_SULE_D:
14800                 case R6_OPC_CMP_OR_D:
14801                 case R6_OPC_CMP_UNE_D:
14802                 case R6_OPC_CMP_NE_D:
14803                 case R6_OPC_CMP_SOR_D:
14804                 case R6_OPC_CMP_SUNE_D:
14805                 case R6_OPC_CMP_SNE_D:
14806                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
14807                     break;
14808                 default:
14809                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
14810                                rt, rd, sa, (imm >> 8) & 0x7);
14811 
14812                     break;
14813                 }
14814             } else {
14815                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
14816                            (imm >> 8) & 0x7);
14817             }
14818             break;
14819         }
14820         default:
14821             MIPS_INVAL("cp1");
14822             gen_reserved_instruction(ctx);
14823             break;
14824         }
14825         break;
14826 
14827     /* Compact branches [R6] and COP2 [non-R6] */
14828     case OPC_BC: /* OPC_LWC2 */
14829     case OPC_BALC: /* OPC_SWC2 */
14830         if (ctx->insn_flags & ISA_MIPS_R6) {
14831             /* OPC_BC, OPC_BALC */
14832             gen_compute_compact_branch(ctx, op, 0, 0,
14833                                        sextract32(ctx->opcode << 2, 0, 28));
14834         } else if (ctx->insn_flags & ASE_LEXT) {
14835             gen_loongson_lswc2(ctx, rt, rs, rd);
14836         } else {
14837             /* OPC_LWC2, OPC_SWC2 */
14838             /* COP2: Not implemented. */
14839             generate_exception_err(ctx, EXCP_CpU, 2);
14840         }
14841         break;
14842     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
14843     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
14844         if (ctx->insn_flags & ISA_MIPS_R6) {
14845             if (rs != 0) {
14846                 /* OPC_BEQZC, OPC_BNEZC */
14847                 gen_compute_compact_branch(ctx, op, rs, 0,
14848                                            sextract32(ctx->opcode << 2, 0, 23));
14849             } else {
14850                 /* OPC_JIC, OPC_JIALC */
14851                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
14852             }
14853         } else if (ctx->insn_flags & ASE_LEXT) {
14854             gen_loongson_lsdc2(ctx, rt, rs, rd);
14855         } else {
14856             /* OPC_LWC2, OPC_SWC2 */
14857             /* COP2: Not implemented. */
14858             generate_exception_err(ctx, EXCP_CpU, 2);
14859         }
14860         break;
14861     case OPC_CP2:
14862         check_insn(ctx, ASE_LMMI);
14863         /* Note that these instructions use different fields.  */
14864         gen_loongson_multimedia(ctx, sa, rd, rt);
14865         break;
14866 
14867     case OPC_CP3:
14868         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14869             check_cp1_enabled(ctx);
14870             op1 = MASK_CP3(ctx->opcode);
14871             switch (op1) {
14872             case OPC_LUXC1:
14873             case OPC_SUXC1:
14874                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
14875                 /* Fallthrough */
14876             case OPC_LWXC1:
14877             case OPC_LDXC1:
14878             case OPC_SWXC1:
14879             case OPC_SDXC1:
14880                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14881                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
14882                 break;
14883             case OPC_PREFX:
14884                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14885                 /* Treat as NOP. */
14886                 break;
14887             case OPC_ALNV_PS:
14888                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
14889                 /* Fallthrough */
14890             case OPC_MADD_S:
14891             case OPC_MADD_D:
14892             case OPC_MADD_PS:
14893             case OPC_MSUB_S:
14894             case OPC_MSUB_D:
14895             case OPC_MSUB_PS:
14896             case OPC_NMADD_S:
14897             case OPC_NMADD_D:
14898             case OPC_NMADD_PS:
14899             case OPC_NMSUB_S:
14900             case OPC_NMSUB_D:
14901             case OPC_NMSUB_PS:
14902                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14903                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
14904                 break;
14905             default:
14906                 MIPS_INVAL("cp3");
14907                 gen_reserved_instruction(ctx);
14908                 break;
14909             }
14910         } else {
14911             generate_exception_err(ctx, EXCP_CpU, 1);
14912         }
14913         break;
14914 
14915 #if defined(TARGET_MIPS64)
14916     /* MIPS64 opcodes */
14917     case OPC_LLD:
14918         if (ctx->insn_flags & INSN_R5900) {
14919             check_insn_opc_user_only(ctx, INSN_R5900);
14920         }
14921         /* fall through */
14922     case OPC_LDL:
14923     case OPC_LDR:
14924     case OPC_LWU:
14925     case OPC_LD:
14926         check_insn(ctx, ISA_MIPS3);
14927         check_mips_64(ctx);
14928         gen_ld(ctx, op, rt, rs, imm);
14929         break;
14930     case OPC_SDL:
14931     case OPC_SDR:
14932     case OPC_SD:
14933         check_insn(ctx, ISA_MIPS3);
14934         check_mips_64(ctx);
14935         gen_st(ctx, op, rt, rs, imm);
14936         break;
14937     case OPC_SCD:
14938         check_insn(ctx, ISA_MIPS3);
14939         if (ctx->insn_flags & INSN_R5900) {
14940             check_insn_opc_user_only(ctx, INSN_R5900);
14941         }
14942         check_mips_64(ctx);
14943         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false);
14944         break;
14945     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
14946         if (ctx->insn_flags & ISA_MIPS_R6) {
14947             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
14948             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14949         } else {
14950             /* OPC_DADDI */
14951             check_insn(ctx, ISA_MIPS3);
14952             check_mips_64(ctx);
14953             gen_arith_imm(ctx, op, rt, rs, imm);
14954         }
14955         break;
14956     case OPC_DADDIU:
14957         check_insn(ctx, ISA_MIPS3);
14958         check_mips_64(ctx);
14959         gen_arith_imm(ctx, op, rt, rs, imm);
14960         break;
14961 #else
14962     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
14963         if (ctx->insn_flags & ISA_MIPS_R6) {
14964             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14965         } else {
14966             MIPS_INVAL("major opcode");
14967             gen_reserved_instruction(ctx);
14968         }
14969         break;
14970 #endif
14971     case OPC_DAUI: /* OPC_JALX */
14972         if (ctx->insn_flags & ISA_MIPS_R6) {
14973 #if defined(TARGET_MIPS64)
14974             /* OPC_DAUI */
14975             check_mips_64(ctx);
14976             if (rs == 0) {
14977                 generate_exception(ctx, EXCP_RI);
14978             } else if (rt != 0) {
14979                 TCGv t0 = tcg_temp_new();
14980                 gen_load_gpr(t0, rs);
14981                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
14982             }
14983 #else
14984             gen_reserved_instruction(ctx);
14985             MIPS_INVAL("major opcode");
14986 #endif
14987         } else {
14988             /* OPC_JALX */
14989             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
14990             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14991             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14992         }
14993         break;
14994     case OPC_MDMX:
14995         /* MDMX: Not implemented. */
14996         break;
14997     case OPC_PCREL:
14998         check_insn(ctx, ISA_MIPS_R6);
14999         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15000         break;
15001     default:            /* Invalid */
15002         MIPS_INVAL("major opcode");
15003         return false;
15004     }
15005     return true;
15006 }
15007 
decode_opc(CPUMIPSState * env,DisasContext * ctx)15008 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15009 {
15010     /* make sure instructions are on a word boundary */
15011     if (ctx->base.pc_next & 0x3) {
15012         env->CP0_BadVAddr = ctx->base.pc_next;
15013         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15014         return;
15015     }
15016 
15017     /* Handle blikely not taken case */
15018     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15019         TCGLabel *l1 = gen_new_label();
15020 
15021         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15022         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15023         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15024         gen_set_label(l1);
15025     }
15026 
15027     /* Transition to the auto-generated decoder.  */
15028 
15029     /* Vendor specific extensions */
15030     if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15031         return;
15032     }
15033     if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15034         return;
15035     }
15036     if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) {
15037         return;
15038     }
15039 #if defined(TARGET_MIPS64)
15040     if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
15041         return;
15042     }
15043     if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15044         return;
15045     }
15046 #endif
15047 
15048     /* ISA extensions */
15049     if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15050         return;
15051     }
15052 
15053     /* ISA (from latest to oldest) */
15054     if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15055         return;
15056     }
15057 
15058     if (decode_opc_legacy(env, ctx)) {
15059         return;
15060     }
15061 
15062     gen_reserved_instruction(ctx);
15063 }
15064 
mips_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)15065 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15066 {
15067     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15068     CPUMIPSState *env = cpu_env(cs);
15069 
15070     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15071     ctx->saved_pc = -1;
15072     ctx->insn_flags = env->insn_flags;
15073     ctx->CP0_Config0 = env->CP0_Config0;
15074     ctx->CP0_Config1 = env->CP0_Config1;
15075     ctx->CP0_Config2 = env->CP0_Config2;
15076     ctx->CP0_Config3 = env->CP0_Config3;
15077     ctx->CP0_Config5 = env->CP0_Config5;
15078     ctx->btarget = 0;
15079     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15080     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15081     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15082     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15083     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15084     ctx->PAMask = env->PAMask;
15085     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15086     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15087     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15088     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15089     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15090     /* Restore delay slot state from the tb context.  */
15091     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
15092     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15093     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15094              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15095     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15096     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15097     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15098     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15099     ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15100     ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15101     ctx->crcp = (env->CP0_Config5 >> CP0C5_CRCP) & 1;
15102     restore_cpu_state(env, ctx);
15103 #ifdef CONFIG_USER_ONLY
15104         ctx->mem_idx = MIPS_HFLAG_UM;
15105 #else
15106         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15107 #endif
15108     ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
15109                                   (ctx->insn_flags & (ISA_MIPS_R6 |
15110                                   INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
15111 
15112     /*
15113      * Execute a branch and its delay slot as a single instruction.
15114      * This is what GDB expects and is consistent with what the
15115      * hardware does (e.g. if a delay slot instruction faults, the
15116      * reported PC is the PC of the branch).
15117      */
15118     if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) &&
15119         (ctx->hflags & MIPS_HFLAG_BMASK)) {
15120         ctx->base.max_insns = 2;
15121     }
15122 
15123     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
15124               ctx->hflags);
15125 }
15126 
mips_tr_tb_start(DisasContextBase * dcbase,CPUState * cs)15127 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
15128 {
15129 }
15130 
mips_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)15131 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
15132 {
15133     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15134 
15135     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
15136                        ctx->btarget);
15137 }
15138 
mips_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)15139 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
15140 {
15141     CPUMIPSState *env = cpu_env(cs);
15142     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15143     int insn_bytes;
15144     int is_slot;
15145 
15146     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
15147     if (ctx->insn_flags & ISA_NANOMIPS32) {
15148         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15149         insn_bytes = decode_isa_nanomips(env, ctx);
15150     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
15151         ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
15152         insn_bytes = 4;
15153         decode_opc(env, ctx);
15154     } else if (ctx->insn_flags & ASE_MICROMIPS) {
15155         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15156         insn_bytes = decode_isa_micromips(env, ctx);
15157     } else if (ctx->insn_flags & ASE_MIPS16) {
15158         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15159         insn_bytes = decode_ase_mips16e(env, ctx);
15160     } else {
15161         gen_reserved_instruction(ctx);
15162         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
15163         return;
15164     }
15165 
15166     if (ctx->hflags & MIPS_HFLAG_BMASK) {
15167         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
15168                              MIPS_HFLAG_FBNSLOT))) {
15169             /*
15170              * Force to generate branch as there is neither delay nor
15171              * forbidden slot.
15172              */
15173             is_slot = 1;
15174         }
15175         if ((ctx->hflags & MIPS_HFLAG_M16) &&
15176             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
15177             /*
15178              * Force to generate branch as microMIPS R6 doesn't restrict
15179              * branches in the forbidden slot.
15180              */
15181             is_slot = 1;
15182         }
15183     }
15184     if (is_slot) {
15185         gen_branch(ctx, insn_bytes);
15186     }
15187     if (ctx->base.is_jmp == DISAS_SEMIHOST) {
15188         generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
15189     }
15190     ctx->base.pc_next += insn_bytes;
15191 
15192     if (ctx->base.is_jmp != DISAS_NEXT) {
15193         return;
15194     }
15195 
15196     /*
15197      * End the TB on (most) page crossings.
15198      * See mips_tr_init_disas_context about single-stepping a branch
15199      * together with its delay slot.
15200      */
15201     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
15202         && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) {
15203         ctx->base.is_jmp = DISAS_TOO_MANY;
15204     }
15205 }
15206 
mips_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)15207 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
15208 {
15209     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15210 
15211     switch (ctx->base.is_jmp) {
15212     case DISAS_STOP:
15213         gen_save_pc(ctx->base.pc_next);
15214         tcg_gen_lookup_and_goto_ptr();
15215         break;
15216     case DISAS_NEXT:
15217     case DISAS_TOO_MANY:
15218         save_cpu_state(ctx, 0);
15219         gen_goto_tb(ctx, 0, ctx->base.pc_next);
15220         break;
15221     case DISAS_EXIT:
15222         tcg_gen_exit_tb(NULL, 0);
15223         break;
15224     case DISAS_NORETURN:
15225         break;
15226     default:
15227         g_assert_not_reached();
15228     }
15229 }
15230 
15231 static const TranslatorOps mips_tr_ops = {
15232     .init_disas_context = mips_tr_init_disas_context,
15233     .tb_start           = mips_tr_tb_start,
15234     .insn_start         = mips_tr_insn_start,
15235     .translate_insn     = mips_tr_translate_insn,
15236     .tb_stop            = mips_tr_tb_stop,
15237 };
15238 
mips_translate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)15239 void mips_translate_code(CPUState *cs, TranslationBlock *tb,
15240                          int *max_insns, vaddr pc, void *host_pc)
15241 {
15242     DisasContext ctx;
15243 
15244     translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
15245 }
15246 
mips_tcg_init(void)15247 void mips_tcg_init(void)
15248 {
15249     cpu_gpr[0] = NULL;
15250     for (unsigned i = 1; i < 32; i++)
15251         cpu_gpr[i] = tcg_global_mem_new(tcg_env,
15252                                         offsetof(CPUMIPSState,
15253                                                  active_tc.gpr[i]),
15254                                         regnames[i]);
15255 #if defined(TARGET_MIPS64)
15256     cpu_gpr_hi[0] = NULL;
15257 
15258     for (unsigned i = 1; i < 32; i++) {
15259         g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
15260 
15261         cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env,
15262                                                offsetof(CPUMIPSState,
15263                                                         active_tc.gpr_hi[i]),
15264                                                rname);
15265     }
15266 #endif /* !TARGET_MIPS64 */
15267     for (unsigned i = 0; i < 32; i++) {
15268         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
15269 
15270         fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]);
15271     }
15272     msa_translate_init();
15273     cpu_PC = tcg_global_mem_new(tcg_env,
15274                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
15275     for (unsigned i = 0; i < MIPS_DSP_ACC; i++) {
15276         cpu_HI[i] = tcg_global_mem_new(tcg_env,
15277                                        offsetof(CPUMIPSState, active_tc.HI[i]),
15278                                        regnames_HI[i]);
15279         cpu_LO[i] = tcg_global_mem_new(tcg_env,
15280                                        offsetof(CPUMIPSState, active_tc.LO[i]),
15281                                        regnames_LO[i]);
15282     }
15283     cpu_dspctrl = tcg_global_mem_new(tcg_env,
15284                                      offsetof(CPUMIPSState,
15285                                               active_tc.DSPControl),
15286                                      "DSPControl");
15287     bcond = tcg_global_mem_new(tcg_env,
15288                                offsetof(CPUMIPSState, bcond), "bcond");
15289     btarget = tcg_global_mem_new(tcg_env,
15290                                  offsetof(CPUMIPSState, btarget), "btarget");
15291     hflags = tcg_global_mem_new_i32(tcg_env,
15292                                     offsetof(CPUMIPSState, hflags), "hflags");
15293 
15294     fpu_fcr0 = tcg_global_mem_new_i32(tcg_env,
15295                                       offsetof(CPUMIPSState, active_fpu.fcr0),
15296                                       "fcr0");
15297     fpu_fcr31 = tcg_global_mem_new_i32(tcg_env,
15298                                        offsetof(CPUMIPSState, active_fpu.fcr31),
15299                                        "fcr31");
15300     cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr),
15301                                     "lladdr");
15302     cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval),
15303                                    "llval");
15304 
15305     if (TARGET_LONG_BITS == 32) {
15306         mxu_translate_init();
15307     }
15308 }
15309 
mips_restore_state_to_opc(CPUState * cs,const TranslationBlock * tb,const uint64_t * data)15310 void mips_restore_state_to_opc(CPUState *cs,
15311                                const TranslationBlock *tb,
15312                                const uint64_t *data)
15313 {
15314     CPUMIPSState *env = cpu_env(cs);
15315 
15316     env->active_tc.PC = data[0];
15317     env->hflags &= ~MIPS_HFLAG_BMASK;
15318     env->hflags |= data[1];
15319     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15320     case MIPS_HFLAG_BR:
15321         break;
15322     case MIPS_HFLAG_BC:
15323     case MIPS_HFLAG_BL:
15324     case MIPS_HFLAG_B:
15325         env->btarget = data[2];
15326         break;
15327     }
15328 }
15329