xref: /qemu/target/mips/tcg/translate.c (revision 9c2ff9cdc9b33472333e9431cbf4417f5f228883)
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 
pc_relative_pc(DisasContext * ctx)1960 static target_ulong pc_relative_pc(DisasContext *ctx)
1961 {
1962     target_ulong pc = ctx->base.pc_next;
1963 
1964     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1965         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1966 
1967         pc -= branch_bytes;
1968     }
1969 
1970     pc &= ~(target_ulong)3;
1971     return pc;
1972 }
1973 
1974 /* LWL or LDL, depending on MemOp. */
gen_lxl(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)1975 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr,
1976                      int mem_idx, MemOp mop)
1977 {
1978     int sizem1 = memop_size(mop) - 1;
1979     TCGv t0 = tcg_temp_new();
1980     TCGv t1 = tcg_temp_new();
1981 
1982     /*
1983      * Do a byte access to possibly trigger a page
1984      * fault with the unaligned address.
1985      */
1986     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
1987     tcg_gen_andi_tl(t1, addr, sizem1);
1988     if (!disas_is_bigendian(ctx)) {
1989         tcg_gen_xori_tl(t1, t1, sizem1);
1990     }
1991     tcg_gen_shli_tl(t1, t1, 3);
1992     tcg_gen_andi_tl(t0, addr, ~sizem1);
1993     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
1994     tcg_gen_shl_tl(t0, t0, t1);
1995     tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1);
1996     tcg_gen_andc_tl(t1, reg, t1);
1997     tcg_gen_or_tl(reg, t0, t1);
1998 }
1999 
2000 /* LWR or LDR, depending on MemOp. */
gen_lxr(DisasContext * ctx,TCGv reg,TCGv addr,int mem_idx,MemOp mop)2001 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr,
2002                      int mem_idx, MemOp mop)
2003 {
2004     int size = memop_size(mop);
2005     int sizem1 = size - 1;
2006     TCGv t0 = tcg_temp_new();
2007     TCGv t1 = tcg_temp_new();
2008 
2009     /*
2010      * Do a byte access to possibly trigger a page
2011      * fault with the unaligned address.
2012      */
2013     tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2014     tcg_gen_andi_tl(t1, addr, sizem1);
2015     if (disas_is_bigendian(ctx)) {
2016         tcg_gen_xori_tl(t1, t1, sizem1);
2017     }
2018     tcg_gen_shli_tl(t1, t1, 3);
2019     tcg_gen_andi_tl(t0, addr, ~sizem1);
2020     tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2021     tcg_gen_shr_tl(t0, t0, t1);
2022     tcg_gen_xori_tl(t1, t1, size * 8 - 1);
2023     tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1);
2024     tcg_gen_and_tl(t1, reg, t1);
2025     tcg_gen_or_tl(reg, t0, t1);
2026 }
2027 
2028 /* Load */
gen_ld(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2029 static void gen_ld(DisasContext *ctx, uint32_t opc,
2030                    int rt, int base, int offset)
2031 {
2032     TCGv t0, t1;
2033     int mem_idx = ctx->mem_idx;
2034 
2035     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2036                                       INSN_LOONGSON3A)) {
2037         /*
2038          * Loongson CPU uses a load to zero register for prefetch.
2039          * We emulate it as a NOP. On other CPU we must perform the
2040          * actual memory access.
2041          */
2042         return;
2043     }
2044 
2045     t0 = tcg_temp_new();
2046     gen_base_offset_addr(ctx, t0, base, offset);
2047 
2048     switch (opc) {
2049 #if defined(TARGET_MIPS64)
2050     case OPC_LWU:
2051         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL |
2052                            ctx->default_tcg_memop_mask);
2053         gen_store_gpr(t0, rt);
2054         break;
2055     case OPC_LD:
2056         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2057                            ctx->default_tcg_memop_mask);
2058         gen_store_gpr(t0, rt);
2059         break;
2060     case OPC_LLD:
2061     case R6_OPC_LLD:
2062         op_ld_lld(t0, t0, mem_idx, ctx);
2063         gen_store_gpr(t0, rt);
2064         break;
2065     case OPC_LDL:
2066         t1 = tcg_temp_new();
2067         gen_load_gpr(t1, rt);
2068         gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2069         gen_store_gpr(t1, rt);
2070         break;
2071     case OPC_LDR:
2072         t1 = tcg_temp_new();
2073         gen_load_gpr(t1, rt);
2074         gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2075         gen_store_gpr(t1, rt);
2076         break;
2077     case OPC_LDPC:
2078         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2079         gen_op_addr_add(ctx, t0, t0, t1);
2080         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2081         gen_store_gpr(t0, rt);
2082         break;
2083 #endif
2084     case OPC_LWPC:
2085         t1 = tcg_constant_tl(pc_relative_pc(ctx));
2086         gen_op_addr_add(ctx, t0, t0, t1);
2087         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL);
2088         gen_store_gpr(t0, rt);
2089         break;
2090     case OPC_LWE:
2091         mem_idx = MIPS_HFLAG_UM;
2092         /* fall through */
2093     case OPC_LW:
2094         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL |
2095                            ctx->default_tcg_memop_mask);
2096         gen_store_gpr(t0, rt);
2097         break;
2098     case OPC_LHE:
2099         mem_idx = MIPS_HFLAG_UM;
2100         /* fall through */
2101     case OPC_LH:
2102         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW |
2103                            ctx->default_tcg_memop_mask);
2104         gen_store_gpr(t0, rt);
2105         break;
2106     case OPC_LHUE:
2107         mem_idx = MIPS_HFLAG_UM;
2108         /* fall through */
2109     case OPC_LHU:
2110         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW |
2111                            ctx->default_tcg_memop_mask);
2112         gen_store_gpr(t0, rt);
2113         break;
2114     case OPC_LBE:
2115         mem_idx = MIPS_HFLAG_UM;
2116         /* fall through */
2117     case OPC_LB:
2118         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2119         gen_store_gpr(t0, rt);
2120         break;
2121     case OPC_LBUE:
2122         mem_idx = MIPS_HFLAG_UM;
2123         /* fall through */
2124     case OPC_LBU:
2125         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2126         gen_store_gpr(t0, rt);
2127         break;
2128     case OPC_LWLE:
2129         mem_idx = MIPS_HFLAG_UM;
2130         /* fall through */
2131     case OPC_LWL:
2132         t1 = tcg_temp_new();
2133         gen_load_gpr(t1, rt);
2134         gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2135         tcg_gen_ext32s_tl(t1, t1);
2136         gen_store_gpr(t1, rt);
2137         break;
2138     case OPC_LWRE:
2139         mem_idx = MIPS_HFLAG_UM;
2140         /* fall through */
2141     case OPC_LWR:
2142         t1 = tcg_temp_new();
2143         gen_load_gpr(t1, rt);
2144         gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2145         tcg_gen_ext32s_tl(t1, t1);
2146         gen_store_gpr(t1, rt);
2147         break;
2148     case OPC_LLE:
2149         mem_idx = MIPS_HFLAG_UM;
2150         /* fall through */
2151     case OPC_LL:
2152     case R6_OPC_LL:
2153         op_ld_ll(t0, t0, mem_idx, ctx);
2154         gen_store_gpr(t0, rt);
2155         break;
2156     }
2157 }
2158 
2159 /* Store */
gen_st(DisasContext * ctx,uint32_t opc,int rt,int base,int offset)2160 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2161                    int base, int offset)
2162 {
2163     TCGv t0 = tcg_temp_new();
2164     TCGv t1 = tcg_temp_new();
2165     int mem_idx = ctx->mem_idx;
2166 
2167     gen_base_offset_addr(ctx, t0, base, offset);
2168     gen_load_gpr(t1, rt);
2169     switch (opc) {
2170 #if defined(TARGET_MIPS64)
2171     case OPC_SD:
2172         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2173                            ctx->default_tcg_memop_mask);
2174         break;
2175     case OPC_SDL:
2176         gen_helper_0e2i(sdl, t1, t0, mem_idx);
2177         break;
2178     case OPC_SDR:
2179         gen_helper_0e2i(sdr, t1, t0, mem_idx);
2180         break;
2181 #endif
2182     case OPC_SWE:
2183         mem_idx = MIPS_HFLAG_UM;
2184         /* fall through */
2185     case OPC_SW:
2186         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL |
2187                            ctx->default_tcg_memop_mask);
2188         break;
2189     case OPC_SHE:
2190         mem_idx = MIPS_HFLAG_UM;
2191         /* fall through */
2192     case OPC_SH:
2193         tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW |
2194                            ctx->default_tcg_memop_mask);
2195         break;
2196     case OPC_SBE:
2197         mem_idx = MIPS_HFLAG_UM;
2198         /* fall through */
2199     case OPC_SB:
2200         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2201         break;
2202     case OPC_SWLE:
2203         mem_idx = MIPS_HFLAG_UM;
2204         /* fall through */
2205     case OPC_SWL:
2206         gen_helper_0e2i(swl, t1, t0, mem_idx);
2207         break;
2208     case OPC_SWRE:
2209         mem_idx = MIPS_HFLAG_UM;
2210         /* fall through */
2211     case OPC_SWR:
2212         gen_helper_0e2i(swr, t1, t0, mem_idx);
2213         break;
2214     }
2215 }
2216 
2217 
2218 /* Store conditional */
gen_st_cond(DisasContext * ctx,int rt,int base,int offset,MemOp tcg_mo,bool eva)2219 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2220                         MemOp tcg_mo, bool eva)
2221 {
2222     TCGv addr, t0, val;
2223     TCGLabel *l1 = gen_new_label();
2224     TCGLabel *done = gen_new_label();
2225 
2226     t0 = tcg_temp_new();
2227     addr = tcg_temp_new();
2228     /* compare the address against that of the preceding LL */
2229     gen_base_offset_addr(ctx, addr, base, offset);
2230     tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2231     gen_store_gpr(tcg_constant_tl(0), rt);
2232     tcg_gen_br(done);
2233 
2234     gen_set_label(l1);
2235     /* generate cmpxchg */
2236     val = tcg_temp_new();
2237     gen_load_gpr(val, rt);
2238     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2239                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2240     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2241     gen_store_gpr(t0, rt);
2242 
2243     gen_set_label(done);
2244 }
2245 
2246 /* Load and store */
gen_flt_ldst(DisasContext * ctx,uint32_t opc,int ft,TCGv t0)2247 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2248                          TCGv t0)
2249 {
2250     /*
2251      * Don't do NOP if destination is zero: we must perform the actual
2252      * memory access.
2253      */
2254     switch (opc) {
2255     case OPC_LWC1:
2256         {
2257             TCGv_i32 fp0 = tcg_temp_new_i32();
2258             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
2259                                 ctx->default_tcg_memop_mask);
2260             gen_store_fpr32(ctx, fp0, ft);
2261         }
2262         break;
2263     case OPC_SWC1:
2264         {
2265             TCGv_i32 fp0 = tcg_temp_new_i32();
2266             gen_load_fpr32(ctx, fp0, ft);
2267             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
2268                                 ctx->default_tcg_memop_mask);
2269         }
2270         break;
2271     case OPC_LDC1:
2272         {
2273             TCGv_i64 fp0 = tcg_temp_new_i64();
2274             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2275                                 ctx->default_tcg_memop_mask);
2276             gen_store_fpr64(ctx, fp0, ft);
2277         }
2278         break;
2279     case OPC_SDC1:
2280         {
2281             TCGv_i64 fp0 = tcg_temp_new_i64();
2282             gen_load_fpr64(ctx, fp0, ft);
2283             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2284                                 ctx->default_tcg_memop_mask);
2285         }
2286         break;
2287     default:
2288         MIPS_INVAL("flt_ldst");
2289         gen_reserved_instruction(ctx);
2290         break;
2291     }
2292 }
2293 
gen_cop1_ldst(DisasContext * ctx,uint32_t op,int rt,int rs,int16_t imm)2294 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2295                           int rs, int16_t imm)
2296 {
2297     TCGv t0 = tcg_temp_new();
2298 
2299     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2300         check_cp1_enabled(ctx);
2301         switch (op) {
2302         case OPC_LDC1:
2303         case OPC_SDC1:
2304             check_insn(ctx, ISA_MIPS2);
2305             /* Fallthrough */
2306         default:
2307             gen_base_offset_addr(ctx, t0, rs, imm);
2308             gen_flt_ldst(ctx, op, rt, t0);
2309         }
2310     } else {
2311         generate_exception_err(ctx, EXCP_CpU, 1);
2312     }
2313 }
2314 
2315 /* Arithmetic with immediate operand */
gen_arith_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int imm)2316 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2317                           int rt, int rs, int imm)
2318 {
2319     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2320 
2321     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2322         /*
2323          * If no destination, treat it as a NOP.
2324          * For addi, we must generate the overflow exception when needed.
2325          */
2326         return;
2327     }
2328     switch (opc) {
2329     case OPC_ADDI:
2330         {
2331             TCGv t0 = tcg_temp_new();
2332             TCGv t1 = tcg_temp_new();
2333             TCGv t2 = tcg_temp_new();
2334             TCGLabel *l1 = gen_new_label();
2335 
2336             gen_load_gpr(t1, rs);
2337             tcg_gen_addi_tl(t0, t1, uimm);
2338             tcg_gen_ext32s_tl(t0, t0);
2339 
2340             tcg_gen_xori_tl(t1, t1, ~uimm);
2341             tcg_gen_xori_tl(t2, t0, uimm);
2342             tcg_gen_and_tl(t1, t1, t2);
2343             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2344             /* operands of same sign, result different sign */
2345             generate_exception(ctx, EXCP_OVERFLOW);
2346             gen_set_label(l1);
2347             tcg_gen_ext32s_tl(t0, t0);
2348             gen_store_gpr(t0, rt);
2349         }
2350         break;
2351     case OPC_ADDIU:
2352         if (rs != 0) {
2353             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2354             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2355         } else {
2356             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2357         }
2358         break;
2359 #if defined(TARGET_MIPS64)
2360     case OPC_DADDI:
2361         {
2362             TCGv t0 = tcg_temp_new();
2363             TCGv t1 = tcg_temp_new();
2364             TCGv t2 = tcg_temp_new();
2365             TCGLabel *l1 = gen_new_label();
2366 
2367             gen_load_gpr(t1, rs);
2368             tcg_gen_addi_tl(t0, t1, uimm);
2369 
2370             tcg_gen_xori_tl(t1, t1, ~uimm);
2371             tcg_gen_xori_tl(t2, t0, uimm);
2372             tcg_gen_and_tl(t1, t1, t2);
2373             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2374             /* operands of same sign, result different sign */
2375             generate_exception(ctx, EXCP_OVERFLOW);
2376             gen_set_label(l1);
2377             gen_store_gpr(t0, rt);
2378         }
2379         break;
2380     case OPC_DADDIU:
2381         if (rs != 0) {
2382             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2383         } else {
2384             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2385         }
2386         break;
2387 #endif
2388     }
2389 }
2390 
2391 /* Logic with immediate operand */
gen_logic_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2392 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2393                           int rt, int rs, int16_t imm)
2394 {
2395     target_ulong uimm;
2396 
2397     if (rt == 0) {
2398         /* If no destination, treat it as a NOP. */
2399         return;
2400     }
2401     uimm = (uint16_t)imm;
2402     switch (opc) {
2403     case OPC_ANDI:
2404         if (likely(rs != 0)) {
2405             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2406         } else {
2407             tcg_gen_movi_tl(cpu_gpr[rt], 0);
2408         }
2409         break;
2410     case OPC_ORI:
2411         if (rs != 0) {
2412             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2413         } else {
2414             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2415         }
2416         break;
2417     case OPC_XORI:
2418         if (likely(rs != 0)) {
2419             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2420         } else {
2421             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2422         }
2423         break;
2424     case OPC_LUI:
2425         if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2426             /* OPC_AUI */
2427             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2428             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2429         } else {
2430             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2431         }
2432         break;
2433 
2434     default:
2435         break;
2436     }
2437 }
2438 
2439 /* Set on less than with immediate operand */
gen_slt_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2440 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2441                         int rt, int rs, int16_t imm)
2442 {
2443     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2444     TCGv t0;
2445 
2446     if (rt == 0) {
2447         /* If no destination, treat it as a NOP. */
2448         return;
2449     }
2450     t0 = tcg_temp_new();
2451     gen_load_gpr(t0, rs);
2452     switch (opc) {
2453     case OPC_SLTI:
2454         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2455         break;
2456     case OPC_SLTIU:
2457         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2458         break;
2459     }
2460 }
2461 
2462 /* Shifts with immediate operand */
gen_shift_imm(DisasContext * ctx,uint32_t opc,int rt,int rs,int16_t imm)2463 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2464                           int rt, int rs, int16_t imm)
2465 {
2466     target_ulong uimm = ((uint16_t)imm) & 0x1f;
2467     TCGv t0;
2468 
2469     if (rt == 0) {
2470         /* If no destination, treat it as a NOP. */
2471         return;
2472     }
2473 
2474     t0 = tcg_temp_new();
2475     gen_load_gpr(t0, rs);
2476     switch (opc) {
2477     case OPC_SLL:
2478         tcg_gen_shli_tl(t0, t0, uimm);
2479         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2480         break;
2481     case OPC_SRA:
2482         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2483         break;
2484     case OPC_SRL:
2485         if (uimm != 0) {
2486             tcg_gen_ext32u_tl(t0, t0);
2487             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2488         } else {
2489             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2490         }
2491         break;
2492     case OPC_ROTR:
2493         if (uimm != 0) {
2494             TCGv_i32 t1 = tcg_temp_new_i32();
2495 
2496             tcg_gen_trunc_tl_i32(t1, t0);
2497             tcg_gen_rotri_i32(t1, t1, uimm);
2498             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2499         } else {
2500             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2501         }
2502         break;
2503 #if defined(TARGET_MIPS64)
2504     case OPC_DSLL:
2505         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2506         break;
2507     case OPC_DSRA:
2508         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2509         break;
2510     case OPC_DSRL:
2511         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2512         break;
2513     case OPC_DROTR:
2514         if (uimm != 0) {
2515             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2516         } else {
2517             tcg_gen_mov_tl(cpu_gpr[rt], t0);
2518         }
2519         break;
2520     case OPC_DSLL32:
2521         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2522         break;
2523     case OPC_DSRA32:
2524         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2525         break;
2526     case OPC_DSRL32:
2527         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2528         break;
2529     case OPC_DROTR32:
2530         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2531         break;
2532 #endif
2533     }
2534 }
2535 
2536 /* Arithmetic */
gen_arith(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2537 static void gen_arith(DisasContext *ctx, uint32_t opc,
2538                       int rd, int rs, int rt)
2539 {
2540     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2541        && opc != OPC_DADD && opc != OPC_DSUB) {
2542         /*
2543          * If no destination, treat it as a NOP.
2544          * For add & sub, we must generate the overflow exception when needed.
2545          */
2546         return;
2547     }
2548 
2549     switch (opc) {
2550     case OPC_ADD:
2551         {
2552             TCGv t0 = tcg_temp_new();
2553             TCGv t1 = tcg_temp_new();
2554             TCGv t2 = tcg_temp_new();
2555             TCGLabel *l1 = gen_new_label();
2556 
2557             gen_load_gpr(t1, rs);
2558             gen_load_gpr(t2, rt);
2559             tcg_gen_add_tl(t0, t1, t2);
2560             tcg_gen_ext32s_tl(t0, t0);
2561             tcg_gen_xor_tl(t1, t1, t2);
2562             tcg_gen_xor_tl(t2, t0, t2);
2563             tcg_gen_andc_tl(t1, t2, t1);
2564             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2565             /* operands of same sign, result different sign */
2566             generate_exception(ctx, EXCP_OVERFLOW);
2567             gen_set_label(l1);
2568             gen_store_gpr(t0, rd);
2569         }
2570         break;
2571     case OPC_ADDU:
2572         if (rs != 0 && rt != 0) {
2573             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2574             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2575         } else if (rs == 0 && rt != 0) {
2576             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2577         } else if (rs != 0 && rt == 0) {
2578             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2579         } else {
2580             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2581         }
2582         break;
2583     case OPC_SUB:
2584         {
2585             TCGv t0 = tcg_temp_new();
2586             TCGv t1 = tcg_temp_new();
2587             TCGv t2 = tcg_temp_new();
2588             TCGLabel *l1 = gen_new_label();
2589 
2590             gen_load_gpr(t1, rs);
2591             gen_load_gpr(t2, rt);
2592             tcg_gen_sub_tl(t0, t1, t2);
2593             tcg_gen_ext32s_tl(t0, t0);
2594             tcg_gen_xor_tl(t2, t1, t2);
2595             tcg_gen_xor_tl(t1, t0, t1);
2596             tcg_gen_and_tl(t1, t1, t2);
2597             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2598             /*
2599              * operands of different sign, first operand and the result
2600              * of different sign
2601              */
2602             generate_exception(ctx, EXCP_OVERFLOW);
2603             gen_set_label(l1);
2604             gen_store_gpr(t0, rd);
2605         }
2606         break;
2607     case OPC_SUBU:
2608         if (rs != 0 && rt != 0) {
2609             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2610             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2611         } else if (rs == 0 && rt != 0) {
2612             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2613             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2614         } else if (rs != 0 && rt == 0) {
2615             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2616         } else {
2617             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2618         }
2619         break;
2620 #if defined(TARGET_MIPS64)
2621     case OPC_DADD:
2622         {
2623             TCGv t0 = tcg_temp_new();
2624             TCGv t1 = tcg_temp_new();
2625             TCGv t2 = tcg_temp_new();
2626             TCGLabel *l1 = gen_new_label();
2627 
2628             gen_load_gpr(t1, rs);
2629             gen_load_gpr(t2, rt);
2630             tcg_gen_add_tl(t0, t1, t2);
2631             tcg_gen_xor_tl(t1, t1, t2);
2632             tcg_gen_xor_tl(t2, t0, t2);
2633             tcg_gen_andc_tl(t1, t2, t1);
2634             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2635             /* operands of same sign, result different sign */
2636             generate_exception(ctx, EXCP_OVERFLOW);
2637             gen_set_label(l1);
2638             gen_store_gpr(t0, rd);
2639         }
2640         break;
2641     case OPC_DADDU:
2642         if (rs != 0 && rt != 0) {
2643             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2644         } else if (rs == 0 && rt != 0) {
2645             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2646         } else if (rs != 0 && rt == 0) {
2647             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2648         } else {
2649             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2650         }
2651         break;
2652     case OPC_DSUB:
2653         {
2654             TCGv t0 = tcg_temp_new();
2655             TCGv t1 = tcg_temp_new();
2656             TCGv t2 = tcg_temp_new();
2657             TCGLabel *l1 = gen_new_label();
2658 
2659             gen_load_gpr(t1, rs);
2660             gen_load_gpr(t2, rt);
2661             tcg_gen_sub_tl(t0, t1, t2);
2662             tcg_gen_xor_tl(t2, t1, t2);
2663             tcg_gen_xor_tl(t1, t0, t1);
2664             tcg_gen_and_tl(t1, t1, t2);
2665             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2666             /*
2667              * Operands of different sign, first operand and result different
2668              * sign.
2669              */
2670             generate_exception(ctx, EXCP_OVERFLOW);
2671             gen_set_label(l1);
2672             gen_store_gpr(t0, rd);
2673         }
2674         break;
2675     case OPC_DSUBU:
2676         if (rs != 0 && rt != 0) {
2677             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2678         } else if (rs == 0 && rt != 0) {
2679             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2680         } else if (rs != 0 && rt == 0) {
2681             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2682         } else {
2683             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2684         }
2685         break;
2686 #endif
2687     case OPC_MUL:
2688         if (likely(rs != 0 && rt != 0)) {
2689             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2690             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2691         } else {
2692             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2693         }
2694         break;
2695     }
2696 }
2697 
2698 /* Conditional move */
gen_cond_move(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2699 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2700                           int rd, int rs, int rt)
2701 {
2702     TCGv t0, t1, t2;
2703 
2704     if (rd == 0) {
2705         /* If no destination, treat it as a NOP. */
2706         return;
2707     }
2708 
2709     t0 = tcg_temp_new();
2710     gen_load_gpr(t0, rt);
2711     t1 = tcg_constant_tl(0);
2712     t2 = tcg_temp_new();
2713     gen_load_gpr(t2, rs);
2714     switch (opc) {
2715     case OPC_MOVN:
2716         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2717         break;
2718     case OPC_MOVZ:
2719         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2720         break;
2721     case OPC_SELNEZ:
2722         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2723         break;
2724     case OPC_SELEQZ:
2725         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2726         break;
2727     }
2728 }
2729 
2730 /* Logic */
gen_logic(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2731 static void gen_logic(DisasContext *ctx, uint32_t opc,
2732                       int rd, int rs, int rt)
2733 {
2734     if (rd == 0) {
2735         /* If no destination, treat it as a NOP. */
2736         return;
2737     }
2738 
2739     switch (opc) {
2740     case OPC_AND:
2741         if (likely(rs != 0 && rt != 0)) {
2742             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2743         } else {
2744             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2745         }
2746         break;
2747     case OPC_NOR:
2748         if (rs != 0 && rt != 0) {
2749             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2750         } else if (rs == 0 && rt != 0) {
2751             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2752         } else if (rs != 0 && rt == 0) {
2753             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2754         } else {
2755             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2756         }
2757         break;
2758     case OPC_OR:
2759         if (likely(rs != 0 && rt != 0)) {
2760             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2761         } else if (rs == 0 && rt != 0) {
2762             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2763         } else if (rs != 0 && rt == 0) {
2764             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2765         } else {
2766             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2767         }
2768         break;
2769     case OPC_XOR:
2770         if (likely(rs != 0 && rt != 0)) {
2771             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2772         } else if (rs == 0 && rt != 0) {
2773             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2774         } else if (rs != 0 && rt == 0) {
2775             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2776         } else {
2777             tcg_gen_movi_tl(cpu_gpr[rd], 0);
2778         }
2779         break;
2780     }
2781 }
2782 
2783 /* Set on lower than */
gen_slt(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2784 static void gen_slt(DisasContext *ctx, uint32_t opc,
2785                     int rd, int rs, int rt)
2786 {
2787     TCGv t0, t1;
2788 
2789     if (rd == 0) {
2790         /* If no destination, treat it as a NOP. */
2791         return;
2792     }
2793 
2794     t0 = tcg_temp_new();
2795     t1 = tcg_temp_new();
2796     gen_load_gpr(t0, rs);
2797     gen_load_gpr(t1, rt);
2798     switch (opc) {
2799     case OPC_SLT:
2800         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2801         break;
2802     case OPC_SLTU:
2803         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2804         break;
2805     }
2806 }
2807 
2808 /* Shifts */
gen_shift(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)2809 static void gen_shift(DisasContext *ctx, uint32_t opc,
2810                       int rd, int rs, int rt)
2811 {
2812     TCGv t0, t1;
2813 
2814     if (rd == 0) {
2815         /*
2816          * If no destination, treat it as a NOP.
2817          * For add & sub, we must generate the overflow exception when needed.
2818          */
2819         return;
2820     }
2821 
2822     t0 = tcg_temp_new();
2823     t1 = tcg_temp_new();
2824     gen_load_gpr(t0, rs);
2825     gen_load_gpr(t1, rt);
2826     switch (opc) {
2827     case OPC_SLLV:
2828         tcg_gen_andi_tl(t0, t0, 0x1f);
2829         tcg_gen_shl_tl(t0, t1, t0);
2830         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2831         break;
2832     case OPC_SRAV:
2833         tcg_gen_andi_tl(t0, t0, 0x1f);
2834         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2835         break;
2836     case OPC_SRLV:
2837         tcg_gen_ext32u_tl(t1, t1);
2838         tcg_gen_andi_tl(t0, t0, 0x1f);
2839         tcg_gen_shr_tl(t0, t1, t0);
2840         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2841         break;
2842     case OPC_ROTRV:
2843         {
2844             TCGv_i32 t2 = tcg_temp_new_i32();
2845             TCGv_i32 t3 = tcg_temp_new_i32();
2846 
2847             tcg_gen_trunc_tl_i32(t2, t0);
2848             tcg_gen_trunc_tl_i32(t3, t1);
2849             tcg_gen_andi_i32(t2, t2, 0x1f);
2850             tcg_gen_rotr_i32(t2, t3, t2);
2851             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2852         }
2853         break;
2854 #if defined(TARGET_MIPS64)
2855     case OPC_DSLLV:
2856         tcg_gen_andi_tl(t0, t0, 0x3f);
2857         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2858         break;
2859     case OPC_DSRAV:
2860         tcg_gen_andi_tl(t0, t0, 0x3f);
2861         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2862         break;
2863     case OPC_DSRLV:
2864         tcg_gen_andi_tl(t0, t0, 0x3f);
2865         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2866         break;
2867     case OPC_DROTRV:
2868         tcg_gen_andi_tl(t0, t0, 0x3f);
2869         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2870         break;
2871 #endif
2872     }
2873 }
2874 
2875 /* Arithmetic on HI/LO registers */
gen_HILO(DisasContext * ctx,uint32_t opc,int acc,int reg)2876 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2877 {
2878     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2879         /* Treat as NOP. */
2880         return;
2881     }
2882 
2883     if (acc != 0) {
2884         check_dsp(ctx);
2885     }
2886 
2887     switch (opc) {
2888     case OPC_MFHI:
2889 #if defined(TARGET_MIPS64)
2890         if (acc != 0) {
2891             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2892         } else
2893 #endif
2894         {
2895             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2896         }
2897         break;
2898     case OPC_MFLO:
2899 #if defined(TARGET_MIPS64)
2900         if (acc != 0) {
2901             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2902         } else
2903 #endif
2904         {
2905             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2906         }
2907         break;
2908     case OPC_MTHI:
2909         if (reg != 0) {
2910 #if defined(TARGET_MIPS64)
2911             if (acc != 0) {
2912                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2913             } else
2914 #endif
2915             {
2916                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2917             }
2918         } else {
2919             tcg_gen_movi_tl(cpu_HI[acc], 0);
2920         }
2921         break;
2922     case OPC_MTLO:
2923         if (reg != 0) {
2924 #if defined(TARGET_MIPS64)
2925             if (acc != 0) {
2926                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2927             } else
2928 #endif
2929             {
2930                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2931             }
2932         } else {
2933             tcg_gen_movi_tl(cpu_LO[acc], 0);
2934         }
2935         break;
2936     }
2937 }
2938 
gen_r6_ld(target_long addr,int reg,int memidx,MemOp memop)2939 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2940                              MemOp memop)
2941 {
2942     TCGv t0 = tcg_temp_new();
2943     tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop);
2944     gen_store_gpr(t0, reg);
2945 }
2946 
gen_pcrel(DisasContext * ctx,int opc,target_ulong pc,int rs)2947 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
2948                              int rs)
2949 {
2950     target_long offset;
2951     target_long addr;
2952 
2953     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
2954     case OPC_ADDIUPC:
2955         if (rs != 0) {
2956             offset = sextract32(ctx->opcode << 2, 0, 21);
2957             addr = addr_add(ctx, pc, offset);
2958             tcg_gen_movi_tl(cpu_gpr[rs], addr);
2959         }
2960         break;
2961     case R6_OPC_LWPC:
2962         offset = sextract32(ctx->opcode << 2, 0, 21);
2963         addr = addr_add(ctx, pc, offset);
2964         gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL);
2965         break;
2966 #if defined(TARGET_MIPS64)
2967     case OPC_LWUPC:
2968         check_mips_64(ctx);
2969         offset = sextract32(ctx->opcode << 2, 0, 21);
2970         addr = addr_add(ctx, pc, offset);
2971         gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL);
2972         break;
2973 #endif
2974     default:
2975         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
2976         case OPC_AUIPC:
2977             if (rs != 0) {
2978                 offset = sextract32(ctx->opcode, 0, 16) << 16;
2979                 addr = addr_add(ctx, pc, offset);
2980                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2981             }
2982             break;
2983         case OPC_ALUIPC:
2984             if (rs != 0) {
2985                 offset = sextract32(ctx->opcode, 0, 16) << 16;
2986                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
2987                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2988             }
2989             break;
2990 #if defined(TARGET_MIPS64)
2991         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
2992         case R6_OPC_LDPC + (1 << 16):
2993         case R6_OPC_LDPC + (2 << 16):
2994         case R6_OPC_LDPC + (3 << 16):
2995             check_mips_64(ctx);
2996             offset = sextract32(ctx->opcode << 3, 0, 21);
2997             addr = addr_add(ctx, (pc & ~0x7), offset);
2998             gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
2999             break;
3000 #endif
3001         default:
3002             MIPS_INVAL("OPC_PCREL");
3003             gen_reserved_instruction(ctx);
3004             break;
3005         }
3006         break;
3007     }
3008 }
3009 
gen_r6_muldiv(DisasContext * ctx,int opc,int rd,int rs,int rt)3010 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3011 {
3012     TCGv t0, t1;
3013 
3014     if (rd == 0) {
3015         /* Treat as NOP. */
3016         return;
3017     }
3018 
3019     t0 = tcg_temp_new();
3020     t1 = tcg_temp_new();
3021 
3022     gen_load_gpr(t0, rs);
3023     gen_load_gpr(t1, rt);
3024 
3025     switch (opc) {
3026     case R6_OPC_DIV:
3027         {
3028             TCGv t2 = tcg_temp_new();
3029             TCGv t3 = tcg_temp_new();
3030             tcg_gen_ext32s_tl(t0, t0);
3031             tcg_gen_ext32s_tl(t1, t1);
3032             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3033             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3034             tcg_gen_and_tl(t2, t2, t3);
3035             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3036             tcg_gen_or_tl(t2, t2, t3);
3037             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3038             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3039             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3040         }
3041         break;
3042     case R6_OPC_MOD:
3043         {
3044             TCGv t2 = tcg_temp_new();
3045             TCGv t3 = tcg_temp_new();
3046             tcg_gen_ext32s_tl(t0, t0);
3047             tcg_gen_ext32s_tl(t1, t1);
3048             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3049             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3050             tcg_gen_and_tl(t2, t2, t3);
3051             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3052             tcg_gen_or_tl(t2, t2, t3);
3053             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3054             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3055             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3056         }
3057         break;
3058     case R6_OPC_DIVU:
3059         {
3060             tcg_gen_ext32u_tl(t0, t0);
3061             tcg_gen_ext32u_tl(t1, t1);
3062             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3063                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3064             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3065             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3066         }
3067         break;
3068     case R6_OPC_MODU:
3069         {
3070             tcg_gen_ext32u_tl(t0, t0);
3071             tcg_gen_ext32u_tl(t1, t1);
3072             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3073                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3074             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3075             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3076         }
3077         break;
3078     case R6_OPC_MUL:
3079         {
3080             TCGv_i32 t2 = tcg_temp_new_i32();
3081             TCGv_i32 t3 = tcg_temp_new_i32();
3082             tcg_gen_trunc_tl_i32(t2, t0);
3083             tcg_gen_trunc_tl_i32(t3, t1);
3084             tcg_gen_mul_i32(t2, t2, t3);
3085             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3086         }
3087         break;
3088     case R6_OPC_MUH:
3089         {
3090             TCGv_i32 t2 = tcg_temp_new_i32();
3091             TCGv_i32 t3 = tcg_temp_new_i32();
3092             tcg_gen_trunc_tl_i32(t2, t0);
3093             tcg_gen_trunc_tl_i32(t3, t1);
3094             tcg_gen_muls2_i32(t2, t3, t2, t3);
3095             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3096         }
3097         break;
3098     case R6_OPC_MULU:
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_MUHU:
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_mulu2_i32(t2, t3, t2, t3);
3115             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3116         }
3117         break;
3118 #if defined(TARGET_MIPS64)
3119     case R6_OPC_DDIV:
3120         {
3121             TCGv t2 = tcg_temp_new();
3122             TCGv t3 = tcg_temp_new();
3123             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3124             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3125             tcg_gen_and_tl(t2, t2, t3);
3126             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3127             tcg_gen_or_tl(t2, t2, t3);
3128             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3129             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3130         }
3131         break;
3132     case R6_OPC_DMOD:
3133         {
3134             TCGv t2 = tcg_temp_new();
3135             TCGv t3 = tcg_temp_new();
3136             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3137             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3138             tcg_gen_and_tl(t2, t2, t3);
3139             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3140             tcg_gen_or_tl(t2, t2, t3);
3141             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3142             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3143         }
3144         break;
3145     case R6_OPC_DDIVU:
3146         {
3147             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3148                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3149             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3150         }
3151         break;
3152     case R6_OPC_DMODU:
3153         {
3154             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3155                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3156             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3157         }
3158         break;
3159     case R6_OPC_DMUL:
3160         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3161         break;
3162     case R6_OPC_DMUH:
3163         {
3164             TCGv t2 = tcg_temp_new();
3165             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3166         }
3167         break;
3168     case R6_OPC_DMULU:
3169         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3170         break;
3171     case R6_OPC_DMUHU:
3172         {
3173             TCGv t2 = tcg_temp_new();
3174             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3175         }
3176         break;
3177 #endif
3178     default:
3179         MIPS_INVAL("r6 mul/div");
3180         gen_reserved_instruction(ctx);
3181         break;
3182     }
3183 }
3184 
3185 #if defined(TARGET_MIPS64)
gen_div1_tx79(DisasContext * ctx,uint32_t opc,int rs,int rt)3186 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3187 {
3188     TCGv t0, t1;
3189 
3190     t0 = tcg_temp_new();
3191     t1 = tcg_temp_new();
3192 
3193     gen_load_gpr(t0, rs);
3194     gen_load_gpr(t1, rt);
3195 
3196     switch (opc) {
3197     case MMI_OPC_DIV1:
3198         {
3199             TCGv t2 = tcg_temp_new();
3200             TCGv t3 = tcg_temp_new();
3201             tcg_gen_ext32s_tl(t0, t0);
3202             tcg_gen_ext32s_tl(t1, t1);
3203             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3204             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3205             tcg_gen_and_tl(t2, t2, t3);
3206             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3207             tcg_gen_or_tl(t2, t2, t3);
3208             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3209             tcg_gen_div_tl(cpu_LO[1], t0, t1);
3210             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3211             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3212             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3213         }
3214         break;
3215     case MMI_OPC_DIVU1:
3216         {
3217             TCGv t2 = tcg_constant_tl(0);
3218             TCGv t3 = tcg_constant_tl(1);
3219             tcg_gen_ext32u_tl(t0, t0);
3220             tcg_gen_ext32u_tl(t1, t1);
3221             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3222             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3223             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3224             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3225             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3226         }
3227         break;
3228     default:
3229         MIPS_INVAL("div1 TX79");
3230         gen_reserved_instruction(ctx);
3231         break;
3232     }
3233 }
3234 #endif
3235 
gen_muldiv(DisasContext * ctx,uint32_t opc,int acc,int rs,int rt)3236 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3237                        int acc, int rs, int rt)
3238 {
3239     TCGv t0, t1;
3240 
3241     t0 = tcg_temp_new();
3242     t1 = tcg_temp_new();
3243 
3244     gen_load_gpr(t0, rs);
3245     gen_load_gpr(t1, rt);
3246 
3247     if (acc != 0) {
3248         check_dsp(ctx);
3249     }
3250 
3251     switch (opc) {
3252     case OPC_DIV:
3253         {
3254             TCGv t2 = tcg_temp_new();
3255             TCGv t3 = tcg_temp_new();
3256             tcg_gen_ext32s_tl(t0, t0);
3257             tcg_gen_ext32s_tl(t1, t1);
3258             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3259             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3260             tcg_gen_and_tl(t2, t2, t3);
3261             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3262             tcg_gen_or_tl(t2, t2, t3);
3263             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3264             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3265             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3266             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3267             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3268         }
3269         break;
3270     case OPC_DIVU:
3271         {
3272             TCGv t2 = tcg_constant_tl(0);
3273             TCGv t3 = tcg_constant_tl(1);
3274             tcg_gen_ext32u_tl(t0, t0);
3275             tcg_gen_ext32u_tl(t1, t1);
3276             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3277             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3278             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3279             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3280             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3281         }
3282         break;
3283     case OPC_MULT:
3284         {
3285             TCGv_i32 t2 = tcg_temp_new_i32();
3286             TCGv_i32 t3 = tcg_temp_new_i32();
3287             tcg_gen_trunc_tl_i32(t2, t0);
3288             tcg_gen_trunc_tl_i32(t3, t1);
3289             tcg_gen_muls2_i32(t2, t3, t2, t3);
3290             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3291             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3292         }
3293         break;
3294     case OPC_MULTU:
3295         {
3296             TCGv_i32 t2 = tcg_temp_new_i32();
3297             TCGv_i32 t3 = tcg_temp_new_i32();
3298             tcg_gen_trunc_tl_i32(t2, t0);
3299             tcg_gen_trunc_tl_i32(t3, t1);
3300             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3301             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3302             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3303         }
3304         break;
3305 #if defined(TARGET_MIPS64)
3306     case OPC_DDIV:
3307         {
3308             TCGv t2 = tcg_temp_new();
3309             TCGv t3 = tcg_temp_new();
3310             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3311             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3312             tcg_gen_and_tl(t2, t2, t3);
3313             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3314             tcg_gen_or_tl(t2, t2, t3);
3315             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3316             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3317             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3318         }
3319         break;
3320     case OPC_DDIVU:
3321         {
3322             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3323                                tcg_constant_tl(0), tcg_constant_tl(1), t1);
3324             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3325             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3326         }
3327         break;
3328     case OPC_DMULT:
3329         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3330         break;
3331     case OPC_DMULTU:
3332         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3333         break;
3334 #endif
3335     case OPC_MADD:
3336         {
3337             TCGv_i64 t2 = tcg_temp_new_i64();
3338             TCGv_i64 t3 = tcg_temp_new_i64();
3339 
3340             tcg_gen_ext_tl_i64(t2, t0);
3341             tcg_gen_ext_tl_i64(t3, t1);
3342             tcg_gen_mul_i64(t2, t2, t3);
3343             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3344             tcg_gen_add_i64(t2, t2, t3);
3345             gen_move_low32(cpu_LO[acc], t2);
3346             gen_move_high32(cpu_HI[acc], t2);
3347         }
3348         break;
3349     case OPC_MADDU:
3350         {
3351             TCGv_i64 t2 = tcg_temp_new_i64();
3352             TCGv_i64 t3 = tcg_temp_new_i64();
3353 
3354             tcg_gen_ext32u_tl(t0, t0);
3355             tcg_gen_ext32u_tl(t1, t1);
3356             tcg_gen_extu_tl_i64(t2, t0);
3357             tcg_gen_extu_tl_i64(t3, t1);
3358             tcg_gen_mul_i64(t2, t2, t3);
3359             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3360             tcg_gen_add_i64(t2, t2, t3);
3361             gen_move_low32(cpu_LO[acc], t2);
3362             gen_move_high32(cpu_HI[acc], t2);
3363         }
3364         break;
3365     case OPC_MSUB:
3366         {
3367             TCGv_i64 t2 = tcg_temp_new_i64();
3368             TCGv_i64 t3 = tcg_temp_new_i64();
3369 
3370             tcg_gen_ext_tl_i64(t2, t0);
3371             tcg_gen_ext_tl_i64(t3, t1);
3372             tcg_gen_mul_i64(t2, t2, t3);
3373             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3374             tcg_gen_sub_i64(t2, t3, t2);
3375             gen_move_low32(cpu_LO[acc], t2);
3376             gen_move_high32(cpu_HI[acc], t2);
3377         }
3378         break;
3379     case OPC_MSUBU:
3380         {
3381             TCGv_i64 t2 = tcg_temp_new_i64();
3382             TCGv_i64 t3 = tcg_temp_new_i64();
3383 
3384             tcg_gen_ext32u_tl(t0, t0);
3385             tcg_gen_ext32u_tl(t1, t1);
3386             tcg_gen_extu_tl_i64(t2, t0);
3387             tcg_gen_extu_tl_i64(t3, t1);
3388             tcg_gen_mul_i64(t2, t2, t3);
3389             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3390             tcg_gen_sub_i64(t2, t3, t2);
3391             gen_move_low32(cpu_LO[acc], t2);
3392             gen_move_high32(cpu_HI[acc], t2);
3393         }
3394         break;
3395     default:
3396         MIPS_INVAL("mul/div");
3397         gen_reserved_instruction(ctx);
3398         break;
3399     }
3400 }
3401 
3402 /*
3403  * These MULT[U] and MADD[U] instructions implemented in for example
3404  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3405  * architectures are special three-operand variants with the syntax
3406  *
3407  *     MULT[U][1] rd, rs, rt
3408  *
3409  * such that
3410  *
3411  *     (rd, LO, HI) <- rs * rt
3412  *
3413  * and
3414  *
3415  *     MADD[U][1] rd, rs, rt
3416  *
3417  * such that
3418  *
3419  *     (rd, LO, HI) <- (LO, HI) + rs * rt
3420  *
3421  * where the low-order 32-bits of the result is placed into both the
3422  * GPR rd and the special register LO. The high-order 32-bits of the
3423  * result is placed into the special register HI.
3424  *
3425  * If the GPR rd is omitted in assembly language, it is taken to be 0,
3426  * which is the zero register that always reads as 0.
3427  */
gen_mul_txx9(DisasContext * ctx,uint32_t opc,int rd,int rs,int rt)3428 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3429                          int rd, int rs, int rt)
3430 {
3431     TCGv t0 = tcg_temp_new();
3432     TCGv t1 = tcg_temp_new();
3433     int acc = 0;
3434 
3435     gen_load_gpr(t0, rs);
3436     gen_load_gpr(t1, rt);
3437 
3438     switch (opc) {
3439     case MMI_OPC_MULT1:
3440         acc = 1;
3441         /* Fall through */
3442     case OPC_MULT:
3443         {
3444             TCGv_i32 t2 = tcg_temp_new_i32();
3445             TCGv_i32 t3 = tcg_temp_new_i32();
3446             tcg_gen_trunc_tl_i32(t2, t0);
3447             tcg_gen_trunc_tl_i32(t3, t1);
3448             tcg_gen_muls2_i32(t2, t3, t2, t3);
3449             if (rd) {
3450                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3451             }
3452             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3453             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3454         }
3455         break;
3456     case MMI_OPC_MULTU1:
3457         acc = 1;
3458         /* Fall through */
3459     case OPC_MULTU:
3460         {
3461             TCGv_i32 t2 = tcg_temp_new_i32();
3462             TCGv_i32 t3 = tcg_temp_new_i32();
3463             tcg_gen_trunc_tl_i32(t2, t0);
3464             tcg_gen_trunc_tl_i32(t3, t1);
3465             tcg_gen_mulu2_i32(t2, t3, t2, t3);
3466             if (rd) {
3467                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3468             }
3469             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3470             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3471         }
3472         break;
3473     case MMI_OPC_MADD1:
3474         acc = 1;
3475         /* Fall through */
3476     case MMI_OPC_MADD:
3477         {
3478             TCGv_i64 t2 = tcg_temp_new_i64();
3479             TCGv_i64 t3 = tcg_temp_new_i64();
3480 
3481             tcg_gen_ext_tl_i64(t2, t0);
3482             tcg_gen_ext_tl_i64(t3, t1);
3483             tcg_gen_mul_i64(t2, t2, t3);
3484             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3485             tcg_gen_add_i64(t2, t2, t3);
3486             gen_move_low32(cpu_LO[acc], t2);
3487             gen_move_high32(cpu_HI[acc], t2);
3488             if (rd) {
3489                 gen_move_low32(cpu_gpr[rd], t2);
3490             }
3491         }
3492         break;
3493     case MMI_OPC_MADDU1:
3494         acc = 1;
3495         /* Fall through */
3496     case MMI_OPC_MADDU:
3497         {
3498             TCGv_i64 t2 = tcg_temp_new_i64();
3499             TCGv_i64 t3 = tcg_temp_new_i64();
3500 
3501             tcg_gen_ext32u_tl(t0, t0);
3502             tcg_gen_ext32u_tl(t1, t1);
3503             tcg_gen_extu_tl_i64(t2, t0);
3504             tcg_gen_extu_tl_i64(t3, t1);
3505             tcg_gen_mul_i64(t2, t2, t3);
3506             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3507             tcg_gen_add_i64(t2, t2, t3);
3508             gen_move_low32(cpu_LO[acc], t2);
3509             gen_move_high32(cpu_HI[acc], t2);
3510             if (rd) {
3511                 gen_move_low32(cpu_gpr[rd], t2);
3512             }
3513         }
3514         break;
3515     default:
3516         MIPS_INVAL("mul/madd TXx9");
3517         gen_reserved_instruction(ctx);
3518         break;
3519     }
3520 }
3521 
gen_cl(DisasContext * ctx,uint32_t opc,int rd,int rs)3522 static void gen_cl(DisasContext *ctx, uint32_t opc,
3523                    int rd, int rs)
3524 {
3525     TCGv t0;
3526 
3527     if (rd == 0) {
3528         /* Treat as NOP. */
3529         return;
3530     }
3531     t0 = cpu_gpr[rd];
3532     gen_load_gpr(t0, rs);
3533 
3534     switch (opc) {
3535     case OPC_CLO:
3536     case R6_OPC_CLO:
3537 #if defined(TARGET_MIPS64)
3538     case OPC_DCLO:
3539     case R6_OPC_DCLO:
3540 #endif
3541         tcg_gen_not_tl(t0, t0);
3542         break;
3543     }
3544 
3545     switch (opc) {
3546     case OPC_CLO:
3547     case R6_OPC_CLO:
3548     case OPC_CLZ:
3549     case R6_OPC_CLZ:
3550         tcg_gen_ext32u_tl(t0, t0);
3551         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3552         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3553         break;
3554 #if defined(TARGET_MIPS64)
3555     case OPC_DCLO:
3556     case R6_OPC_DCLO:
3557     case OPC_DCLZ:
3558     case R6_OPC_DCLZ:
3559         tcg_gen_clzi_i64(t0, t0, 64);
3560         break;
3561 #endif
3562     }
3563 }
3564 
3565 /* Loongson multimedia instructions */
gen_loongson_multimedia(DisasContext * ctx,int rd,int rs,int rt)3566 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3567 {
3568     uint32_t opc, shift_max;
3569     TCGv_i64 t0, t1;
3570     TCGCond cond;
3571 
3572     opc = MASK_LMMI(ctx->opcode);
3573     check_cp1_enabled(ctx);
3574 
3575     t0 = tcg_temp_new_i64();
3576     t1 = tcg_temp_new_i64();
3577     gen_load_fpr64(ctx, t0, rs);
3578     gen_load_fpr64(ctx, t1, rt);
3579 
3580     switch (opc) {
3581     case OPC_PADDSH:
3582         gen_helper_paddsh(t0, t0, t1);
3583         break;
3584     case OPC_PADDUSH:
3585         gen_helper_paddush(t0, t0, t1);
3586         break;
3587     case OPC_PADDH:
3588         gen_helper_paddh(t0, t0, t1);
3589         break;
3590     case OPC_PADDW:
3591         gen_helper_paddw(t0, t0, t1);
3592         break;
3593     case OPC_PADDSB:
3594         gen_helper_paddsb(t0, t0, t1);
3595         break;
3596     case OPC_PADDUSB:
3597         gen_helper_paddusb(t0, t0, t1);
3598         break;
3599     case OPC_PADDB:
3600         gen_helper_paddb(t0, t0, t1);
3601         break;
3602 
3603     case OPC_PSUBSH:
3604         gen_helper_psubsh(t0, t0, t1);
3605         break;
3606     case OPC_PSUBUSH:
3607         gen_helper_psubush(t0, t0, t1);
3608         break;
3609     case OPC_PSUBH:
3610         gen_helper_psubh(t0, t0, t1);
3611         break;
3612     case OPC_PSUBW:
3613         gen_helper_psubw(t0, t0, t1);
3614         break;
3615     case OPC_PSUBSB:
3616         gen_helper_psubsb(t0, t0, t1);
3617         break;
3618     case OPC_PSUBUSB:
3619         gen_helper_psubusb(t0, t0, t1);
3620         break;
3621     case OPC_PSUBB:
3622         gen_helper_psubb(t0, t0, t1);
3623         break;
3624 
3625     case OPC_PSHUFH:
3626         gen_helper_pshufh(t0, t0, t1);
3627         break;
3628     case OPC_PACKSSWH:
3629         gen_helper_packsswh(t0, t0, t1);
3630         break;
3631     case OPC_PACKSSHB:
3632         gen_helper_packsshb(t0, t0, t1);
3633         break;
3634     case OPC_PACKUSHB:
3635         gen_helper_packushb(t0, t0, t1);
3636         break;
3637 
3638     case OPC_PUNPCKLHW:
3639         gen_helper_punpcklhw(t0, t0, t1);
3640         break;
3641     case OPC_PUNPCKHHW:
3642         gen_helper_punpckhhw(t0, t0, t1);
3643         break;
3644     case OPC_PUNPCKLBH:
3645         gen_helper_punpcklbh(t0, t0, t1);
3646         break;
3647     case OPC_PUNPCKHBH:
3648         gen_helper_punpckhbh(t0, t0, t1);
3649         break;
3650     case OPC_PUNPCKLWD:
3651         gen_helper_punpcklwd(t0, t0, t1);
3652         break;
3653     case OPC_PUNPCKHWD:
3654         gen_helper_punpckhwd(t0, t0, t1);
3655         break;
3656 
3657     case OPC_PAVGH:
3658         gen_helper_pavgh(t0, t0, t1);
3659         break;
3660     case OPC_PAVGB:
3661         gen_helper_pavgb(t0, t0, t1);
3662         break;
3663     case OPC_PMAXSH:
3664         gen_helper_pmaxsh(t0, t0, t1);
3665         break;
3666     case OPC_PMINSH:
3667         gen_helper_pminsh(t0, t0, t1);
3668         break;
3669     case OPC_PMAXUB:
3670         gen_helper_pmaxub(t0, t0, t1);
3671         break;
3672     case OPC_PMINUB:
3673         gen_helper_pminub(t0, t0, t1);
3674         break;
3675 
3676     case OPC_PCMPEQW:
3677         gen_helper_pcmpeqw(t0, t0, t1);
3678         break;
3679     case OPC_PCMPGTW:
3680         gen_helper_pcmpgtw(t0, t0, t1);
3681         break;
3682     case OPC_PCMPEQH:
3683         gen_helper_pcmpeqh(t0, t0, t1);
3684         break;
3685     case OPC_PCMPGTH:
3686         gen_helper_pcmpgth(t0, t0, t1);
3687         break;
3688     case OPC_PCMPEQB:
3689         gen_helper_pcmpeqb(t0, t0, t1);
3690         break;
3691     case OPC_PCMPGTB:
3692         gen_helper_pcmpgtb(t0, t0, t1);
3693         break;
3694 
3695     case OPC_PSLLW:
3696         gen_helper_psllw(t0, t0, t1);
3697         break;
3698     case OPC_PSLLH:
3699         gen_helper_psllh(t0, t0, t1);
3700         break;
3701     case OPC_PSRLW:
3702         gen_helper_psrlw(t0, t0, t1);
3703         break;
3704     case OPC_PSRLH:
3705         gen_helper_psrlh(t0, t0, t1);
3706         break;
3707     case OPC_PSRAW:
3708         gen_helper_psraw(t0, t0, t1);
3709         break;
3710     case OPC_PSRAH:
3711         gen_helper_psrah(t0, t0, t1);
3712         break;
3713 
3714     case OPC_PMULLH:
3715         gen_helper_pmullh(t0, t0, t1);
3716         break;
3717     case OPC_PMULHH:
3718         gen_helper_pmulhh(t0, t0, t1);
3719         break;
3720     case OPC_PMULHUH:
3721         gen_helper_pmulhuh(t0, t0, t1);
3722         break;
3723     case OPC_PMADDHW:
3724         gen_helper_pmaddhw(t0, t0, t1);
3725         break;
3726 
3727     case OPC_PASUBUB:
3728         gen_helper_pasubub(t0, t0, t1);
3729         break;
3730     case OPC_BIADD:
3731         gen_helper_biadd(t0, t0);
3732         break;
3733     case OPC_PMOVMSKB:
3734         gen_helper_pmovmskb(t0, t0);
3735         break;
3736 
3737     case OPC_PADDD:
3738         tcg_gen_add_i64(t0, t0, t1);
3739         break;
3740     case OPC_PSUBD:
3741         tcg_gen_sub_i64(t0, t0, t1);
3742         break;
3743     case OPC_XOR_CP2:
3744         tcg_gen_xor_i64(t0, t0, t1);
3745         break;
3746     case OPC_NOR_CP2:
3747         tcg_gen_nor_i64(t0, t0, t1);
3748         break;
3749     case OPC_AND_CP2:
3750         tcg_gen_and_i64(t0, t0, t1);
3751         break;
3752     case OPC_OR_CP2:
3753         tcg_gen_or_i64(t0, t0, t1);
3754         break;
3755 
3756     case OPC_PANDN:
3757         tcg_gen_andc_i64(t0, t1, t0);
3758         break;
3759 
3760     case OPC_PINSRH_0:
3761         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3762         break;
3763     case OPC_PINSRH_1:
3764         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3765         break;
3766     case OPC_PINSRH_2:
3767         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3768         break;
3769     case OPC_PINSRH_3:
3770         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3771         break;
3772 
3773     case OPC_PEXTRH:
3774         tcg_gen_andi_i64(t1, t1, 3);
3775         tcg_gen_shli_i64(t1, t1, 4);
3776         tcg_gen_shr_i64(t0, t0, t1);
3777         tcg_gen_ext16u_i64(t0, t0);
3778         break;
3779 
3780     case OPC_ADDU_CP2:
3781         tcg_gen_add_i64(t0, t0, t1);
3782         tcg_gen_ext32s_i64(t0, t0);
3783         break;
3784     case OPC_SUBU_CP2:
3785         tcg_gen_sub_i64(t0, t0, t1);
3786         tcg_gen_ext32s_i64(t0, t0);
3787         break;
3788 
3789     case OPC_SLL_CP2:
3790         shift_max = 32;
3791         goto do_shift;
3792     case OPC_SRL_CP2:
3793         shift_max = 32;
3794         goto do_shift;
3795     case OPC_SRA_CP2:
3796         shift_max = 32;
3797         goto do_shift;
3798     case OPC_DSLL_CP2:
3799         shift_max = 64;
3800         goto do_shift;
3801     case OPC_DSRL_CP2:
3802         shift_max = 64;
3803         goto do_shift;
3804     case OPC_DSRA_CP2:
3805         shift_max = 64;
3806         goto do_shift;
3807     do_shift:
3808         /* Make sure shift count isn't TCG undefined behaviour.  */
3809         tcg_gen_andi_i64(t1, t1, shift_max - 1);
3810 
3811         switch (opc) {
3812         case OPC_SLL_CP2:
3813         case OPC_DSLL_CP2:
3814             tcg_gen_shl_i64(t0, t0, t1);
3815             break;
3816         case OPC_SRA_CP2:
3817         case OPC_DSRA_CP2:
3818             /*
3819              * Since SRA is UndefinedResult without sign-extended inputs,
3820              * we can treat SRA and DSRA the same.
3821              */
3822             tcg_gen_sar_i64(t0, t0, t1);
3823             break;
3824         case OPC_SRL_CP2:
3825             /* We want to shift in zeros for SRL; zero-extend first.  */
3826             tcg_gen_ext32u_i64(t0, t0);
3827             /* FALLTHRU */
3828         case OPC_DSRL_CP2:
3829             tcg_gen_shr_i64(t0, t0, t1);
3830             break;
3831         }
3832 
3833         if (shift_max == 32) {
3834             tcg_gen_ext32s_i64(t0, t0);
3835         }
3836 
3837         /* Shifts larger than MAX produce zero.  */
3838         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3839         tcg_gen_neg_i64(t1, t1);
3840         tcg_gen_and_i64(t0, t0, t1);
3841         break;
3842 
3843     case OPC_ADD_CP2:
3844     case OPC_DADD_CP2:
3845         {
3846             TCGv_i64 t2 = tcg_temp_new_i64();
3847             TCGLabel *lab = gen_new_label();
3848 
3849             tcg_gen_mov_i64(t2, t0);
3850             tcg_gen_add_i64(t0, t1, t2);
3851             if (opc == OPC_ADD_CP2) {
3852                 tcg_gen_ext32s_i64(t0, t0);
3853             }
3854             tcg_gen_xor_i64(t1, t1, t2);
3855             tcg_gen_xor_i64(t2, t2, t0);
3856             tcg_gen_andc_i64(t1, t2, t1);
3857             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3858             generate_exception(ctx, EXCP_OVERFLOW);
3859             gen_set_label(lab);
3860             break;
3861         }
3862 
3863     case OPC_SUB_CP2:
3864     case OPC_DSUB_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_sub_i64(t0, t1, t2);
3871             if (opc == OPC_SUB_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_and_i64(t1, t1, t2);
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_PMULUW:
3884         tcg_gen_ext32u_i64(t0, t0);
3885         tcg_gen_ext32u_i64(t1, t1);
3886         tcg_gen_mul_i64(t0, t0, t1);
3887         break;
3888 
3889     case OPC_SEQU_CP2:
3890     case OPC_SEQ_CP2:
3891         cond = TCG_COND_EQ;
3892         goto do_cc_cond;
3893         break;
3894     case OPC_SLTU_CP2:
3895         cond = TCG_COND_LTU;
3896         goto do_cc_cond;
3897         break;
3898     case OPC_SLT_CP2:
3899         cond = TCG_COND_LT;
3900         goto do_cc_cond;
3901         break;
3902     case OPC_SLEU_CP2:
3903         cond = TCG_COND_LEU;
3904         goto do_cc_cond;
3905         break;
3906     case OPC_SLE_CP2:
3907         cond = TCG_COND_LE;
3908     do_cc_cond:
3909         {
3910             int cc = (ctx->opcode >> 8) & 0x7;
3911             TCGv_i64 t64 = tcg_temp_new_i64();
3912             TCGv_i32 t32 = tcg_temp_new_i32();
3913 
3914             tcg_gen_setcond_i64(cond, t64, t0, t1);
3915             tcg_gen_extrl_i64_i32(t32, t64);
3916             tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
3917                                 get_fp_bit(cc), 1);
3918         }
3919         return;
3920     default:
3921         MIPS_INVAL("loongson_cp2");
3922         gen_reserved_instruction(ctx);
3923         return;
3924     }
3925 
3926     gen_store_fpr64(ctx, t0, rd);
3927 }
3928 
gen_loongson_lswc2(DisasContext * ctx,int rt,int rs,int rd)3929 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
3930                                int rs, int rd)
3931 {
3932     TCGv t0, t1;
3933     TCGv_i32 fp0;
3934 #if defined(TARGET_MIPS64)
3935     int lsq_rt1 = ctx->opcode & 0x1f;
3936     int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
3937 #endif
3938     int shf_offset = sextract32(ctx->opcode, 6, 8);
3939 
3940     t0 = tcg_temp_new();
3941 
3942     switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
3943 #if defined(TARGET_MIPS64)
3944     case OPC_GSLQ:
3945         t1 = tcg_temp_new();
3946         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3947         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3948                            ctx->default_tcg_memop_mask);
3949         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3950         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3951                            ctx->default_tcg_memop_mask);
3952         gen_store_gpr(t1, rt);
3953         gen_store_gpr(t0, lsq_rt1);
3954         break;
3955     case OPC_GSLQC1:
3956         check_cp1_enabled(ctx);
3957         t1 = tcg_temp_new();
3958         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3959         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3960                            ctx->default_tcg_memop_mask);
3961         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3962         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3963                            ctx->default_tcg_memop_mask);
3964         gen_store_fpr64(ctx, t1, rt);
3965         gen_store_fpr64(ctx, t0, lsq_rt1);
3966         break;
3967     case OPC_GSSQ:
3968         t1 = tcg_temp_new();
3969         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3970         gen_load_gpr(t1, rt);
3971         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3972                            ctx->default_tcg_memop_mask);
3973         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3974         gen_load_gpr(t1, lsq_rt1);
3975         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3976                            ctx->default_tcg_memop_mask);
3977         break;
3978     case OPC_GSSQC1:
3979         check_cp1_enabled(ctx);
3980         t1 = tcg_temp_new();
3981         gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3982         gen_load_fpr64(ctx, t1, rt);
3983         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3984                            ctx->default_tcg_memop_mask);
3985         gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3986         gen_load_fpr64(ctx, t1, lsq_rt1);
3987         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3988                            ctx->default_tcg_memop_mask);
3989         break;
3990 #endif
3991     case OPC_GSSHFL:
3992         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
3993         case OPC_GSLWLC1:
3994             check_cp1_enabled(ctx);
3995             gen_base_offset_addr(ctx, t0, rs, shf_offset);
3996             fp0 = tcg_temp_new_i32();
3997             gen_load_fpr32(ctx, fp0, rt);
3998             t1 = tcg_temp_new();
3999             tcg_gen_ext_i32_tl(t1, fp0);
4000             gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4001             tcg_gen_trunc_tl_i32(fp0, t1);
4002             gen_store_fpr32(ctx, fp0, rt);
4003             break;
4004         case OPC_GSLWRC1:
4005             check_cp1_enabled(ctx);
4006             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4007             fp0 = tcg_temp_new_i32();
4008             gen_load_fpr32(ctx, fp0, rt);
4009             t1 = tcg_temp_new();
4010             tcg_gen_ext_i32_tl(t1, fp0);
4011             gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4012             tcg_gen_trunc_tl_i32(fp0, t1);
4013             gen_store_fpr32(ctx, fp0, rt);
4014             break;
4015 #if defined(TARGET_MIPS64)
4016         case OPC_GSLDLC1:
4017             check_cp1_enabled(ctx);
4018             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4019             t1 = tcg_temp_new();
4020             gen_load_fpr64(ctx, t1, rt);
4021             gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4022             gen_store_fpr64(ctx, t1, rt);
4023             break;
4024         case OPC_GSLDRC1:
4025             check_cp1_enabled(ctx);
4026             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4027             t1 = tcg_temp_new();
4028             gen_load_fpr64(ctx, t1, rt);
4029             gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4030             gen_store_fpr64(ctx, t1, rt);
4031             break;
4032 #endif
4033         default:
4034             MIPS_INVAL("loongson_gsshfl");
4035             gen_reserved_instruction(ctx);
4036             break;
4037         }
4038         break;
4039     case OPC_GSSHFS:
4040         switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4041         case OPC_GSSWLC1:
4042             check_cp1_enabled(ctx);
4043             t1 = tcg_temp_new();
4044             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4045             fp0 = tcg_temp_new_i32();
4046             gen_load_fpr32(ctx, fp0, rt);
4047             tcg_gen_ext_i32_tl(t1, fp0);
4048             gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4049             break;
4050         case OPC_GSSWRC1:
4051             check_cp1_enabled(ctx);
4052             t1 = tcg_temp_new();
4053             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4054             fp0 = tcg_temp_new_i32();
4055             gen_load_fpr32(ctx, fp0, rt);
4056             tcg_gen_ext_i32_tl(t1, fp0);
4057             gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4058             break;
4059 #if defined(TARGET_MIPS64)
4060         case OPC_GSSDLC1:
4061             check_cp1_enabled(ctx);
4062             t1 = tcg_temp_new();
4063             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4064             gen_load_fpr64(ctx, t1, rt);
4065             gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4066             break;
4067         case OPC_GSSDRC1:
4068             check_cp1_enabled(ctx);
4069             t1 = tcg_temp_new();
4070             gen_base_offset_addr(ctx, t0, rs, shf_offset);
4071             gen_load_fpr64(ctx, t1, rt);
4072             gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4073             break;
4074 #endif
4075         default:
4076             MIPS_INVAL("loongson_gsshfs");
4077             gen_reserved_instruction(ctx);
4078             break;
4079         }
4080         break;
4081     default:
4082         MIPS_INVAL("loongson_gslsq");
4083         gen_reserved_instruction(ctx);
4084         break;
4085     }
4086 }
4087 
4088 /* Loongson EXT LDC2/SDC2 */
gen_loongson_lsdc2(DisasContext * ctx,int rt,int rs,int rd)4089 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4090                                int rs, int rd)
4091 {
4092     int offset = sextract32(ctx->opcode, 3, 8);
4093     uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4094     TCGv t0, t1;
4095     TCGv_i32 fp0;
4096 
4097     /* Pre-conditions */
4098     switch (opc) {
4099     case OPC_GSLBX:
4100     case OPC_GSLHX:
4101     case OPC_GSLWX:
4102     case OPC_GSLDX:
4103         /* prefetch, implement as NOP */
4104         if (rt == 0) {
4105             return;
4106         }
4107         break;
4108     case OPC_GSSBX:
4109     case OPC_GSSHX:
4110     case OPC_GSSWX:
4111     case OPC_GSSDX:
4112         break;
4113     case OPC_GSLWXC1:
4114 #if defined(TARGET_MIPS64)
4115     case OPC_GSLDXC1:
4116 #endif
4117         check_cp1_enabled(ctx);
4118         /* prefetch, implement as NOP */
4119         if (rt == 0) {
4120             return;
4121         }
4122         break;
4123     case OPC_GSSWXC1:
4124 #if defined(TARGET_MIPS64)
4125     case OPC_GSSDXC1:
4126 #endif
4127         check_cp1_enabled(ctx);
4128         break;
4129     default:
4130         MIPS_INVAL("loongson_lsdc2");
4131         gen_reserved_instruction(ctx);
4132         return;
4133         break;
4134     }
4135 
4136     t0 = tcg_temp_new();
4137 
4138     gen_base_offset_addr(ctx, t0, rs, offset);
4139     gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4140 
4141     switch (opc) {
4142     case OPC_GSLBX:
4143         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4144         gen_store_gpr(t0, rt);
4145         break;
4146     case OPC_GSLHX:
4147         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW |
4148                            ctx->default_tcg_memop_mask);
4149         gen_store_gpr(t0, rt);
4150         break;
4151     case OPC_GSLWX:
4152         gen_base_offset_addr(ctx, t0, rs, offset);
4153         if (rd) {
4154             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4155         }
4156         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4157                            ctx->default_tcg_memop_mask);
4158         gen_store_gpr(t0, rt);
4159         break;
4160 #if defined(TARGET_MIPS64)
4161     case OPC_GSLDX:
4162         gen_base_offset_addr(ctx, t0, rs, offset);
4163         if (rd) {
4164             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4165         }
4166         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4167                            ctx->default_tcg_memop_mask);
4168         gen_store_gpr(t0, rt);
4169         break;
4170 #endif
4171     case OPC_GSLWXC1:
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         fp0 = tcg_temp_new_i32();
4177         tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4178                             ctx->default_tcg_memop_mask);
4179         gen_store_fpr32(ctx, fp0, rt);
4180         break;
4181 #if defined(TARGET_MIPS64)
4182     case OPC_GSLDXC1:
4183         gen_base_offset_addr(ctx, t0, rs, offset);
4184         if (rd) {
4185             gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4186         }
4187         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4188                            ctx->default_tcg_memop_mask);
4189         gen_store_fpr64(ctx, t0, rt);
4190         break;
4191 #endif
4192     case OPC_GSSBX:
4193         t1 = tcg_temp_new();
4194         gen_load_gpr(t1, rt);
4195         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4196         break;
4197     case OPC_GSSHX:
4198         t1 = tcg_temp_new();
4199         gen_load_gpr(t1, rt);
4200         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW |
4201                            ctx->default_tcg_memop_mask);
4202         break;
4203     case OPC_GSSWX:
4204         t1 = tcg_temp_new();
4205         gen_load_gpr(t1, rt);
4206         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4207                            ctx->default_tcg_memop_mask);
4208         break;
4209 #if defined(TARGET_MIPS64)
4210     case OPC_GSSDX:
4211         t1 = tcg_temp_new();
4212         gen_load_gpr(t1, rt);
4213         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4214                            ctx->default_tcg_memop_mask);
4215         break;
4216 #endif
4217     case OPC_GSSWXC1:
4218         fp0 = tcg_temp_new_i32();
4219         gen_load_fpr32(ctx, fp0, rt);
4220         tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4221                             ctx->default_tcg_memop_mask);
4222         break;
4223 #if defined(TARGET_MIPS64)
4224     case OPC_GSSDXC1:
4225         t1 = tcg_temp_new();
4226         gen_load_fpr64(ctx, t1, rt);
4227         tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4228                             ctx->default_tcg_memop_mask);
4229         break;
4230 #endif
4231     default:
4232         break;
4233     }
4234 }
4235 
4236 /* Traps */
gen_trap(DisasContext * ctx,uint32_t opc,int rs,int rt,int16_t imm,int code)4237 static void gen_trap(DisasContext *ctx, uint32_t opc,
4238                      int rs, int rt, int16_t imm, int code)
4239 {
4240     int cond;
4241     TCGv t0 = tcg_temp_new();
4242     TCGv t1 = tcg_temp_new();
4243 
4244     cond = 0;
4245     /* Load needed operands */
4246     switch (opc) {
4247     case OPC_TEQ:
4248     case OPC_TGE:
4249     case OPC_TGEU:
4250     case OPC_TLT:
4251     case OPC_TLTU:
4252     case OPC_TNE:
4253         /* Compare two registers */
4254         if (rs != rt) {
4255             gen_load_gpr(t0, rs);
4256             gen_load_gpr(t1, rt);
4257             cond = 1;
4258         }
4259         break;
4260     case OPC_TEQI:
4261     case OPC_TGEI:
4262     case OPC_TGEIU:
4263     case OPC_TLTI:
4264     case OPC_TLTIU:
4265     case OPC_TNEI:
4266         /* Compare register to immediate */
4267         if (rs != 0 || imm != 0) {
4268             gen_load_gpr(t0, rs);
4269             tcg_gen_movi_tl(t1, (int32_t)imm);
4270             cond = 1;
4271         }
4272         break;
4273     }
4274     if (cond == 0) {
4275         switch (opc) {
4276         case OPC_TEQ:   /* rs == rs */
4277         case OPC_TEQI:  /* r0 == 0  */
4278         case OPC_TGE:   /* rs >= rs */
4279         case OPC_TGEI:  /* r0 >= 0  */
4280         case OPC_TGEU:  /* rs >= rs unsigned */
4281         case OPC_TGEIU: /* r0 >= 0  unsigned */
4282             /* Always trap */
4283 #ifdef CONFIG_USER_ONLY
4284             /* Pass the break code along to cpu_loop. */
4285             tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4286                            offsetof(CPUMIPSState, error_code));
4287 #endif
4288             generate_exception_end(ctx, EXCP_TRAP);
4289             break;
4290         case OPC_TLT:   /* rs < rs           */
4291         case OPC_TLTI:  /* r0 < 0            */
4292         case OPC_TLTU:  /* rs < rs unsigned  */
4293         case OPC_TLTIU: /* r0 < 0  unsigned  */
4294         case OPC_TNE:   /* rs != rs          */
4295         case OPC_TNEI:  /* r0 != 0           */
4296             /* Never trap: treat as NOP. */
4297             break;
4298         }
4299     } else {
4300         TCGLabel *l1 = gen_new_label();
4301 
4302         switch (opc) {
4303         case OPC_TEQ:
4304         case OPC_TEQI:
4305             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4306             break;
4307         case OPC_TGE:
4308         case OPC_TGEI:
4309             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4310             break;
4311         case OPC_TGEU:
4312         case OPC_TGEIU:
4313             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4314             break;
4315         case OPC_TLT:
4316         case OPC_TLTI:
4317             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4318             break;
4319         case OPC_TLTU:
4320         case OPC_TLTIU:
4321             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4322             break;
4323         case OPC_TNE:
4324         case OPC_TNEI:
4325             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4326             break;
4327         }
4328 #ifdef CONFIG_USER_ONLY
4329         /* Pass the break code along to cpu_loop. */
4330         tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4331                        offsetof(CPUMIPSState, error_code));
4332 #endif
4333         /* Like save_cpu_state, only don't update saved values. */
4334         if (ctx->base.pc_next != ctx->saved_pc) {
4335             gen_save_pc(ctx->base.pc_next);
4336         }
4337         if (ctx->hflags != ctx->saved_hflags) {
4338             tcg_gen_movi_i32(hflags, ctx->hflags);
4339         }
4340         generate_exception(ctx, EXCP_TRAP);
4341         gen_set_label(l1);
4342     }
4343 }
4344 
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)4345 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4346 {
4347     if (translator_use_goto_tb(&ctx->base, dest)) {
4348         tcg_gen_goto_tb(n);
4349         gen_save_pc(dest);
4350         tcg_gen_exit_tb(ctx->base.tb, n);
4351     } else {
4352         gen_save_pc(dest);
4353         tcg_gen_lookup_and_goto_ptr();
4354     }
4355 }
4356 
4357 /* 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)4358 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4359                                int insn_bytes,
4360                                int rs, int rt, int32_t offset,
4361                                int delayslot_size)
4362 {
4363     target_ulong btgt = -1;
4364     int blink = 0;
4365     int bcond_compute = 0;
4366     TCGv t0 = tcg_temp_new();
4367     TCGv t1 = tcg_temp_new();
4368 
4369     if (ctx->hflags & MIPS_HFLAG_BMASK) {
4370 #ifdef MIPS_DEBUG_DISAS
4371         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
4372                   VADDR_PRIx "\n", ctx->base.pc_next);
4373 #endif
4374         gen_reserved_instruction(ctx);
4375         goto out;
4376     }
4377 
4378     /* Load needed operands */
4379     switch (opc) {
4380     case OPC_BEQ:
4381     case OPC_BEQL:
4382     case OPC_BNE:
4383     case OPC_BNEL:
4384         /* Compare two registers */
4385         if (rs != rt) {
4386             gen_load_gpr(t0, rs);
4387             gen_load_gpr(t1, rt);
4388             bcond_compute = 1;
4389         }
4390         btgt = ctx->base.pc_next + insn_bytes + offset;
4391         break;
4392     case OPC_BGEZ:
4393     case OPC_BGEZAL:
4394     case OPC_BGEZALL:
4395     case OPC_BGEZL:
4396     case OPC_BGTZ:
4397     case OPC_BGTZL:
4398     case OPC_BLEZ:
4399     case OPC_BLEZL:
4400     case OPC_BLTZ:
4401     case OPC_BLTZAL:
4402     case OPC_BLTZALL:
4403     case OPC_BLTZL:
4404         /* Compare to zero */
4405         if (rs != 0) {
4406             gen_load_gpr(t0, rs);
4407             bcond_compute = 1;
4408         }
4409         btgt = ctx->base.pc_next + insn_bytes + offset;
4410         break;
4411     case OPC_BPOSGE32:
4412 #if defined(TARGET_MIPS64)
4413     case OPC_BPOSGE64:
4414         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4415 #else
4416         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4417 #endif
4418         bcond_compute = 1;
4419         btgt = ctx->base.pc_next + insn_bytes + offset;
4420         break;
4421     case OPC_J:
4422     case OPC_JAL:
4423         {
4424             /* Jump to immediate */
4425             int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
4426                                                         : 0xF0000000;
4427             btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
4428                    | (uint32_t)offset;
4429             break;
4430         }
4431     case OPC_JALX:
4432         /* Jump to immediate */
4433         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4434             (uint32_t)offset;
4435         break;
4436     case OPC_JR:
4437     case OPC_JALR:
4438         /* Jump to register */
4439         if (offset != 0 && offset != 16) {
4440             /*
4441              * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4442              * others are reserved.
4443              */
4444             MIPS_INVAL("jump hint");
4445             gen_reserved_instruction(ctx);
4446             goto out;
4447         }
4448         gen_load_gpr(btarget, rs);
4449         break;
4450     default:
4451         MIPS_INVAL("branch/jump");
4452         gen_reserved_instruction(ctx);
4453         goto out;
4454     }
4455     if (bcond_compute == 0) {
4456         /* No condition to be computed */
4457         switch (opc) {
4458         case OPC_BEQ:     /* rx == rx        */
4459         case OPC_BEQL:    /* rx == rx likely */
4460         case OPC_BGEZ:    /* 0 >= 0          */
4461         case OPC_BGEZL:   /* 0 >= 0 likely   */
4462         case OPC_BLEZ:    /* 0 <= 0          */
4463         case OPC_BLEZL:   /* 0 <= 0 likely   */
4464             /* Always take */
4465             ctx->hflags |= MIPS_HFLAG_B;
4466             break;
4467         case OPC_BGEZAL:  /* 0 >= 0          */
4468         case OPC_BGEZALL: /* 0 >= 0 likely   */
4469             /* Always take and link */
4470             blink = 31;
4471             ctx->hflags |= MIPS_HFLAG_B;
4472             break;
4473         case OPC_BNE:     /* rx != rx        */
4474         case OPC_BGTZ:    /* 0 > 0           */
4475         case OPC_BLTZ:    /* 0 < 0           */
4476             /* Treat as NOP. */
4477             goto out;
4478         case OPC_BLTZAL:  /* 0 < 0           */
4479             /*
4480              * Handle as an unconditional branch to get correct delay
4481              * slot checking.
4482              */
4483             blink = 31;
4484             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4485             ctx->hflags |= MIPS_HFLAG_B;
4486             break;
4487         case OPC_BLTZALL: /* 0 < 0 likely */
4488             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4489             /* Skip the instruction in the delay slot */
4490             ctx->base.pc_next += 4;
4491             goto out;
4492         case OPC_BNEL:    /* rx != rx likely */
4493         case OPC_BGTZL:   /* 0 > 0 likely */
4494         case OPC_BLTZL:   /* 0 < 0 likely */
4495             /* Skip the instruction in the delay slot */
4496             ctx->base.pc_next += 4;
4497             goto out;
4498         case OPC_J:
4499             ctx->hflags |= MIPS_HFLAG_B;
4500             break;
4501         case OPC_JALX:
4502             ctx->hflags |= MIPS_HFLAG_BX;
4503             /* Fallthrough */
4504         case OPC_JAL:
4505             blink = 31;
4506             ctx->hflags |= MIPS_HFLAG_B;
4507             break;
4508         case OPC_JR:
4509             ctx->hflags |= MIPS_HFLAG_BR;
4510             break;
4511         case OPC_JALR:
4512             blink = rt;
4513             ctx->hflags |= MIPS_HFLAG_BR;
4514             break;
4515         default:
4516             MIPS_INVAL("branch/jump");
4517             gen_reserved_instruction(ctx);
4518             goto out;
4519         }
4520     } else {
4521         switch (opc) {
4522         case OPC_BEQ:
4523             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4524             goto not_likely;
4525         case OPC_BEQL:
4526             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4527             goto likely;
4528         case OPC_BNE:
4529             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4530             goto not_likely;
4531         case OPC_BNEL:
4532             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4533             goto likely;
4534         case OPC_BGEZ:
4535             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4536             goto not_likely;
4537         case OPC_BGEZL:
4538             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4539             goto likely;
4540         case OPC_BGEZAL:
4541             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4542             blink = 31;
4543             goto not_likely;
4544         case OPC_BGEZALL:
4545             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4546             blink = 31;
4547             goto likely;
4548         case OPC_BGTZ:
4549             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4550             goto not_likely;
4551         case OPC_BGTZL:
4552             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4553             goto likely;
4554         case OPC_BLEZ:
4555             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4556             goto not_likely;
4557         case OPC_BLEZL:
4558             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4559             goto likely;
4560         case OPC_BLTZ:
4561             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4562             goto not_likely;
4563         case OPC_BLTZL:
4564             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4565             goto likely;
4566         case OPC_BPOSGE32:
4567             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4568             goto not_likely;
4569 #if defined(TARGET_MIPS64)
4570         case OPC_BPOSGE64:
4571             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4572             goto not_likely;
4573 #endif
4574         case OPC_BLTZAL:
4575             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4576             blink = 31;
4577         not_likely:
4578             ctx->hflags |= MIPS_HFLAG_BC;
4579             break;
4580         case OPC_BLTZALL:
4581             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4582             blink = 31;
4583         likely:
4584             ctx->hflags |= MIPS_HFLAG_BL;
4585             break;
4586         default:
4587             MIPS_INVAL("conditional branch/jump");
4588             gen_reserved_instruction(ctx);
4589             goto out;
4590         }
4591     }
4592 
4593     ctx->btarget = btgt;
4594 
4595     switch (delayslot_size) {
4596     case 2:
4597         ctx->hflags |= MIPS_HFLAG_BDS16;
4598         break;
4599     case 4:
4600         ctx->hflags |= MIPS_HFLAG_BDS32;
4601         break;
4602     }
4603 
4604     if (blink > 0) {
4605         int post_delay = insn_bytes + delayslot_size;
4606         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4607 
4608         tcg_gen_movi_tl(cpu_gpr[blink],
4609                         ctx->base.pc_next + post_delay + lowbit);
4610     }
4611 
4612  out:
4613     if (insn_bytes == 2) {
4614         ctx->hflags |= MIPS_HFLAG_B16;
4615     }
4616 }
4617 
4618 
4619 /* special3 bitfield operations */
gen_bitops(DisasContext * ctx,uint32_t opc,int rt,int rs,int lsb,int msb)4620 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
4621                        int rs, int lsb, int msb)
4622 {
4623     TCGv t0 = tcg_temp_new();
4624     TCGv t1 = tcg_temp_new();
4625 
4626     gen_load_gpr(t1, rs);
4627     switch (opc) {
4628     case OPC_EXT:
4629         if (lsb + msb > 31) {
4630             goto fail;
4631         }
4632         if (msb != 31) {
4633             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4634         } else {
4635             /*
4636              * The two checks together imply that lsb == 0,
4637              * so this is a simple sign-extension.
4638              */
4639             tcg_gen_ext32s_tl(t0, t1);
4640         }
4641         break;
4642 #if defined(TARGET_MIPS64)
4643     case OPC_DEXTU:
4644         lsb += 32;
4645         goto do_dext;
4646     case OPC_DEXTM:
4647         msb += 32;
4648         goto do_dext;
4649     case OPC_DEXT:
4650     do_dext:
4651         if (lsb + msb > 63) {
4652             goto fail;
4653         }
4654         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4655         break;
4656 #endif
4657     case OPC_INS:
4658         if (lsb > msb) {
4659             goto fail;
4660         }
4661         gen_load_gpr(t0, rt);
4662         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4663         tcg_gen_ext32s_tl(t0, t0);
4664         break;
4665 #if defined(TARGET_MIPS64)
4666     case OPC_DINSU:
4667         lsb += 32;
4668         /* FALLTHRU */
4669     case OPC_DINSM:
4670         msb += 32;
4671         /* FALLTHRU */
4672     case OPC_DINS:
4673         if (lsb > msb) {
4674             goto fail;
4675         }
4676         gen_load_gpr(t0, rt);
4677         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4678         break;
4679 #endif
4680     default:
4681 fail:
4682         MIPS_INVAL("bitops");
4683         gen_reserved_instruction(ctx);
4684         return;
4685     }
4686     gen_store_gpr(t0, rt);
4687 }
4688 
gen_bshfl(DisasContext * ctx,uint32_t op2,int rt,int rd)4689 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
4690 {
4691     TCGv t0;
4692 
4693     if (rd == 0) {
4694         /* If no destination, treat it as a NOP. */
4695         return;
4696     }
4697 
4698     t0 = tcg_temp_new();
4699     gen_load_gpr(t0, rt);
4700     switch (op2) {
4701     case OPC_WSBH:
4702         {
4703             TCGv t1 = tcg_temp_new();
4704             TCGv t2 = tcg_constant_tl(0x00FF00FF);
4705 
4706             tcg_gen_shri_tl(t1, t0, 8);
4707             tcg_gen_and_tl(t1, t1, t2);
4708             tcg_gen_and_tl(t0, t0, t2);
4709             tcg_gen_shli_tl(t0, t0, 8);
4710             tcg_gen_or_tl(t0, t0, t1);
4711             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4712         }
4713         break;
4714     case OPC_SEB:
4715         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4716         break;
4717     case OPC_SEH:
4718         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4719         break;
4720 #if defined(TARGET_MIPS64)
4721     case OPC_DSBH:
4722         {
4723             TCGv t1 = tcg_temp_new();
4724             TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL);
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(cpu_gpr[rd], t0, t1);
4731         }
4732         break;
4733     case OPC_DSHD:
4734         {
4735             TCGv t1 = tcg_temp_new();
4736             TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL);
4737 
4738             tcg_gen_shri_tl(t1, t0, 16);
4739             tcg_gen_and_tl(t1, t1, t2);
4740             tcg_gen_and_tl(t0, t0, t2);
4741             tcg_gen_shli_tl(t0, t0, 16);
4742             tcg_gen_or_tl(t0, t0, t1);
4743             tcg_gen_shri_tl(t1, t0, 32);
4744             tcg_gen_shli_tl(t0, t0, 32);
4745             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4746         }
4747         break;
4748 #endif
4749     default:
4750         MIPS_INVAL("bsfhl");
4751         gen_reserved_instruction(ctx);
4752         return;
4753     }
4754 }
4755 
gen_align_bits(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bits)4756 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
4757                            int rt, int bits)
4758 {
4759     TCGv t0;
4760     if (rd == 0) {
4761         /* Treat as NOP. */
4762         return;
4763     }
4764     t0 = tcg_temp_new();
4765     if (bits == 0 || bits == wordsz) {
4766         if (bits == 0) {
4767             gen_load_gpr(t0, rt);
4768         } else {
4769             gen_load_gpr(t0, rs);
4770         }
4771         switch (wordsz) {
4772         case 32:
4773             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4774             break;
4775 #if defined(TARGET_MIPS64)
4776         case 64:
4777             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4778             break;
4779 #endif
4780         }
4781     } else {
4782         TCGv t1 = tcg_temp_new();
4783         gen_load_gpr(t0, rt);
4784         gen_load_gpr(t1, rs);
4785         switch (wordsz) {
4786         case 32:
4787             {
4788                 TCGv_i64 t2 = tcg_temp_new_i64();
4789                 tcg_gen_concat_tl_i64(t2, t1, t0);
4790                 tcg_gen_shri_i64(t2, t2, 32 - bits);
4791                 gen_move_low32(cpu_gpr[rd], t2);
4792             }
4793             break;
4794 #if defined(TARGET_MIPS64)
4795         case 64:
4796             tcg_gen_shli_tl(t0, t0, bits);
4797             tcg_gen_shri_tl(t1, t1, 64 - bits);
4798             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4799             break;
4800 #endif
4801         }
4802     }
4803 }
4804 
gen_align(DisasContext * ctx,int wordsz,int rd,int rs,int rt,int bp)4805 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
4806 {
4807     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
4808 }
4809 
gen_bitswap(DisasContext * ctx,int opc,int rd,int rt)4810 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4811 {
4812     TCGv t0;
4813     if (rd == 0) {
4814         /* Treat as NOP. */
4815         return;
4816     }
4817     t0 = tcg_temp_new();
4818     gen_load_gpr(t0, rt);
4819     switch (opc) {
4820     case OPC_BITSWAP:
4821         gen_helper_bitswap(cpu_gpr[rd], t0);
4822         break;
4823 #if defined(TARGET_MIPS64)
4824     case OPC_DBITSWAP:
4825         gen_helper_dbitswap(cpu_gpr[rd], t0);
4826         break;
4827 #endif
4828     }
4829 }
4830 
4831 #ifndef CONFIG_USER_ONLY
4832 /* CP0 (MMU and control) */
gen_mthc0_entrylo(TCGv arg,target_ulong off)4833 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4834 {
4835     TCGv_i64 t0 = tcg_temp_new_i64();
4836     TCGv_i64 t1 = tcg_temp_new_i64();
4837 
4838     tcg_gen_ext_tl_i64(t0, arg);
4839     tcg_gen_ld_i64(t1, tcg_env, off);
4840 #if defined(TARGET_MIPS64)
4841     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4842 #else
4843     tcg_gen_concat32_i64(t1, t1, t0);
4844 #endif
4845     tcg_gen_st_i64(t1, tcg_env, off);
4846 }
4847 
gen_mthc0_store64(TCGv arg,target_ulong off)4848 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4849 {
4850     TCGv_i64 t0 = tcg_temp_new_i64();
4851     TCGv_i64 t1 = tcg_temp_new_i64();
4852 
4853     tcg_gen_ext_tl_i64(t0, arg);
4854     tcg_gen_ld_i64(t1, tcg_env, off);
4855     tcg_gen_concat32_i64(t1, t1, t0);
4856     tcg_gen_st_i64(t1, tcg_env, off);
4857 }
4858 
gen_mfhc0_entrylo(TCGv arg,target_ulong off)4859 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4860 {
4861     TCGv_i64 t0 = tcg_temp_new_i64();
4862 
4863     tcg_gen_ld_i64(t0, tcg_env, off);
4864 #if defined(TARGET_MIPS64)
4865     tcg_gen_shri_i64(t0, t0, 30);
4866 #else
4867     tcg_gen_shri_i64(t0, t0, 32);
4868 #endif
4869     gen_move_low32(arg, t0);
4870 }
4871 
gen_mfhc0_load64(TCGv arg,target_ulong off,int shift)4872 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4873 {
4874     TCGv_i64 t0 = tcg_temp_new_i64();
4875 
4876     tcg_gen_ld_i64(t0, tcg_env, off);
4877     tcg_gen_shri_i64(t0, t0, 32 + shift);
4878     gen_move_low32(arg, t0);
4879 }
4880 
gen_mfc0_load32(TCGv arg,target_ulong off)4881 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
4882 {
4883     TCGv_i32 t0 = tcg_temp_new_i32();
4884 
4885     tcg_gen_ld_i32(t0, tcg_env, off);
4886     tcg_gen_ext_i32_tl(arg, t0);
4887 }
4888 
gen_mfc0_load64(TCGv arg,target_ulong off)4889 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
4890 {
4891     tcg_gen_ld_tl(arg, tcg_env, off);
4892     tcg_gen_ext32s_tl(arg, arg);
4893 }
4894 
gen_mtc0_store32(TCGv arg,target_ulong off)4895 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
4896 {
4897     TCGv_i32 t0 = tcg_temp_new_i32();
4898 
4899     tcg_gen_trunc_tl_i32(t0, arg);
4900     tcg_gen_st_i32(t0, tcg_env, off);
4901 }
4902 
4903 #define CP0_CHECK(c)                            \
4904     do {                                        \
4905         if (!(c)) {                             \
4906             goto cp0_unimplemented;             \
4907         }                                       \
4908     } while (0)
4909 
gen_mfhc0(DisasContext * ctx,TCGv arg,int reg,int sel)4910 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4911 {
4912     const char *register_name = "invalid";
4913 
4914     switch (reg) {
4915     case CP0_REGISTER_02:
4916         switch (sel) {
4917         case 0:
4918             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4919             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4920             register_name = "EntryLo0";
4921             break;
4922         default:
4923             goto cp0_unimplemented;
4924         }
4925         break;
4926     case CP0_REGISTER_03:
4927         switch (sel) {
4928         case CP0_REG03__ENTRYLO1:
4929             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4930             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4931             register_name = "EntryLo1";
4932             break;
4933         default:
4934             goto cp0_unimplemented;
4935         }
4936         break;
4937     case CP0_REGISTER_17:
4938         switch (sel) {
4939         case CP0_REG17__LLADDR:
4940             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
4941                              ctx->CP0_LLAddr_shift);
4942             register_name = "LLAddr";
4943             break;
4944         case CP0_REG17__MAAR:
4945             CP0_CHECK(ctx->mrp);
4946             gen_helper_mfhc0_maar(arg, tcg_env);
4947             register_name = "MAAR";
4948             break;
4949         default:
4950             goto cp0_unimplemented;
4951         }
4952         break;
4953     case CP0_REGISTER_19:
4954         switch (sel) {
4955         case CP0_REG19__WATCHHI0:
4956         case CP0_REG19__WATCHHI1:
4957         case CP0_REG19__WATCHHI2:
4958         case CP0_REG19__WATCHHI3:
4959         case CP0_REG19__WATCHHI4:
4960         case CP0_REG19__WATCHHI5:
4961         case CP0_REG19__WATCHHI6:
4962         case CP0_REG19__WATCHHI7:
4963             /* upper 32 bits are only available when Config5MI != 0 */
4964             CP0_CHECK(ctx->mi);
4965             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
4966             register_name = "WatchHi";
4967             break;
4968         default:
4969             goto cp0_unimplemented;
4970         }
4971         break;
4972     case CP0_REGISTER_28:
4973         switch (sel) {
4974         case 0:
4975         case 2:
4976         case 4:
4977         case 6:
4978             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4979             register_name = "TagLo";
4980             break;
4981         default:
4982             goto cp0_unimplemented;
4983         }
4984         break;
4985     default:
4986         goto cp0_unimplemented;
4987     }
4988     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
4989     return;
4990 
4991 cp0_unimplemented:
4992     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
4993                   register_name, reg, sel);
4994     tcg_gen_movi_tl(arg, 0);
4995 }
4996 
gen_mthc0(DisasContext * ctx,TCGv arg,int reg,int sel)4997 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4998 {
4999     const char *register_name = "invalid";
5000     uint64_t mask = ctx->PAMask >> 36;
5001 
5002     switch (reg) {
5003     case CP0_REGISTER_02:
5004         switch (sel) {
5005         case 0:
5006             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5007             tcg_gen_andi_tl(arg, arg, mask);
5008             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5009             register_name = "EntryLo0";
5010             break;
5011         default:
5012             goto cp0_unimplemented;
5013         }
5014         break;
5015     case CP0_REGISTER_03:
5016         switch (sel) {
5017         case CP0_REG03__ENTRYLO1:
5018             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5019             tcg_gen_andi_tl(arg, arg, mask);
5020             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5021             register_name = "EntryLo1";
5022             break;
5023         default:
5024             goto cp0_unimplemented;
5025         }
5026         break;
5027     case CP0_REGISTER_17:
5028         switch (sel) {
5029         case CP0_REG17__LLADDR:
5030             /*
5031              * LLAddr is read-only (the only exception is bit 0 if LLB is
5032              * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5033              * relevant for modern MIPS cores supporting MTHC0, therefore
5034              * treating MTHC0 to LLAddr as NOP.
5035              */
5036             register_name = "LLAddr";
5037             break;
5038         case CP0_REG17__MAAR:
5039             CP0_CHECK(ctx->mrp);
5040             gen_helper_mthc0_maar(tcg_env, arg);
5041             register_name = "MAAR";
5042             break;
5043         default:
5044             goto cp0_unimplemented;
5045         }
5046         break;
5047     case CP0_REGISTER_19:
5048         switch (sel) {
5049         case CP0_REG19__WATCHHI0:
5050         case CP0_REG19__WATCHHI1:
5051         case CP0_REG19__WATCHHI2:
5052         case CP0_REG19__WATCHHI3:
5053         case CP0_REG19__WATCHHI4:
5054         case CP0_REG19__WATCHHI5:
5055         case CP0_REG19__WATCHHI6:
5056         case CP0_REG19__WATCHHI7:
5057             /* upper 32 bits are only available when Config5MI != 0 */
5058             CP0_CHECK(ctx->mi);
5059             gen_helper_0e1i(mthc0_watchhi, arg, sel);
5060             register_name = "WatchHi";
5061             break;
5062         default:
5063             goto cp0_unimplemented;
5064         }
5065         break;
5066     case CP0_REGISTER_28:
5067         switch (sel) {
5068         case 0:
5069         case 2:
5070         case 4:
5071         case 6:
5072             tcg_gen_andi_tl(arg, arg, mask);
5073             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5074             register_name = "TagLo";
5075             break;
5076         default:
5077             goto cp0_unimplemented;
5078         }
5079         break;
5080     default:
5081         goto cp0_unimplemented;
5082     }
5083     trace_mips_translate_c0("mthc0", register_name, reg, sel);
5084     return;
5085 
5086 cp0_unimplemented:
5087     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5088                   register_name, reg, sel);
5089 }
5090 
gen_mfc0_unimplemented(DisasContext * ctx,TCGv arg)5091 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5092 {
5093     if (ctx->insn_flags & ISA_MIPS_R6) {
5094         tcg_gen_movi_tl(arg, 0);
5095     } else {
5096         tcg_gen_movi_tl(arg, ~0);
5097     }
5098 }
5099 
gen_mfc0(DisasContext * ctx,TCGv arg,int reg,int sel)5100 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5101 {
5102     const char *register_name = "invalid";
5103 
5104     if (sel != 0) {
5105         check_insn(ctx, ISA_MIPS_R1);
5106     }
5107 
5108     switch (reg) {
5109     case CP0_REGISTER_00:
5110         switch (sel) {
5111         case CP0_REG00__INDEX:
5112             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5113             register_name = "Index";
5114             break;
5115         case CP0_REG00__MVPCONTROL:
5116             CP0_CHECK(disas_mt_available(ctx));
5117             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
5118             register_name = "MVPControl";
5119             break;
5120         case CP0_REG00__MVPCONF0:
5121             CP0_CHECK(disas_mt_available(ctx));
5122             gen_helper_mfc0_mvpconf0(arg, tcg_env);
5123             register_name = "MVPConf0";
5124             break;
5125         case CP0_REG00__MVPCONF1:
5126             CP0_CHECK(disas_mt_available(ctx));
5127             gen_helper_mfc0_mvpconf1(arg, tcg_env);
5128             register_name = "MVPConf1";
5129             break;
5130         case CP0_REG00__VPCONTROL:
5131             CP0_CHECK(ctx->vp);
5132             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5133             register_name = "VPControl";
5134             break;
5135         default:
5136             goto cp0_unimplemented;
5137         }
5138         break;
5139     case CP0_REGISTER_01:
5140         switch (sel) {
5141         case CP0_REG01__RANDOM:
5142             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5143             gen_helper_mfc0_random(arg, tcg_env);
5144             register_name = "Random";
5145             break;
5146         case CP0_REG01__VPECONTROL:
5147             CP0_CHECK(disas_mt_available(ctx));
5148             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5149             register_name = "VPEControl";
5150             break;
5151         case CP0_REG01__VPECONF0:
5152             CP0_CHECK(disas_mt_available(ctx));
5153             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5154             register_name = "VPEConf0";
5155             break;
5156         case CP0_REG01__VPECONF1:
5157             CP0_CHECK(disas_mt_available(ctx));
5158             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5159             register_name = "VPEConf1";
5160             break;
5161         case CP0_REG01__YQMASK:
5162             CP0_CHECK(disas_mt_available(ctx));
5163             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5164             register_name = "YQMask";
5165             break;
5166         case CP0_REG01__VPESCHEDULE:
5167             CP0_CHECK(disas_mt_available(ctx));
5168             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5169             register_name = "VPESchedule";
5170             break;
5171         case CP0_REG01__VPESCHEFBACK:
5172             CP0_CHECK(disas_mt_available(ctx));
5173             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5174             register_name = "VPEScheFBack";
5175             break;
5176         case CP0_REG01__VPEOPT:
5177             CP0_CHECK(disas_mt_available(ctx));
5178             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5179             register_name = "VPEOpt";
5180             break;
5181         default:
5182             goto cp0_unimplemented;
5183         }
5184         break;
5185     case CP0_REGISTER_02:
5186         switch (sel) {
5187         case CP0_REG02__ENTRYLO0:
5188             {
5189                 TCGv_i64 tmp = tcg_temp_new_i64();
5190                 tcg_gen_ld_i64(tmp, tcg_env,
5191                                offsetof(CPUMIPSState, CP0_EntryLo0));
5192 #if defined(TARGET_MIPS64)
5193                 if (ctx->rxi) {
5194                     /* Move RI/XI fields to bits 31:30 */
5195                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5196                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5197                 }
5198 #endif
5199                 gen_move_low32(arg, tmp);
5200             }
5201             register_name = "EntryLo0";
5202             break;
5203         case CP0_REG02__TCSTATUS:
5204             CP0_CHECK(disas_mt_available(ctx));
5205             gen_helper_mfc0_tcstatus(arg, tcg_env);
5206             register_name = "TCStatus";
5207             break;
5208         case CP0_REG02__TCBIND:
5209             CP0_CHECK(disas_mt_available(ctx));
5210             gen_helper_mfc0_tcbind(arg, tcg_env);
5211             register_name = "TCBind";
5212             break;
5213         case CP0_REG02__TCRESTART:
5214             CP0_CHECK(disas_mt_available(ctx));
5215             gen_helper_mfc0_tcrestart(arg, tcg_env);
5216             register_name = "TCRestart";
5217             break;
5218         case CP0_REG02__TCHALT:
5219             CP0_CHECK(disas_mt_available(ctx));
5220             gen_helper_mfc0_tchalt(arg, tcg_env);
5221             register_name = "TCHalt";
5222             break;
5223         case CP0_REG02__TCCONTEXT:
5224             CP0_CHECK(disas_mt_available(ctx));
5225             gen_helper_mfc0_tccontext(arg, tcg_env);
5226             register_name = "TCContext";
5227             break;
5228         case CP0_REG02__TCSCHEDULE:
5229             CP0_CHECK(disas_mt_available(ctx));
5230             gen_helper_mfc0_tcschedule(arg, tcg_env);
5231             register_name = "TCSchedule";
5232             break;
5233         case CP0_REG02__TCSCHEFBACK:
5234             CP0_CHECK(disas_mt_available(ctx));
5235             gen_helper_mfc0_tcschefback(arg, tcg_env);
5236             register_name = "TCScheFBack";
5237             break;
5238         default:
5239             goto cp0_unimplemented;
5240         }
5241         break;
5242     case CP0_REGISTER_03:
5243         switch (sel) {
5244         case CP0_REG03__ENTRYLO1:
5245             {
5246                 TCGv_i64 tmp = tcg_temp_new_i64();
5247                 tcg_gen_ld_i64(tmp, tcg_env,
5248                                offsetof(CPUMIPSState, CP0_EntryLo1));
5249 #if defined(TARGET_MIPS64)
5250                 if (ctx->rxi) {
5251                     /* Move RI/XI fields to bits 31:30 */
5252                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5253                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5254                 }
5255 #endif
5256                 gen_move_low32(arg, tmp);
5257             }
5258             register_name = "EntryLo1";
5259             break;
5260         case CP0_REG03__GLOBALNUM:
5261             CP0_CHECK(ctx->vp);
5262             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5263             register_name = "GlobalNumber";
5264             break;
5265         default:
5266             goto cp0_unimplemented;
5267         }
5268         break;
5269     case CP0_REGISTER_04:
5270         switch (sel) {
5271         case CP0_REG04__CONTEXT:
5272             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
5273             tcg_gen_ext32s_tl(arg, arg);
5274             register_name = "Context";
5275             break;
5276         case CP0_REG04__CONTEXTCONFIG:
5277             /* SmartMIPS ASE */
5278             /* gen_helper_mfc0_contextconfig(arg); */
5279             register_name = "ContextConfig";
5280             goto cp0_unimplemented;
5281         case CP0_REG04__USERLOCAL:
5282             CP0_CHECK(ctx->ulri);
5283             tcg_gen_ld_tl(arg, tcg_env,
5284                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5285             tcg_gen_ext32s_tl(arg, arg);
5286             register_name = "UserLocal";
5287             break;
5288         case CP0_REG04__MMID:
5289             CP0_CHECK(ctx->mi);
5290             gen_helper_mtc0_memorymapid(tcg_env, arg);
5291             register_name = "MMID";
5292             break;
5293         default:
5294             goto cp0_unimplemented;
5295         }
5296         break;
5297     case CP0_REGISTER_05:
5298         switch (sel) {
5299         case CP0_REG05__PAGEMASK:
5300             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5301             register_name = "PageMask";
5302             break;
5303         case CP0_REG05__PAGEGRAIN:
5304             check_insn(ctx, ISA_MIPS_R2);
5305             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5306             register_name = "PageGrain";
5307             break;
5308         case CP0_REG05__SEGCTL0:
5309             CP0_CHECK(ctx->sc);
5310             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5311             tcg_gen_ext32s_tl(arg, arg);
5312             register_name = "SegCtl0";
5313             break;
5314         case CP0_REG05__SEGCTL1:
5315             CP0_CHECK(ctx->sc);
5316             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5317             tcg_gen_ext32s_tl(arg, arg);
5318             register_name = "SegCtl1";
5319             break;
5320         case CP0_REG05__SEGCTL2:
5321             CP0_CHECK(ctx->sc);
5322             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5323             tcg_gen_ext32s_tl(arg, arg);
5324             register_name = "SegCtl2";
5325             break;
5326         case CP0_REG05__PWBASE:
5327             check_pw(ctx);
5328             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5329             register_name = "PWBase";
5330             break;
5331         case CP0_REG05__PWFIELD:
5332             check_pw(ctx);
5333             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5334             register_name = "PWField";
5335             break;
5336         case CP0_REG05__PWSIZE:
5337             check_pw(ctx);
5338             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5339             register_name = "PWSize";
5340             break;
5341         default:
5342             goto cp0_unimplemented;
5343         }
5344         break;
5345     case CP0_REGISTER_06:
5346         switch (sel) {
5347         case CP0_REG06__WIRED:
5348             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5349             register_name = "Wired";
5350             break;
5351         case CP0_REG06__SRSCONF0:
5352             check_insn(ctx, ISA_MIPS_R2);
5353             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5354             register_name = "SRSConf0";
5355             break;
5356         case CP0_REG06__SRSCONF1:
5357             check_insn(ctx, ISA_MIPS_R2);
5358             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5359             register_name = "SRSConf1";
5360             break;
5361         case CP0_REG06__SRSCONF2:
5362             check_insn(ctx, ISA_MIPS_R2);
5363             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5364             register_name = "SRSConf2";
5365             break;
5366         case CP0_REG06__SRSCONF3:
5367             check_insn(ctx, ISA_MIPS_R2);
5368             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5369             register_name = "SRSConf3";
5370             break;
5371         case CP0_REG06__SRSCONF4:
5372             check_insn(ctx, ISA_MIPS_R2);
5373             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5374             register_name = "SRSConf4";
5375             break;
5376         case CP0_REG06__PWCTL:
5377             check_pw(ctx);
5378             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5379             register_name = "PWCtl";
5380             break;
5381         default:
5382             goto cp0_unimplemented;
5383         }
5384         break;
5385     case CP0_REGISTER_07:
5386         switch (sel) {
5387         case CP0_REG07__HWRENA:
5388             check_insn(ctx, ISA_MIPS_R2);
5389             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5390             register_name = "HWREna";
5391             break;
5392         default:
5393             goto cp0_unimplemented;
5394         }
5395         break;
5396     case CP0_REGISTER_08:
5397         switch (sel) {
5398         case CP0_REG08__BADVADDR:
5399             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5400             tcg_gen_ext32s_tl(arg, arg);
5401             register_name = "BadVAddr";
5402             break;
5403         case CP0_REG08__BADINSTR:
5404             CP0_CHECK(ctx->bi);
5405             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5406             register_name = "BadInstr";
5407             break;
5408         case CP0_REG08__BADINSTRP:
5409             CP0_CHECK(ctx->bp);
5410             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5411             register_name = "BadInstrP";
5412             break;
5413         case CP0_REG08__BADINSTRX:
5414             CP0_CHECK(ctx->bi);
5415             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5416             tcg_gen_andi_tl(arg, arg, ~0xffff);
5417             register_name = "BadInstrX";
5418             break;
5419         default:
5420             goto cp0_unimplemented;
5421         }
5422         break;
5423     case CP0_REGISTER_09:
5424         switch (sel) {
5425         case CP0_REG09__COUNT:
5426             /* Mark as an IO operation because we read the time.  */
5427             translator_io_start(&ctx->base);
5428 
5429             gen_helper_mfc0_count(arg, tcg_env);
5430             /*
5431              * Break the TB to be able to take timer interrupts immediately
5432              * after reading count. DISAS_STOP isn't sufficient, we need to
5433              * ensure we break completely out of translated code.
5434              */
5435             gen_save_pc(ctx->base.pc_next + 4);
5436             ctx->base.is_jmp = DISAS_EXIT;
5437             register_name = "Count";
5438             break;
5439         default:
5440             goto cp0_unimplemented;
5441         }
5442         break;
5443     case CP0_REGISTER_10:
5444         switch (sel) {
5445         case CP0_REG10__ENTRYHI:
5446             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
5447             tcg_gen_ext32s_tl(arg, arg);
5448             register_name = "EntryHi";
5449             break;
5450         default:
5451             goto cp0_unimplemented;
5452         }
5453         break;
5454     case CP0_REGISTER_11:
5455         switch (sel) {
5456         case CP0_REG11__COMPARE:
5457             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5458             register_name = "Compare";
5459             break;
5460         /* 6,7 are implementation dependent */
5461         default:
5462             goto cp0_unimplemented;
5463         }
5464         break;
5465     case CP0_REGISTER_12:
5466         switch (sel) {
5467         case CP0_REG12__STATUS:
5468             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5469             register_name = "Status";
5470             break;
5471         case CP0_REG12__INTCTL:
5472             check_insn(ctx, ISA_MIPS_R2);
5473             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5474             register_name = "IntCtl";
5475             break;
5476         case CP0_REG12__SRSCTL:
5477             check_insn(ctx, ISA_MIPS_R2);
5478             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5479             register_name = "SRSCtl";
5480             break;
5481         case CP0_REG12__SRSMAP:
5482             check_insn(ctx, ISA_MIPS_R2);
5483             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5484             register_name = "SRSMap";
5485             break;
5486         default:
5487             goto cp0_unimplemented;
5488        }
5489         break;
5490     case CP0_REGISTER_13:
5491         switch (sel) {
5492         case CP0_REG13__CAUSE:
5493             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5494             register_name = "Cause";
5495             break;
5496         default:
5497             goto cp0_unimplemented;
5498        }
5499         break;
5500     case CP0_REGISTER_14:
5501         switch (sel) {
5502         case CP0_REG14__EPC:
5503             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
5504             tcg_gen_ext32s_tl(arg, arg);
5505             register_name = "EPC";
5506             break;
5507         default:
5508             goto cp0_unimplemented;
5509         }
5510         break;
5511     case CP0_REGISTER_15:
5512         switch (sel) {
5513         case CP0_REG15__PRID:
5514             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5515             register_name = "PRid";
5516             break;
5517         case CP0_REG15__EBASE:
5518             check_insn(ctx, ISA_MIPS_R2);
5519             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
5520             tcg_gen_ext32s_tl(arg, arg);
5521             register_name = "EBase";
5522             break;
5523         case CP0_REG15__CMGCRBASE:
5524             check_insn(ctx, ISA_MIPS_R2);
5525             CP0_CHECK(ctx->cmgcr);
5526             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5527             tcg_gen_ext32s_tl(arg, arg);
5528             register_name = "CMGCRBase";
5529             break;
5530         default:
5531             goto cp0_unimplemented;
5532        }
5533         break;
5534     case CP0_REGISTER_16:
5535         switch (sel) {
5536         case CP0_REG16__CONFIG:
5537             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5538             register_name = "Config";
5539             break;
5540         case CP0_REG16__CONFIG1:
5541             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5542             register_name = "Config1";
5543             break;
5544         case CP0_REG16__CONFIG2:
5545             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5546             register_name = "Config2";
5547             break;
5548         case CP0_REG16__CONFIG3:
5549             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5550             register_name = "Config3";
5551             break;
5552         case CP0_REG16__CONFIG4:
5553             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5554             register_name = "Config4";
5555             break;
5556         case CP0_REG16__CONFIG5:
5557             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5558             register_name = "Config5";
5559             break;
5560         /* 6,7 are implementation dependent */
5561         case CP0_REG16__CONFIG6:
5562             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5563             register_name = "Config6";
5564             break;
5565         case CP0_REG16__CONFIG7:
5566             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5567             register_name = "Config7";
5568             break;
5569         default:
5570             goto cp0_unimplemented;
5571         }
5572         break;
5573     case CP0_REGISTER_17:
5574         switch (sel) {
5575         case CP0_REG17__LLADDR:
5576             gen_helper_mfc0_lladdr(arg, tcg_env);
5577             register_name = "LLAddr";
5578             break;
5579         case CP0_REG17__MAAR:
5580             CP0_CHECK(ctx->mrp);
5581             gen_helper_mfc0_maar(arg, tcg_env);
5582             register_name = "MAAR";
5583             break;
5584         case CP0_REG17__MAARI:
5585             CP0_CHECK(ctx->mrp);
5586             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5587             register_name = "MAARI";
5588             break;
5589         default:
5590             goto cp0_unimplemented;
5591         }
5592         break;
5593     case CP0_REGISTER_18:
5594         switch (sel) {
5595         case CP0_REG18__WATCHLO0:
5596         case CP0_REG18__WATCHLO1:
5597         case CP0_REG18__WATCHLO2:
5598         case CP0_REG18__WATCHLO3:
5599         case CP0_REG18__WATCHLO4:
5600         case CP0_REG18__WATCHLO5:
5601         case CP0_REG18__WATCHLO6:
5602         case CP0_REG18__WATCHLO7:
5603             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5604             gen_helper_1e0i(mfc0_watchlo, arg, sel);
5605             register_name = "WatchLo";
5606             break;
5607         default:
5608             goto cp0_unimplemented;
5609         }
5610         break;
5611     case CP0_REGISTER_19:
5612         switch (sel) {
5613         case CP0_REG19__WATCHHI0:
5614         case CP0_REG19__WATCHHI1:
5615         case CP0_REG19__WATCHHI2:
5616         case CP0_REG19__WATCHHI3:
5617         case CP0_REG19__WATCHHI4:
5618         case CP0_REG19__WATCHHI5:
5619         case CP0_REG19__WATCHHI6:
5620         case CP0_REG19__WATCHHI7:
5621             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5622             gen_helper_1e0i(mfc0_watchhi, arg, sel);
5623             register_name = "WatchHi";
5624             break;
5625         default:
5626             goto cp0_unimplemented;
5627         }
5628         break;
5629     case CP0_REGISTER_20:
5630         switch (sel) {
5631         case CP0_REG20__XCONTEXT:
5632 #if defined(TARGET_MIPS64)
5633             check_insn(ctx, ISA_MIPS3);
5634             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
5635             tcg_gen_ext32s_tl(arg, arg);
5636             register_name = "XContext";
5637             break;
5638 #endif
5639         default:
5640             goto cp0_unimplemented;
5641         }
5642         break;
5643     case CP0_REGISTER_21:
5644        /* Officially reserved, but sel 0 is used for R1x000 framemask */
5645         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5646         switch (sel) {
5647         case 0:
5648             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5649             register_name = "Framemask";
5650             break;
5651         default:
5652             goto cp0_unimplemented;
5653         }
5654         break;
5655     case CP0_REGISTER_22:
5656         tcg_gen_movi_tl(arg, 0); /* unimplemented */
5657         register_name = "'Diagnostic"; /* implementation dependent */
5658         break;
5659     case CP0_REGISTER_23:
5660         switch (sel) {
5661         case CP0_REG23__DEBUG:
5662             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
5663             register_name = "Debug";
5664             break;
5665         case CP0_REG23__TRACECONTROL:
5666             /* PDtrace support */
5667             /* gen_helper_mfc0_tracecontrol(arg);  */
5668             register_name = "TraceControl";
5669             goto cp0_unimplemented;
5670         case CP0_REG23__TRACECONTROL2:
5671             /* PDtrace support */
5672             /* gen_helper_mfc0_tracecontrol2(arg); */
5673             register_name = "TraceControl2";
5674             goto cp0_unimplemented;
5675         case CP0_REG23__USERTRACEDATA1:
5676             /* PDtrace support */
5677             /* gen_helper_mfc0_usertracedata1(arg);*/
5678             register_name = "UserTraceData1";
5679             goto cp0_unimplemented;
5680         case CP0_REG23__TRACEIBPC:
5681             /* PDtrace support */
5682             /* gen_helper_mfc0_traceibpc(arg);     */
5683             register_name = "TraceIBPC";
5684             goto cp0_unimplemented;
5685         case CP0_REG23__TRACEDBPC:
5686             /* PDtrace support */
5687             /* gen_helper_mfc0_tracedbpc(arg);     */
5688             register_name = "TraceDBPC";
5689             goto cp0_unimplemented;
5690         default:
5691             goto cp0_unimplemented;
5692         }
5693         break;
5694     case CP0_REGISTER_24:
5695         switch (sel) {
5696         case CP0_REG24__DEPC:
5697             /* EJTAG support */
5698             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
5699             tcg_gen_ext32s_tl(arg, arg);
5700             register_name = "DEPC";
5701             break;
5702         default:
5703             goto cp0_unimplemented;
5704         }
5705         break;
5706     case CP0_REGISTER_25:
5707         switch (sel) {
5708         case CP0_REG25__PERFCTL0:
5709             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5710             register_name = "Performance0";
5711             break;
5712         case CP0_REG25__PERFCNT0:
5713             /* gen_helper_mfc0_performance1(arg); */
5714             register_name = "Performance1";
5715             goto cp0_unimplemented;
5716         case CP0_REG25__PERFCTL1:
5717             /* gen_helper_mfc0_performance2(arg); */
5718             register_name = "Performance2";
5719             goto cp0_unimplemented;
5720         case CP0_REG25__PERFCNT1:
5721             /* gen_helper_mfc0_performance3(arg); */
5722             register_name = "Performance3";
5723             goto cp0_unimplemented;
5724         case CP0_REG25__PERFCTL2:
5725             /* gen_helper_mfc0_performance4(arg); */
5726             register_name = "Performance4";
5727             goto cp0_unimplemented;
5728         case CP0_REG25__PERFCNT2:
5729             /* gen_helper_mfc0_performance5(arg); */
5730             register_name = "Performance5";
5731             goto cp0_unimplemented;
5732         case CP0_REG25__PERFCTL3:
5733             /* gen_helper_mfc0_performance6(arg); */
5734             register_name = "Performance6";
5735             goto cp0_unimplemented;
5736         case CP0_REG25__PERFCNT3:
5737             /* gen_helper_mfc0_performance7(arg); */
5738             register_name = "Performance7";
5739             goto cp0_unimplemented;
5740         default:
5741             goto cp0_unimplemented;
5742         }
5743         break;
5744     case CP0_REGISTER_26:
5745         switch (sel) {
5746         case CP0_REG26__ERRCTL:
5747             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5748             register_name = "ErrCtl";
5749             break;
5750         default:
5751             goto cp0_unimplemented;
5752         }
5753         break;
5754     case CP0_REGISTER_27:
5755         switch (sel) {
5756         case CP0_REG27__CACHERR:
5757             tcg_gen_movi_tl(arg, 0); /* unimplemented */
5758             register_name = "CacheErr";
5759             break;
5760         default:
5761             goto cp0_unimplemented;
5762         }
5763         break;
5764     case CP0_REGISTER_28:
5765         switch (sel) {
5766         case CP0_REG28__TAGLO:
5767         case CP0_REG28__TAGLO1:
5768         case CP0_REG28__TAGLO2:
5769         case CP0_REG28__TAGLO3:
5770             {
5771                 TCGv_i64 tmp = tcg_temp_new_i64();
5772                 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo));
5773                 gen_move_low32(arg, tmp);
5774             }
5775             register_name = "TagLo";
5776             break;
5777         case CP0_REG28__DATALO:
5778         case CP0_REG28__DATALO1:
5779         case CP0_REG28__DATALO2:
5780         case CP0_REG28__DATALO3:
5781             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5782             register_name = "DataLo";
5783             break;
5784         default:
5785             goto cp0_unimplemented;
5786         }
5787         break;
5788     case CP0_REGISTER_29:
5789         switch (sel) {
5790         case CP0_REG29__TAGHI:
5791         case CP0_REG29__TAGHI1:
5792         case CP0_REG29__TAGHI2:
5793         case CP0_REG29__TAGHI3:
5794             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5795             register_name = "TagHi";
5796             break;
5797         case CP0_REG29__DATAHI:
5798         case CP0_REG29__DATAHI1:
5799         case CP0_REG29__DATAHI2:
5800         case CP0_REG29__DATAHI3:
5801             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5802             register_name = "DataHi";
5803             break;
5804         default:
5805             goto cp0_unimplemented;
5806         }
5807         break;
5808     case CP0_REGISTER_30:
5809         switch (sel) {
5810         case CP0_REG30__ERROREPC:
5811             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5812             tcg_gen_ext32s_tl(arg, arg);
5813             register_name = "ErrorEPC";
5814             break;
5815         default:
5816             goto cp0_unimplemented;
5817         }
5818         break;
5819     case CP0_REGISTER_31:
5820         switch (sel) {
5821         case CP0_REG31__DESAVE:
5822             /* EJTAG support */
5823             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5824             register_name = "DESAVE";
5825             break;
5826         case CP0_REG31__KSCRATCH1:
5827         case CP0_REG31__KSCRATCH2:
5828         case CP0_REG31__KSCRATCH3:
5829         case CP0_REG31__KSCRATCH4:
5830         case CP0_REG31__KSCRATCH5:
5831         case CP0_REG31__KSCRATCH6:
5832             CP0_CHECK(ctx->kscrexist & (1 << sel));
5833             tcg_gen_ld_tl(arg, tcg_env,
5834                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
5835             tcg_gen_ext32s_tl(arg, arg);
5836             register_name = "KScratch";
5837             break;
5838         default:
5839             goto cp0_unimplemented;
5840         }
5841         break;
5842     default:
5843        goto cp0_unimplemented;
5844     }
5845     trace_mips_translate_c0("mfc0", register_name, reg, sel);
5846     return;
5847 
5848 cp0_unimplemented:
5849     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
5850                   register_name, reg, sel);
5851     gen_mfc0_unimplemented(ctx, arg);
5852 }
5853 
gen_mtc0(DisasContext * ctx,TCGv arg,int reg,int sel)5854 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5855 {
5856     const char *register_name = "invalid";
5857     bool icount;
5858 
5859     if (sel != 0) {
5860         check_insn(ctx, ISA_MIPS_R1);
5861     }
5862 
5863     icount = translator_io_start(&ctx->base);
5864 
5865     switch (reg) {
5866     case CP0_REGISTER_00:
5867         switch (sel) {
5868         case CP0_REG00__INDEX:
5869             gen_helper_mtc0_index(tcg_env, arg);
5870             register_name = "Index";
5871             break;
5872         case CP0_REG00__MVPCONTROL:
5873             CP0_CHECK(disas_mt_available(ctx));
5874             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
5875             register_name = "MVPControl";
5876             break;
5877         case CP0_REG00__MVPCONF0:
5878             CP0_CHECK(disas_mt_available(ctx));
5879             /* ignored */
5880             register_name = "MVPConf0";
5881             break;
5882         case CP0_REG00__MVPCONF1:
5883             CP0_CHECK(disas_mt_available(ctx));
5884             /* ignored */
5885             register_name = "MVPConf1";
5886             break;
5887         case CP0_REG00__VPCONTROL:
5888             CP0_CHECK(ctx->vp);
5889             /* ignored */
5890             register_name = "VPControl";
5891             break;
5892         default:
5893             goto cp0_unimplemented;
5894         }
5895         break;
5896     case CP0_REGISTER_01:
5897         switch (sel) {
5898         case CP0_REG01__RANDOM:
5899             /* ignored */
5900             register_name = "Random";
5901             break;
5902         case CP0_REG01__VPECONTROL:
5903             CP0_CHECK(disas_mt_available(ctx));
5904             gen_helper_mtc0_vpecontrol(tcg_env, arg);
5905             register_name = "VPEControl";
5906             break;
5907         case CP0_REG01__VPECONF0:
5908             CP0_CHECK(disas_mt_available(ctx));
5909             gen_helper_mtc0_vpeconf0(tcg_env, arg);
5910             register_name = "VPEConf0";
5911             break;
5912         case CP0_REG01__VPECONF1:
5913             CP0_CHECK(disas_mt_available(ctx));
5914             gen_helper_mtc0_vpeconf1(tcg_env, arg);
5915             register_name = "VPEConf1";
5916             break;
5917         case CP0_REG01__YQMASK:
5918             CP0_CHECK(disas_mt_available(ctx));
5919             gen_helper_mtc0_yqmask(tcg_env, arg);
5920             register_name = "YQMask";
5921             break;
5922         case CP0_REG01__VPESCHEDULE:
5923             CP0_CHECK(disas_mt_available(ctx));
5924             tcg_gen_st_tl(arg, tcg_env,
5925                           offsetof(CPUMIPSState, CP0_VPESchedule));
5926             register_name = "VPESchedule";
5927             break;
5928         case CP0_REG01__VPESCHEFBACK:
5929             CP0_CHECK(disas_mt_available(ctx));
5930             tcg_gen_st_tl(arg, tcg_env,
5931                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
5932             register_name = "VPEScheFBack";
5933             break;
5934         case CP0_REG01__VPEOPT:
5935             CP0_CHECK(disas_mt_available(ctx));
5936             gen_helper_mtc0_vpeopt(tcg_env, arg);
5937             register_name = "VPEOpt";
5938             break;
5939         default:
5940             goto cp0_unimplemented;
5941         }
5942         break;
5943     case CP0_REGISTER_02:
5944         switch (sel) {
5945         case CP0_REG02__ENTRYLO0:
5946             gen_helper_mtc0_entrylo0(tcg_env, arg);
5947             register_name = "EntryLo0";
5948             break;
5949         case CP0_REG02__TCSTATUS:
5950             CP0_CHECK(disas_mt_available(ctx));
5951             gen_helper_mtc0_tcstatus(tcg_env, arg);
5952             register_name = "TCStatus";
5953             break;
5954         case CP0_REG02__TCBIND:
5955             CP0_CHECK(disas_mt_available(ctx));
5956             gen_helper_mtc0_tcbind(tcg_env, arg);
5957             register_name = "TCBind";
5958             break;
5959         case CP0_REG02__TCRESTART:
5960             CP0_CHECK(disas_mt_available(ctx));
5961             gen_helper_mtc0_tcrestart(tcg_env, arg);
5962             register_name = "TCRestart";
5963             break;
5964         case CP0_REG02__TCHALT:
5965             CP0_CHECK(disas_mt_available(ctx));
5966             gen_helper_mtc0_tchalt(tcg_env, arg);
5967             register_name = "TCHalt";
5968             break;
5969         case CP0_REG02__TCCONTEXT:
5970             CP0_CHECK(disas_mt_available(ctx));
5971             gen_helper_mtc0_tccontext(tcg_env, arg);
5972             register_name = "TCContext";
5973             break;
5974         case CP0_REG02__TCSCHEDULE:
5975             CP0_CHECK(disas_mt_available(ctx));
5976             gen_helper_mtc0_tcschedule(tcg_env, arg);
5977             register_name = "TCSchedule";
5978             break;
5979         case CP0_REG02__TCSCHEFBACK:
5980             CP0_CHECK(disas_mt_available(ctx));
5981             gen_helper_mtc0_tcschefback(tcg_env, arg);
5982             register_name = "TCScheFBack";
5983             break;
5984         default:
5985             goto cp0_unimplemented;
5986         }
5987         break;
5988     case CP0_REGISTER_03:
5989         switch (sel) {
5990         case CP0_REG03__ENTRYLO1:
5991             gen_helper_mtc0_entrylo1(tcg_env, arg);
5992             register_name = "EntryLo1";
5993             break;
5994         case CP0_REG03__GLOBALNUM:
5995             CP0_CHECK(ctx->vp);
5996             /* ignored */
5997             register_name = "GlobalNumber";
5998             break;
5999         default:
6000             goto cp0_unimplemented;
6001         }
6002         break;
6003     case CP0_REGISTER_04:
6004         switch (sel) {
6005         case CP0_REG04__CONTEXT:
6006             gen_helper_mtc0_context(tcg_env, arg);
6007             register_name = "Context";
6008             break;
6009         case CP0_REG04__CONTEXTCONFIG:
6010             /* SmartMIPS ASE */
6011             /* gen_helper_mtc0_contextconfig(arg); */
6012             register_name = "ContextConfig";
6013             goto cp0_unimplemented;
6014         case CP0_REG04__USERLOCAL:
6015             CP0_CHECK(ctx->ulri);
6016             tcg_gen_st_tl(arg, tcg_env,
6017                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6018             register_name = "UserLocal";
6019             break;
6020         case CP0_REG04__MMID:
6021             CP0_CHECK(ctx->mi);
6022             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6023             register_name = "MMID";
6024             break;
6025         default:
6026             goto cp0_unimplemented;
6027         }
6028         break;
6029     case CP0_REGISTER_05:
6030         switch (sel) {
6031         case CP0_REG05__PAGEMASK:
6032             gen_helper_mtc0_pagemask(tcg_env, arg);
6033             register_name = "PageMask";
6034             break;
6035         case CP0_REG05__PAGEGRAIN:
6036             check_insn(ctx, ISA_MIPS_R2);
6037             gen_helper_mtc0_pagegrain(tcg_env, arg);
6038             register_name = "PageGrain";
6039             ctx->base.is_jmp = DISAS_STOP;
6040             break;
6041         case CP0_REG05__SEGCTL0:
6042             CP0_CHECK(ctx->sc);
6043             gen_helper_mtc0_segctl0(tcg_env, arg);
6044             register_name = "SegCtl0";
6045             break;
6046         case CP0_REG05__SEGCTL1:
6047             CP0_CHECK(ctx->sc);
6048             gen_helper_mtc0_segctl1(tcg_env, arg);
6049             register_name = "SegCtl1";
6050             break;
6051         case CP0_REG05__SEGCTL2:
6052             CP0_CHECK(ctx->sc);
6053             gen_helper_mtc0_segctl2(tcg_env, arg);
6054             register_name = "SegCtl2";
6055             break;
6056         case CP0_REG05__PWBASE:
6057             check_pw(ctx);
6058             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6059             register_name = "PWBase";
6060             break;
6061         case CP0_REG05__PWFIELD:
6062             check_pw(ctx);
6063             gen_helper_mtc0_pwfield(tcg_env, arg);
6064             register_name = "PWField";
6065             break;
6066         case CP0_REG05__PWSIZE:
6067             check_pw(ctx);
6068             gen_helper_mtc0_pwsize(tcg_env, arg);
6069             register_name = "PWSize";
6070             break;
6071         default:
6072             goto cp0_unimplemented;
6073         }
6074         break;
6075     case CP0_REGISTER_06:
6076         switch (sel) {
6077         case CP0_REG06__WIRED:
6078             gen_helper_mtc0_wired(tcg_env, arg);
6079             register_name = "Wired";
6080             break;
6081         case CP0_REG06__SRSCONF0:
6082             check_insn(ctx, ISA_MIPS_R2);
6083             gen_helper_mtc0_srsconf0(tcg_env, arg);
6084             register_name = "SRSConf0";
6085             break;
6086         case CP0_REG06__SRSCONF1:
6087             check_insn(ctx, ISA_MIPS_R2);
6088             gen_helper_mtc0_srsconf1(tcg_env, arg);
6089             register_name = "SRSConf1";
6090             break;
6091         case CP0_REG06__SRSCONF2:
6092             check_insn(ctx, ISA_MIPS_R2);
6093             gen_helper_mtc0_srsconf2(tcg_env, arg);
6094             register_name = "SRSConf2";
6095             break;
6096         case CP0_REG06__SRSCONF3:
6097             check_insn(ctx, ISA_MIPS_R2);
6098             gen_helper_mtc0_srsconf3(tcg_env, arg);
6099             register_name = "SRSConf3";
6100             break;
6101         case CP0_REG06__SRSCONF4:
6102             check_insn(ctx, ISA_MIPS_R2);
6103             gen_helper_mtc0_srsconf4(tcg_env, arg);
6104             register_name = "SRSConf4";
6105             break;
6106         case CP0_REG06__PWCTL:
6107             check_pw(ctx);
6108             gen_helper_mtc0_pwctl(tcg_env, arg);
6109             register_name = "PWCtl";
6110             break;
6111         default:
6112             goto cp0_unimplemented;
6113         }
6114         break;
6115     case CP0_REGISTER_07:
6116         switch (sel) {
6117         case CP0_REG07__HWRENA:
6118             check_insn(ctx, ISA_MIPS_R2);
6119             gen_helper_mtc0_hwrena(tcg_env, arg);
6120             ctx->base.is_jmp = DISAS_STOP;
6121             register_name = "HWREna";
6122             break;
6123         default:
6124             goto cp0_unimplemented;
6125         }
6126         break;
6127     case CP0_REGISTER_08:
6128         switch (sel) {
6129         case CP0_REG08__BADVADDR:
6130             /* ignored */
6131             register_name = "BadVAddr";
6132             break;
6133         case CP0_REG08__BADINSTR:
6134             /* ignored */
6135             register_name = "BadInstr";
6136             break;
6137         case CP0_REG08__BADINSTRP:
6138             /* ignored */
6139             register_name = "BadInstrP";
6140             break;
6141         case CP0_REG08__BADINSTRX:
6142             /* ignored */
6143             register_name = "BadInstrX";
6144             break;
6145         default:
6146             goto cp0_unimplemented;
6147         }
6148         break;
6149     case CP0_REGISTER_09:
6150         switch (sel) {
6151         case CP0_REG09__COUNT:
6152             gen_helper_mtc0_count(tcg_env, arg);
6153             register_name = "Count";
6154             break;
6155         default:
6156             goto cp0_unimplemented;
6157         }
6158         break;
6159     case CP0_REGISTER_10:
6160         switch (sel) {
6161         case CP0_REG10__ENTRYHI:
6162             gen_helper_mtc0_entryhi(tcg_env, arg);
6163             register_name = "EntryHi";
6164             break;
6165         default:
6166             goto cp0_unimplemented;
6167         }
6168         break;
6169     case CP0_REGISTER_11:
6170         switch (sel) {
6171         case CP0_REG11__COMPARE:
6172             gen_helper_mtc0_compare(tcg_env, arg);
6173             register_name = "Compare";
6174             break;
6175         /* 6,7 are implementation dependent */
6176         default:
6177             goto cp0_unimplemented;
6178         }
6179         break;
6180     case CP0_REGISTER_12:
6181         switch (sel) {
6182         case CP0_REG12__STATUS:
6183             save_cpu_state(ctx, 1);
6184             gen_helper_mtc0_status(tcg_env, arg);
6185             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6186             gen_save_pc(ctx->base.pc_next + 4);
6187             ctx->base.is_jmp = DISAS_EXIT;
6188             register_name = "Status";
6189             break;
6190         case CP0_REG12__INTCTL:
6191             check_insn(ctx, ISA_MIPS_R2);
6192             gen_helper_mtc0_intctl(tcg_env, arg);
6193             /* Stop translation as we may have switched the execution mode */
6194             ctx->base.is_jmp = DISAS_STOP;
6195             register_name = "IntCtl";
6196             break;
6197         case CP0_REG12__SRSCTL:
6198             check_insn(ctx, ISA_MIPS_R2);
6199             gen_helper_mtc0_srsctl(tcg_env, arg);
6200             /* Stop translation as we may have switched the execution mode */
6201             ctx->base.is_jmp = DISAS_STOP;
6202             register_name = "SRSCtl";
6203             break;
6204         case CP0_REG12__SRSMAP:
6205             check_insn(ctx, ISA_MIPS_R2);
6206             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6207             /* Stop translation as we may have switched the execution mode */
6208             ctx->base.is_jmp = DISAS_STOP;
6209             register_name = "SRSMap";
6210             break;
6211         default:
6212             goto cp0_unimplemented;
6213         }
6214         break;
6215     case CP0_REGISTER_13:
6216         switch (sel) {
6217         case CP0_REG13__CAUSE:
6218             save_cpu_state(ctx, 1);
6219             gen_helper_mtc0_cause(tcg_env, arg);
6220             /*
6221              * Stop translation as we may have triggered an interrupt.
6222              * DISAS_STOP isn't sufficient, we need to ensure we break out of
6223              * translated code to check for pending interrupts.
6224              */
6225             gen_save_pc(ctx->base.pc_next + 4);
6226             ctx->base.is_jmp = DISAS_EXIT;
6227             register_name = "Cause";
6228             break;
6229         default:
6230             goto cp0_unimplemented;
6231         }
6232         break;
6233     case CP0_REGISTER_14:
6234         switch (sel) {
6235         case CP0_REG14__EPC:
6236             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
6237             register_name = "EPC";
6238             break;
6239         default:
6240             goto cp0_unimplemented;
6241         }
6242         break;
6243     case CP0_REGISTER_15:
6244         switch (sel) {
6245         case CP0_REG15__PRID:
6246             /* ignored */
6247             register_name = "PRid";
6248             break;
6249         case CP0_REG15__EBASE:
6250             check_insn(ctx, ISA_MIPS_R2);
6251             gen_helper_mtc0_ebase(tcg_env, arg);
6252             register_name = "EBase";
6253             break;
6254         default:
6255             goto cp0_unimplemented;
6256         }
6257         break;
6258     case CP0_REGISTER_16:
6259         switch (sel) {
6260         case CP0_REG16__CONFIG:
6261             gen_helper_mtc0_config0(tcg_env, arg);
6262             register_name = "Config";
6263             /* Stop translation as we may have switched the execution mode */
6264             ctx->base.is_jmp = DISAS_STOP;
6265             break;
6266         case CP0_REG16__CONFIG1:
6267             /* ignored, read only */
6268             register_name = "Config1";
6269             break;
6270         case CP0_REG16__CONFIG2:
6271             gen_helper_mtc0_config2(tcg_env, arg);
6272             register_name = "Config2";
6273             /* Stop translation as we may have switched the execution mode */
6274             ctx->base.is_jmp = DISAS_STOP;
6275             break;
6276         case CP0_REG16__CONFIG3:
6277             gen_helper_mtc0_config3(tcg_env, arg);
6278             register_name = "Config3";
6279             /* Stop translation as we may have switched the execution mode */
6280             ctx->base.is_jmp = DISAS_STOP;
6281             break;
6282         case CP0_REG16__CONFIG4:
6283             gen_helper_mtc0_config4(tcg_env, arg);
6284             register_name = "Config4";
6285             ctx->base.is_jmp = DISAS_STOP;
6286             break;
6287         case CP0_REG16__CONFIG5:
6288             gen_helper_mtc0_config5(tcg_env, arg);
6289             register_name = "Config5";
6290             /* Stop translation as we may have switched the execution mode */
6291             ctx->base.is_jmp = DISAS_STOP;
6292             break;
6293         /* 6,7 are implementation dependent */
6294         case CP0_REG16__CONFIG6:
6295             /* ignored */
6296             register_name = "Config6";
6297             break;
6298         case CP0_REG16__CONFIG7:
6299             /* ignored */
6300             register_name = "Config7";
6301             break;
6302         default:
6303             register_name = "Invalid config selector";
6304             goto cp0_unimplemented;
6305         }
6306         break;
6307     case CP0_REGISTER_17:
6308         switch (sel) {
6309         case CP0_REG17__LLADDR:
6310             gen_helper_mtc0_lladdr(tcg_env, arg);
6311             register_name = "LLAddr";
6312             break;
6313         case CP0_REG17__MAAR:
6314             CP0_CHECK(ctx->mrp);
6315             gen_helper_mtc0_maar(tcg_env, arg);
6316             register_name = "MAAR";
6317             break;
6318         case CP0_REG17__MAARI:
6319             CP0_CHECK(ctx->mrp);
6320             gen_helper_mtc0_maari(tcg_env, arg);
6321             register_name = "MAARI";
6322             break;
6323         default:
6324             goto cp0_unimplemented;
6325         }
6326         break;
6327     case CP0_REGISTER_18:
6328         switch (sel) {
6329         case CP0_REG18__WATCHLO0:
6330         case CP0_REG18__WATCHLO1:
6331         case CP0_REG18__WATCHLO2:
6332         case CP0_REG18__WATCHLO3:
6333         case CP0_REG18__WATCHLO4:
6334         case CP0_REG18__WATCHLO5:
6335         case CP0_REG18__WATCHLO6:
6336         case CP0_REG18__WATCHLO7:
6337             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6338             gen_helper_0e1i(mtc0_watchlo, arg, sel);
6339             register_name = "WatchLo";
6340             break;
6341         default:
6342             goto cp0_unimplemented;
6343         }
6344         break;
6345     case CP0_REGISTER_19:
6346         switch (sel) {
6347         case CP0_REG19__WATCHHI0:
6348         case CP0_REG19__WATCHHI1:
6349         case CP0_REG19__WATCHHI2:
6350         case CP0_REG19__WATCHHI3:
6351         case CP0_REG19__WATCHHI4:
6352         case CP0_REG19__WATCHHI5:
6353         case CP0_REG19__WATCHHI6:
6354         case CP0_REG19__WATCHHI7:
6355             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6356             gen_helper_0e1i(mtc0_watchhi, arg, sel);
6357             register_name = "WatchHi";
6358             break;
6359         default:
6360             goto cp0_unimplemented;
6361         }
6362         break;
6363     case CP0_REGISTER_20:
6364         switch (sel) {
6365         case CP0_REG20__XCONTEXT:
6366 #if defined(TARGET_MIPS64)
6367             check_insn(ctx, ISA_MIPS3);
6368             gen_helper_mtc0_xcontext(tcg_env, arg);
6369             register_name = "XContext";
6370             break;
6371 #endif
6372         default:
6373             goto cp0_unimplemented;
6374         }
6375         break;
6376     case CP0_REGISTER_21:
6377        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6378         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6379         switch (sel) {
6380         case 0:
6381             gen_helper_mtc0_framemask(tcg_env, arg);
6382             register_name = "Framemask";
6383             break;
6384         default:
6385             goto cp0_unimplemented;
6386         }
6387         break;
6388     case CP0_REGISTER_22:
6389         /* ignored */
6390         register_name = "Diagnostic"; /* implementation dependent */
6391         break;
6392     case CP0_REGISTER_23:
6393         switch (sel) {
6394         case CP0_REG23__DEBUG:
6395             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
6396             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6397             gen_save_pc(ctx->base.pc_next + 4);
6398             ctx->base.is_jmp = DISAS_EXIT;
6399             register_name = "Debug";
6400             break;
6401         case CP0_REG23__TRACECONTROL:
6402             /* PDtrace support */
6403             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
6404             register_name = "TraceControl";
6405             /* Stop translation as we may have switched the execution mode */
6406             ctx->base.is_jmp = DISAS_STOP;
6407             goto cp0_unimplemented;
6408         case CP0_REG23__TRACECONTROL2:
6409             /* PDtrace support */
6410             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
6411             register_name = "TraceControl2";
6412             /* Stop translation as we may have switched the execution mode */
6413             ctx->base.is_jmp = DISAS_STOP;
6414             goto cp0_unimplemented;
6415         case CP0_REG23__USERTRACEDATA1:
6416             /* Stop translation as we may have switched the execution mode */
6417             ctx->base.is_jmp = DISAS_STOP;
6418             /* PDtrace support */
6419             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
6420             register_name = "UserTraceData";
6421             /* Stop translation as we may have switched the execution mode */
6422             ctx->base.is_jmp = DISAS_STOP;
6423             goto cp0_unimplemented;
6424         case CP0_REG23__TRACEIBPC:
6425             /* PDtrace support */
6426             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
6427             /* Stop translation as we may have switched the execution mode */
6428             ctx->base.is_jmp = DISAS_STOP;
6429             register_name = "TraceIBPC";
6430             goto cp0_unimplemented;
6431         case CP0_REG23__TRACEDBPC:
6432             /* PDtrace support */
6433             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
6434             /* Stop translation as we may have switched the execution mode */
6435             ctx->base.is_jmp = DISAS_STOP;
6436             register_name = "TraceDBPC";
6437             goto cp0_unimplemented;
6438         default:
6439             goto cp0_unimplemented;
6440         }
6441         break;
6442     case CP0_REGISTER_24:
6443         switch (sel) {
6444         case CP0_REG24__DEPC:
6445             /* EJTAG support */
6446             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
6447             register_name = "DEPC";
6448             break;
6449         default:
6450             goto cp0_unimplemented;
6451         }
6452         break;
6453     case CP0_REGISTER_25:
6454         switch (sel) {
6455         case CP0_REG25__PERFCTL0:
6456             gen_helper_mtc0_performance0(tcg_env, arg);
6457             register_name = "Performance0";
6458             break;
6459         case CP0_REG25__PERFCNT0:
6460             /* gen_helper_mtc0_performance1(arg); */
6461             register_name = "Performance1";
6462             goto cp0_unimplemented;
6463         case CP0_REG25__PERFCTL1:
6464             /* gen_helper_mtc0_performance2(arg); */
6465             register_name = "Performance2";
6466             goto cp0_unimplemented;
6467         case CP0_REG25__PERFCNT1:
6468             /* gen_helper_mtc0_performance3(arg); */
6469             register_name = "Performance3";
6470             goto cp0_unimplemented;
6471         case CP0_REG25__PERFCTL2:
6472             /* gen_helper_mtc0_performance4(arg); */
6473             register_name = "Performance4";
6474             goto cp0_unimplemented;
6475         case CP0_REG25__PERFCNT2:
6476             /* gen_helper_mtc0_performance5(arg); */
6477             register_name = "Performance5";
6478             goto cp0_unimplemented;
6479         case CP0_REG25__PERFCTL3:
6480             /* gen_helper_mtc0_performance6(arg); */
6481             register_name = "Performance6";
6482             goto cp0_unimplemented;
6483         case CP0_REG25__PERFCNT3:
6484             /* gen_helper_mtc0_performance7(arg); */
6485             register_name = "Performance7";
6486             goto cp0_unimplemented;
6487         default:
6488             goto cp0_unimplemented;
6489         }
6490        break;
6491     case CP0_REGISTER_26:
6492         switch (sel) {
6493         case CP0_REG26__ERRCTL:
6494             gen_helper_mtc0_errctl(tcg_env, arg);
6495             ctx->base.is_jmp = DISAS_STOP;
6496             register_name = "ErrCtl";
6497             break;
6498         default:
6499             goto cp0_unimplemented;
6500         }
6501         break;
6502     case CP0_REGISTER_27:
6503         switch (sel) {
6504         case CP0_REG27__CACHERR:
6505             /* ignored */
6506             register_name = "CacheErr";
6507             break;
6508         default:
6509             goto cp0_unimplemented;
6510         }
6511        break;
6512     case CP0_REGISTER_28:
6513         switch (sel) {
6514         case CP0_REG28__TAGLO:
6515         case CP0_REG28__TAGLO1:
6516         case CP0_REG28__TAGLO2:
6517         case CP0_REG28__TAGLO3:
6518             gen_helper_mtc0_taglo(tcg_env, arg);
6519             register_name = "TagLo";
6520             break;
6521         case CP0_REG28__DATALO:
6522         case CP0_REG28__DATALO1:
6523         case CP0_REG28__DATALO2:
6524         case CP0_REG28__DATALO3:
6525             gen_helper_mtc0_datalo(tcg_env, arg);
6526             register_name = "DataLo";
6527             break;
6528         default:
6529             goto cp0_unimplemented;
6530         }
6531         break;
6532     case CP0_REGISTER_29:
6533         switch (sel) {
6534         case CP0_REG29__TAGHI:
6535         case CP0_REG29__TAGHI1:
6536         case CP0_REG29__TAGHI2:
6537         case CP0_REG29__TAGHI3:
6538             gen_helper_mtc0_taghi(tcg_env, arg);
6539             register_name = "TagHi";
6540             break;
6541         case CP0_REG29__DATAHI:
6542         case CP0_REG29__DATAHI1:
6543         case CP0_REG29__DATAHI2:
6544         case CP0_REG29__DATAHI3:
6545             gen_helper_mtc0_datahi(tcg_env, arg);
6546             register_name = "DataHi";
6547             break;
6548         default:
6549             register_name = "invalid sel";
6550             goto cp0_unimplemented;
6551         }
6552        break;
6553     case CP0_REGISTER_30:
6554         switch (sel) {
6555         case CP0_REG30__ERROREPC:
6556             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6557             register_name = "ErrorEPC";
6558             break;
6559         default:
6560             goto cp0_unimplemented;
6561         }
6562         break;
6563     case CP0_REGISTER_31:
6564         switch (sel) {
6565         case CP0_REG31__DESAVE:
6566             /* EJTAG support */
6567             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6568             register_name = "DESAVE";
6569             break;
6570         case CP0_REG31__KSCRATCH1:
6571         case CP0_REG31__KSCRATCH2:
6572         case CP0_REG31__KSCRATCH3:
6573         case CP0_REG31__KSCRATCH4:
6574         case CP0_REG31__KSCRATCH5:
6575         case CP0_REG31__KSCRATCH6:
6576             CP0_CHECK(ctx->kscrexist & (1 << sel));
6577             tcg_gen_st_tl(arg, tcg_env,
6578                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6579             register_name = "KScratch";
6580             break;
6581         default:
6582             goto cp0_unimplemented;
6583         }
6584         break;
6585     default:
6586        goto cp0_unimplemented;
6587     }
6588     trace_mips_translate_c0("mtc0", register_name, reg, sel);
6589 
6590     /* For simplicity assume that all writes can cause interrupts.  */
6591     if (icount) {
6592         /*
6593          * DISAS_STOP isn't sufficient, we need to ensure we break out of
6594          * translated code to check for pending interrupts.
6595          */
6596         gen_save_pc(ctx->base.pc_next + 4);
6597         ctx->base.is_jmp = DISAS_EXIT;
6598     }
6599     return;
6600 
6601 cp0_unimplemented:
6602     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
6603                   register_name, reg, sel);
6604 }
6605 
6606 #if defined(TARGET_MIPS64)
gen_dmfc0(DisasContext * ctx,TCGv arg,int reg,int sel)6607 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6608 {
6609     const char *register_name = "invalid";
6610 
6611     if (sel != 0) {
6612         check_insn(ctx, ISA_MIPS_R1);
6613     }
6614 
6615     switch (reg) {
6616     case CP0_REGISTER_00:
6617         switch (sel) {
6618         case CP0_REG00__INDEX:
6619             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6620             register_name = "Index";
6621             break;
6622         case CP0_REG00__MVPCONTROL:
6623             CP0_CHECK(disas_mt_available(ctx));
6624             gen_helper_mfc0_mvpcontrol(arg, tcg_env);
6625             register_name = "MVPControl";
6626             break;
6627         case CP0_REG00__MVPCONF0:
6628             CP0_CHECK(disas_mt_available(ctx));
6629             gen_helper_mfc0_mvpconf0(arg, tcg_env);
6630             register_name = "MVPConf0";
6631             break;
6632         case CP0_REG00__MVPCONF1:
6633             CP0_CHECK(disas_mt_available(ctx));
6634             gen_helper_mfc0_mvpconf1(arg, tcg_env);
6635             register_name = "MVPConf1";
6636             break;
6637         case CP0_REG00__VPCONTROL:
6638             CP0_CHECK(ctx->vp);
6639             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6640             register_name = "VPControl";
6641             break;
6642         default:
6643             goto cp0_unimplemented;
6644         }
6645         break;
6646     case CP0_REGISTER_01:
6647         switch (sel) {
6648         case CP0_REG01__RANDOM:
6649             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6650             gen_helper_mfc0_random(arg, tcg_env);
6651             register_name = "Random";
6652             break;
6653         case CP0_REG01__VPECONTROL:
6654             CP0_CHECK(disas_mt_available(ctx));
6655             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6656             register_name = "VPEControl";
6657             break;
6658         case CP0_REG01__VPECONF0:
6659             CP0_CHECK(disas_mt_available(ctx));
6660             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6661             register_name = "VPEConf0";
6662             break;
6663         case CP0_REG01__VPECONF1:
6664             CP0_CHECK(disas_mt_available(ctx));
6665             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6666             register_name = "VPEConf1";
6667             break;
6668         case CP0_REG01__YQMASK:
6669             CP0_CHECK(disas_mt_available(ctx));
6670             tcg_gen_ld_tl(arg, tcg_env,
6671                           offsetof(CPUMIPSState, CP0_YQMask));
6672             register_name = "YQMask";
6673             break;
6674         case CP0_REG01__VPESCHEDULE:
6675             CP0_CHECK(disas_mt_available(ctx));
6676             tcg_gen_ld_tl(arg, tcg_env,
6677                           offsetof(CPUMIPSState, CP0_VPESchedule));
6678             register_name = "VPESchedule";
6679             break;
6680         case CP0_REG01__VPESCHEFBACK:
6681             CP0_CHECK(disas_mt_available(ctx));
6682             tcg_gen_ld_tl(arg, tcg_env,
6683                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6684             register_name = "VPEScheFBack";
6685             break;
6686         case CP0_REG01__VPEOPT:
6687             CP0_CHECK(disas_mt_available(ctx));
6688             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6689             register_name = "VPEOpt";
6690             break;
6691         default:
6692             goto cp0_unimplemented;
6693         }
6694         break;
6695     case CP0_REGISTER_02:
6696         switch (sel) {
6697         case CP0_REG02__ENTRYLO0:
6698             tcg_gen_ld_tl(arg, tcg_env,
6699                           offsetof(CPUMIPSState, CP0_EntryLo0));
6700             register_name = "EntryLo0";
6701             break;
6702         case CP0_REG02__TCSTATUS:
6703             CP0_CHECK(disas_mt_available(ctx));
6704             gen_helper_mfc0_tcstatus(arg, tcg_env);
6705             register_name = "TCStatus";
6706             break;
6707         case CP0_REG02__TCBIND:
6708             CP0_CHECK(disas_mt_available(ctx));
6709             gen_helper_mfc0_tcbind(arg, tcg_env);
6710             register_name = "TCBind";
6711             break;
6712         case CP0_REG02__TCRESTART:
6713             CP0_CHECK(disas_mt_available(ctx));
6714             gen_helper_dmfc0_tcrestart(arg, tcg_env);
6715             register_name = "TCRestart";
6716             break;
6717         case CP0_REG02__TCHALT:
6718             CP0_CHECK(disas_mt_available(ctx));
6719             gen_helper_dmfc0_tchalt(arg, tcg_env);
6720             register_name = "TCHalt";
6721             break;
6722         case CP0_REG02__TCCONTEXT:
6723             CP0_CHECK(disas_mt_available(ctx));
6724             gen_helper_dmfc0_tccontext(arg, tcg_env);
6725             register_name = "TCContext";
6726             break;
6727         case CP0_REG02__TCSCHEDULE:
6728             CP0_CHECK(disas_mt_available(ctx));
6729             gen_helper_dmfc0_tcschedule(arg, tcg_env);
6730             register_name = "TCSchedule";
6731             break;
6732         case CP0_REG02__TCSCHEFBACK:
6733             CP0_CHECK(disas_mt_available(ctx));
6734             gen_helper_dmfc0_tcschefback(arg, tcg_env);
6735             register_name = "TCScheFBack";
6736             break;
6737         default:
6738             goto cp0_unimplemented;
6739         }
6740         break;
6741     case CP0_REGISTER_03:
6742         switch (sel) {
6743         case CP0_REG03__ENTRYLO1:
6744             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6745             register_name = "EntryLo1";
6746             break;
6747         case CP0_REG03__GLOBALNUM:
6748             CP0_CHECK(ctx->vp);
6749             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6750             register_name = "GlobalNumber";
6751             break;
6752         default:
6753             goto cp0_unimplemented;
6754         }
6755         break;
6756     case CP0_REGISTER_04:
6757         switch (sel) {
6758         case CP0_REG04__CONTEXT:
6759             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
6760             register_name = "Context";
6761             break;
6762         case CP0_REG04__CONTEXTCONFIG:
6763             /* SmartMIPS ASE */
6764             /* gen_helper_dmfc0_contextconfig(arg); */
6765             register_name = "ContextConfig";
6766             goto cp0_unimplemented;
6767         case CP0_REG04__USERLOCAL:
6768             CP0_CHECK(ctx->ulri);
6769             tcg_gen_ld_tl(arg, tcg_env,
6770                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6771             register_name = "UserLocal";
6772             break;
6773         case CP0_REG04__MMID:
6774             CP0_CHECK(ctx->mi);
6775             gen_helper_mtc0_memorymapid(tcg_env, arg);
6776             register_name = "MMID";
6777             break;
6778         default:
6779             goto cp0_unimplemented;
6780         }
6781         break;
6782     case CP0_REGISTER_05:
6783         switch (sel) {
6784         case CP0_REG05__PAGEMASK:
6785             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6786             register_name = "PageMask";
6787             break;
6788         case CP0_REG05__PAGEGRAIN:
6789             check_insn(ctx, ISA_MIPS_R2);
6790             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6791             register_name = "PageGrain";
6792             break;
6793         case CP0_REG05__SEGCTL0:
6794             CP0_CHECK(ctx->sc);
6795             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6796             register_name = "SegCtl0";
6797             break;
6798         case CP0_REG05__SEGCTL1:
6799             CP0_CHECK(ctx->sc);
6800             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6801             register_name = "SegCtl1";
6802             break;
6803         case CP0_REG05__SEGCTL2:
6804             CP0_CHECK(ctx->sc);
6805             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6806             register_name = "SegCtl2";
6807             break;
6808         case CP0_REG05__PWBASE:
6809             check_pw(ctx);
6810             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
6811             register_name = "PWBase";
6812             break;
6813         case CP0_REG05__PWFIELD:
6814             check_pw(ctx);
6815             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField));
6816             register_name = "PWField";
6817             break;
6818         case CP0_REG05__PWSIZE:
6819             check_pw(ctx);
6820             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize));
6821             register_name = "PWSize";
6822             break;
6823         default:
6824             goto cp0_unimplemented;
6825         }
6826         break;
6827     case CP0_REGISTER_06:
6828         switch (sel) {
6829         case CP0_REG06__WIRED:
6830             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6831             register_name = "Wired";
6832             break;
6833         case CP0_REG06__SRSCONF0:
6834             check_insn(ctx, ISA_MIPS_R2);
6835             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6836             register_name = "SRSConf0";
6837             break;
6838         case CP0_REG06__SRSCONF1:
6839             check_insn(ctx, ISA_MIPS_R2);
6840             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6841             register_name = "SRSConf1";
6842             break;
6843         case CP0_REG06__SRSCONF2:
6844             check_insn(ctx, ISA_MIPS_R2);
6845             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6846             register_name = "SRSConf2";
6847             break;
6848         case CP0_REG06__SRSCONF3:
6849             check_insn(ctx, ISA_MIPS_R2);
6850             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6851             register_name = "SRSConf3";
6852             break;
6853         case CP0_REG06__SRSCONF4:
6854             check_insn(ctx, ISA_MIPS_R2);
6855             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6856             register_name = "SRSConf4";
6857             break;
6858         case CP0_REG06__PWCTL:
6859             check_pw(ctx);
6860             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6861             register_name = "PWCtl";
6862             break;
6863         default:
6864             goto cp0_unimplemented;
6865         }
6866         break;
6867     case CP0_REGISTER_07:
6868         switch (sel) {
6869         case CP0_REG07__HWRENA:
6870             check_insn(ctx, ISA_MIPS_R2);
6871             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6872             register_name = "HWREna";
6873             break;
6874         default:
6875             goto cp0_unimplemented;
6876         }
6877         break;
6878     case CP0_REGISTER_08:
6879         switch (sel) {
6880         case CP0_REG08__BADVADDR:
6881             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6882             register_name = "BadVAddr";
6883             break;
6884         case CP0_REG08__BADINSTR:
6885             CP0_CHECK(ctx->bi);
6886             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6887             register_name = "BadInstr";
6888             break;
6889         case CP0_REG08__BADINSTRP:
6890             CP0_CHECK(ctx->bp);
6891             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6892             register_name = "BadInstrP";
6893             break;
6894         case CP0_REG08__BADINSTRX:
6895             CP0_CHECK(ctx->bi);
6896             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6897             tcg_gen_andi_tl(arg, arg, ~0xffff);
6898             register_name = "BadInstrX";
6899             break;
6900         default:
6901             goto cp0_unimplemented;
6902         }
6903         break;
6904     case CP0_REGISTER_09:
6905         switch (sel) {
6906         case CP0_REG09__COUNT:
6907             /* Mark as an IO operation because we read the time.  */
6908             translator_io_start(&ctx->base);
6909             gen_helper_mfc0_count(arg, tcg_env);
6910             /*
6911              * Break the TB to be able to take timer interrupts immediately
6912              * after reading count. DISAS_STOP isn't sufficient, we need to
6913              * ensure we break completely out of translated code.
6914              */
6915             gen_save_pc(ctx->base.pc_next + 4);
6916             ctx->base.is_jmp = DISAS_EXIT;
6917             register_name = "Count";
6918             break;
6919         default:
6920             goto cp0_unimplemented;
6921         }
6922         break;
6923     case CP0_REGISTER_10:
6924         switch (sel) {
6925         case CP0_REG10__ENTRYHI:
6926             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
6927             register_name = "EntryHi";
6928             break;
6929         default:
6930             goto cp0_unimplemented;
6931         }
6932         break;
6933     case CP0_REGISTER_11:
6934         switch (sel) {
6935         case CP0_REG11__COMPARE:
6936             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6937             register_name = "Compare";
6938             break;
6939         /* 6,7 are implementation dependent */
6940         default:
6941             goto cp0_unimplemented;
6942         }
6943         break;
6944     case CP0_REGISTER_12:
6945         switch (sel) {
6946         case CP0_REG12__STATUS:
6947             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6948             register_name = "Status";
6949             break;
6950         case CP0_REG12__INTCTL:
6951             check_insn(ctx, ISA_MIPS_R2);
6952             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6953             register_name = "IntCtl";
6954             break;
6955         case CP0_REG12__SRSCTL:
6956             check_insn(ctx, ISA_MIPS_R2);
6957             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6958             register_name = "SRSCtl";
6959             break;
6960         case CP0_REG12__SRSMAP:
6961             check_insn(ctx, ISA_MIPS_R2);
6962             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6963             register_name = "SRSMap";
6964             break;
6965         default:
6966             goto cp0_unimplemented;
6967         }
6968         break;
6969     case CP0_REGISTER_13:
6970         switch (sel) {
6971         case CP0_REG13__CAUSE:
6972             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6973             register_name = "Cause";
6974             break;
6975         default:
6976             goto cp0_unimplemented;
6977         }
6978         break;
6979     case CP0_REGISTER_14:
6980         switch (sel) {
6981         case CP0_REG14__EPC:
6982             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
6983             register_name = "EPC";
6984             break;
6985         default:
6986             goto cp0_unimplemented;
6987         }
6988         break;
6989     case CP0_REGISTER_15:
6990         switch (sel) {
6991         case CP0_REG15__PRID:
6992             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6993             register_name = "PRid";
6994             break;
6995         case CP0_REG15__EBASE:
6996             check_insn(ctx, ISA_MIPS_R2);
6997             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
6998             register_name = "EBase";
6999             break;
7000         case CP0_REG15__CMGCRBASE:
7001             check_insn(ctx, ISA_MIPS_R2);
7002             CP0_CHECK(ctx->cmgcr);
7003             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7004             register_name = "CMGCRBase";
7005             break;
7006         default:
7007             goto cp0_unimplemented;
7008         }
7009         break;
7010     case CP0_REGISTER_16:
7011         switch (sel) {
7012         case CP0_REG16__CONFIG:
7013             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7014             register_name = "Config";
7015             break;
7016         case CP0_REG16__CONFIG1:
7017             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7018             register_name = "Config1";
7019             break;
7020         case CP0_REG16__CONFIG2:
7021             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7022             register_name = "Config2";
7023             break;
7024         case CP0_REG16__CONFIG3:
7025             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7026             register_name = "Config3";
7027             break;
7028         case CP0_REG16__CONFIG4:
7029             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7030             register_name = "Config4";
7031             break;
7032         case CP0_REG16__CONFIG5:
7033             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7034             register_name = "Config5";
7035             break;
7036         /* 6,7 are implementation dependent */
7037         case CP0_REG16__CONFIG6:
7038             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7039             register_name = "Config6";
7040             break;
7041         case CP0_REG16__CONFIG7:
7042             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7043             register_name = "Config7";
7044             break;
7045         default:
7046             goto cp0_unimplemented;
7047         }
7048         break;
7049     case CP0_REGISTER_17:
7050         switch (sel) {
7051         case CP0_REG17__LLADDR:
7052             gen_helper_dmfc0_lladdr(arg, tcg_env);
7053             register_name = "LLAddr";
7054             break;
7055         case CP0_REG17__MAAR:
7056             CP0_CHECK(ctx->mrp);
7057             gen_helper_dmfc0_maar(arg, tcg_env);
7058             register_name = "MAAR";
7059             break;
7060         case CP0_REG17__MAARI:
7061             CP0_CHECK(ctx->mrp);
7062             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7063             register_name = "MAARI";
7064             break;
7065         default:
7066             goto cp0_unimplemented;
7067         }
7068         break;
7069     case CP0_REGISTER_18:
7070         switch (sel) {
7071         case CP0_REG18__WATCHLO0:
7072         case CP0_REG18__WATCHLO1:
7073         case CP0_REG18__WATCHLO2:
7074         case CP0_REG18__WATCHLO3:
7075         case CP0_REG18__WATCHLO4:
7076         case CP0_REG18__WATCHLO5:
7077         case CP0_REG18__WATCHLO6:
7078         case CP0_REG18__WATCHLO7:
7079             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7080             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7081             register_name = "WatchLo";
7082             break;
7083         default:
7084             goto cp0_unimplemented;
7085         }
7086         break;
7087     case CP0_REGISTER_19:
7088         switch (sel) {
7089         case CP0_REG19__WATCHHI0:
7090         case CP0_REG19__WATCHHI1:
7091         case CP0_REG19__WATCHHI2:
7092         case CP0_REG19__WATCHHI3:
7093         case CP0_REG19__WATCHHI4:
7094         case CP0_REG19__WATCHHI5:
7095         case CP0_REG19__WATCHHI6:
7096         case CP0_REG19__WATCHHI7:
7097             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7098             gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7099             register_name = "WatchHi";
7100             break;
7101         default:
7102             goto cp0_unimplemented;
7103         }
7104         break;
7105     case CP0_REGISTER_20:
7106         switch (sel) {
7107         case CP0_REG20__XCONTEXT:
7108             check_insn(ctx, ISA_MIPS3);
7109             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
7110             register_name = "XContext";
7111             break;
7112         default:
7113             goto cp0_unimplemented;
7114         }
7115         break;
7116     case CP0_REGISTER_21:
7117         /* Officially reserved, but sel 0 is used for R1x000 framemask */
7118         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7119         switch (sel) {
7120         case 0:
7121             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7122             register_name = "Framemask";
7123             break;
7124         default:
7125             goto cp0_unimplemented;
7126         }
7127         break;
7128     case CP0_REGISTER_22:
7129         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7130         register_name = "'Diagnostic"; /* implementation dependent */
7131         break;
7132     case CP0_REGISTER_23:
7133         switch (sel) {
7134         case CP0_REG23__DEBUG:
7135             gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
7136             register_name = "Debug";
7137             break;
7138         case CP0_REG23__TRACECONTROL:
7139             /* PDtrace support */
7140             /* gen_helper_dmfc0_tracecontrol(arg, tcg_env);  */
7141             register_name = "TraceControl";
7142             goto cp0_unimplemented;
7143         case CP0_REG23__TRACECONTROL2:
7144             /* PDtrace support */
7145             /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */
7146             register_name = "TraceControl2";
7147             goto cp0_unimplemented;
7148         case CP0_REG23__USERTRACEDATA1:
7149             /* PDtrace support */
7150             /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/
7151             register_name = "UserTraceData1";
7152             goto cp0_unimplemented;
7153         case CP0_REG23__TRACEIBPC:
7154             /* PDtrace support */
7155             /* gen_helper_dmfc0_traceibpc(arg, tcg_env);     */
7156             register_name = "TraceIBPC";
7157             goto cp0_unimplemented;
7158         case CP0_REG23__TRACEDBPC:
7159             /* PDtrace support */
7160             /* gen_helper_dmfc0_tracedbpc(arg, tcg_env);     */
7161             register_name = "TraceDBPC";
7162             goto cp0_unimplemented;
7163         default:
7164             goto cp0_unimplemented;
7165         }
7166         break;
7167     case CP0_REGISTER_24:
7168         switch (sel) {
7169         case CP0_REG24__DEPC:
7170             /* EJTAG support */
7171             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7172             register_name = "DEPC";
7173             break;
7174         default:
7175             goto cp0_unimplemented;
7176         }
7177         break;
7178     case CP0_REGISTER_25:
7179         switch (sel) {
7180         case CP0_REG25__PERFCTL0:
7181             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7182             register_name = "Performance0";
7183             break;
7184         case CP0_REG25__PERFCNT0:
7185             /* gen_helper_dmfc0_performance1(arg); */
7186             register_name = "Performance1";
7187             goto cp0_unimplemented;
7188         case CP0_REG25__PERFCTL1:
7189             /* gen_helper_dmfc0_performance2(arg); */
7190             register_name = "Performance2";
7191             goto cp0_unimplemented;
7192         case CP0_REG25__PERFCNT1:
7193             /* gen_helper_dmfc0_performance3(arg); */
7194             register_name = "Performance3";
7195             goto cp0_unimplemented;
7196         case CP0_REG25__PERFCTL2:
7197             /* gen_helper_dmfc0_performance4(arg); */
7198             register_name = "Performance4";
7199             goto cp0_unimplemented;
7200         case CP0_REG25__PERFCNT2:
7201             /* gen_helper_dmfc0_performance5(arg); */
7202             register_name = "Performance5";
7203             goto cp0_unimplemented;
7204         case CP0_REG25__PERFCTL3:
7205             /* gen_helper_dmfc0_performance6(arg); */
7206             register_name = "Performance6";
7207             goto cp0_unimplemented;
7208         case CP0_REG25__PERFCNT3:
7209             /* gen_helper_dmfc0_performance7(arg); */
7210             register_name = "Performance7";
7211             goto cp0_unimplemented;
7212         default:
7213             goto cp0_unimplemented;
7214         }
7215         break;
7216     case CP0_REGISTER_26:
7217         switch (sel) {
7218         case CP0_REG26__ERRCTL:
7219             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7220             register_name = "ErrCtl";
7221             break;
7222         default:
7223             goto cp0_unimplemented;
7224         }
7225         break;
7226     case CP0_REGISTER_27:
7227         switch (sel) {
7228         /* ignored */
7229         case CP0_REG27__CACHERR:
7230             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7231             register_name = "CacheErr";
7232             break;
7233         default:
7234             goto cp0_unimplemented;
7235         }
7236         break;
7237     case CP0_REGISTER_28:
7238         switch (sel) {
7239         case CP0_REG28__TAGLO:
7240         case CP0_REG28__TAGLO1:
7241         case CP0_REG28__TAGLO2:
7242         case CP0_REG28__TAGLO3:
7243             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7244             register_name = "TagLo";
7245             break;
7246         case CP0_REG28__DATALO:
7247         case CP0_REG28__DATALO1:
7248         case CP0_REG28__DATALO2:
7249         case CP0_REG28__DATALO3:
7250             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7251             register_name = "DataLo";
7252             break;
7253         default:
7254             goto cp0_unimplemented;
7255         }
7256         break;
7257     case CP0_REGISTER_29:
7258         switch (sel) {
7259         case CP0_REG29__TAGHI:
7260         case CP0_REG29__TAGHI1:
7261         case CP0_REG29__TAGHI2:
7262         case CP0_REG29__TAGHI3:
7263             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7264             register_name = "TagHi";
7265             break;
7266         case CP0_REG29__DATAHI:
7267         case CP0_REG29__DATAHI1:
7268         case CP0_REG29__DATAHI2:
7269         case CP0_REG29__DATAHI3:
7270             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7271             register_name = "DataHi";
7272             break;
7273         default:
7274             goto cp0_unimplemented;
7275         }
7276         break;
7277     case CP0_REGISTER_30:
7278         switch (sel) {
7279         case CP0_REG30__ERROREPC:
7280             tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7281             register_name = "ErrorEPC";
7282             break;
7283         default:
7284             goto cp0_unimplemented;
7285         }
7286         break;
7287     case CP0_REGISTER_31:
7288         switch (sel) {
7289         case CP0_REG31__DESAVE:
7290             /* EJTAG support */
7291             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7292             register_name = "DESAVE";
7293             break;
7294         case CP0_REG31__KSCRATCH1:
7295         case CP0_REG31__KSCRATCH2:
7296         case CP0_REG31__KSCRATCH3:
7297         case CP0_REG31__KSCRATCH4:
7298         case CP0_REG31__KSCRATCH5:
7299         case CP0_REG31__KSCRATCH6:
7300             CP0_CHECK(ctx->kscrexist & (1 << sel));
7301             tcg_gen_ld_tl(arg, tcg_env,
7302                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7303             register_name = "KScratch";
7304             break;
7305         default:
7306             goto cp0_unimplemented;
7307         }
7308         break;
7309     default:
7310         goto cp0_unimplemented;
7311     }
7312     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7313     return;
7314 
7315 cp0_unimplemented:
7316     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7317                   register_name, reg, sel);
7318     gen_mfc0_unimplemented(ctx, arg);
7319 }
7320 
gen_dmtc0(DisasContext * ctx,TCGv arg,int reg,int sel)7321 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7322 {
7323     const char *register_name = "invalid";
7324     bool icount;
7325 
7326     if (sel != 0) {
7327         check_insn(ctx, ISA_MIPS_R1);
7328     }
7329 
7330     icount = translator_io_start(&ctx->base);
7331 
7332     switch (reg) {
7333     case CP0_REGISTER_00:
7334         switch (sel) {
7335         case CP0_REG00__INDEX:
7336             gen_helper_mtc0_index(tcg_env, arg);
7337             register_name = "Index";
7338             break;
7339         case CP0_REG00__MVPCONTROL:
7340             CP0_CHECK(disas_mt_available(ctx));
7341             gen_helper_mtc0_mvpcontrol(tcg_env, arg);
7342             register_name = "MVPControl";
7343             break;
7344         case CP0_REG00__MVPCONF0:
7345             CP0_CHECK(disas_mt_available(ctx));
7346             /* ignored */
7347             register_name = "MVPConf0";
7348             break;
7349         case CP0_REG00__MVPCONF1:
7350             CP0_CHECK(disas_mt_available(ctx));
7351             /* ignored */
7352             register_name = "MVPConf1";
7353             break;
7354         case CP0_REG00__VPCONTROL:
7355             CP0_CHECK(ctx->vp);
7356             /* ignored */
7357             register_name = "VPControl";
7358             break;
7359         default:
7360             goto cp0_unimplemented;
7361         }
7362         break;
7363     case CP0_REGISTER_01:
7364         switch (sel) {
7365         case CP0_REG01__RANDOM:
7366             /* ignored */
7367             register_name = "Random";
7368             break;
7369         case CP0_REG01__VPECONTROL:
7370             CP0_CHECK(disas_mt_available(ctx));
7371             gen_helper_mtc0_vpecontrol(tcg_env, arg);
7372             register_name = "VPEControl";
7373             break;
7374         case CP0_REG01__VPECONF0:
7375             CP0_CHECK(disas_mt_available(ctx));
7376             gen_helper_mtc0_vpeconf0(tcg_env, arg);
7377             register_name = "VPEConf0";
7378             break;
7379         case CP0_REG01__VPECONF1:
7380             CP0_CHECK(disas_mt_available(ctx));
7381             gen_helper_mtc0_vpeconf1(tcg_env, arg);
7382             register_name = "VPEConf1";
7383             break;
7384         case CP0_REG01__YQMASK:
7385             CP0_CHECK(disas_mt_available(ctx));
7386             gen_helper_mtc0_yqmask(tcg_env, arg);
7387             register_name = "YQMask";
7388             break;
7389         case CP0_REG01__VPESCHEDULE:
7390             CP0_CHECK(disas_mt_available(ctx));
7391             tcg_gen_st_tl(arg, tcg_env,
7392                           offsetof(CPUMIPSState, CP0_VPESchedule));
7393             register_name = "VPESchedule";
7394             break;
7395         case CP0_REG01__VPESCHEFBACK:
7396             CP0_CHECK(disas_mt_available(ctx));
7397             tcg_gen_st_tl(arg, tcg_env,
7398                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7399             register_name = "VPEScheFBack";
7400             break;
7401         case CP0_REG01__VPEOPT:
7402             CP0_CHECK(disas_mt_available(ctx));
7403             gen_helper_mtc0_vpeopt(tcg_env, arg);
7404             register_name = "VPEOpt";
7405             break;
7406         default:
7407             goto cp0_unimplemented;
7408         }
7409         break;
7410     case CP0_REGISTER_02:
7411         switch (sel) {
7412         case CP0_REG02__ENTRYLO0:
7413             gen_helper_dmtc0_entrylo0(tcg_env, arg);
7414             register_name = "EntryLo0";
7415             break;
7416         case CP0_REG02__TCSTATUS:
7417             CP0_CHECK(disas_mt_available(ctx));
7418             gen_helper_mtc0_tcstatus(tcg_env, arg);
7419             register_name = "TCStatus";
7420             break;
7421         case CP0_REG02__TCBIND:
7422             CP0_CHECK(disas_mt_available(ctx));
7423             gen_helper_mtc0_tcbind(tcg_env, arg);
7424             register_name = "TCBind";
7425             break;
7426         case CP0_REG02__TCRESTART:
7427             CP0_CHECK(disas_mt_available(ctx));
7428             gen_helper_mtc0_tcrestart(tcg_env, arg);
7429             register_name = "TCRestart";
7430             break;
7431         case CP0_REG02__TCHALT:
7432             CP0_CHECK(disas_mt_available(ctx));
7433             gen_helper_mtc0_tchalt(tcg_env, arg);
7434             register_name = "TCHalt";
7435             break;
7436         case CP0_REG02__TCCONTEXT:
7437             CP0_CHECK(disas_mt_available(ctx));
7438             gen_helper_mtc0_tccontext(tcg_env, arg);
7439             register_name = "TCContext";
7440             break;
7441         case CP0_REG02__TCSCHEDULE:
7442             CP0_CHECK(disas_mt_available(ctx));
7443             gen_helper_mtc0_tcschedule(tcg_env, arg);
7444             register_name = "TCSchedule";
7445             break;
7446         case CP0_REG02__TCSCHEFBACK:
7447             CP0_CHECK(disas_mt_available(ctx));
7448             gen_helper_mtc0_tcschefback(tcg_env, arg);
7449             register_name = "TCScheFBack";
7450             break;
7451         default:
7452             goto cp0_unimplemented;
7453         }
7454         break;
7455     case CP0_REGISTER_03:
7456         switch (sel) {
7457         case CP0_REG03__ENTRYLO1:
7458             gen_helper_dmtc0_entrylo1(tcg_env, arg);
7459             register_name = "EntryLo1";
7460             break;
7461         case CP0_REG03__GLOBALNUM:
7462             CP0_CHECK(ctx->vp);
7463             /* ignored */
7464             register_name = "GlobalNumber";
7465             break;
7466         default:
7467             goto cp0_unimplemented;
7468         }
7469         break;
7470     case CP0_REGISTER_04:
7471         switch (sel) {
7472         case CP0_REG04__CONTEXT:
7473             gen_helper_mtc0_context(tcg_env, arg);
7474             register_name = "Context";
7475             break;
7476         case CP0_REG04__CONTEXTCONFIG:
7477             /* SmartMIPS ASE */
7478             /* gen_helper_dmtc0_contextconfig(arg); */
7479             register_name = "ContextConfig";
7480             goto cp0_unimplemented;
7481         case CP0_REG04__USERLOCAL:
7482             CP0_CHECK(ctx->ulri);
7483             tcg_gen_st_tl(arg, tcg_env,
7484                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7485             register_name = "UserLocal";
7486             break;
7487         case CP0_REG04__MMID:
7488             CP0_CHECK(ctx->mi);
7489             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7490             register_name = "MMID";
7491             break;
7492         default:
7493             goto cp0_unimplemented;
7494         }
7495         break;
7496     case CP0_REGISTER_05:
7497         switch (sel) {
7498         case CP0_REG05__PAGEMASK:
7499             gen_helper_mtc0_pagemask(tcg_env, arg);
7500             register_name = "PageMask";
7501             break;
7502         case CP0_REG05__PAGEGRAIN:
7503             check_insn(ctx, ISA_MIPS_R2);
7504             gen_helper_mtc0_pagegrain(tcg_env, arg);
7505             register_name = "PageGrain";
7506             break;
7507         case CP0_REG05__SEGCTL0:
7508             CP0_CHECK(ctx->sc);
7509             gen_helper_mtc0_segctl0(tcg_env, arg);
7510             register_name = "SegCtl0";
7511             break;
7512         case CP0_REG05__SEGCTL1:
7513             CP0_CHECK(ctx->sc);
7514             gen_helper_mtc0_segctl1(tcg_env, arg);
7515             register_name = "SegCtl1";
7516             break;
7517         case CP0_REG05__SEGCTL2:
7518             CP0_CHECK(ctx->sc);
7519             gen_helper_mtc0_segctl2(tcg_env, arg);
7520             register_name = "SegCtl2";
7521             break;
7522         case CP0_REG05__PWBASE:
7523             check_pw(ctx);
7524             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
7525             register_name = "PWBase";
7526             break;
7527         case CP0_REG05__PWFIELD:
7528             check_pw(ctx);
7529             gen_helper_mtc0_pwfield(tcg_env, arg);
7530             register_name = "PWField";
7531             break;
7532         case CP0_REG05__PWSIZE:
7533             check_pw(ctx);
7534             gen_helper_mtc0_pwsize(tcg_env, arg);
7535             register_name = "PWSize";
7536             break;
7537         default:
7538             goto cp0_unimplemented;
7539         }
7540         break;
7541     case CP0_REGISTER_06:
7542         switch (sel) {
7543         case CP0_REG06__WIRED:
7544             gen_helper_mtc0_wired(tcg_env, arg);
7545             register_name = "Wired";
7546             break;
7547         case CP0_REG06__SRSCONF0:
7548             check_insn(ctx, ISA_MIPS_R2);
7549             gen_helper_mtc0_srsconf0(tcg_env, arg);
7550             register_name = "SRSConf0";
7551             break;
7552         case CP0_REG06__SRSCONF1:
7553             check_insn(ctx, ISA_MIPS_R2);
7554             gen_helper_mtc0_srsconf1(tcg_env, arg);
7555             register_name = "SRSConf1";
7556             break;
7557         case CP0_REG06__SRSCONF2:
7558             check_insn(ctx, ISA_MIPS_R2);
7559             gen_helper_mtc0_srsconf2(tcg_env, arg);
7560             register_name = "SRSConf2";
7561             break;
7562         case CP0_REG06__SRSCONF3:
7563             check_insn(ctx, ISA_MIPS_R2);
7564             gen_helper_mtc0_srsconf3(tcg_env, arg);
7565             register_name = "SRSConf3";
7566             break;
7567         case CP0_REG06__SRSCONF4:
7568             check_insn(ctx, ISA_MIPS_R2);
7569             gen_helper_mtc0_srsconf4(tcg_env, arg);
7570             register_name = "SRSConf4";
7571             break;
7572         case CP0_REG06__PWCTL:
7573             check_pw(ctx);
7574             gen_helper_mtc0_pwctl(tcg_env, arg);
7575             register_name = "PWCtl";
7576             break;
7577         default:
7578             goto cp0_unimplemented;
7579         }
7580         break;
7581     case CP0_REGISTER_07:
7582         switch (sel) {
7583         case CP0_REG07__HWRENA:
7584             check_insn(ctx, ISA_MIPS_R2);
7585             gen_helper_mtc0_hwrena(tcg_env, arg);
7586             ctx->base.is_jmp = DISAS_STOP;
7587             register_name = "HWREna";
7588             break;
7589         default:
7590             goto cp0_unimplemented;
7591         }
7592         break;
7593     case CP0_REGISTER_08:
7594         switch (sel) {
7595         case CP0_REG08__BADVADDR:
7596             /* ignored */
7597             register_name = "BadVAddr";
7598             break;
7599         case CP0_REG08__BADINSTR:
7600             /* ignored */
7601             register_name = "BadInstr";
7602             break;
7603         case CP0_REG08__BADINSTRP:
7604             /* ignored */
7605             register_name = "BadInstrP";
7606             break;
7607         case CP0_REG08__BADINSTRX:
7608             /* ignored */
7609             register_name = "BadInstrX";
7610             break;
7611         default:
7612             goto cp0_unimplemented;
7613         }
7614         break;
7615     case CP0_REGISTER_09:
7616         switch (sel) {
7617         case CP0_REG09__COUNT:
7618             gen_helper_mtc0_count(tcg_env, arg);
7619             register_name = "Count";
7620             break;
7621         default:
7622             goto cp0_unimplemented;
7623         }
7624         /* Stop translation as we may have switched the execution mode */
7625         ctx->base.is_jmp = DISAS_STOP;
7626         break;
7627     case CP0_REGISTER_10:
7628         switch (sel) {
7629         case CP0_REG10__ENTRYHI:
7630             gen_helper_mtc0_entryhi(tcg_env, arg);
7631             register_name = "EntryHi";
7632             break;
7633         default:
7634             goto cp0_unimplemented;
7635         }
7636         break;
7637     case CP0_REGISTER_11:
7638         switch (sel) {
7639         case CP0_REG11__COMPARE:
7640             gen_helper_mtc0_compare(tcg_env, arg);
7641             register_name = "Compare";
7642             break;
7643         /* 6,7 are implementation dependent */
7644         default:
7645             goto cp0_unimplemented;
7646         }
7647         /* Stop translation as we may have switched the execution mode */
7648         ctx->base.is_jmp = DISAS_STOP;
7649         break;
7650     case CP0_REGISTER_12:
7651         switch (sel) {
7652         case CP0_REG12__STATUS:
7653             save_cpu_state(ctx, 1);
7654             gen_helper_mtc0_status(tcg_env, arg);
7655             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7656             gen_save_pc(ctx->base.pc_next + 4);
7657             ctx->base.is_jmp = DISAS_EXIT;
7658             register_name = "Status";
7659             break;
7660         case CP0_REG12__INTCTL:
7661             check_insn(ctx, ISA_MIPS_R2);
7662             gen_helper_mtc0_intctl(tcg_env, arg);
7663             /* Stop translation as we may have switched the execution mode */
7664             ctx->base.is_jmp = DISAS_STOP;
7665             register_name = "IntCtl";
7666             break;
7667         case CP0_REG12__SRSCTL:
7668             check_insn(ctx, ISA_MIPS_R2);
7669             gen_helper_mtc0_srsctl(tcg_env, arg);
7670             /* Stop translation as we may have switched the execution mode */
7671             ctx->base.is_jmp = DISAS_STOP;
7672             register_name = "SRSCtl";
7673             break;
7674         case CP0_REG12__SRSMAP:
7675             check_insn(ctx, ISA_MIPS_R2);
7676             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7677             /* Stop translation as we may have switched the execution mode */
7678             ctx->base.is_jmp = DISAS_STOP;
7679             register_name = "SRSMap";
7680             break;
7681         default:
7682             goto cp0_unimplemented;
7683         }
7684         break;
7685     case CP0_REGISTER_13:
7686         switch (sel) {
7687         case CP0_REG13__CAUSE:
7688             save_cpu_state(ctx, 1);
7689             gen_helper_mtc0_cause(tcg_env, arg);
7690             /*
7691              * Stop translation as we may have triggered an interrupt.
7692              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7693              * translated code to check for pending interrupts.
7694              */
7695             gen_save_pc(ctx->base.pc_next + 4);
7696             ctx->base.is_jmp = DISAS_EXIT;
7697             register_name = "Cause";
7698             break;
7699         default:
7700             goto cp0_unimplemented;
7701         }
7702         break;
7703     case CP0_REGISTER_14:
7704         switch (sel) {
7705         case CP0_REG14__EPC:
7706             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7707             register_name = "EPC";
7708             break;
7709         default:
7710             goto cp0_unimplemented;
7711         }
7712         break;
7713     case CP0_REGISTER_15:
7714         switch (sel) {
7715         case CP0_REG15__PRID:
7716             /* ignored */
7717             register_name = "PRid";
7718             break;
7719         case CP0_REG15__EBASE:
7720             check_insn(ctx, ISA_MIPS_R2);
7721             gen_helper_mtc0_ebase(tcg_env, arg);
7722             register_name = "EBase";
7723             break;
7724         default:
7725             goto cp0_unimplemented;
7726         }
7727         break;
7728     case CP0_REGISTER_16:
7729         switch (sel) {
7730         case CP0_REG16__CONFIG:
7731             gen_helper_mtc0_config0(tcg_env, arg);
7732             register_name = "Config";
7733             /* Stop translation as we may have switched the execution mode */
7734             ctx->base.is_jmp = DISAS_STOP;
7735             break;
7736         case CP0_REG16__CONFIG1:
7737             /* ignored, read only */
7738             register_name = "Config1";
7739             break;
7740         case CP0_REG16__CONFIG2:
7741             gen_helper_mtc0_config2(tcg_env, arg);
7742             register_name = "Config2";
7743             /* Stop translation as we may have switched the execution mode */
7744             ctx->base.is_jmp = DISAS_STOP;
7745             break;
7746         case CP0_REG16__CONFIG3:
7747             gen_helper_mtc0_config3(tcg_env, arg);
7748             register_name = "Config3";
7749             /* Stop translation as we may have switched the execution mode */
7750             ctx->base.is_jmp = DISAS_STOP;
7751             break;
7752         case CP0_REG16__CONFIG4:
7753             /* currently ignored */
7754             register_name = "Config4";
7755             break;
7756         case CP0_REG16__CONFIG5:
7757             gen_helper_mtc0_config5(tcg_env, arg);
7758             register_name = "Config5";
7759             /* Stop translation as we may have switched the execution mode */
7760             ctx->base.is_jmp = DISAS_STOP;
7761             break;
7762         /* 6,7 are implementation dependent */
7763         default:
7764             register_name = "Invalid config selector";
7765             goto cp0_unimplemented;
7766         }
7767         break;
7768     case CP0_REGISTER_17:
7769         switch (sel) {
7770         case CP0_REG17__LLADDR:
7771             gen_helper_mtc0_lladdr(tcg_env, arg);
7772             register_name = "LLAddr";
7773             break;
7774         case CP0_REG17__MAAR:
7775             CP0_CHECK(ctx->mrp);
7776             gen_helper_mtc0_maar(tcg_env, arg);
7777             register_name = "MAAR";
7778             break;
7779         case CP0_REG17__MAARI:
7780             CP0_CHECK(ctx->mrp);
7781             gen_helper_mtc0_maari(tcg_env, arg);
7782             register_name = "MAARI";
7783             break;
7784         default:
7785             goto cp0_unimplemented;
7786         }
7787         break;
7788     case CP0_REGISTER_18:
7789         switch (sel) {
7790         case CP0_REG18__WATCHLO0:
7791         case CP0_REG18__WATCHLO1:
7792         case CP0_REG18__WATCHLO2:
7793         case CP0_REG18__WATCHLO3:
7794         case CP0_REG18__WATCHLO4:
7795         case CP0_REG18__WATCHLO5:
7796         case CP0_REG18__WATCHLO6:
7797         case CP0_REG18__WATCHLO7:
7798             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7799             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7800             register_name = "WatchLo";
7801             break;
7802         default:
7803             goto cp0_unimplemented;
7804         }
7805         break;
7806     case CP0_REGISTER_19:
7807         switch (sel) {
7808         case CP0_REG19__WATCHHI0:
7809         case CP0_REG19__WATCHHI1:
7810         case CP0_REG19__WATCHHI2:
7811         case CP0_REG19__WATCHHI3:
7812         case CP0_REG19__WATCHHI4:
7813         case CP0_REG19__WATCHHI5:
7814         case CP0_REG19__WATCHHI6:
7815         case CP0_REG19__WATCHHI7:
7816             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7817             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7818             register_name = "WatchHi";
7819             break;
7820         default:
7821             goto cp0_unimplemented;
7822         }
7823         break;
7824     case CP0_REGISTER_20:
7825         switch (sel) {
7826         case CP0_REG20__XCONTEXT:
7827             check_insn(ctx, ISA_MIPS3);
7828             gen_helper_mtc0_xcontext(tcg_env, arg);
7829             register_name = "XContext";
7830             break;
7831         default:
7832             goto cp0_unimplemented;
7833         }
7834         break;
7835     case CP0_REGISTER_21:
7836        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7837         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7838         switch (sel) {
7839         case 0:
7840             gen_helper_mtc0_framemask(tcg_env, arg);
7841             register_name = "Framemask";
7842             break;
7843         default:
7844             goto cp0_unimplemented;
7845         }
7846         break;
7847     case CP0_REGISTER_22:
7848         /* ignored */
7849         register_name = "Diagnostic"; /* implementation dependent */
7850         break;
7851     case CP0_REGISTER_23:
7852         switch (sel) {
7853         case CP0_REG23__DEBUG:
7854             gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
7855             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7856             gen_save_pc(ctx->base.pc_next + 4);
7857             ctx->base.is_jmp = DISAS_EXIT;
7858             register_name = "Debug";
7859             break;
7860         case CP0_REG23__TRACECONTROL:
7861             /* PDtrace support */
7862             /* gen_helper_mtc0_tracecontrol(tcg_env, arg);  */
7863             /* Stop translation as we may have switched the execution mode */
7864             ctx->base.is_jmp = DISAS_STOP;
7865             register_name = "TraceControl";
7866             goto cp0_unimplemented;
7867         case CP0_REG23__TRACECONTROL2:
7868             /* PDtrace support */
7869             /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
7870             /* Stop translation as we may have switched the execution mode */
7871             ctx->base.is_jmp = DISAS_STOP;
7872             register_name = "TraceControl2";
7873             goto cp0_unimplemented;
7874         case CP0_REG23__USERTRACEDATA1:
7875             /* PDtrace support */
7876             /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
7877             /* Stop translation as we may have switched the execution mode */
7878             ctx->base.is_jmp = DISAS_STOP;
7879             register_name = "UserTraceData1";
7880             goto cp0_unimplemented;
7881         case CP0_REG23__TRACEIBPC:
7882             /* PDtrace support */
7883             /* gen_helper_mtc0_traceibpc(tcg_env, arg);     */
7884             /* Stop translation as we may have switched the execution mode */
7885             ctx->base.is_jmp = DISAS_STOP;
7886             register_name = "TraceIBPC";
7887             goto cp0_unimplemented;
7888         case CP0_REG23__TRACEDBPC:
7889             /* PDtrace support */
7890             /* gen_helper_mtc0_tracedbpc(tcg_env, arg);     */
7891             /* Stop translation as we may have switched the execution mode */
7892             ctx->base.is_jmp = DISAS_STOP;
7893             register_name = "TraceDBPC";
7894             goto cp0_unimplemented;
7895         default:
7896             goto cp0_unimplemented;
7897         }
7898         break;
7899     case CP0_REGISTER_24:
7900         switch (sel) {
7901         case CP0_REG24__DEPC:
7902             /* EJTAG support */
7903             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7904             register_name = "DEPC";
7905             break;
7906         default:
7907             goto cp0_unimplemented;
7908         }
7909         break;
7910     case CP0_REGISTER_25:
7911         switch (sel) {
7912         case CP0_REG25__PERFCTL0:
7913             gen_helper_mtc0_performance0(tcg_env, arg);
7914             register_name = "Performance0";
7915             break;
7916         case CP0_REG25__PERFCNT0:
7917             /* gen_helper_mtc0_performance1(tcg_env, arg); */
7918             register_name = "Performance1";
7919             goto cp0_unimplemented;
7920         case CP0_REG25__PERFCTL1:
7921             /* gen_helper_mtc0_performance2(tcg_env, arg); */
7922             register_name = "Performance2";
7923             goto cp0_unimplemented;
7924         case CP0_REG25__PERFCNT1:
7925             /* gen_helper_mtc0_performance3(tcg_env, arg); */
7926             register_name = "Performance3";
7927             goto cp0_unimplemented;
7928         case CP0_REG25__PERFCTL2:
7929             /* gen_helper_mtc0_performance4(tcg_env, arg); */
7930             register_name = "Performance4";
7931             goto cp0_unimplemented;
7932         case CP0_REG25__PERFCNT2:
7933             /* gen_helper_mtc0_performance5(tcg_env, arg); */
7934             register_name = "Performance5";
7935             goto cp0_unimplemented;
7936         case CP0_REG25__PERFCTL3:
7937             /* gen_helper_mtc0_performance6(tcg_env, arg); */
7938             register_name = "Performance6";
7939             goto cp0_unimplemented;
7940         case CP0_REG25__PERFCNT3:
7941             /* gen_helper_mtc0_performance7(tcg_env, arg); */
7942             register_name = "Performance7";
7943             goto cp0_unimplemented;
7944         default:
7945             goto cp0_unimplemented;
7946         }
7947         break;
7948     case CP0_REGISTER_26:
7949         switch (sel) {
7950         case CP0_REG26__ERRCTL:
7951             gen_helper_mtc0_errctl(tcg_env, arg);
7952             ctx->base.is_jmp = DISAS_STOP;
7953             register_name = "ErrCtl";
7954             break;
7955         default:
7956             goto cp0_unimplemented;
7957         }
7958         break;
7959     case CP0_REGISTER_27:
7960         switch (sel) {
7961         case CP0_REG27__CACHERR:
7962             /* ignored */
7963             register_name = "CacheErr";
7964             break;
7965         default:
7966             goto cp0_unimplemented;
7967         }
7968         break;
7969     case CP0_REGISTER_28:
7970         switch (sel) {
7971         case CP0_REG28__TAGLO:
7972         case CP0_REG28__TAGLO1:
7973         case CP0_REG28__TAGLO2:
7974         case CP0_REG28__TAGLO3:
7975             gen_helper_mtc0_taglo(tcg_env, arg);
7976             register_name = "TagLo";
7977             break;
7978         case CP0_REG28__DATALO:
7979         case CP0_REG28__DATALO1:
7980         case CP0_REG28__DATALO2:
7981         case CP0_REG28__DATALO3:
7982             gen_helper_mtc0_datalo(tcg_env, arg);
7983             register_name = "DataLo";
7984             break;
7985         default:
7986             goto cp0_unimplemented;
7987         }
7988         break;
7989     case CP0_REGISTER_29:
7990         switch (sel) {
7991         case CP0_REG29__TAGHI:
7992         case CP0_REG29__TAGHI1:
7993         case CP0_REG29__TAGHI2:
7994         case CP0_REG29__TAGHI3:
7995             gen_helper_mtc0_taghi(tcg_env, arg);
7996             register_name = "TagHi";
7997             break;
7998         case CP0_REG29__DATAHI:
7999         case CP0_REG29__DATAHI1:
8000         case CP0_REG29__DATAHI2:
8001         case CP0_REG29__DATAHI3:
8002             gen_helper_mtc0_datahi(tcg_env, arg);
8003             register_name = "DataHi";
8004             break;
8005         default:
8006             register_name = "invalid sel";
8007             goto cp0_unimplemented;
8008         }
8009         break;
8010     case CP0_REGISTER_30:
8011         switch (sel) {
8012         case CP0_REG30__ERROREPC:
8013             tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8014             register_name = "ErrorEPC";
8015             break;
8016         default:
8017             goto cp0_unimplemented;
8018         }
8019         break;
8020     case CP0_REGISTER_31:
8021         switch (sel) {
8022         case CP0_REG31__DESAVE:
8023             /* EJTAG support */
8024             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8025             register_name = "DESAVE";
8026             break;
8027         case CP0_REG31__KSCRATCH1:
8028         case CP0_REG31__KSCRATCH2:
8029         case CP0_REG31__KSCRATCH3:
8030         case CP0_REG31__KSCRATCH4:
8031         case CP0_REG31__KSCRATCH5:
8032         case CP0_REG31__KSCRATCH6:
8033             CP0_CHECK(ctx->kscrexist & (1 << sel));
8034             tcg_gen_st_tl(arg, tcg_env,
8035                           offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8036             register_name = "KScratch";
8037             break;
8038         default:
8039             goto cp0_unimplemented;
8040         }
8041         break;
8042     default:
8043         goto cp0_unimplemented;
8044     }
8045     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8046 
8047     /* For simplicity assume that all writes can cause interrupts.  */
8048     if (icount) {
8049         /*
8050          * DISAS_STOP isn't sufficient, we need to ensure we break out of
8051          * translated code to check for pending interrupts.
8052          */
8053         gen_save_pc(ctx->base.pc_next + 4);
8054         ctx->base.is_jmp = DISAS_EXIT;
8055     }
8056     return;
8057 
8058 cp0_unimplemented:
8059     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8060                   register_name, reg, sel);
8061 }
8062 #endif /* TARGET_MIPS64 */
8063 
gen_mftr(CPUMIPSState * env,DisasContext * ctx,int rt,int rd,int u,int sel,int h)8064 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8065                      int u, int sel, int h)
8066 {
8067     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8068     TCGv t0 = tcg_temp_new();
8069 
8070     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8071         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8072          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8073         tcg_gen_movi_tl(t0, -1);
8074     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8075                (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8076         tcg_gen_movi_tl(t0, -1);
8077     } else if (u == 0) {
8078         switch (rt) {
8079         case 1:
8080             switch (sel) {
8081             case 1:
8082                 gen_helper_mftc0_vpecontrol(t0, tcg_env);
8083                 break;
8084             case 2:
8085                 gen_helper_mftc0_vpeconf0(t0, tcg_env);
8086                 break;
8087             default:
8088                 goto die;
8089                 break;
8090             }
8091             break;
8092         case 2:
8093             switch (sel) {
8094             case 1:
8095                 gen_helper_mftc0_tcstatus(t0, tcg_env);
8096                 break;
8097             case 2:
8098                 gen_helper_mftc0_tcbind(t0, tcg_env);
8099                 break;
8100             case 3:
8101                 gen_helper_mftc0_tcrestart(t0, tcg_env);
8102                 break;
8103             case 4:
8104                 gen_helper_mftc0_tchalt(t0, tcg_env);
8105                 break;
8106             case 5:
8107                 gen_helper_mftc0_tccontext(t0, tcg_env);
8108                 break;
8109             case 6:
8110                 gen_helper_mftc0_tcschedule(t0, tcg_env);
8111                 break;
8112             case 7:
8113                 gen_helper_mftc0_tcschefback(t0, tcg_env);
8114                 break;
8115             default:
8116                 gen_mfc0(ctx, t0, rt, sel);
8117                 break;
8118             }
8119             break;
8120         case 10:
8121             switch (sel) {
8122             case 0:
8123                 gen_helper_mftc0_entryhi(t0, tcg_env);
8124                 break;
8125             default:
8126                 gen_mfc0(ctx, t0, rt, sel);
8127                 break;
8128             }
8129             break;
8130         case 12:
8131             switch (sel) {
8132             case 0:
8133                 gen_helper_mftc0_status(t0, tcg_env);
8134                 break;
8135             default:
8136                 gen_mfc0(ctx, t0, rt, sel);
8137                 break;
8138             }
8139             break;
8140         case 13:
8141             switch (sel) {
8142             case 0:
8143                 gen_helper_mftc0_cause(t0, tcg_env);
8144                 break;
8145             default:
8146                 goto die;
8147                 break;
8148             }
8149             break;
8150         case 14:
8151             switch (sel) {
8152             case 0:
8153                 gen_helper_mftc0_epc(t0, tcg_env);
8154                 break;
8155             default:
8156                 goto die;
8157                 break;
8158             }
8159             break;
8160         case 15:
8161             switch (sel) {
8162             case 1:
8163                 gen_helper_mftc0_ebase(t0, tcg_env);
8164                 break;
8165             default:
8166                 goto die;
8167                 break;
8168             }
8169             break;
8170         case 16:
8171             switch (sel) {
8172             case 0:
8173             case 1:
8174             case 2:
8175             case 3:
8176             case 4:
8177             case 5:
8178             case 6:
8179             case 7:
8180                 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel));
8181                 break;
8182             default:
8183                 goto die;
8184                 break;
8185             }
8186             break;
8187         case 23:
8188             switch (sel) {
8189             case 0:
8190                 gen_helper_mftc0_debug(t0, tcg_env);
8191                 break;
8192             default:
8193                 gen_mfc0(ctx, t0, rt, sel);
8194                 break;
8195             }
8196             break;
8197         default:
8198             gen_mfc0(ctx, t0, rt, sel);
8199         }
8200     } else {
8201         switch (sel) {
8202         /* GPR registers. */
8203         case 0:
8204             gen_helper_1e0i(mftgpr, t0, rt);
8205             break;
8206         /* Auxiliary CPU registers */
8207         case 1:
8208             switch (rt) {
8209             case 0:
8210                 gen_helper_1e0i(mftlo, t0, 0);
8211                 break;
8212             case 1:
8213                 gen_helper_1e0i(mfthi, t0, 0);
8214                 break;
8215             case 2:
8216                 gen_helper_1e0i(mftacx, t0, 0);
8217                 break;
8218             case 4:
8219                 gen_helper_1e0i(mftlo, t0, 1);
8220                 break;
8221             case 5:
8222                 gen_helper_1e0i(mfthi, t0, 1);
8223                 break;
8224             case 6:
8225                 gen_helper_1e0i(mftacx, t0, 1);
8226                 break;
8227             case 8:
8228                 gen_helper_1e0i(mftlo, t0, 2);
8229                 break;
8230             case 9:
8231                 gen_helper_1e0i(mfthi, t0, 2);
8232                 break;
8233             case 10:
8234                 gen_helper_1e0i(mftacx, t0, 2);
8235                 break;
8236             case 12:
8237                 gen_helper_1e0i(mftlo, t0, 3);
8238                 break;
8239             case 13:
8240                 gen_helper_1e0i(mfthi, t0, 3);
8241                 break;
8242             case 14:
8243                 gen_helper_1e0i(mftacx, t0, 3);
8244                 break;
8245             case 16:
8246                 gen_helper_mftdsp(t0, tcg_env);
8247                 break;
8248             default:
8249                 goto die;
8250             }
8251             break;
8252         /* Floating point (COP1). */
8253         case 2:
8254             /* XXX: For now we support only a single FPU context. */
8255             if (h == 0) {
8256                 TCGv_i32 fp0 = tcg_temp_new_i32();
8257 
8258                 gen_load_fpr32(ctx, fp0, rt);
8259                 tcg_gen_ext_i32_tl(t0, fp0);
8260             } else {
8261                 TCGv_i32 fp0 = tcg_temp_new_i32();
8262 
8263                 gen_load_fpr32h(ctx, fp0, rt);
8264                 tcg_gen_ext_i32_tl(t0, fp0);
8265             }
8266             break;
8267         case 3:
8268             /* XXX: For now we support only a single FPU context. */
8269             gen_helper_1e0i(cfc1, t0, rt);
8270             break;
8271         /* COP2: Not implemented. */
8272         case 4:
8273         case 5:
8274             /* fall through */
8275         default:
8276             goto die;
8277         }
8278     }
8279     trace_mips_translate_tr("mftr", rt, u, sel, h);
8280     gen_store_gpr(t0, rd);
8281     return;
8282 
8283 die:
8284     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8285     gen_reserved_instruction(ctx);
8286 }
8287 
gen_mttr(CPUMIPSState * env,DisasContext * ctx,int rd,int rt,int u,int sel,int h)8288 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8289                      int u, int sel, int h)
8290 {
8291     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8292     TCGv t0 = tcg_temp_new();
8293 
8294     gen_load_gpr(t0, rt);
8295     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8296         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8297          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8298         /* NOP */
8299         ;
8300     } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8301              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8302         /* NOP */
8303         ;
8304     } else if (u == 0) {
8305         switch (rd) {
8306         case 1:
8307             switch (sel) {
8308             case 1:
8309                 gen_helper_mttc0_vpecontrol(tcg_env, t0);
8310                 break;
8311             case 2:
8312                 gen_helper_mttc0_vpeconf0(tcg_env, t0);
8313                 break;
8314             default:
8315                 goto die;
8316                 break;
8317             }
8318             break;
8319         case 2:
8320             switch (sel) {
8321             case 1:
8322                 gen_helper_mttc0_tcstatus(tcg_env, t0);
8323                 break;
8324             case 2:
8325                 gen_helper_mttc0_tcbind(tcg_env, t0);
8326                 break;
8327             case 3:
8328                 gen_helper_mttc0_tcrestart(tcg_env, t0);
8329                 break;
8330             case 4:
8331                 gen_helper_mttc0_tchalt(tcg_env, t0);
8332                 break;
8333             case 5:
8334                 gen_helper_mttc0_tccontext(tcg_env, t0);
8335                 break;
8336             case 6:
8337                 gen_helper_mttc0_tcschedule(tcg_env, t0);
8338                 break;
8339             case 7:
8340                 gen_helper_mttc0_tcschefback(tcg_env, t0);
8341                 break;
8342             default:
8343                 gen_mtc0(ctx, t0, rd, sel);
8344                 break;
8345             }
8346             break;
8347         case 10:
8348             switch (sel) {
8349             case 0:
8350                 gen_helper_mttc0_entryhi(tcg_env, t0);
8351                 break;
8352             default:
8353                 gen_mtc0(ctx, t0, rd, sel);
8354                 break;
8355             }
8356             break;
8357         case 12:
8358             switch (sel) {
8359             case 0:
8360                 gen_helper_mttc0_status(tcg_env, t0);
8361                 break;
8362             default:
8363                 gen_mtc0(ctx, t0, rd, sel);
8364                 break;
8365             }
8366             break;
8367         case 13:
8368             switch (sel) {
8369             case 0:
8370                 gen_helper_mttc0_cause(tcg_env, t0);
8371                 break;
8372             default:
8373                 goto die;
8374                 break;
8375             }
8376             break;
8377         case 15:
8378             switch (sel) {
8379             case 1:
8380                 gen_helper_mttc0_ebase(tcg_env, t0);
8381                 break;
8382             default:
8383                 goto die;
8384                 break;
8385             }
8386             break;
8387         case 23:
8388             switch (sel) {
8389             case 0:
8390                 gen_helper_mttc0_debug(tcg_env, t0);
8391                 break;
8392             default:
8393                 gen_mtc0(ctx, t0, rd, sel);
8394                 break;
8395             }
8396             break;
8397         default:
8398             gen_mtc0(ctx, t0, rd, sel);
8399         }
8400     } else {
8401         switch (sel) {
8402         /* GPR registers. */
8403         case 0:
8404             gen_helper_0e1i(mttgpr, t0, rd);
8405             break;
8406         /* Auxiliary CPU registers */
8407         case 1:
8408             switch (rd) {
8409             case 0:
8410                 gen_helper_0e1i(mttlo, t0, 0);
8411                 break;
8412             case 1:
8413                 gen_helper_0e1i(mtthi, t0, 0);
8414                 break;
8415             case 2:
8416                 gen_helper_0e1i(mttacx, t0, 0);
8417                 break;
8418             case 4:
8419                 gen_helper_0e1i(mttlo, t0, 1);
8420                 break;
8421             case 5:
8422                 gen_helper_0e1i(mtthi, t0, 1);
8423                 break;
8424             case 6:
8425                 gen_helper_0e1i(mttacx, t0, 1);
8426                 break;
8427             case 8:
8428                 gen_helper_0e1i(mttlo, t0, 2);
8429                 break;
8430             case 9:
8431                 gen_helper_0e1i(mtthi, t0, 2);
8432                 break;
8433             case 10:
8434                 gen_helper_0e1i(mttacx, t0, 2);
8435                 break;
8436             case 12:
8437                 gen_helper_0e1i(mttlo, t0, 3);
8438                 break;
8439             case 13:
8440                 gen_helper_0e1i(mtthi, t0, 3);
8441                 break;
8442             case 14:
8443                 gen_helper_0e1i(mttacx, t0, 3);
8444                 break;
8445             case 16:
8446                 gen_helper_mttdsp(tcg_env, t0);
8447                 break;
8448             default:
8449                 goto die;
8450             }
8451             break;
8452         /* Floating point (COP1). */
8453         case 2:
8454             /* XXX: For now we support only a single FPU context. */
8455             if (h == 0) {
8456                 TCGv_i32 fp0 = tcg_temp_new_i32();
8457 
8458                 tcg_gen_trunc_tl_i32(fp0, t0);
8459                 gen_store_fpr32(ctx, fp0, rd);
8460             } else {
8461                 TCGv_i32 fp0 = tcg_temp_new_i32();
8462 
8463                 tcg_gen_trunc_tl_i32(fp0, t0);
8464                 gen_store_fpr32h(ctx, fp0, rd);
8465             }
8466             break;
8467         case 3:
8468             /* XXX: For now we support only a single FPU context. */
8469             gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
8470             /* Stop translation as we may have changed hflags */
8471             ctx->base.is_jmp = DISAS_STOP;
8472             break;
8473         /* COP2: Not implemented. */
8474         case 4:
8475         case 5:
8476             /* fall through */
8477         default:
8478             goto die;
8479         }
8480     }
8481     trace_mips_translate_tr("mttr", rd, u, sel, h);
8482     return;
8483 
8484 die:
8485     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8486     gen_reserved_instruction(ctx);
8487 }
8488 
gen_cp0(CPUMIPSState * env,DisasContext * ctx,uint32_t opc,int rt,int rd)8489 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
8490                     int rt, int rd)
8491 {
8492     const char *opn = "ldst";
8493 
8494     check_cp0_enabled(ctx);
8495     switch (opc) {
8496     case OPC_MFC0:
8497         if (rt == 0) {
8498             /* Treat as NOP. */
8499             return;
8500         }
8501         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8502         opn = "mfc0";
8503         break;
8504     case OPC_MTC0:
8505         {
8506             TCGv t0 = tcg_temp_new();
8507 
8508             gen_load_gpr(t0, rt);
8509             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8510         }
8511         opn = "mtc0";
8512         break;
8513 #if defined(TARGET_MIPS64)
8514     case OPC_DMFC0:
8515         check_insn(ctx, ISA_MIPS3);
8516         if (rt == 0) {
8517             /* Treat as NOP. */
8518             return;
8519         }
8520         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8521         opn = "dmfc0";
8522         break;
8523     case OPC_DMTC0:
8524         check_insn(ctx, ISA_MIPS3);
8525         {
8526             TCGv t0 = tcg_temp_new();
8527 
8528             gen_load_gpr(t0, rt);
8529             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8530         }
8531         opn = "dmtc0";
8532         break;
8533 #endif
8534     case OPC_MFHC0:
8535         check_mvh(ctx);
8536         if (rt == 0) {
8537             /* Treat as NOP. */
8538             return;
8539         }
8540         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8541         opn = "mfhc0";
8542         break;
8543     case OPC_MTHC0:
8544         check_mvh(ctx);
8545         {
8546             TCGv t0 = tcg_temp_new();
8547             gen_load_gpr(t0, rt);
8548             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8549         }
8550         opn = "mthc0";
8551         break;
8552     case OPC_MFTR:
8553         check_cp0_enabled(ctx);
8554         if (rd == 0) {
8555             /* Treat as NOP. */
8556             return;
8557         }
8558         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8559                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8560         opn = "mftr";
8561         break;
8562     case OPC_MTTR:
8563         check_cp0_enabled(ctx);
8564         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8565                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8566         opn = "mttr";
8567         break;
8568     case OPC_TLBWI:
8569         opn = "tlbwi";
8570         if (!env->tlb->helper_tlbwi) {
8571             goto die;
8572         }
8573         gen_helper_tlbwi(tcg_env);
8574         break;
8575     case OPC_TLBINV:
8576         opn = "tlbinv";
8577         if (ctx->ie >= 2) {
8578             if (!env->tlb->helper_tlbinv) {
8579                 goto die;
8580             }
8581             gen_helper_tlbinv(tcg_env);
8582         } /* treat as nop if TLBINV not supported */
8583         break;
8584     case OPC_TLBINVF:
8585         opn = "tlbinvf";
8586         if (ctx->ie >= 2) {
8587             if (!env->tlb->helper_tlbinvf) {
8588                 goto die;
8589             }
8590             gen_helper_tlbinvf(tcg_env);
8591         } /* treat as nop if TLBINV not supported */
8592         break;
8593     case OPC_TLBWR:
8594         opn = "tlbwr";
8595         if (!env->tlb->helper_tlbwr) {
8596             goto die;
8597         }
8598         gen_helper_tlbwr(tcg_env);
8599         break;
8600     case OPC_TLBP:
8601         opn = "tlbp";
8602         if (!env->tlb->helper_tlbp) {
8603             goto die;
8604         }
8605         gen_helper_tlbp(tcg_env);
8606         break;
8607     case OPC_TLBR:
8608         opn = "tlbr";
8609         if (!env->tlb->helper_tlbr) {
8610             goto die;
8611         }
8612         gen_helper_tlbr(tcg_env);
8613         break;
8614     case OPC_ERET: /* OPC_ERETNC */
8615         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8616             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8617             goto die;
8618         } else {
8619             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8620             if (ctx->opcode & (1 << bit_shift)) {
8621                 /* OPC_ERETNC */
8622                 opn = "eretnc";
8623                 check_insn(ctx, ISA_MIPS_R5);
8624                 gen_helper_eretnc(tcg_env);
8625             } else {
8626                 /* OPC_ERET */
8627                 opn = "eret";
8628                 check_insn(ctx, ISA_MIPS2);
8629                 gen_helper_eret(tcg_env);
8630             }
8631             ctx->base.is_jmp = DISAS_EXIT;
8632         }
8633         break;
8634     case OPC_DERET:
8635         opn = "deret";
8636         check_insn(ctx, ISA_MIPS_R1);
8637         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8638             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8639             goto die;
8640         }
8641         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8642             MIPS_INVAL(opn);
8643             gen_reserved_instruction(ctx);
8644         } else {
8645             gen_helper_deret(tcg_env);
8646             ctx->base.is_jmp = DISAS_EXIT;
8647         }
8648         break;
8649     case OPC_WAIT:
8650         opn = "wait";
8651         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
8652         if ((ctx->insn_flags & ISA_MIPS_R6) &&
8653             (ctx->hflags & MIPS_HFLAG_BMASK)) {
8654             goto die;
8655         }
8656         /* If we get an exception, we want to restart at next instruction */
8657         ctx->base.pc_next += 4;
8658         save_cpu_state(ctx, 1);
8659         ctx->base.pc_next -= 4;
8660         gen_helper_wait(tcg_env);
8661         ctx->base.is_jmp = DISAS_NORETURN;
8662         break;
8663     default:
8664  die:
8665         MIPS_INVAL(opn);
8666         gen_reserved_instruction(ctx);
8667         return;
8668     }
8669     (void)opn; /* avoid a compiler warning */
8670 }
8671 #endif /* !CONFIG_USER_ONLY */
8672 
8673 /* CP1 Branches (before delay slot) */
gen_compute_branch1(DisasContext * ctx,uint32_t op,int32_t cc,int32_t offset)8674 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8675                                 int32_t cc, int32_t offset)
8676 {
8677     target_ulong btarget;
8678     TCGv_i32 t0 = tcg_temp_new_i32();
8679 
8680     if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8681         gen_reserved_instruction(ctx);
8682         return;
8683     }
8684 
8685     if (cc != 0) {
8686         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
8687     }
8688 
8689     btarget = ctx->base.pc_next + 4 + offset;
8690 
8691     switch (op) {
8692     case OPC_BC1F:
8693         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8694         tcg_gen_not_i32(t0, t0);
8695         tcg_gen_andi_i32(t0, t0, 1);
8696         tcg_gen_extu_i32_tl(bcond, t0);
8697         goto not_likely;
8698     case OPC_BC1FL:
8699         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8700         tcg_gen_not_i32(t0, t0);
8701         tcg_gen_andi_i32(t0, t0, 1);
8702         tcg_gen_extu_i32_tl(bcond, t0);
8703         goto likely;
8704     case OPC_BC1T:
8705         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8706         tcg_gen_andi_i32(t0, t0, 1);
8707         tcg_gen_extu_i32_tl(bcond, t0);
8708         goto not_likely;
8709     case OPC_BC1TL:
8710         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8711         tcg_gen_andi_i32(t0, t0, 1);
8712         tcg_gen_extu_i32_tl(bcond, t0);
8713     likely:
8714         ctx->hflags |= MIPS_HFLAG_BL;
8715         break;
8716     case OPC_BC1FANY2:
8717         {
8718             TCGv_i32 t1 = tcg_temp_new_i32();
8719             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8720             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8721             tcg_gen_nand_i32(t0, t0, t1);
8722             tcg_gen_andi_i32(t0, t0, 1);
8723             tcg_gen_extu_i32_tl(bcond, t0);
8724         }
8725         goto not_likely;
8726     case OPC_BC1TANY2:
8727         {
8728             TCGv_i32 t1 = tcg_temp_new_i32();
8729             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8730             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8731             tcg_gen_or_i32(t0, t0, t1);
8732             tcg_gen_andi_i32(t0, t0, 1);
8733             tcg_gen_extu_i32_tl(bcond, t0);
8734         }
8735         goto not_likely;
8736     case OPC_BC1FANY4:
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_and_i32(t0, t0, t1);
8742             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8743             tcg_gen_and_i32(t0, t0, t1);
8744             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8745             tcg_gen_nand_i32(t0, t0, t1);
8746             tcg_gen_andi_i32(t0, t0, 1);
8747             tcg_gen_extu_i32_tl(bcond, t0);
8748         }
8749         goto not_likely;
8750     case OPC_BC1TANY4:
8751         {
8752             TCGv_i32 t1 = tcg_temp_new_i32();
8753             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8754             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
8755             tcg_gen_or_i32(t0, t0, t1);
8756             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
8757             tcg_gen_or_i32(t0, t0, t1);
8758             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
8759             tcg_gen_or_i32(t0, t0, t1);
8760             tcg_gen_andi_i32(t0, t0, 1);
8761             tcg_gen_extu_i32_tl(bcond, t0);
8762         }
8763     not_likely:
8764         ctx->hflags |= MIPS_HFLAG_BC;
8765         break;
8766     default:
8767         MIPS_INVAL("cp1 cond branch");
8768         gen_reserved_instruction(ctx);
8769         return;
8770     }
8771     ctx->btarget = btarget;
8772     ctx->hflags |= MIPS_HFLAG_BDS32;
8773 }
8774 
8775 /* R6 CP1 Branches */
gen_compute_branch1_r6(DisasContext * ctx,uint32_t op,int32_t ft,int32_t offset,int delayslot_size)8776 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8777                                    int32_t ft, int32_t offset,
8778                                    int delayslot_size)
8779 {
8780     target_ulong btarget;
8781     TCGv_i64 t0 = tcg_temp_new_i64();
8782 
8783     if (ctx->hflags & MIPS_HFLAG_BMASK) {
8784 #ifdef MIPS_DEBUG_DISAS
8785         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
8786                   VADDR_PRIx "\n", ctx->base.pc_next);
8787 #endif
8788         gen_reserved_instruction(ctx);
8789         return;
8790     }
8791 
8792     gen_load_fpr64(ctx, t0, ft);
8793     tcg_gen_andi_i64(t0, t0, 1);
8794 
8795     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
8796 
8797     switch (op) {
8798     case OPC_BC1EQZ:
8799         tcg_gen_xori_i64(t0, t0, 1);
8800         ctx->hflags |= MIPS_HFLAG_BC;
8801         break;
8802     case OPC_BC1NEZ:
8803         /* t0 already set */
8804         ctx->hflags |= MIPS_HFLAG_BC;
8805         break;
8806     default:
8807         MIPS_INVAL("cp1 cond branch");
8808         gen_reserved_instruction(ctx);
8809         return;
8810     }
8811 
8812     tcg_gen_trunc_i64_tl(bcond, t0);
8813 
8814     ctx->btarget = btarget;
8815 
8816     switch (delayslot_size) {
8817     case 2:
8818         ctx->hflags |= MIPS_HFLAG_BDS16;
8819         break;
8820     case 4:
8821         ctx->hflags |= MIPS_HFLAG_BDS32;
8822         break;
8823     }
8824 }
8825 
8826 /* Coprocessor 1 (FPU) */
8827 
8828 #define FOP(func, fmt) (((fmt) << 21) | (func))
8829 
8830 enum fopcode {
8831     OPC_ADD_S = FOP(0, FMT_S),
8832     OPC_SUB_S = FOP(1, FMT_S),
8833     OPC_MUL_S = FOP(2, FMT_S),
8834     OPC_DIV_S = FOP(3, FMT_S),
8835     OPC_SQRT_S = FOP(4, FMT_S),
8836     OPC_ABS_S = FOP(5, FMT_S),
8837     OPC_MOV_S = FOP(6, FMT_S),
8838     OPC_NEG_S = FOP(7, FMT_S),
8839     OPC_ROUND_L_S = FOP(8, FMT_S),
8840     OPC_TRUNC_L_S = FOP(9, FMT_S),
8841     OPC_CEIL_L_S = FOP(10, FMT_S),
8842     OPC_FLOOR_L_S = FOP(11, FMT_S),
8843     OPC_ROUND_W_S = FOP(12, FMT_S),
8844     OPC_TRUNC_W_S = FOP(13, FMT_S),
8845     OPC_CEIL_W_S = FOP(14, FMT_S),
8846     OPC_FLOOR_W_S = FOP(15, FMT_S),
8847     OPC_SEL_S = FOP(16, FMT_S),
8848     OPC_MOVCF_S = FOP(17, FMT_S),
8849     OPC_MOVZ_S = FOP(18, FMT_S),
8850     OPC_MOVN_S = FOP(19, FMT_S),
8851     OPC_SELEQZ_S = FOP(20, FMT_S),
8852     OPC_RECIP_S = FOP(21, FMT_S),
8853     OPC_RSQRT_S = FOP(22, FMT_S),
8854     OPC_SELNEZ_S = FOP(23, FMT_S),
8855     OPC_MADDF_S = FOP(24, FMT_S),
8856     OPC_MSUBF_S = FOP(25, FMT_S),
8857     OPC_RINT_S = FOP(26, FMT_S),
8858     OPC_CLASS_S = FOP(27, FMT_S),
8859     OPC_MIN_S = FOP(28, FMT_S),
8860     OPC_RECIP2_S = FOP(28, FMT_S),
8861     OPC_MINA_S = FOP(29, FMT_S),
8862     OPC_RECIP1_S = FOP(29, FMT_S),
8863     OPC_MAX_S = FOP(30, FMT_S),
8864     OPC_RSQRT1_S = FOP(30, FMT_S),
8865     OPC_MAXA_S = FOP(31, FMT_S),
8866     OPC_RSQRT2_S = FOP(31, FMT_S),
8867     OPC_CVT_D_S = FOP(33, FMT_S),
8868     OPC_CVT_W_S = FOP(36, FMT_S),
8869     OPC_CVT_L_S = FOP(37, FMT_S),
8870     OPC_CVT_PS_S = FOP(38, FMT_S),
8871     OPC_CMP_F_S = FOP(48, FMT_S),
8872     OPC_CMP_UN_S = FOP(49, FMT_S),
8873     OPC_CMP_EQ_S = FOP(50, FMT_S),
8874     OPC_CMP_UEQ_S = FOP(51, FMT_S),
8875     OPC_CMP_OLT_S = FOP(52, FMT_S),
8876     OPC_CMP_ULT_S = FOP(53, FMT_S),
8877     OPC_CMP_OLE_S = FOP(54, FMT_S),
8878     OPC_CMP_ULE_S = FOP(55, FMT_S),
8879     OPC_CMP_SF_S = FOP(56, FMT_S),
8880     OPC_CMP_NGLE_S = FOP(57, FMT_S),
8881     OPC_CMP_SEQ_S = FOP(58, FMT_S),
8882     OPC_CMP_NGL_S = FOP(59, FMT_S),
8883     OPC_CMP_LT_S = FOP(60, FMT_S),
8884     OPC_CMP_NGE_S = FOP(61, FMT_S),
8885     OPC_CMP_LE_S = FOP(62, FMT_S),
8886     OPC_CMP_NGT_S = FOP(63, FMT_S),
8887 
8888     OPC_ADD_D = FOP(0, FMT_D),
8889     OPC_SUB_D = FOP(1, FMT_D),
8890     OPC_MUL_D = FOP(2, FMT_D),
8891     OPC_DIV_D = FOP(3, FMT_D),
8892     OPC_SQRT_D = FOP(4, FMT_D),
8893     OPC_ABS_D = FOP(5, FMT_D),
8894     OPC_MOV_D = FOP(6, FMT_D),
8895     OPC_NEG_D = FOP(7, FMT_D),
8896     OPC_ROUND_L_D = FOP(8, FMT_D),
8897     OPC_TRUNC_L_D = FOP(9, FMT_D),
8898     OPC_CEIL_L_D = FOP(10, FMT_D),
8899     OPC_FLOOR_L_D = FOP(11, FMT_D),
8900     OPC_ROUND_W_D = FOP(12, FMT_D),
8901     OPC_TRUNC_W_D = FOP(13, FMT_D),
8902     OPC_CEIL_W_D = FOP(14, FMT_D),
8903     OPC_FLOOR_W_D = FOP(15, FMT_D),
8904     OPC_SEL_D = FOP(16, FMT_D),
8905     OPC_MOVCF_D = FOP(17, FMT_D),
8906     OPC_MOVZ_D = FOP(18, FMT_D),
8907     OPC_MOVN_D = FOP(19, FMT_D),
8908     OPC_SELEQZ_D = FOP(20, FMT_D),
8909     OPC_RECIP_D = FOP(21, FMT_D),
8910     OPC_RSQRT_D = FOP(22, FMT_D),
8911     OPC_SELNEZ_D = FOP(23, FMT_D),
8912     OPC_MADDF_D = FOP(24, FMT_D),
8913     OPC_MSUBF_D = FOP(25, FMT_D),
8914     OPC_RINT_D = FOP(26, FMT_D),
8915     OPC_CLASS_D = FOP(27, FMT_D),
8916     OPC_MIN_D = FOP(28, FMT_D),
8917     OPC_RECIP2_D = FOP(28, FMT_D),
8918     OPC_MINA_D = FOP(29, FMT_D),
8919     OPC_RECIP1_D = FOP(29, FMT_D),
8920     OPC_MAX_D = FOP(30, FMT_D),
8921     OPC_RSQRT1_D = FOP(30, FMT_D),
8922     OPC_MAXA_D = FOP(31, FMT_D),
8923     OPC_RSQRT2_D = FOP(31, FMT_D),
8924     OPC_CVT_S_D = FOP(32, FMT_D),
8925     OPC_CVT_W_D = FOP(36, FMT_D),
8926     OPC_CVT_L_D = FOP(37, FMT_D),
8927     OPC_CMP_F_D = FOP(48, FMT_D),
8928     OPC_CMP_UN_D = FOP(49, FMT_D),
8929     OPC_CMP_EQ_D = FOP(50, FMT_D),
8930     OPC_CMP_UEQ_D = FOP(51, FMT_D),
8931     OPC_CMP_OLT_D = FOP(52, FMT_D),
8932     OPC_CMP_ULT_D = FOP(53, FMT_D),
8933     OPC_CMP_OLE_D = FOP(54, FMT_D),
8934     OPC_CMP_ULE_D = FOP(55, FMT_D),
8935     OPC_CMP_SF_D = FOP(56, FMT_D),
8936     OPC_CMP_NGLE_D = FOP(57, FMT_D),
8937     OPC_CMP_SEQ_D = FOP(58, FMT_D),
8938     OPC_CMP_NGL_D = FOP(59, FMT_D),
8939     OPC_CMP_LT_D = FOP(60, FMT_D),
8940     OPC_CMP_NGE_D = FOP(61, FMT_D),
8941     OPC_CMP_LE_D = FOP(62, FMT_D),
8942     OPC_CMP_NGT_D = FOP(63, FMT_D),
8943 
8944     OPC_CVT_S_W = FOP(32, FMT_W),
8945     OPC_CVT_D_W = FOP(33, FMT_W),
8946     OPC_CVT_S_L = FOP(32, FMT_L),
8947     OPC_CVT_D_L = FOP(33, FMT_L),
8948     OPC_CVT_PS_PW = FOP(38, FMT_W),
8949 
8950     OPC_ADD_PS = FOP(0, FMT_PS),
8951     OPC_SUB_PS = FOP(1, FMT_PS),
8952     OPC_MUL_PS = FOP(2, FMT_PS),
8953     OPC_DIV_PS = FOP(3, FMT_PS),
8954     OPC_ABS_PS = FOP(5, FMT_PS),
8955     OPC_MOV_PS = FOP(6, FMT_PS),
8956     OPC_NEG_PS = FOP(7, FMT_PS),
8957     OPC_MOVCF_PS = FOP(17, FMT_PS),
8958     OPC_MOVZ_PS = FOP(18, FMT_PS),
8959     OPC_MOVN_PS = FOP(19, FMT_PS),
8960     OPC_ADDR_PS = FOP(24, FMT_PS),
8961     OPC_MULR_PS = FOP(26, FMT_PS),
8962     OPC_RECIP2_PS = FOP(28, FMT_PS),
8963     OPC_RECIP1_PS = FOP(29, FMT_PS),
8964     OPC_RSQRT1_PS = FOP(30, FMT_PS),
8965     OPC_RSQRT2_PS = FOP(31, FMT_PS),
8966 
8967     OPC_CVT_S_PU = FOP(32, FMT_PS),
8968     OPC_CVT_PW_PS = FOP(36, FMT_PS),
8969     OPC_CVT_S_PL = FOP(40, FMT_PS),
8970     OPC_PLL_PS = FOP(44, FMT_PS),
8971     OPC_PLU_PS = FOP(45, FMT_PS),
8972     OPC_PUL_PS = FOP(46, FMT_PS),
8973     OPC_PUU_PS = FOP(47, FMT_PS),
8974     OPC_CMP_F_PS = FOP(48, FMT_PS),
8975     OPC_CMP_UN_PS = FOP(49, FMT_PS),
8976     OPC_CMP_EQ_PS = FOP(50, FMT_PS),
8977     OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
8978     OPC_CMP_OLT_PS = FOP(52, FMT_PS),
8979     OPC_CMP_ULT_PS = FOP(53, FMT_PS),
8980     OPC_CMP_OLE_PS = FOP(54, FMT_PS),
8981     OPC_CMP_ULE_PS = FOP(55, FMT_PS),
8982     OPC_CMP_SF_PS = FOP(56, FMT_PS),
8983     OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
8984     OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
8985     OPC_CMP_NGL_PS = FOP(59, FMT_PS),
8986     OPC_CMP_LT_PS = FOP(60, FMT_PS),
8987     OPC_CMP_NGE_PS = FOP(61, FMT_PS),
8988     OPC_CMP_LE_PS = FOP(62, FMT_PS),
8989     OPC_CMP_NGT_PS = FOP(63, FMT_PS),
8990 };
8991 
8992 enum r6_f_cmp_op {
8993     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
8994     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
8995     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
8996     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
8997     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
8998     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
8999     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9000     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9001     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9002     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9003     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9004     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9005     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9006     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9007     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9008     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9009     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9010     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9011     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9012     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9013     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9014     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9015 
9016     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9017     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9018     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9019     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9020     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9021     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9022     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9023     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9024     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9025     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9026     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9027     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9028     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9029     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9030     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9031     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9032     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9033     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9034     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9035     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9036     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9037     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9038 };
9039 
gen_cp1(DisasContext * ctx,uint32_t opc,int rt,int fs)9040 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9041 {
9042     TCGv t0 = tcg_temp_new();
9043 
9044     switch (opc) {
9045     case OPC_MFC1:
9046         {
9047             TCGv_i32 fp0 = tcg_temp_new_i32();
9048 
9049             gen_load_fpr32(ctx, fp0, fs);
9050             tcg_gen_ext_i32_tl(t0, fp0);
9051         }
9052         gen_store_gpr(t0, rt);
9053         break;
9054     case OPC_MTC1:
9055         gen_load_gpr(t0, rt);
9056         {
9057             TCGv_i32 fp0 = tcg_temp_new_i32();
9058 
9059             tcg_gen_trunc_tl_i32(fp0, t0);
9060             gen_store_fpr32(ctx, fp0, fs);
9061         }
9062         break;
9063     case OPC_CFC1:
9064         gen_helper_1e0i(cfc1, t0, fs);
9065         gen_store_gpr(t0, rt);
9066         break;
9067     case OPC_CTC1:
9068         gen_load_gpr(t0, rt);
9069         save_cpu_state(ctx, 0);
9070         gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9071         /* Stop translation as we may have changed hflags */
9072         ctx->base.is_jmp = DISAS_STOP;
9073         break;
9074 #if defined(TARGET_MIPS64)
9075     case OPC_DMFC1:
9076         gen_load_fpr64(ctx, t0, fs);
9077         gen_store_gpr(t0, rt);
9078         break;
9079     case OPC_DMTC1:
9080         gen_load_gpr(t0, rt);
9081         gen_store_fpr64(ctx, t0, fs);
9082         break;
9083 #endif
9084     case OPC_MFHC1:
9085         {
9086             TCGv_i32 fp0 = tcg_temp_new_i32();
9087 
9088             gen_load_fpr32h(ctx, fp0, fs);
9089             tcg_gen_ext_i32_tl(t0, fp0);
9090         }
9091         gen_store_gpr(t0, rt);
9092         break;
9093     case OPC_MTHC1:
9094         gen_load_gpr(t0, rt);
9095         {
9096             TCGv_i32 fp0 = tcg_temp_new_i32();
9097 
9098             tcg_gen_trunc_tl_i32(fp0, t0);
9099             gen_store_fpr32h(ctx, fp0, fs);
9100         }
9101         break;
9102     default:
9103         MIPS_INVAL("cp1 move");
9104         gen_reserved_instruction(ctx);
9105         return;
9106     }
9107 }
9108 
gen_movci(DisasContext * ctx,int rd,int rs,int cc,int tf)9109 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9110 {
9111     TCGLabel *l1;
9112     TCGCond cond;
9113     TCGv_i32 t0;
9114 
9115     if (rd == 0) {
9116         /* Treat as NOP. */
9117         return;
9118     }
9119 
9120     if (tf) {
9121         cond = TCG_COND_EQ;
9122     } else {
9123         cond = TCG_COND_NE;
9124     }
9125 
9126     l1 = gen_new_label();
9127     t0 = tcg_temp_new_i32();
9128     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9129     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9130     gen_load_gpr(cpu_gpr[rd], rs);
9131     gen_set_label(l1);
9132 }
9133 
gen_movcf_s(DisasContext * ctx,int fs,int fd,int cc,int tf)9134 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9135                                int tf)
9136 {
9137     int cond;
9138     TCGv_i32 t0 = tcg_temp_new_i32();
9139     TCGLabel *l1 = gen_new_label();
9140 
9141     if (tf) {
9142         cond = TCG_COND_EQ;
9143     } else {
9144         cond = TCG_COND_NE;
9145     }
9146 
9147     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9148     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9149     gen_load_fpr32(ctx, t0, fs);
9150     gen_store_fpr32(ctx, t0, fd);
9151     gen_set_label(l1);
9152 }
9153 
gen_movcf_d(DisasContext * ctx,int fs,int fd,int cc,int tf)9154 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9155                                int tf)
9156 {
9157     int cond;
9158     TCGv_i32 t0 = tcg_temp_new_i32();
9159     TCGv_i64 fp0;
9160     TCGLabel *l1 = gen_new_label();
9161 
9162     if (tf) {
9163         cond = TCG_COND_EQ;
9164     } else {
9165         cond = TCG_COND_NE;
9166     }
9167 
9168     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9169     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9170     fp0 = tcg_temp_new_i64();
9171     gen_load_fpr64(ctx, fp0, fs);
9172     gen_store_fpr64(ctx, fp0, fd);
9173     gen_set_label(l1);
9174 }
9175 
gen_movcf_ps(DisasContext * ctx,int fs,int fd,int cc,int tf)9176 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9177                                 int cc, int tf)
9178 {
9179     int cond;
9180     TCGv_i32 t0 = tcg_temp_new_i32();
9181     TCGLabel *l1 = gen_new_label();
9182     TCGLabel *l2 = gen_new_label();
9183 
9184     if (tf) {
9185         cond = TCG_COND_EQ;
9186     } else {
9187         cond = TCG_COND_NE;
9188     }
9189 
9190     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9191     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9192     gen_load_fpr32(ctx, t0, fs);
9193     gen_store_fpr32(ctx, t0, fd);
9194     gen_set_label(l1);
9195 
9196     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9197     tcg_gen_brcondi_i32(cond, t0, 0, l2);
9198     gen_load_fpr32h(ctx, t0, fs);
9199     gen_store_fpr32h(ctx, t0, fd);
9200     gen_set_label(l2);
9201 }
9202 
gen_sel_s(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9203 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9204                       int fs)
9205 {
9206     TCGv_i32 t1 = tcg_constant_i32(0);
9207     TCGv_i32 fp0 = tcg_temp_new_i32();
9208     TCGv_i32 fp1 = tcg_temp_new_i32();
9209     TCGv_i32 fp2 = tcg_temp_new_i32();
9210     gen_load_fpr32(ctx, fp0, fd);
9211     gen_load_fpr32(ctx, fp1, ft);
9212     gen_load_fpr32(ctx, fp2, fs);
9213 
9214     switch (op1) {
9215     case OPC_SEL_S:
9216         tcg_gen_andi_i32(fp0, fp0, 1);
9217         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9218         break;
9219     case OPC_SELEQZ_S:
9220         tcg_gen_andi_i32(fp1, fp1, 1);
9221         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9222         break;
9223     case OPC_SELNEZ_S:
9224         tcg_gen_andi_i32(fp1, fp1, 1);
9225         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9226         break;
9227     default:
9228         MIPS_INVAL("gen_sel_s");
9229         gen_reserved_instruction(ctx);
9230         break;
9231     }
9232 
9233     gen_store_fpr32(ctx, fp0, fd);
9234 }
9235 
gen_sel_d(DisasContext * ctx,enum fopcode op1,int fd,int ft,int fs)9236 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9237                       int fs)
9238 {
9239     TCGv_i64 t1 = tcg_constant_i64(0);
9240     TCGv_i64 fp0 = tcg_temp_new_i64();
9241     TCGv_i64 fp1 = tcg_temp_new_i64();
9242     TCGv_i64 fp2 = tcg_temp_new_i64();
9243     gen_load_fpr64(ctx, fp0, fd);
9244     gen_load_fpr64(ctx, fp1, ft);
9245     gen_load_fpr64(ctx, fp2, fs);
9246 
9247     switch (op1) {
9248     case OPC_SEL_D:
9249         tcg_gen_andi_i64(fp0, fp0, 1);
9250         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9251         break;
9252     case OPC_SELEQZ_D:
9253         tcg_gen_andi_i64(fp1, fp1, 1);
9254         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9255         break;
9256     case OPC_SELNEZ_D:
9257         tcg_gen_andi_i64(fp1, fp1, 1);
9258         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9259         break;
9260     default:
9261         MIPS_INVAL("gen_sel_d");
9262         gen_reserved_instruction(ctx);
9263         break;
9264     }
9265 
9266     gen_store_fpr64(ctx, fp0, fd);
9267 }
9268 
gen_farith(DisasContext * ctx,enum fopcode op1,int ft,int fs,int fd,int cc)9269 static void gen_farith(DisasContext *ctx, enum fopcode op1,
9270                        int ft, int fs, int fd, int cc)
9271 {
9272     uint32_t func = ctx->opcode & 0x3f;
9273     switch (op1) {
9274     case OPC_ADD_S:
9275         {
9276             TCGv_i32 fp0 = tcg_temp_new_i32();
9277             TCGv_i32 fp1 = tcg_temp_new_i32();
9278 
9279             gen_load_fpr32(ctx, fp0, fs);
9280             gen_load_fpr32(ctx, fp1, ft);
9281             gen_helper_float_add_s(fp0, tcg_env, fp0, fp1);
9282             gen_store_fpr32(ctx, fp0, fd);
9283         }
9284         break;
9285     case OPC_SUB_S:
9286         {
9287             TCGv_i32 fp0 = tcg_temp_new_i32();
9288             TCGv_i32 fp1 = tcg_temp_new_i32();
9289 
9290             gen_load_fpr32(ctx, fp0, fs);
9291             gen_load_fpr32(ctx, fp1, ft);
9292             gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1);
9293             gen_store_fpr32(ctx, fp0, fd);
9294         }
9295         break;
9296     case OPC_MUL_S:
9297         {
9298             TCGv_i32 fp0 = tcg_temp_new_i32();
9299             TCGv_i32 fp1 = tcg_temp_new_i32();
9300 
9301             gen_load_fpr32(ctx, fp0, fs);
9302             gen_load_fpr32(ctx, fp1, ft);
9303             gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1);
9304             gen_store_fpr32(ctx, fp0, fd);
9305         }
9306         break;
9307     case OPC_DIV_S:
9308         {
9309             TCGv_i32 fp0 = tcg_temp_new_i32();
9310             TCGv_i32 fp1 = tcg_temp_new_i32();
9311 
9312             gen_load_fpr32(ctx, fp0, fs);
9313             gen_load_fpr32(ctx, fp1, ft);
9314             gen_helper_float_div_s(fp0, tcg_env, fp0, fp1);
9315             gen_store_fpr32(ctx, fp0, fd);
9316         }
9317         break;
9318     case OPC_SQRT_S:
9319         {
9320             TCGv_i32 fp0 = tcg_temp_new_i32();
9321 
9322             gen_load_fpr32(ctx, fp0, fs);
9323             gen_helper_float_sqrt_s(fp0, tcg_env, fp0);
9324             gen_store_fpr32(ctx, fp0, fd);
9325         }
9326         break;
9327     case OPC_ABS_S:
9328         {
9329             TCGv_i32 fp0 = tcg_temp_new_i32();
9330 
9331             gen_load_fpr32(ctx, fp0, fs);
9332             if (ctx->abs2008) {
9333                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9334             } else {
9335                 gen_helper_float_abs_s(fp0, fp0);
9336             }
9337             gen_store_fpr32(ctx, fp0, fd);
9338         }
9339         break;
9340     case OPC_MOV_S:
9341         {
9342             TCGv_i32 fp0 = tcg_temp_new_i32();
9343 
9344             gen_load_fpr32(ctx, fp0, fs);
9345             gen_store_fpr32(ctx, fp0, fd);
9346         }
9347         break;
9348     case OPC_NEG_S:
9349         {
9350             TCGv_i32 fp0 = tcg_temp_new_i32();
9351 
9352             gen_load_fpr32(ctx, fp0, fs);
9353             if (ctx->abs2008) {
9354                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9355             } else {
9356                 gen_helper_float_chs_s(fp0, fp0);
9357             }
9358             gen_store_fpr32(ctx, fp0, fd);
9359         }
9360         break;
9361     case OPC_ROUND_L_S:
9362         check_cp1_64bitmode(ctx);
9363         {
9364             TCGv_i32 fp32 = tcg_temp_new_i32();
9365             TCGv_i64 fp64 = tcg_temp_new_i64();
9366 
9367             gen_load_fpr32(ctx, fp32, fs);
9368             if (ctx->nan2008) {
9369                 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32);
9370             } else {
9371                 gen_helper_float_round_l_s(fp64, tcg_env, fp32);
9372             }
9373             gen_store_fpr64(ctx, fp64, fd);
9374         }
9375         break;
9376     case OPC_TRUNC_L_S:
9377         check_cp1_64bitmode(ctx);
9378         {
9379             TCGv_i32 fp32 = tcg_temp_new_i32();
9380             TCGv_i64 fp64 = tcg_temp_new_i64();
9381 
9382             gen_load_fpr32(ctx, fp32, fs);
9383             if (ctx->nan2008) {
9384                 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32);
9385             } else {
9386                 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32);
9387             }
9388             gen_store_fpr64(ctx, fp64, fd);
9389         }
9390         break;
9391     case OPC_CEIL_L_S:
9392         check_cp1_64bitmode(ctx);
9393         {
9394             TCGv_i32 fp32 = tcg_temp_new_i32();
9395             TCGv_i64 fp64 = tcg_temp_new_i64();
9396 
9397             gen_load_fpr32(ctx, fp32, fs);
9398             if (ctx->nan2008) {
9399                 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32);
9400             } else {
9401                 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32);
9402             }
9403             gen_store_fpr64(ctx, fp64, fd);
9404         }
9405         break;
9406     case OPC_FLOOR_L_S:
9407         check_cp1_64bitmode(ctx);
9408         {
9409             TCGv_i32 fp32 = tcg_temp_new_i32();
9410             TCGv_i64 fp64 = tcg_temp_new_i64();
9411 
9412             gen_load_fpr32(ctx, fp32, fs);
9413             if (ctx->nan2008) {
9414                 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32);
9415             } else {
9416                 gen_helper_float_floor_l_s(fp64, tcg_env, fp32);
9417             }
9418             gen_store_fpr64(ctx, fp64, fd);
9419         }
9420         break;
9421     case OPC_ROUND_W_S:
9422         {
9423             TCGv_i32 fp0 = tcg_temp_new_i32();
9424 
9425             gen_load_fpr32(ctx, fp0, fs);
9426             if (ctx->nan2008) {
9427                 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0);
9428             } else {
9429                 gen_helper_float_round_w_s(fp0, tcg_env, fp0);
9430             }
9431             gen_store_fpr32(ctx, fp0, fd);
9432         }
9433         break;
9434     case OPC_TRUNC_W_S:
9435         {
9436             TCGv_i32 fp0 = tcg_temp_new_i32();
9437 
9438             gen_load_fpr32(ctx, fp0, fs);
9439             if (ctx->nan2008) {
9440                 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0);
9441             } else {
9442                 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0);
9443             }
9444             gen_store_fpr32(ctx, fp0, fd);
9445         }
9446         break;
9447     case OPC_CEIL_W_S:
9448         {
9449             TCGv_i32 fp0 = tcg_temp_new_i32();
9450 
9451             gen_load_fpr32(ctx, fp0, fs);
9452             if (ctx->nan2008) {
9453                 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0);
9454             } else {
9455                 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0);
9456             }
9457             gen_store_fpr32(ctx, fp0, fd);
9458         }
9459         break;
9460     case OPC_FLOOR_W_S:
9461         {
9462             TCGv_i32 fp0 = tcg_temp_new_i32();
9463 
9464             gen_load_fpr32(ctx, fp0, fs);
9465             if (ctx->nan2008) {
9466                 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0);
9467             } else {
9468                 gen_helper_float_floor_w_s(fp0, tcg_env, fp0);
9469             }
9470             gen_store_fpr32(ctx, fp0, fd);
9471         }
9472         break;
9473     case OPC_SEL_S:
9474         check_insn(ctx, ISA_MIPS_R6);
9475         gen_sel_s(ctx, op1, fd, ft, fs);
9476         break;
9477     case OPC_SELEQZ_S:
9478         check_insn(ctx, ISA_MIPS_R6);
9479         gen_sel_s(ctx, op1, fd, ft, fs);
9480         break;
9481     case OPC_SELNEZ_S:
9482         check_insn(ctx, ISA_MIPS_R6);
9483         gen_sel_s(ctx, op1, fd, ft, fs);
9484         break;
9485     case OPC_MOVCF_S:
9486         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9487         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9488         break;
9489     case OPC_MOVZ_S:
9490         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9491         {
9492             TCGLabel *l1 = gen_new_label();
9493             TCGv_i32 fp0;
9494 
9495             if (ft != 0) {
9496                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9497             }
9498             fp0 = tcg_temp_new_i32();
9499             gen_load_fpr32(ctx, fp0, fs);
9500             gen_store_fpr32(ctx, fp0, fd);
9501             gen_set_label(l1);
9502         }
9503         break;
9504     case OPC_MOVN_S:
9505         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9506         {
9507             TCGLabel *l1 = gen_new_label();
9508             TCGv_i32 fp0;
9509 
9510             if (ft != 0) {
9511                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9512                 fp0 = tcg_temp_new_i32();
9513                 gen_load_fpr32(ctx, fp0, fs);
9514                 gen_store_fpr32(ctx, fp0, fd);
9515                 gen_set_label(l1);
9516             }
9517         }
9518         break;
9519     case OPC_RECIP_S:
9520         {
9521             TCGv_i32 fp0 = tcg_temp_new_i32();
9522 
9523             gen_load_fpr32(ctx, fp0, fs);
9524             gen_helper_float_recip_s(fp0, tcg_env, fp0);
9525             gen_store_fpr32(ctx, fp0, fd);
9526         }
9527         break;
9528     case OPC_RSQRT_S:
9529         {
9530             TCGv_i32 fp0 = tcg_temp_new_i32();
9531 
9532             gen_load_fpr32(ctx, fp0, fs);
9533             gen_helper_float_rsqrt_s(fp0, tcg_env, fp0);
9534             gen_store_fpr32(ctx, fp0, fd);
9535         }
9536         break;
9537     case OPC_MADDF_S:
9538         check_insn(ctx, ISA_MIPS_R6);
9539         {
9540             TCGv_i32 fp0 = tcg_temp_new_i32();
9541             TCGv_i32 fp1 = tcg_temp_new_i32();
9542             TCGv_i32 fp2 = tcg_temp_new_i32();
9543             gen_load_fpr32(ctx, fp0, fs);
9544             gen_load_fpr32(ctx, fp1, ft);
9545             gen_load_fpr32(ctx, fp2, fd);
9546             gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2);
9547             gen_store_fpr32(ctx, fp2, fd);
9548         }
9549         break;
9550     case OPC_MSUBF_S:
9551         check_insn(ctx, ISA_MIPS_R6);
9552         {
9553             TCGv_i32 fp0 = tcg_temp_new_i32();
9554             TCGv_i32 fp1 = tcg_temp_new_i32();
9555             TCGv_i32 fp2 = tcg_temp_new_i32();
9556             gen_load_fpr32(ctx, fp0, fs);
9557             gen_load_fpr32(ctx, fp1, ft);
9558             gen_load_fpr32(ctx, fp2, fd);
9559             gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2);
9560             gen_store_fpr32(ctx, fp2, fd);
9561         }
9562         break;
9563     case OPC_RINT_S:
9564         check_insn(ctx, ISA_MIPS_R6);
9565         {
9566             TCGv_i32 fp0 = tcg_temp_new_i32();
9567             gen_load_fpr32(ctx, fp0, fs);
9568             gen_helper_float_rint_s(fp0, tcg_env, fp0);
9569             gen_store_fpr32(ctx, fp0, fd);
9570         }
9571         break;
9572     case OPC_CLASS_S:
9573         check_insn(ctx, ISA_MIPS_R6);
9574         {
9575             TCGv_i32 fp0 = tcg_temp_new_i32();
9576             gen_load_fpr32(ctx, fp0, fs);
9577             gen_helper_float_class_s(fp0, tcg_env, fp0);
9578             gen_store_fpr32(ctx, fp0, fd);
9579         }
9580         break;
9581     case OPC_MIN_S: /* OPC_RECIP2_S */
9582         if (ctx->insn_flags & ISA_MIPS_R6) {
9583             /* OPC_MIN_S */
9584             TCGv_i32 fp0 = tcg_temp_new_i32();
9585             TCGv_i32 fp1 = tcg_temp_new_i32();
9586             TCGv_i32 fp2 = tcg_temp_new_i32();
9587             gen_load_fpr32(ctx, fp0, fs);
9588             gen_load_fpr32(ctx, fp1, ft);
9589             gen_helper_float_min_s(fp2, tcg_env, fp0, fp1);
9590             gen_store_fpr32(ctx, fp2, fd);
9591         } else {
9592             /* OPC_RECIP2_S */
9593             check_cp1_64bitmode(ctx);
9594             {
9595                 TCGv_i32 fp0 = tcg_temp_new_i32();
9596                 TCGv_i32 fp1 = tcg_temp_new_i32();
9597 
9598                 gen_load_fpr32(ctx, fp0, fs);
9599                 gen_load_fpr32(ctx, fp1, ft);
9600                 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1);
9601                 gen_store_fpr32(ctx, fp0, fd);
9602             }
9603         }
9604         break;
9605     case OPC_MINA_S: /* OPC_RECIP1_S */
9606         if (ctx->insn_flags & ISA_MIPS_R6) {
9607             /* OPC_MINA_S */
9608             TCGv_i32 fp0 = tcg_temp_new_i32();
9609             TCGv_i32 fp1 = tcg_temp_new_i32();
9610             TCGv_i32 fp2 = tcg_temp_new_i32();
9611             gen_load_fpr32(ctx, fp0, fs);
9612             gen_load_fpr32(ctx, fp1, ft);
9613             gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1);
9614             gen_store_fpr32(ctx, fp2, fd);
9615         } else {
9616             /* OPC_RECIP1_S */
9617             check_cp1_64bitmode(ctx);
9618             {
9619                 TCGv_i32 fp0 = tcg_temp_new_i32();
9620 
9621                 gen_load_fpr32(ctx, fp0, fs);
9622                 gen_helper_float_recip1_s(fp0, tcg_env, fp0);
9623                 gen_store_fpr32(ctx, fp0, fd);
9624             }
9625         }
9626         break;
9627     case OPC_MAX_S: /* OPC_RSQRT1_S */
9628         if (ctx->insn_flags & ISA_MIPS_R6) {
9629             /* OPC_MAX_S */
9630             TCGv_i32 fp0 = tcg_temp_new_i32();
9631             TCGv_i32 fp1 = tcg_temp_new_i32();
9632             gen_load_fpr32(ctx, fp0, fs);
9633             gen_load_fpr32(ctx, fp1, ft);
9634             gen_helper_float_max_s(fp1, tcg_env, fp0, fp1);
9635             gen_store_fpr32(ctx, fp1, fd);
9636         } else {
9637             /* OPC_RSQRT1_S */
9638             check_cp1_64bitmode(ctx);
9639             {
9640                 TCGv_i32 fp0 = tcg_temp_new_i32();
9641 
9642                 gen_load_fpr32(ctx, fp0, fs);
9643                 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0);
9644                 gen_store_fpr32(ctx, fp0, fd);
9645             }
9646         }
9647         break;
9648     case OPC_MAXA_S: /* OPC_RSQRT2_S */
9649         if (ctx->insn_flags & ISA_MIPS_R6) {
9650             /* OPC_MAXA_S */
9651             TCGv_i32 fp0 = tcg_temp_new_i32();
9652             TCGv_i32 fp1 = tcg_temp_new_i32();
9653             gen_load_fpr32(ctx, fp0, fs);
9654             gen_load_fpr32(ctx, fp1, ft);
9655             gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1);
9656             gen_store_fpr32(ctx, fp1, fd);
9657         } else {
9658             /* OPC_RSQRT2_S */
9659             check_cp1_64bitmode(ctx);
9660             {
9661                 TCGv_i32 fp0 = tcg_temp_new_i32();
9662                 TCGv_i32 fp1 = tcg_temp_new_i32();
9663 
9664                 gen_load_fpr32(ctx, fp0, fs);
9665                 gen_load_fpr32(ctx, fp1, ft);
9666                 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1);
9667                 gen_store_fpr32(ctx, fp0, fd);
9668             }
9669         }
9670         break;
9671     case OPC_CVT_D_S:
9672         check_cp1_registers(ctx, fd);
9673         {
9674             TCGv_i32 fp32 = tcg_temp_new_i32();
9675             TCGv_i64 fp64 = tcg_temp_new_i64();
9676 
9677             gen_load_fpr32(ctx, fp32, fs);
9678             gen_helper_float_cvtd_s(fp64, tcg_env, fp32);
9679             gen_store_fpr64(ctx, fp64, fd);
9680         }
9681         break;
9682     case OPC_CVT_W_S:
9683         {
9684             TCGv_i32 fp0 = tcg_temp_new_i32();
9685 
9686             gen_load_fpr32(ctx, fp0, fs);
9687             if (ctx->nan2008) {
9688                 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0);
9689             } else {
9690                 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0);
9691             }
9692             gen_store_fpr32(ctx, fp0, fd);
9693         }
9694         break;
9695     case OPC_CVT_L_S:
9696         check_cp1_64bitmode(ctx);
9697         {
9698             TCGv_i32 fp32 = tcg_temp_new_i32();
9699             TCGv_i64 fp64 = tcg_temp_new_i64();
9700 
9701             gen_load_fpr32(ctx, fp32, fs);
9702             if (ctx->nan2008) {
9703                 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32);
9704             } else {
9705                 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32);
9706             }
9707             gen_store_fpr64(ctx, fp64, fd);
9708         }
9709         break;
9710     case OPC_CVT_PS_S:
9711         check_ps(ctx);
9712         {
9713             TCGv_i64 fp64 = tcg_temp_new_i64();
9714             TCGv_i32 fp32_0 = tcg_temp_new_i32();
9715             TCGv_i32 fp32_1 = tcg_temp_new_i32();
9716 
9717             gen_load_fpr32(ctx, fp32_0, fs);
9718             gen_load_fpr32(ctx, fp32_1, ft);
9719             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9720             gen_store_fpr64(ctx, fp64, fd);
9721         }
9722         break;
9723     case OPC_CMP_F_S:
9724     case OPC_CMP_UN_S:
9725     case OPC_CMP_EQ_S:
9726     case OPC_CMP_UEQ_S:
9727     case OPC_CMP_OLT_S:
9728     case OPC_CMP_ULT_S:
9729     case OPC_CMP_OLE_S:
9730     case OPC_CMP_ULE_S:
9731     case OPC_CMP_SF_S:
9732     case OPC_CMP_NGLE_S:
9733     case OPC_CMP_SEQ_S:
9734     case OPC_CMP_NGL_S:
9735     case OPC_CMP_LT_S:
9736     case OPC_CMP_NGE_S:
9737     case OPC_CMP_LE_S:
9738     case OPC_CMP_NGT_S:
9739         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9740         if (ctx->opcode & (1 << 6)) {
9741             gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
9742         } else {
9743             gen_cmp_s(ctx, func - 48, ft, fs, cc);
9744         }
9745         break;
9746     case OPC_ADD_D:
9747         check_cp1_registers(ctx, fs | ft | fd);
9748         {
9749             TCGv_i64 fp0 = tcg_temp_new_i64();
9750             TCGv_i64 fp1 = tcg_temp_new_i64();
9751 
9752             gen_load_fpr64(ctx, fp0, fs);
9753             gen_load_fpr64(ctx, fp1, ft);
9754             gen_helper_float_add_d(fp0, tcg_env, fp0, fp1);
9755             gen_store_fpr64(ctx, fp0, fd);
9756         }
9757         break;
9758     case OPC_SUB_D:
9759         check_cp1_registers(ctx, fs | ft | fd);
9760         {
9761             TCGv_i64 fp0 = tcg_temp_new_i64();
9762             TCGv_i64 fp1 = tcg_temp_new_i64();
9763 
9764             gen_load_fpr64(ctx, fp0, fs);
9765             gen_load_fpr64(ctx, fp1, ft);
9766             gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1);
9767             gen_store_fpr64(ctx, fp0, fd);
9768         }
9769         break;
9770     case OPC_MUL_D:
9771         check_cp1_registers(ctx, fs | ft | fd);
9772         {
9773             TCGv_i64 fp0 = tcg_temp_new_i64();
9774             TCGv_i64 fp1 = tcg_temp_new_i64();
9775 
9776             gen_load_fpr64(ctx, fp0, fs);
9777             gen_load_fpr64(ctx, fp1, ft);
9778             gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1);
9779             gen_store_fpr64(ctx, fp0, fd);
9780         }
9781         break;
9782     case OPC_DIV_D:
9783         check_cp1_registers(ctx, fs | ft | fd);
9784         {
9785             TCGv_i64 fp0 = tcg_temp_new_i64();
9786             TCGv_i64 fp1 = tcg_temp_new_i64();
9787 
9788             gen_load_fpr64(ctx, fp0, fs);
9789             gen_load_fpr64(ctx, fp1, ft);
9790             gen_helper_float_div_d(fp0, tcg_env, fp0, fp1);
9791             gen_store_fpr64(ctx, fp0, fd);
9792         }
9793         break;
9794     case OPC_SQRT_D:
9795         check_cp1_registers(ctx, fs | fd);
9796         {
9797             TCGv_i64 fp0 = tcg_temp_new_i64();
9798 
9799             gen_load_fpr64(ctx, fp0, fs);
9800             gen_helper_float_sqrt_d(fp0, tcg_env, fp0);
9801             gen_store_fpr64(ctx, fp0, fd);
9802         }
9803         break;
9804     case OPC_ABS_D:
9805         check_cp1_registers(ctx, fs | fd);
9806         {
9807             TCGv_i64 fp0 = tcg_temp_new_i64();
9808 
9809             gen_load_fpr64(ctx, fp0, fs);
9810             if (ctx->abs2008) {
9811                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9812             } else {
9813                 gen_helper_float_abs_d(fp0, fp0);
9814             }
9815             gen_store_fpr64(ctx, fp0, fd);
9816         }
9817         break;
9818     case OPC_MOV_D:
9819         check_cp1_registers(ctx, fs | fd);
9820         {
9821             TCGv_i64 fp0 = tcg_temp_new_i64();
9822 
9823             gen_load_fpr64(ctx, fp0, fs);
9824             gen_store_fpr64(ctx, fp0, fd);
9825         }
9826         break;
9827     case OPC_NEG_D:
9828         check_cp1_registers(ctx, fs | fd);
9829         {
9830             TCGv_i64 fp0 = tcg_temp_new_i64();
9831 
9832             gen_load_fpr64(ctx, fp0, fs);
9833             if (ctx->abs2008) {
9834                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9835             } else {
9836                 gen_helper_float_chs_d(fp0, fp0);
9837             }
9838             gen_store_fpr64(ctx, fp0, fd);
9839         }
9840         break;
9841     case OPC_ROUND_L_D:
9842         check_cp1_64bitmode(ctx);
9843         {
9844             TCGv_i64 fp0 = tcg_temp_new_i64();
9845 
9846             gen_load_fpr64(ctx, fp0, fs);
9847             if (ctx->nan2008) {
9848                 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0);
9849             } else {
9850                 gen_helper_float_round_l_d(fp0, tcg_env, fp0);
9851             }
9852             gen_store_fpr64(ctx, fp0, fd);
9853         }
9854         break;
9855     case OPC_TRUNC_L_D:
9856         check_cp1_64bitmode(ctx);
9857         {
9858             TCGv_i64 fp0 = tcg_temp_new_i64();
9859 
9860             gen_load_fpr64(ctx, fp0, fs);
9861             if (ctx->nan2008) {
9862                 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0);
9863             } else {
9864                 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0);
9865             }
9866             gen_store_fpr64(ctx, fp0, fd);
9867         }
9868         break;
9869     case OPC_CEIL_L_D:
9870         check_cp1_64bitmode(ctx);
9871         {
9872             TCGv_i64 fp0 = tcg_temp_new_i64();
9873 
9874             gen_load_fpr64(ctx, fp0, fs);
9875             if (ctx->nan2008) {
9876                 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0);
9877             } else {
9878                 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0);
9879             }
9880             gen_store_fpr64(ctx, fp0, fd);
9881         }
9882         break;
9883     case OPC_FLOOR_L_D:
9884         check_cp1_64bitmode(ctx);
9885         {
9886             TCGv_i64 fp0 = tcg_temp_new_i64();
9887 
9888             gen_load_fpr64(ctx, fp0, fs);
9889             if (ctx->nan2008) {
9890                 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0);
9891             } else {
9892                 gen_helper_float_floor_l_d(fp0, tcg_env, fp0);
9893             }
9894             gen_store_fpr64(ctx, fp0, fd);
9895         }
9896         break;
9897     case OPC_ROUND_W_D:
9898         check_cp1_registers(ctx, fs);
9899         {
9900             TCGv_i32 fp32 = tcg_temp_new_i32();
9901             TCGv_i64 fp64 = tcg_temp_new_i64();
9902 
9903             gen_load_fpr64(ctx, fp64, fs);
9904             if (ctx->nan2008) {
9905                 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64);
9906             } else {
9907                 gen_helper_float_round_w_d(fp32, tcg_env, fp64);
9908             }
9909             gen_store_fpr32(ctx, fp32, fd);
9910         }
9911         break;
9912     case OPC_TRUNC_W_D:
9913         check_cp1_registers(ctx, fs);
9914         {
9915             TCGv_i32 fp32 = tcg_temp_new_i32();
9916             TCGv_i64 fp64 = tcg_temp_new_i64();
9917 
9918             gen_load_fpr64(ctx, fp64, fs);
9919             if (ctx->nan2008) {
9920                 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64);
9921             } else {
9922                 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64);
9923             }
9924             gen_store_fpr32(ctx, fp32, fd);
9925         }
9926         break;
9927     case OPC_CEIL_W_D:
9928         check_cp1_registers(ctx, fs);
9929         {
9930             TCGv_i32 fp32 = tcg_temp_new_i32();
9931             TCGv_i64 fp64 = tcg_temp_new_i64();
9932 
9933             gen_load_fpr64(ctx, fp64, fs);
9934             if (ctx->nan2008) {
9935                 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64);
9936             } else {
9937                 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64);
9938             }
9939             gen_store_fpr32(ctx, fp32, fd);
9940         }
9941         break;
9942     case OPC_FLOOR_W_D:
9943         check_cp1_registers(ctx, fs);
9944         {
9945             TCGv_i32 fp32 = tcg_temp_new_i32();
9946             TCGv_i64 fp64 = tcg_temp_new_i64();
9947 
9948             gen_load_fpr64(ctx, fp64, fs);
9949             if (ctx->nan2008) {
9950                 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64);
9951             } else {
9952                 gen_helper_float_floor_w_d(fp32, tcg_env, fp64);
9953             }
9954             gen_store_fpr32(ctx, fp32, fd);
9955         }
9956         break;
9957     case OPC_SEL_D:
9958         check_insn(ctx, ISA_MIPS_R6);
9959         gen_sel_d(ctx, op1, fd, ft, fs);
9960         break;
9961     case OPC_SELEQZ_D:
9962         check_insn(ctx, ISA_MIPS_R6);
9963         gen_sel_d(ctx, op1, fd, ft, fs);
9964         break;
9965     case OPC_SELNEZ_D:
9966         check_insn(ctx, ISA_MIPS_R6);
9967         gen_sel_d(ctx, op1, fd, ft, fs);
9968         break;
9969     case OPC_MOVCF_D:
9970         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9971         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9972         break;
9973     case OPC_MOVZ_D:
9974         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9975         {
9976             TCGLabel *l1 = gen_new_label();
9977             TCGv_i64 fp0;
9978 
9979             if (ft != 0) {
9980                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9981             }
9982             fp0 = tcg_temp_new_i64();
9983             gen_load_fpr64(ctx, fp0, fs);
9984             gen_store_fpr64(ctx, fp0, fd);
9985             gen_set_label(l1);
9986         }
9987         break;
9988     case OPC_MOVN_D:
9989         check_insn_opc_removed(ctx, ISA_MIPS_R6);
9990         {
9991             TCGLabel *l1 = gen_new_label();
9992             TCGv_i64 fp0;
9993 
9994             if (ft != 0) {
9995                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9996                 fp0 = tcg_temp_new_i64();
9997                 gen_load_fpr64(ctx, fp0, fs);
9998                 gen_store_fpr64(ctx, fp0, fd);
9999                 gen_set_label(l1);
10000             }
10001         }
10002         break;
10003     case OPC_RECIP_D:
10004         check_cp1_registers(ctx, fs | fd);
10005         {
10006             TCGv_i64 fp0 = tcg_temp_new_i64();
10007 
10008             gen_load_fpr64(ctx, fp0, fs);
10009             gen_helper_float_recip_d(fp0, tcg_env, fp0);
10010             gen_store_fpr64(ctx, fp0, fd);
10011         }
10012         break;
10013     case OPC_RSQRT_D:
10014         check_cp1_registers(ctx, fs | fd);
10015         {
10016             TCGv_i64 fp0 = tcg_temp_new_i64();
10017 
10018             gen_load_fpr64(ctx, fp0, fs);
10019             gen_helper_float_rsqrt_d(fp0, tcg_env, fp0);
10020             gen_store_fpr64(ctx, fp0, fd);
10021         }
10022         break;
10023     case OPC_MADDF_D:
10024         check_insn(ctx, ISA_MIPS_R6);
10025         {
10026             TCGv_i64 fp0 = tcg_temp_new_i64();
10027             TCGv_i64 fp1 = tcg_temp_new_i64();
10028             TCGv_i64 fp2 = tcg_temp_new_i64();
10029             gen_load_fpr64(ctx, fp0, fs);
10030             gen_load_fpr64(ctx, fp1, ft);
10031             gen_load_fpr64(ctx, fp2, fd);
10032             gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2);
10033             gen_store_fpr64(ctx, fp2, fd);
10034         }
10035         break;
10036     case OPC_MSUBF_D:
10037         check_insn(ctx, ISA_MIPS_R6);
10038         {
10039             TCGv_i64 fp0 = tcg_temp_new_i64();
10040             TCGv_i64 fp1 = tcg_temp_new_i64();
10041             TCGv_i64 fp2 = tcg_temp_new_i64();
10042             gen_load_fpr64(ctx, fp0, fs);
10043             gen_load_fpr64(ctx, fp1, ft);
10044             gen_load_fpr64(ctx, fp2, fd);
10045             gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2);
10046             gen_store_fpr64(ctx, fp2, fd);
10047         }
10048         break;
10049     case OPC_RINT_D:
10050         check_insn(ctx, ISA_MIPS_R6);
10051         {
10052             TCGv_i64 fp0 = tcg_temp_new_i64();
10053             gen_load_fpr64(ctx, fp0, fs);
10054             gen_helper_float_rint_d(fp0, tcg_env, fp0);
10055             gen_store_fpr64(ctx, fp0, fd);
10056         }
10057         break;
10058     case OPC_CLASS_D:
10059         check_insn(ctx, ISA_MIPS_R6);
10060         {
10061             TCGv_i64 fp0 = tcg_temp_new_i64();
10062             gen_load_fpr64(ctx, fp0, fs);
10063             gen_helper_float_class_d(fp0, tcg_env, fp0);
10064             gen_store_fpr64(ctx, fp0, fd);
10065         }
10066         break;
10067     case OPC_MIN_D: /* OPC_RECIP2_D */
10068         if (ctx->insn_flags & ISA_MIPS_R6) {
10069             /* OPC_MIN_D */
10070             TCGv_i64 fp0 = tcg_temp_new_i64();
10071             TCGv_i64 fp1 = tcg_temp_new_i64();
10072             gen_load_fpr64(ctx, fp0, fs);
10073             gen_load_fpr64(ctx, fp1, ft);
10074             gen_helper_float_min_d(fp1, tcg_env, fp0, fp1);
10075             gen_store_fpr64(ctx, fp1, fd);
10076         } else {
10077             /* OPC_RECIP2_D */
10078             check_cp1_64bitmode(ctx);
10079             {
10080                 TCGv_i64 fp0 = tcg_temp_new_i64();
10081                 TCGv_i64 fp1 = tcg_temp_new_i64();
10082 
10083                 gen_load_fpr64(ctx, fp0, fs);
10084                 gen_load_fpr64(ctx, fp1, ft);
10085                 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1);
10086                 gen_store_fpr64(ctx, fp0, fd);
10087             }
10088         }
10089         break;
10090     case OPC_MINA_D: /* OPC_RECIP1_D */
10091         if (ctx->insn_flags & ISA_MIPS_R6) {
10092             /* OPC_MINA_D */
10093             TCGv_i64 fp0 = tcg_temp_new_i64();
10094             TCGv_i64 fp1 = tcg_temp_new_i64();
10095             gen_load_fpr64(ctx, fp0, fs);
10096             gen_load_fpr64(ctx, fp1, ft);
10097             gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1);
10098             gen_store_fpr64(ctx, fp1, fd);
10099         } else {
10100             /* OPC_RECIP1_D */
10101             check_cp1_64bitmode(ctx);
10102             {
10103                 TCGv_i64 fp0 = tcg_temp_new_i64();
10104 
10105                 gen_load_fpr64(ctx, fp0, fs);
10106                 gen_helper_float_recip1_d(fp0, tcg_env, fp0);
10107                 gen_store_fpr64(ctx, fp0, fd);
10108             }
10109         }
10110         break;
10111     case OPC_MAX_D: /*  OPC_RSQRT1_D */
10112         if (ctx->insn_flags & ISA_MIPS_R6) {
10113             /* OPC_MAX_D */
10114             TCGv_i64 fp0 = tcg_temp_new_i64();
10115             TCGv_i64 fp1 = tcg_temp_new_i64();
10116             gen_load_fpr64(ctx, fp0, fs);
10117             gen_load_fpr64(ctx, fp1, ft);
10118             gen_helper_float_max_d(fp1, tcg_env, fp0, fp1);
10119             gen_store_fpr64(ctx, fp1, fd);
10120         } else {
10121             /* OPC_RSQRT1_D */
10122             check_cp1_64bitmode(ctx);
10123             {
10124                 TCGv_i64 fp0 = tcg_temp_new_i64();
10125 
10126                 gen_load_fpr64(ctx, fp0, fs);
10127                 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0);
10128                 gen_store_fpr64(ctx, fp0, fd);
10129             }
10130         }
10131         break;
10132     case OPC_MAXA_D: /* OPC_RSQRT2_D */
10133         if (ctx->insn_flags & ISA_MIPS_R6) {
10134             /* OPC_MAXA_D */
10135             TCGv_i64 fp0 = tcg_temp_new_i64();
10136             TCGv_i64 fp1 = tcg_temp_new_i64();
10137             gen_load_fpr64(ctx, fp0, fs);
10138             gen_load_fpr64(ctx, fp1, ft);
10139             gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1);
10140             gen_store_fpr64(ctx, fp1, fd);
10141         } else {
10142             /* OPC_RSQRT2_D */
10143             check_cp1_64bitmode(ctx);
10144             {
10145                 TCGv_i64 fp0 = tcg_temp_new_i64();
10146                 TCGv_i64 fp1 = tcg_temp_new_i64();
10147 
10148                 gen_load_fpr64(ctx, fp0, fs);
10149                 gen_load_fpr64(ctx, fp1, ft);
10150                 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1);
10151                 gen_store_fpr64(ctx, fp0, fd);
10152             }
10153         }
10154         break;
10155     case OPC_CMP_F_D:
10156     case OPC_CMP_UN_D:
10157     case OPC_CMP_EQ_D:
10158     case OPC_CMP_UEQ_D:
10159     case OPC_CMP_OLT_D:
10160     case OPC_CMP_ULT_D:
10161     case OPC_CMP_OLE_D:
10162     case OPC_CMP_ULE_D:
10163     case OPC_CMP_SF_D:
10164     case OPC_CMP_NGLE_D:
10165     case OPC_CMP_SEQ_D:
10166     case OPC_CMP_NGL_D:
10167     case OPC_CMP_LT_D:
10168     case OPC_CMP_NGE_D:
10169     case OPC_CMP_LE_D:
10170     case OPC_CMP_NGT_D:
10171         check_insn_opc_removed(ctx, ISA_MIPS_R6);
10172         if (ctx->opcode & (1 << 6)) {
10173             gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10174         } else {
10175             gen_cmp_d(ctx, func - 48, ft, fs, cc);
10176         }
10177         break;
10178     case OPC_CVT_S_D:
10179         check_cp1_registers(ctx, fs);
10180         {
10181             TCGv_i32 fp32 = tcg_temp_new_i32();
10182             TCGv_i64 fp64 = tcg_temp_new_i64();
10183 
10184             gen_load_fpr64(ctx, fp64, fs);
10185             gen_helper_float_cvts_d(fp32, tcg_env, fp64);
10186             gen_store_fpr32(ctx, fp32, fd);
10187         }
10188         break;
10189     case OPC_CVT_W_D:
10190         check_cp1_registers(ctx, fs);
10191         {
10192             TCGv_i32 fp32 = tcg_temp_new_i32();
10193             TCGv_i64 fp64 = tcg_temp_new_i64();
10194 
10195             gen_load_fpr64(ctx, fp64, fs);
10196             if (ctx->nan2008) {
10197                 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64);
10198             } else {
10199                 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64);
10200             }
10201             gen_store_fpr32(ctx, fp32, fd);
10202         }
10203         break;
10204     case OPC_CVT_L_D:
10205         check_cp1_64bitmode(ctx);
10206         {
10207             TCGv_i64 fp0 = tcg_temp_new_i64();
10208 
10209             gen_load_fpr64(ctx, fp0, fs);
10210             if (ctx->nan2008) {
10211                 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0);
10212             } else {
10213                 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0);
10214             }
10215             gen_store_fpr64(ctx, fp0, fd);
10216         }
10217         break;
10218     case OPC_CVT_S_W:
10219         {
10220             TCGv_i32 fp0 = tcg_temp_new_i32();
10221 
10222             gen_load_fpr32(ctx, fp0, fs);
10223             gen_helper_float_cvts_w(fp0, tcg_env, fp0);
10224             gen_store_fpr32(ctx, fp0, fd);
10225         }
10226         break;
10227     case OPC_CVT_D_W:
10228         check_cp1_registers(ctx, fd);
10229         {
10230             TCGv_i32 fp32 = tcg_temp_new_i32();
10231             TCGv_i64 fp64 = tcg_temp_new_i64();
10232 
10233             gen_load_fpr32(ctx, fp32, fs);
10234             gen_helper_float_cvtd_w(fp64, tcg_env, fp32);
10235             gen_store_fpr64(ctx, fp64, fd);
10236         }
10237         break;
10238     case OPC_CVT_S_L:
10239         check_cp1_64bitmode(ctx);
10240         {
10241             TCGv_i32 fp32 = tcg_temp_new_i32();
10242             TCGv_i64 fp64 = tcg_temp_new_i64();
10243 
10244             gen_load_fpr64(ctx, fp64, fs);
10245             gen_helper_float_cvts_l(fp32, tcg_env, fp64);
10246             gen_store_fpr32(ctx, fp32, fd);
10247         }
10248         break;
10249     case OPC_CVT_D_L:
10250         check_cp1_64bitmode(ctx);
10251         {
10252             TCGv_i64 fp0 = tcg_temp_new_i64();
10253 
10254             gen_load_fpr64(ctx, fp0, fs);
10255             gen_helper_float_cvtd_l(fp0, tcg_env, fp0);
10256             gen_store_fpr64(ctx, fp0, fd);
10257         }
10258         break;
10259     case OPC_CVT_PS_PW:
10260         check_ps(ctx);
10261         {
10262             TCGv_i64 fp0 = tcg_temp_new_i64();
10263 
10264             gen_load_fpr64(ctx, fp0, fs);
10265             gen_helper_float_cvtps_pw(fp0, tcg_env, fp0);
10266             gen_store_fpr64(ctx, fp0, fd);
10267         }
10268         break;
10269     case OPC_ADD_PS:
10270         check_ps(ctx);
10271         {
10272             TCGv_i64 fp0 = tcg_temp_new_i64();
10273             TCGv_i64 fp1 = tcg_temp_new_i64();
10274 
10275             gen_load_fpr64(ctx, fp0, fs);
10276             gen_load_fpr64(ctx, fp1, ft);
10277             gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1);
10278             gen_store_fpr64(ctx, fp0, fd);
10279         }
10280         break;
10281     case OPC_SUB_PS:
10282         check_ps(ctx);
10283         {
10284             TCGv_i64 fp0 = tcg_temp_new_i64();
10285             TCGv_i64 fp1 = tcg_temp_new_i64();
10286 
10287             gen_load_fpr64(ctx, fp0, fs);
10288             gen_load_fpr64(ctx, fp1, ft);
10289             gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1);
10290             gen_store_fpr64(ctx, fp0, fd);
10291         }
10292         break;
10293     case OPC_MUL_PS:
10294         check_ps(ctx);
10295         {
10296             TCGv_i64 fp0 = tcg_temp_new_i64();
10297             TCGv_i64 fp1 = tcg_temp_new_i64();
10298 
10299             gen_load_fpr64(ctx, fp0, fs);
10300             gen_load_fpr64(ctx, fp1, ft);
10301             gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1);
10302             gen_store_fpr64(ctx, fp0, fd);
10303         }
10304         break;
10305     case OPC_ABS_PS:
10306         check_ps(ctx);
10307         {
10308             TCGv_i64 fp0 = tcg_temp_new_i64();
10309 
10310             gen_load_fpr64(ctx, fp0, fs);
10311             gen_helper_float_abs_ps(fp0, fp0);
10312             gen_store_fpr64(ctx, fp0, fd);
10313         }
10314         break;
10315     case OPC_MOV_PS:
10316         check_ps(ctx);
10317         {
10318             TCGv_i64 fp0 = tcg_temp_new_i64();
10319 
10320             gen_load_fpr64(ctx, fp0, fs);
10321             gen_store_fpr64(ctx, fp0, fd);
10322         }
10323         break;
10324     case OPC_NEG_PS:
10325         check_ps(ctx);
10326         {
10327             TCGv_i64 fp0 = tcg_temp_new_i64();
10328 
10329             gen_load_fpr64(ctx, fp0, fs);
10330             gen_helper_float_chs_ps(fp0, fp0);
10331             gen_store_fpr64(ctx, fp0, fd);
10332         }
10333         break;
10334     case OPC_MOVCF_PS:
10335         check_ps(ctx);
10336         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10337         break;
10338     case OPC_MOVZ_PS:
10339         check_ps(ctx);
10340         {
10341             TCGLabel *l1 = gen_new_label();
10342             TCGv_i64 fp0;
10343 
10344             if (ft != 0) {
10345                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10346             }
10347             fp0 = tcg_temp_new_i64();
10348             gen_load_fpr64(ctx, fp0, fs);
10349             gen_store_fpr64(ctx, fp0, fd);
10350             gen_set_label(l1);
10351         }
10352         break;
10353     case OPC_MOVN_PS:
10354         check_ps(ctx);
10355         {
10356             TCGLabel *l1 = gen_new_label();
10357             TCGv_i64 fp0;
10358 
10359             if (ft != 0) {
10360                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10361                 fp0 = tcg_temp_new_i64();
10362                 gen_load_fpr64(ctx, fp0, fs);
10363                 gen_store_fpr64(ctx, fp0, fd);
10364                 gen_set_label(l1);
10365             }
10366         }
10367         break;
10368     case OPC_ADDR_PS:
10369         check_ps(ctx);
10370         {
10371             TCGv_i64 fp0 = tcg_temp_new_i64();
10372             TCGv_i64 fp1 = tcg_temp_new_i64();
10373 
10374             gen_load_fpr64(ctx, fp0, ft);
10375             gen_load_fpr64(ctx, fp1, fs);
10376             gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1);
10377             gen_store_fpr64(ctx, fp0, fd);
10378         }
10379         break;
10380     case OPC_MULR_PS:
10381         check_ps(ctx);
10382         {
10383             TCGv_i64 fp0 = tcg_temp_new_i64();
10384             TCGv_i64 fp1 = tcg_temp_new_i64();
10385 
10386             gen_load_fpr64(ctx, fp0, ft);
10387             gen_load_fpr64(ctx, fp1, fs);
10388             gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1);
10389             gen_store_fpr64(ctx, fp0, fd);
10390         }
10391         break;
10392     case OPC_RECIP2_PS:
10393         check_ps(ctx);
10394         {
10395             TCGv_i64 fp0 = tcg_temp_new_i64();
10396             TCGv_i64 fp1 = tcg_temp_new_i64();
10397 
10398             gen_load_fpr64(ctx, fp0, fs);
10399             gen_load_fpr64(ctx, fp1, ft);
10400             gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1);
10401             gen_store_fpr64(ctx, fp0, fd);
10402         }
10403         break;
10404     case OPC_RECIP1_PS:
10405         check_ps(ctx);
10406         {
10407             TCGv_i64 fp0 = tcg_temp_new_i64();
10408 
10409             gen_load_fpr64(ctx, fp0, fs);
10410             gen_helper_float_recip1_ps(fp0, tcg_env, fp0);
10411             gen_store_fpr64(ctx, fp0, fd);
10412         }
10413         break;
10414     case OPC_RSQRT1_PS:
10415         check_ps(ctx);
10416         {
10417             TCGv_i64 fp0 = tcg_temp_new_i64();
10418 
10419             gen_load_fpr64(ctx, fp0, fs);
10420             gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0);
10421             gen_store_fpr64(ctx, fp0, fd);
10422         }
10423         break;
10424     case OPC_RSQRT2_PS:
10425         check_ps(ctx);
10426         {
10427             TCGv_i64 fp0 = tcg_temp_new_i64();
10428             TCGv_i64 fp1 = tcg_temp_new_i64();
10429 
10430             gen_load_fpr64(ctx, fp0, fs);
10431             gen_load_fpr64(ctx, fp1, ft);
10432             gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1);
10433             gen_store_fpr64(ctx, fp0, fd);
10434         }
10435         break;
10436     case OPC_CVT_S_PU:
10437         check_cp1_64bitmode(ctx);
10438         {
10439             TCGv_i32 fp0 = tcg_temp_new_i32();
10440 
10441             gen_load_fpr32h(ctx, fp0, fs);
10442             gen_helper_float_cvts_pu(fp0, tcg_env, fp0);
10443             gen_store_fpr32(ctx, fp0, fd);
10444         }
10445         break;
10446     case OPC_CVT_PW_PS:
10447         check_ps(ctx);
10448         {
10449             TCGv_i64 fp0 = tcg_temp_new_i64();
10450 
10451             gen_load_fpr64(ctx, fp0, fs);
10452             gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0);
10453             gen_store_fpr64(ctx, fp0, fd);
10454         }
10455         break;
10456     case OPC_CVT_S_PL:
10457         check_cp1_64bitmode(ctx);
10458         {
10459             TCGv_i32 fp0 = tcg_temp_new_i32();
10460 
10461             gen_load_fpr32(ctx, fp0, fs);
10462             gen_helper_float_cvts_pl(fp0, tcg_env, fp0);
10463             gen_store_fpr32(ctx, fp0, fd);
10464         }
10465         break;
10466     case OPC_PLL_PS:
10467         check_ps(ctx);
10468         {
10469             TCGv_i32 fp0 = tcg_temp_new_i32();
10470             TCGv_i32 fp1 = tcg_temp_new_i32();
10471 
10472             gen_load_fpr32(ctx, fp0, fs);
10473             gen_load_fpr32(ctx, fp1, ft);
10474             gen_store_fpr32h(ctx, fp0, fd);
10475             gen_store_fpr32(ctx, fp1, fd);
10476         }
10477         break;
10478     case OPC_PLU_PS:
10479         check_ps(ctx);
10480         {
10481             TCGv_i32 fp0 = tcg_temp_new_i32();
10482             TCGv_i32 fp1 = tcg_temp_new_i32();
10483 
10484             gen_load_fpr32(ctx, fp0, fs);
10485             gen_load_fpr32h(ctx, fp1, ft);
10486             gen_store_fpr32(ctx, fp1, fd);
10487             gen_store_fpr32h(ctx, fp0, fd);
10488         }
10489         break;
10490     case OPC_PUL_PS:
10491         check_ps(ctx);
10492         {
10493             TCGv_i32 fp0 = tcg_temp_new_i32();
10494             TCGv_i32 fp1 = tcg_temp_new_i32();
10495 
10496             gen_load_fpr32h(ctx, fp0, fs);
10497             gen_load_fpr32(ctx, fp1, ft);
10498             gen_store_fpr32(ctx, fp1, fd);
10499             gen_store_fpr32h(ctx, fp0, fd);
10500         }
10501         break;
10502     case OPC_PUU_PS:
10503         check_ps(ctx);
10504         {
10505             TCGv_i32 fp0 = tcg_temp_new_i32();
10506             TCGv_i32 fp1 = tcg_temp_new_i32();
10507 
10508             gen_load_fpr32h(ctx, fp0, fs);
10509             gen_load_fpr32h(ctx, fp1, ft);
10510             gen_store_fpr32(ctx, fp1, fd);
10511             gen_store_fpr32h(ctx, fp0, fd);
10512         }
10513         break;
10514     case OPC_CMP_F_PS:
10515     case OPC_CMP_UN_PS:
10516     case OPC_CMP_EQ_PS:
10517     case OPC_CMP_UEQ_PS:
10518     case OPC_CMP_OLT_PS:
10519     case OPC_CMP_ULT_PS:
10520     case OPC_CMP_OLE_PS:
10521     case OPC_CMP_ULE_PS:
10522     case OPC_CMP_SF_PS:
10523     case OPC_CMP_NGLE_PS:
10524     case OPC_CMP_SEQ_PS:
10525     case OPC_CMP_NGL_PS:
10526     case OPC_CMP_LT_PS:
10527     case OPC_CMP_NGE_PS:
10528     case OPC_CMP_LE_PS:
10529     case OPC_CMP_NGT_PS:
10530         if (ctx->opcode & (1 << 6)) {
10531             gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
10532         } else {
10533             gen_cmp_ps(ctx, func - 48, ft, fs, cc);
10534         }
10535         break;
10536     default:
10537         MIPS_INVAL("farith");
10538         gen_reserved_instruction(ctx);
10539         return;
10540     }
10541 }
10542 
10543 /* Coprocessor 3 (FPU) */
gen_flt3_ldst(DisasContext * ctx,uint32_t opc,int fd,int fs,int base,int index)10544 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
10545                           int fd, int fs, int base, int index)
10546 {
10547     TCGv t0 = tcg_temp_new();
10548 
10549     if (base == 0) {
10550         gen_load_gpr(t0, index);
10551     } else if (index == 0) {
10552         gen_load_gpr(t0, base);
10553     } else {
10554         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10555     }
10556     /*
10557      * Don't do NOP if destination is zero: we must perform the actual
10558      * memory access.
10559      */
10560     switch (opc) {
10561     case OPC_LWXC1:
10562         check_cop1x(ctx);
10563         {
10564             TCGv_i32 fp0 = tcg_temp_new_i32();
10565 
10566             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
10567             tcg_gen_trunc_tl_i32(fp0, t0);
10568             gen_store_fpr32(ctx, fp0, fd);
10569         }
10570         break;
10571     case OPC_LDXC1:
10572         check_cop1x(ctx);
10573         check_cp1_registers(ctx, fd);
10574         {
10575             TCGv_i64 fp0 = tcg_temp_new_i64();
10576             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10577             gen_store_fpr64(ctx, fp0, fd);
10578         }
10579         break;
10580     case OPC_LUXC1:
10581         check_cp1_64bitmode(ctx);
10582         tcg_gen_andi_tl(t0, t0, ~0x7);
10583         {
10584             TCGv_i64 fp0 = tcg_temp_new_i64();
10585 
10586             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10587             gen_store_fpr64(ctx, fp0, fd);
10588         }
10589         break;
10590     case OPC_SWXC1:
10591         check_cop1x(ctx);
10592         {
10593             TCGv_i32 fp0 = tcg_temp_new_i32();
10594             gen_load_fpr32(ctx, fp0, fs);
10595             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
10596         }
10597         break;
10598     case OPC_SDXC1:
10599         check_cop1x(ctx);
10600         check_cp1_registers(ctx, fs);
10601         {
10602             TCGv_i64 fp0 = tcg_temp_new_i64();
10603             gen_load_fpr64(ctx, fp0, fs);
10604             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10605         }
10606         break;
10607     case OPC_SUXC1:
10608         check_cp1_64bitmode(ctx);
10609         tcg_gen_andi_tl(t0, t0, ~0x7);
10610         {
10611             TCGv_i64 fp0 = tcg_temp_new_i64();
10612             gen_load_fpr64(ctx, fp0, fs);
10613             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
10614         }
10615         break;
10616     }
10617 }
10618 
gen_flt3_arith(DisasContext * ctx,uint32_t opc,int fd,int fr,int fs,int ft)10619 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
10620                            int fd, int fr, int fs, int ft)
10621 {
10622     switch (opc) {
10623     case OPC_ALNV_PS:
10624         check_ps(ctx);
10625         {
10626             TCGv t0 = tcg_temp_new();
10627             TCGv_i32 fp = tcg_temp_new_i32();
10628             TCGv_i32 fph = tcg_temp_new_i32();
10629             TCGLabel *l1 = gen_new_label();
10630             TCGLabel *l2 = gen_new_label();
10631 
10632             gen_load_gpr(t0, fr);
10633             tcg_gen_andi_tl(t0, t0, 0x7);
10634 
10635             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10636             gen_load_fpr32(ctx, fp, fs);
10637             gen_load_fpr32h(ctx, fph, fs);
10638             gen_store_fpr32(ctx, fp, fd);
10639             gen_store_fpr32h(ctx, fph, fd);
10640             tcg_gen_br(l2);
10641             gen_set_label(l1);
10642             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10643             if (disas_is_bigendian(ctx)) {
10644                 gen_load_fpr32(ctx, fp, fs);
10645                 gen_load_fpr32h(ctx, fph, ft);
10646                 gen_store_fpr32h(ctx, fp, fd);
10647                 gen_store_fpr32(ctx, fph, fd);
10648             } else {
10649                 gen_load_fpr32h(ctx, fph, fs);
10650                 gen_load_fpr32(ctx, fp, ft);
10651                 gen_store_fpr32(ctx, fph, fd);
10652                 gen_store_fpr32h(ctx, fp, fd);
10653             }
10654             gen_set_label(l2);
10655         }
10656         break;
10657     case OPC_MADD_S:
10658         check_cop1x(ctx);
10659         {
10660             TCGv_i32 fp0 = tcg_temp_new_i32();
10661             TCGv_i32 fp1 = tcg_temp_new_i32();
10662             TCGv_i32 fp2 = tcg_temp_new_i32();
10663 
10664             gen_load_fpr32(ctx, fp0, fs);
10665             gen_load_fpr32(ctx, fp1, ft);
10666             gen_load_fpr32(ctx, fp2, fr);
10667             gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2);
10668             gen_store_fpr32(ctx, fp2, fd);
10669         }
10670         break;
10671     case OPC_MADD_D:
10672         check_cop1x(ctx);
10673         check_cp1_registers(ctx, fd | fs | ft | fr);
10674         {
10675             TCGv_i64 fp0 = tcg_temp_new_i64();
10676             TCGv_i64 fp1 = tcg_temp_new_i64();
10677             TCGv_i64 fp2 = tcg_temp_new_i64();
10678 
10679             gen_load_fpr64(ctx, fp0, fs);
10680             gen_load_fpr64(ctx, fp1, ft);
10681             gen_load_fpr64(ctx, fp2, fr);
10682             gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2);
10683             gen_store_fpr64(ctx, fp2, fd);
10684         }
10685         break;
10686     case OPC_MADD_PS:
10687         check_ps(ctx);
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_ps(fp2, tcg_env, fp0, fp1, fp2);
10697             gen_store_fpr64(ctx, fp2, fd);
10698         }
10699         break;
10700     case OPC_MSUB_S:
10701         check_cop1x(ctx);
10702         {
10703             TCGv_i32 fp0 = tcg_temp_new_i32();
10704             TCGv_i32 fp1 = tcg_temp_new_i32();
10705             TCGv_i32 fp2 = tcg_temp_new_i32();
10706 
10707             gen_load_fpr32(ctx, fp0, fs);
10708             gen_load_fpr32(ctx, fp1, ft);
10709             gen_load_fpr32(ctx, fp2, fr);
10710             gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2);
10711             gen_store_fpr32(ctx, fp2, fd);
10712         }
10713         break;
10714     case OPC_MSUB_D:
10715         check_cop1x(ctx);
10716         check_cp1_registers(ctx, fd | fs | ft | fr);
10717         {
10718             TCGv_i64 fp0 = tcg_temp_new_i64();
10719             TCGv_i64 fp1 = tcg_temp_new_i64();
10720             TCGv_i64 fp2 = tcg_temp_new_i64();
10721 
10722             gen_load_fpr64(ctx, fp0, fs);
10723             gen_load_fpr64(ctx, fp1, ft);
10724             gen_load_fpr64(ctx, fp2, fr);
10725             gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2);
10726             gen_store_fpr64(ctx, fp2, fd);
10727         }
10728         break;
10729     case OPC_MSUB_PS:
10730         check_ps(ctx);
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_ps(fp2, tcg_env, fp0, fp1, fp2);
10740             gen_store_fpr64(ctx, fp2, fd);
10741         }
10742         break;
10743     case OPC_NMADD_S:
10744         check_cop1x(ctx);
10745         {
10746             TCGv_i32 fp0 = tcg_temp_new_i32();
10747             TCGv_i32 fp1 = tcg_temp_new_i32();
10748             TCGv_i32 fp2 = tcg_temp_new_i32();
10749 
10750             gen_load_fpr32(ctx, fp0, fs);
10751             gen_load_fpr32(ctx, fp1, ft);
10752             gen_load_fpr32(ctx, fp2, fr);
10753             gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2);
10754             gen_store_fpr32(ctx, fp2, fd);
10755         }
10756         break;
10757     case OPC_NMADD_D:
10758         check_cop1x(ctx);
10759         check_cp1_registers(ctx, fd | fs | ft | fr);
10760         {
10761             TCGv_i64 fp0 = tcg_temp_new_i64();
10762             TCGv_i64 fp1 = tcg_temp_new_i64();
10763             TCGv_i64 fp2 = tcg_temp_new_i64();
10764 
10765             gen_load_fpr64(ctx, fp0, fs);
10766             gen_load_fpr64(ctx, fp1, ft);
10767             gen_load_fpr64(ctx, fp2, fr);
10768             gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2);
10769             gen_store_fpr64(ctx, fp2, fd);
10770         }
10771         break;
10772     case OPC_NMADD_PS:
10773         check_ps(ctx);
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_ps(fp2, tcg_env, fp0, fp1, fp2);
10783             gen_store_fpr64(ctx, fp2, fd);
10784         }
10785         break;
10786     case OPC_NMSUB_S:
10787         check_cop1x(ctx);
10788         {
10789             TCGv_i32 fp0 = tcg_temp_new_i32();
10790             TCGv_i32 fp1 = tcg_temp_new_i32();
10791             TCGv_i32 fp2 = tcg_temp_new_i32();
10792 
10793             gen_load_fpr32(ctx, fp0, fs);
10794             gen_load_fpr32(ctx, fp1, ft);
10795             gen_load_fpr32(ctx, fp2, fr);
10796             gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2);
10797             gen_store_fpr32(ctx, fp2, fd);
10798         }
10799         break;
10800     case OPC_NMSUB_D:
10801         check_cop1x(ctx);
10802         check_cp1_registers(ctx, fd | fs | ft | fr);
10803         {
10804             TCGv_i64 fp0 = tcg_temp_new_i64();
10805             TCGv_i64 fp1 = tcg_temp_new_i64();
10806             TCGv_i64 fp2 = tcg_temp_new_i64();
10807 
10808             gen_load_fpr64(ctx, fp0, fs);
10809             gen_load_fpr64(ctx, fp1, ft);
10810             gen_load_fpr64(ctx, fp2, fr);
10811             gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2);
10812             gen_store_fpr64(ctx, fp2, fd);
10813         }
10814         break;
10815     case OPC_NMSUB_PS:
10816         check_ps(ctx);
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_ps(fp2, tcg_env, fp0, fp1, fp2);
10826             gen_store_fpr64(ctx, fp2, fd);
10827         }
10828         break;
10829     default:
10830         MIPS_INVAL("flt3_arith");
10831         gen_reserved_instruction(ctx);
10832         return;
10833     }
10834 }
10835 
gen_rdhwr(DisasContext * ctx,int rt,int rd,int sel)10836 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10837 {
10838     TCGv t0;
10839 
10840 #if !defined(CONFIG_USER_ONLY)
10841     /*
10842      * The Linux kernel will emulate rdhwr if it's not supported natively.
10843      * Therefore only check the ISA in system mode.
10844      */
10845     check_insn(ctx, ISA_MIPS_R2);
10846 #endif
10847     t0 = tcg_temp_new();
10848 
10849     switch (rd) {
10850     case 0:
10851         gen_helper_rdhwr_cpunum(t0, tcg_env);
10852         gen_store_gpr(t0, rt);
10853         break;
10854     case 1:
10855         gen_helper_rdhwr_synci_step(t0, tcg_env);
10856         gen_store_gpr(t0, rt);
10857         break;
10858     case 2:
10859         translator_io_start(&ctx->base);
10860         gen_helper_rdhwr_cc(t0, tcg_env);
10861         gen_store_gpr(t0, rt);
10862         /*
10863          * Break the TB to be able to take timer interrupts immediately
10864          * after reading count. DISAS_STOP isn't sufficient, we need to ensure
10865          * we break completely out of translated code.
10866          */
10867         gen_save_pc(ctx->base.pc_next + 4);
10868         ctx->base.is_jmp = DISAS_EXIT;
10869         break;
10870     case 3:
10871         gen_helper_rdhwr_ccres(t0, tcg_env);
10872         gen_store_gpr(t0, rt);
10873         break;
10874     case 4:
10875         check_insn(ctx, ISA_MIPS_R6);
10876         if (sel != 0) {
10877             /*
10878              * Performance counter registers are not implemented other than
10879              * control register 0.
10880              */
10881             generate_exception(ctx, EXCP_RI);
10882         }
10883         gen_helper_rdhwr_performance(t0, tcg_env);
10884         gen_store_gpr(t0, rt);
10885         break;
10886     case 5:
10887         check_insn(ctx, ISA_MIPS_R6);
10888         gen_helper_rdhwr_xnp(t0, tcg_env);
10889         gen_store_gpr(t0, rt);
10890         break;
10891     case 29:
10892 #if defined(CONFIG_USER_ONLY)
10893         tcg_gen_ld_tl(t0, tcg_env,
10894                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10895         gen_store_gpr(t0, rt);
10896         break;
10897 #else
10898         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10899             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10900             tcg_gen_ld_tl(t0, tcg_env,
10901                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10902             gen_store_gpr(t0, rt);
10903         } else {
10904             gen_reserved_instruction(ctx);
10905         }
10906         break;
10907 #endif
10908     default:            /* Invalid */
10909         MIPS_INVAL("rdhwr");
10910         gen_reserved_instruction(ctx);
10911         break;
10912     }
10913 }
10914 
clear_branch_hflags(DisasContext * ctx)10915 static inline void clear_branch_hflags(DisasContext *ctx)
10916 {
10917     ctx->hflags &= ~MIPS_HFLAG_BMASK;
10918     if (ctx->base.is_jmp == DISAS_NEXT) {
10919         save_cpu_state(ctx, 0);
10920     } else {
10921         /*
10922          * It is not safe to save ctx->hflags as hflags may be changed
10923          * in execution time by the instruction in delay / forbidden slot.
10924          */
10925         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10926     }
10927 }
10928 
gen_branch(DisasContext * ctx,int insn_bytes)10929 static void gen_branch(DisasContext *ctx, int insn_bytes)
10930 {
10931     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10932         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10933         /* Branches completion */
10934         clear_branch_hflags(ctx);
10935         ctx->base.is_jmp = DISAS_NORETURN;
10936         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10937         case MIPS_HFLAG_FBNSLOT:
10938             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
10939             break;
10940         case MIPS_HFLAG_B:
10941             /* unconditional branch */
10942             if (proc_hflags & MIPS_HFLAG_BX) {
10943                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10944             }
10945             gen_goto_tb(ctx, 0, ctx->btarget);
10946             break;
10947         case MIPS_HFLAG_BL:
10948             /* blikely taken case */
10949             gen_goto_tb(ctx, 0, ctx->btarget);
10950             break;
10951         case MIPS_HFLAG_BC:
10952             /* Conditional branch */
10953             {
10954                 TCGLabel *l1 = gen_new_label();
10955 
10956                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10957                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
10958                 gen_set_label(l1);
10959                 gen_goto_tb(ctx, 0, ctx->btarget);
10960             }
10961             break;
10962         case MIPS_HFLAG_BR:
10963             /* unconditional branch to register */
10964             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10965                 TCGv t0 = tcg_temp_new();
10966                 TCGv_i32 t1 = tcg_temp_new_i32();
10967 
10968                 tcg_gen_andi_tl(t0, btarget, 0x1);
10969                 tcg_gen_trunc_tl_i32(t1, t0);
10970                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10971                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10972                 tcg_gen_or_i32(hflags, hflags, t1);
10973 
10974                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10975             } else {
10976                 tcg_gen_mov_tl(cpu_PC, btarget);
10977             }
10978             tcg_gen_lookup_and_goto_ptr();
10979             break;
10980         default:
10981             LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
10982             gen_reserved_instruction(ctx);
10983         }
10984     }
10985 }
10986 
10987 /* Compact Branches */
gen_compute_compact_branch(DisasContext * ctx,uint32_t opc,int rs,int rt,int32_t offset)10988 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10989                                        int rs, int rt, int32_t offset)
10990 {
10991     int bcond_compute = 0;
10992     TCGv t0 = tcg_temp_new();
10993     TCGv t1 = tcg_temp_new();
10994     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10995 
10996     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10997 #ifdef MIPS_DEBUG_DISAS
10998         LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
10999                   VADDR_PRIx "\n", ctx->base.pc_next);
11000 #endif
11001         gen_reserved_instruction(ctx);
11002         return;
11003     }
11004 
11005     /* Load needed operands and calculate btarget */
11006     switch (opc) {
11007     /* compact branch */
11008     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11009     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11010         gen_load_gpr(t0, rs);
11011         gen_load_gpr(t1, rt);
11012         bcond_compute = 1;
11013         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11014         if (rs <= rt && rs == 0) {
11015             /* OPC_BEQZALC, OPC_BNEZALC */
11016             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11017         }
11018         break;
11019     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11020     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11021         gen_load_gpr(t0, rs);
11022         gen_load_gpr(t1, rt);
11023         bcond_compute = 1;
11024         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11025         break;
11026     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11027     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11028         if (rs == 0 || rs == rt) {
11029             /* OPC_BLEZALC, OPC_BGEZALC */
11030             /* OPC_BGTZALC, OPC_BLTZALC */
11031             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11032         }
11033         gen_load_gpr(t0, rs);
11034         gen_load_gpr(t1, rt);
11035         bcond_compute = 1;
11036         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11037         break;
11038     case OPC_BC:
11039     case OPC_BALC:
11040         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11041         break;
11042     case OPC_BEQZC:
11043     case OPC_BNEZC:
11044         if (rs != 0) {
11045             /* OPC_BEQZC, OPC_BNEZC */
11046             gen_load_gpr(t0, rs);
11047             bcond_compute = 1;
11048             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11049         } else {
11050             /* OPC_JIC, OPC_JIALC */
11051             TCGv tbase = tcg_temp_new();
11052 
11053             gen_load_gpr(tbase, rt);
11054             gen_op_addr_addi(ctx, btarget, tbase, offset);
11055         }
11056         break;
11057     default:
11058         MIPS_INVAL("Compact branch/jump");
11059         gen_reserved_instruction(ctx);
11060         return;
11061     }
11062 
11063     if (bcond_compute == 0) {
11064         /* Unconditional compact branch */
11065         switch (opc) {
11066         case OPC_JIALC:
11067             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11068             /* Fallthrough */
11069         case OPC_JIC:
11070             ctx->hflags |= MIPS_HFLAG_BR;
11071             break;
11072         case OPC_BALC:
11073             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11074             /* Fallthrough */
11075         case OPC_BC:
11076             ctx->hflags |= MIPS_HFLAG_B;
11077             break;
11078         default:
11079             MIPS_INVAL("Compact branch/jump");
11080             gen_reserved_instruction(ctx);
11081             return;
11082         }
11083 
11084         /* Generating branch here as compact branches don't have delay slot */
11085         gen_branch(ctx, 4);
11086     } else {
11087         /* Conditional compact branch */
11088         TCGLabel *fs = gen_new_label();
11089         save_cpu_state(ctx, 0);
11090 
11091         switch (opc) {
11092         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11093             if (rs == 0 && rt != 0) {
11094                 /* OPC_BLEZALC */
11095                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11096             } else if (rs != 0 && rt != 0 && rs == rt) {
11097                 /* OPC_BGEZALC */
11098                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11099             } else {
11100                 /* OPC_BGEUC */
11101                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11102             }
11103             break;
11104         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11105             if (rs == 0 && rt != 0) {
11106                 /* OPC_BGTZALC */
11107                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11108             } else if (rs != 0 && rt != 0 && rs == rt) {
11109                 /* OPC_BLTZALC */
11110                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11111             } else {
11112                 /* OPC_BLTUC */
11113                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11114             }
11115             break;
11116         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11117             if (rs == 0 && rt != 0) {
11118                 /* OPC_BLEZC */
11119                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11120             } else if (rs != 0 && rt != 0 && rs == rt) {
11121                 /* OPC_BGEZC */
11122                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11123             } else {
11124                 /* OPC_BGEC */
11125                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11126             }
11127             break;
11128         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11129             if (rs == 0 && rt != 0) {
11130                 /* OPC_BGTZC */
11131                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11132             } else if (rs != 0 && rt != 0 && rs == rt) {
11133                 /* OPC_BLTZC */
11134                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11135             } else {
11136                 /* OPC_BLTC */
11137                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11138             }
11139             break;
11140         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11141         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11142             if (rs >= rt) {
11143                 /* OPC_BOVC, OPC_BNVC */
11144                 TCGv t2 = tcg_temp_new();
11145                 TCGv t3 = tcg_temp_new();
11146                 TCGv t4 = tcg_temp_new();
11147                 TCGv input_overflow = tcg_temp_new();
11148 
11149                 gen_load_gpr(t0, rs);
11150                 gen_load_gpr(t1, rt);
11151                 tcg_gen_ext32s_tl(t2, t0);
11152                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11153                 tcg_gen_ext32s_tl(t3, t1);
11154                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11155                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11156 
11157                 tcg_gen_add_tl(t4, t2, t3);
11158                 tcg_gen_ext32s_tl(t4, t4);
11159                 tcg_gen_xor_tl(t2, t2, t3);
11160                 tcg_gen_xor_tl(t3, t4, t3);
11161                 tcg_gen_andc_tl(t2, t3, t2);
11162                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11163                 tcg_gen_or_tl(t4, t4, input_overflow);
11164                 if (opc == OPC_BOVC) {
11165                     /* OPC_BOVC */
11166                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11167                 } else {
11168                     /* OPC_BNVC */
11169                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11170                 }
11171             } else if (rs < rt && rs == 0) {
11172                 /* OPC_BEQZALC, OPC_BNEZALC */
11173                 if (opc == OPC_BEQZALC) {
11174                     /* OPC_BEQZALC */
11175                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11176                 } else {
11177                     /* OPC_BNEZALC */
11178                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11179                 }
11180             } else {
11181                 /* OPC_BEQC, OPC_BNEC */
11182                 if (opc == OPC_BEQC) {
11183                     /* OPC_BEQC */
11184                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11185                 } else {
11186                     /* OPC_BNEC */
11187                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11188                 }
11189             }
11190             break;
11191         case OPC_BEQZC:
11192             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11193             break;
11194         case OPC_BNEZC:
11195             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11196             break;
11197         default:
11198             MIPS_INVAL("Compact conditional branch/jump");
11199             gen_reserved_instruction(ctx);
11200             return;
11201         }
11202 
11203         /* Generating branch here as compact branches don't have delay slot */
11204         gen_goto_tb(ctx, 1, ctx->btarget);
11205         gen_set_label(fs);
11206 
11207         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11208     }
11209 }
11210 
gen_addiupc(DisasContext * ctx,int rx,int imm,int is_64_bit,int extended)11211 void gen_addiupc(DisasContext *ctx, int rx, int imm,
11212                  int is_64_bit, int extended)
11213 {
11214     target_ulong npc;
11215 
11216     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11217         gen_reserved_instruction(ctx);
11218         return;
11219     }
11220 
11221     npc = pc_relative_pc(ctx) + imm;
11222     if (!is_64_bit) {
11223         npc = (int32_t)npc;
11224     }
11225     tcg_gen_movi_tl(cpu_gpr[rx], npc);
11226 }
11227 
gen_cache_operation(DisasContext * ctx,uint32_t op,int base,int16_t offset)11228 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11229                                 int16_t offset)
11230 {
11231     TCGv_i32 t0 = tcg_constant_i32(op);
11232     TCGv t1 = tcg_temp_new();
11233     gen_base_offset_addr(ctx, t1, base, offset);
11234     gen_helper_cache(tcg_env, t1, t0);
11235 }
11236 
is_uhi(DisasContext * ctx,int sdbbp_code)11237 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
11238 {
11239 #ifdef CONFIG_USER_ONLY
11240     return false;
11241 #else
11242     bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
11243     return semihosting_enabled(is_user) && sdbbp_code == 1;
11244 #endif
11245 }
11246 
gen_ldxs(DisasContext * ctx,int base,int index,int rd)11247 void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
11248 {
11249     TCGv t0 = tcg_temp_new();
11250     TCGv t1 = tcg_temp_new();
11251 
11252     gen_load_gpr(t0, base);
11253 
11254     if (index != 0) {
11255         gen_load_gpr(t1, index);
11256         tcg_gen_shli_tl(t1, t1, 2);
11257         gen_op_addr_add(ctx, t0, t1, t0);
11258     }
11259 
11260     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
11261     gen_store_gpr(t1, rd);
11262 }
11263 
gen_sync(int stype)11264 static void gen_sync(int stype)
11265 {
11266     TCGBar tcg_mo = TCG_BAR_SC;
11267 
11268     switch (stype) {
11269     case 0x4: /* SYNC_WMB */
11270         tcg_mo |= TCG_MO_ST_ST;
11271         break;
11272     case 0x10: /* SYNC_MB */
11273         tcg_mo |= TCG_MO_ALL;
11274         break;
11275     case 0x11: /* SYNC_ACQUIRE */
11276         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
11277         break;
11278     case 0x12: /* SYNC_RELEASE */
11279         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
11280         break;
11281     case 0x13: /* SYNC_RMB */
11282         tcg_mo |= TCG_MO_LD_LD;
11283         break;
11284     default:
11285         tcg_mo |= TCG_MO_ALL;
11286         break;
11287     }
11288 
11289     tcg_gen_mb(tcg_mo);
11290 }
11291 
11292 /* ISA extensions (ASEs) */
11293 
11294 /* MIPS16 extension to MIPS32 */
11295 #include "mips16e_translate.c.inc"
11296 
11297 /* microMIPS extension to MIPS32/MIPS64 */
11298 
11299 /*
11300  * Values for microMIPS fmt field.  Variable-width, depending on which
11301  * formats the instruction supports.
11302  */
11303 enum {
11304     FMT_SD_S = 0,
11305     FMT_SD_D = 1,
11306 
11307     FMT_SDPS_S = 0,
11308     FMT_SDPS_D = 1,
11309     FMT_SDPS_PS = 2,
11310 
11311     FMT_SWL_S = 0,
11312     FMT_SWL_W = 1,
11313     FMT_SWL_L = 2,
11314 
11315     FMT_DWL_D = 0,
11316     FMT_DWL_W = 1,
11317     FMT_DWL_L = 2
11318 };
11319 
11320 #include "micromips_translate.c.inc"
11321 
11322 #include "nanomips_translate.c.inc"
11323 
11324 /* MIPSDSP functions. */
11325 
11326 /* Indexed load is not for DSP only */
gen_mips_lx(DisasContext * ctx,uint32_t opc,int rd,int base,int offset)11327 static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
11328                         int rd, int base, int offset)
11329 {
11330     TCGv t0;
11331 
11332     if (!(ctx->insn_flags & INSN_OCTEON)) {
11333         check_dsp(ctx);
11334     }
11335     t0 = tcg_temp_new();
11336 
11337     if (base == 0) {
11338         gen_load_gpr(t0, offset);
11339     } else if (offset == 0) {
11340         gen_load_gpr(t0, base);
11341     } else {
11342         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
11343     }
11344 
11345     switch (opc) {
11346     case OPC_LBUX:
11347         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
11348         gen_store_gpr(t0, rd);
11349         break;
11350     case OPC_LHX:
11351         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW);
11352         gen_store_gpr(t0, rd);
11353         break;
11354     case OPC_LWX:
11355         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL);
11356         gen_store_gpr(t0, rd);
11357         break;
11358 #if defined(TARGET_MIPS64)
11359     case OPC_LDX:
11360         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
11361         gen_store_gpr(t0, rd);
11362         break;
11363 #endif
11364     }
11365 }
11366 
gen_mipsdsp_arith(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2)11367 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
11368                               int ret, int v1, int v2)
11369 {
11370     TCGv v1_t;
11371     TCGv v2_t;
11372 
11373     if (ret == 0) {
11374         /* Treat as NOP. */
11375         return;
11376     }
11377 
11378     v1_t = tcg_temp_new();
11379     v2_t = tcg_temp_new();
11380 
11381     gen_load_gpr(v1_t, v1);
11382     gen_load_gpr(v2_t, v2);
11383 
11384     switch (op1) {
11385     case OPC_ADDUH_QB_DSP:
11386         check_dsp_r2(ctx);
11387         switch (op2) {
11388         case OPC_ADDUH_QB:
11389             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
11390             break;
11391         case OPC_ADDUH_R_QB:
11392             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11393             break;
11394         case OPC_ADDQH_PH:
11395             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
11396             break;
11397         case OPC_ADDQH_R_PH:
11398             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11399             break;
11400         case OPC_ADDQH_W:
11401             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
11402             break;
11403         case OPC_ADDQH_R_W:
11404             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11405             break;
11406         case OPC_SUBUH_QB:
11407             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
11408             break;
11409         case OPC_SUBUH_R_QB:
11410             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11411             break;
11412         case OPC_SUBQH_PH:
11413             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
11414             break;
11415         case OPC_SUBQH_R_PH:
11416             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11417             break;
11418         case OPC_SUBQH_W:
11419             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
11420             break;
11421         case OPC_SUBQH_R_W:
11422             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11423             break;
11424         }
11425         break;
11426     case OPC_ABSQ_S_PH_DSP:
11427         switch (op2) {
11428         case OPC_ABSQ_S_QB:
11429             check_dsp_r2(ctx);
11430             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env);
11431             break;
11432         case OPC_ABSQ_S_PH:
11433             check_dsp(ctx);
11434             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env);
11435             break;
11436         case OPC_ABSQ_S_W:
11437             check_dsp(ctx);
11438             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env);
11439             break;
11440         case OPC_PRECEQ_W_PHL:
11441             check_dsp(ctx);
11442             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
11443             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11444             break;
11445         case OPC_PRECEQ_W_PHR:
11446             check_dsp(ctx);
11447             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
11448             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
11449             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11450             break;
11451         case OPC_PRECEQU_PH_QBL:
11452             check_dsp(ctx);
11453             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
11454             break;
11455         case OPC_PRECEQU_PH_QBR:
11456             check_dsp(ctx);
11457             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
11458             break;
11459         case OPC_PRECEQU_PH_QBLA:
11460             check_dsp(ctx);
11461             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
11462             break;
11463         case OPC_PRECEQU_PH_QBRA:
11464             check_dsp(ctx);
11465             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
11466             break;
11467         case OPC_PRECEU_PH_QBL:
11468             check_dsp(ctx);
11469             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
11470             break;
11471         case OPC_PRECEU_PH_QBR:
11472             check_dsp(ctx);
11473             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
11474             break;
11475         case OPC_PRECEU_PH_QBLA:
11476             check_dsp(ctx);
11477             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
11478             break;
11479         case OPC_PRECEU_PH_QBRA:
11480             check_dsp(ctx);
11481             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
11482             break;
11483         }
11484         break;
11485     case OPC_ADDU_QB_DSP:
11486         switch (op2) {
11487         case OPC_ADDQ_PH:
11488             check_dsp(ctx);
11489             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11490             break;
11491         case OPC_ADDQ_S_PH:
11492             check_dsp(ctx);
11493             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11494             break;
11495         case OPC_ADDQ_S_W:
11496             check_dsp(ctx);
11497             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11498             break;
11499         case OPC_ADDU_QB:
11500             check_dsp(ctx);
11501             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11502             break;
11503         case OPC_ADDU_S_QB:
11504             check_dsp(ctx);
11505             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11506             break;
11507         case OPC_ADDU_PH:
11508             check_dsp_r2(ctx);
11509             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11510             break;
11511         case OPC_ADDU_S_PH:
11512             check_dsp_r2(ctx);
11513             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11514             break;
11515         case OPC_SUBQ_PH:
11516             check_dsp(ctx);
11517             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11518             break;
11519         case OPC_SUBQ_S_PH:
11520             check_dsp(ctx);
11521             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11522             break;
11523         case OPC_SUBQ_S_W:
11524             check_dsp(ctx);
11525             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11526             break;
11527         case OPC_SUBU_QB:
11528             check_dsp(ctx);
11529             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11530             break;
11531         case OPC_SUBU_S_QB:
11532             check_dsp(ctx);
11533             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11534             break;
11535         case OPC_SUBU_PH:
11536             check_dsp_r2(ctx);
11537             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11538             break;
11539         case OPC_SUBU_S_PH:
11540             check_dsp_r2(ctx);
11541             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11542             break;
11543         case OPC_ADDSC:
11544             check_dsp(ctx);
11545             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11546             break;
11547         case OPC_ADDWC:
11548             check_dsp(ctx);
11549             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11550             break;
11551         case OPC_MODSUB:
11552             check_dsp(ctx);
11553             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
11554             break;
11555         case OPC_RADDU_W_QB:
11556             check_dsp(ctx);
11557             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
11558             break;
11559         }
11560         break;
11561     case OPC_CMPU_EQ_QB_DSP:
11562         switch (op2) {
11563         case OPC_PRECR_QB_PH:
11564             check_dsp_r2(ctx);
11565             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11566             break;
11567         case OPC_PRECRQ_QB_PH:
11568             check_dsp(ctx);
11569             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11570             break;
11571         case OPC_PRECR_SRA_PH_W:
11572             check_dsp_r2(ctx);
11573             {
11574                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11575                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
11576                                           cpu_gpr[ret]);
11577                 break;
11578             }
11579         case OPC_PRECR_SRA_R_PH_W:
11580             check_dsp_r2(ctx);
11581             {
11582                 TCGv_i32 sa_t = tcg_constant_i32(v2);
11583                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
11584                                             cpu_gpr[ret]);
11585                 break;
11586             }
11587         case OPC_PRECRQ_PH_W:
11588             check_dsp(ctx);
11589             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
11590             break;
11591         case OPC_PRECRQ_RS_PH_W:
11592             check_dsp(ctx);
11593             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11594             break;
11595         case OPC_PRECRQU_S_QB_PH:
11596             check_dsp(ctx);
11597             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11598             break;
11599         }
11600         break;
11601 #ifdef TARGET_MIPS64
11602     case OPC_ABSQ_S_QH_DSP:
11603         switch (op2) {
11604         case OPC_PRECEQ_L_PWL:
11605             check_dsp(ctx);
11606             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
11607             break;
11608         case OPC_PRECEQ_L_PWR:
11609             check_dsp(ctx);
11610             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
11611             break;
11612         case OPC_PRECEQ_PW_QHL:
11613             check_dsp(ctx);
11614             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
11615             break;
11616         case OPC_PRECEQ_PW_QHR:
11617             check_dsp(ctx);
11618             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
11619             break;
11620         case OPC_PRECEQ_PW_QHLA:
11621             check_dsp(ctx);
11622             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
11623             break;
11624         case OPC_PRECEQ_PW_QHRA:
11625             check_dsp(ctx);
11626             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
11627             break;
11628         case OPC_PRECEQU_QH_OBL:
11629             check_dsp(ctx);
11630             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
11631             break;
11632         case OPC_PRECEQU_QH_OBR:
11633             check_dsp(ctx);
11634             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
11635             break;
11636         case OPC_PRECEQU_QH_OBLA:
11637             check_dsp(ctx);
11638             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
11639             break;
11640         case OPC_PRECEQU_QH_OBRA:
11641             check_dsp(ctx);
11642             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
11643             break;
11644         case OPC_PRECEU_QH_OBL:
11645             check_dsp(ctx);
11646             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
11647             break;
11648         case OPC_PRECEU_QH_OBR:
11649             check_dsp(ctx);
11650             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
11651             break;
11652         case OPC_PRECEU_QH_OBLA:
11653             check_dsp(ctx);
11654             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
11655             break;
11656         case OPC_PRECEU_QH_OBRA:
11657             check_dsp(ctx);
11658             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
11659             break;
11660         case OPC_ABSQ_S_OB:
11661             check_dsp_r2(ctx);
11662             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env);
11663             break;
11664         case OPC_ABSQ_S_PW:
11665             check_dsp(ctx);
11666             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env);
11667             break;
11668         case OPC_ABSQ_S_QH:
11669             check_dsp(ctx);
11670             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env);
11671             break;
11672         }
11673         break;
11674     case OPC_ADDU_OB_DSP:
11675         switch (op2) {
11676         case OPC_RADDU_L_OB:
11677             check_dsp(ctx);
11678             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
11679             break;
11680         case OPC_SUBQ_PW:
11681             check_dsp(ctx);
11682             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11683             break;
11684         case OPC_SUBQ_S_PW:
11685             check_dsp(ctx);
11686             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11687             break;
11688         case OPC_SUBQ_QH:
11689             check_dsp(ctx);
11690             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11691             break;
11692         case OPC_SUBQ_S_QH:
11693             check_dsp(ctx);
11694             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11695             break;
11696         case OPC_SUBU_OB:
11697             check_dsp(ctx);
11698             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11699             break;
11700         case OPC_SUBU_S_OB:
11701             check_dsp(ctx);
11702             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11703             break;
11704         case OPC_SUBU_QH:
11705             check_dsp_r2(ctx);
11706             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11707             break;
11708         case OPC_SUBU_S_QH:
11709             check_dsp_r2(ctx);
11710             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11711             break;
11712         case OPC_SUBUH_OB:
11713             check_dsp_r2(ctx);
11714             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
11715             break;
11716         case OPC_SUBUH_R_OB:
11717             check_dsp_r2(ctx);
11718             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11719             break;
11720         case OPC_ADDQ_PW:
11721             check_dsp(ctx);
11722             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11723             break;
11724         case OPC_ADDQ_S_PW:
11725             check_dsp(ctx);
11726             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11727             break;
11728         case OPC_ADDQ_QH:
11729             check_dsp(ctx);
11730             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11731             break;
11732         case OPC_ADDQ_S_QH:
11733             check_dsp(ctx);
11734             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11735             break;
11736         case OPC_ADDU_OB:
11737             check_dsp(ctx);
11738             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11739             break;
11740         case OPC_ADDU_S_OB:
11741             check_dsp(ctx);
11742             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11743             break;
11744         case OPC_ADDU_QH:
11745             check_dsp_r2(ctx);
11746             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11747             break;
11748         case OPC_ADDU_S_QH:
11749             check_dsp_r2(ctx);
11750             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11751             break;
11752         case OPC_ADDUH_OB:
11753             check_dsp_r2(ctx);
11754             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
11755             break;
11756         case OPC_ADDUH_R_OB:
11757             check_dsp_r2(ctx);
11758             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
11759             break;
11760         }
11761         break;
11762     case OPC_CMPU_EQ_OB_DSP:
11763         switch (op2) {
11764         case OPC_PRECR_OB_QH:
11765             check_dsp_r2(ctx);
11766             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
11767             break;
11768         case OPC_PRECR_SRA_QH_PW:
11769             check_dsp_r2(ctx);
11770             {
11771                 TCGv_i32 ret_t = tcg_constant_i32(ret);
11772                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
11773                 break;
11774             }
11775         case OPC_PRECR_SRA_R_QH_PW:
11776             check_dsp_r2(ctx);
11777             {
11778                 TCGv_i32 sa_v = tcg_constant_i32(ret);
11779                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
11780                 break;
11781             }
11782         case OPC_PRECRQ_OB_QH:
11783             check_dsp(ctx);
11784             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
11785             break;
11786         case OPC_PRECRQ_PW_L:
11787             check_dsp(ctx);
11788             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
11789             break;
11790         case OPC_PRECRQ_QH_PW:
11791             check_dsp(ctx);
11792             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
11793             break;
11794         case OPC_PRECRQ_RS_QH_PW:
11795             check_dsp(ctx);
11796             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11797             break;
11798         case OPC_PRECRQU_S_OB_QH:
11799             check_dsp(ctx);
11800             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11801             break;
11802         }
11803         break;
11804 #endif
11805     }
11806 }
11807 
gen_mipsdsp_shift(DisasContext * ctx,uint32_t opc,int ret,int v1,int v2)11808 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
11809                               int ret, int v1, int v2)
11810 {
11811     uint32_t op2;
11812     TCGv t0;
11813     TCGv v1_t;
11814     TCGv v2_t;
11815 
11816     if (ret == 0) {
11817         /* Treat as NOP. */
11818         return;
11819     }
11820 
11821     t0 = tcg_temp_new();
11822     v1_t = tcg_temp_new();
11823     v2_t = tcg_temp_new();
11824 
11825     tcg_gen_movi_tl(t0, v1);
11826     gen_load_gpr(v1_t, v1);
11827     gen_load_gpr(v2_t, v2);
11828 
11829     switch (opc) {
11830     case OPC_SHLL_QB_DSP:
11831         {
11832             op2 = MASK_SHLL_QB(ctx->opcode);
11833             switch (op2) {
11834             case OPC_SHLL_QB:
11835                 check_dsp(ctx);
11836                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env);
11837                 break;
11838             case OPC_SHLLV_QB:
11839                 check_dsp(ctx);
11840                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11841                 break;
11842             case OPC_SHLL_PH:
11843                 check_dsp(ctx);
11844                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
11845                 break;
11846             case OPC_SHLLV_PH:
11847                 check_dsp(ctx);
11848                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11849                 break;
11850             case OPC_SHLL_S_PH:
11851                 check_dsp(ctx);
11852                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
11853                 break;
11854             case OPC_SHLLV_S_PH:
11855                 check_dsp(ctx);
11856                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11857                 break;
11858             case OPC_SHLL_S_W:
11859                 check_dsp(ctx);
11860                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env);
11861                 break;
11862             case OPC_SHLLV_S_W:
11863                 check_dsp(ctx);
11864                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11865                 break;
11866             case OPC_SHRL_QB:
11867                 check_dsp(ctx);
11868                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
11869                 break;
11870             case OPC_SHRLV_QB:
11871                 check_dsp(ctx);
11872                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
11873                 break;
11874             case OPC_SHRL_PH:
11875                 check_dsp_r2(ctx);
11876                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
11877                 break;
11878             case OPC_SHRLV_PH:
11879                 check_dsp_r2(ctx);
11880                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
11881                 break;
11882             case OPC_SHRA_QB:
11883                 check_dsp_r2(ctx);
11884                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
11885                 break;
11886             case OPC_SHRA_R_QB:
11887                 check_dsp_r2(ctx);
11888                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
11889                 break;
11890             case OPC_SHRAV_QB:
11891                 check_dsp_r2(ctx);
11892                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
11893                 break;
11894             case OPC_SHRAV_R_QB:
11895                 check_dsp_r2(ctx);
11896                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
11897                 break;
11898             case OPC_SHRA_PH:
11899                 check_dsp(ctx);
11900                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
11901                 break;
11902             case OPC_SHRA_R_PH:
11903                 check_dsp(ctx);
11904                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
11905                 break;
11906             case OPC_SHRAV_PH:
11907                 check_dsp(ctx);
11908                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
11909                 break;
11910             case OPC_SHRAV_R_PH:
11911                 check_dsp(ctx);
11912                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
11913                 break;
11914             case OPC_SHRA_R_W:
11915                 check_dsp(ctx);
11916                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
11917                 break;
11918             case OPC_SHRAV_R_W:
11919                 check_dsp(ctx);
11920                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
11921                 break;
11922             default:            /* Invalid */
11923                 MIPS_INVAL("MASK SHLL.QB");
11924                 gen_reserved_instruction(ctx);
11925                 break;
11926             }
11927             break;
11928         }
11929 #ifdef TARGET_MIPS64
11930     case OPC_SHLL_OB_DSP:
11931         op2 = MASK_SHLL_OB(ctx->opcode);
11932         switch (op2) {
11933         case OPC_SHLL_PW:
11934             check_dsp(ctx);
11935             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
11936             break;
11937         case OPC_SHLLV_PW:
11938             check_dsp(ctx);
11939             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11940             break;
11941         case OPC_SHLL_S_PW:
11942             check_dsp(ctx);
11943             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
11944             break;
11945         case OPC_SHLLV_S_PW:
11946             check_dsp(ctx);
11947             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11948             break;
11949         case OPC_SHLL_OB:
11950             check_dsp(ctx);
11951             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env);
11952             break;
11953         case OPC_SHLLV_OB:
11954             check_dsp(ctx);
11955             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11956             break;
11957         case OPC_SHLL_QH:
11958             check_dsp(ctx);
11959             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
11960             break;
11961         case OPC_SHLLV_QH:
11962             check_dsp(ctx);
11963             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11964             break;
11965         case OPC_SHLL_S_QH:
11966             check_dsp(ctx);
11967             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
11968             break;
11969         case OPC_SHLLV_S_QH:
11970             check_dsp(ctx);
11971             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
11972             break;
11973         case OPC_SHRA_OB:
11974             check_dsp_r2(ctx);
11975             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
11976             break;
11977         case OPC_SHRAV_OB:
11978             check_dsp_r2(ctx);
11979             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
11980             break;
11981         case OPC_SHRA_R_OB:
11982             check_dsp_r2(ctx);
11983             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
11984             break;
11985         case OPC_SHRAV_R_OB:
11986             check_dsp_r2(ctx);
11987             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
11988             break;
11989         case OPC_SHRA_PW:
11990             check_dsp(ctx);
11991             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
11992             break;
11993         case OPC_SHRAV_PW:
11994             check_dsp(ctx);
11995             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
11996             break;
11997         case OPC_SHRA_R_PW:
11998             check_dsp(ctx);
11999             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12000             break;
12001         case OPC_SHRAV_R_PW:
12002             check_dsp(ctx);
12003             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12004             break;
12005         case OPC_SHRA_QH:
12006             check_dsp(ctx);
12007             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12008             break;
12009         case OPC_SHRAV_QH:
12010             check_dsp(ctx);
12011             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12012             break;
12013         case OPC_SHRA_R_QH:
12014             check_dsp(ctx);
12015             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12016             break;
12017         case OPC_SHRAV_R_QH:
12018             check_dsp(ctx);
12019             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12020             break;
12021         case OPC_SHRL_OB:
12022             check_dsp(ctx);
12023             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12024             break;
12025         case OPC_SHRLV_OB:
12026             check_dsp(ctx);
12027             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12028             break;
12029         case OPC_SHRL_QH:
12030             check_dsp_r2(ctx);
12031             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12032             break;
12033         case OPC_SHRLV_QH:
12034             check_dsp_r2(ctx);
12035             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12036             break;
12037         default:            /* Invalid */
12038             MIPS_INVAL("MASK SHLL.OB");
12039             gen_reserved_instruction(ctx);
12040             break;
12041         }
12042         break;
12043 #endif
12044     }
12045 }
12046 
gen_mipsdsp_multiply(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12047 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12048                                  int ret, int v1, int v2, int check_ret)
12049 {
12050     TCGv_i32 t0;
12051     TCGv v1_t;
12052     TCGv v2_t;
12053 
12054     if ((ret == 0) && (check_ret == 1)) {
12055         /* Treat as NOP. */
12056         return;
12057     }
12058 
12059     t0 = tcg_temp_new_i32();
12060     v1_t = tcg_temp_new();
12061     v2_t = tcg_temp_new();
12062 
12063     tcg_gen_movi_i32(t0, ret);
12064     gen_load_gpr(v1_t, v1);
12065     gen_load_gpr(v2_t, v2);
12066 
12067     switch (op1) {
12068     case OPC_MUL_PH_DSP:
12069         check_dsp_r2(ctx);
12070         switch (op2) {
12071         case  OPC_MUL_PH:
12072             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12073             break;
12074         case  OPC_MUL_S_PH:
12075             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12076             break;
12077         case OPC_MULQ_S_W:
12078             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12079             break;
12080         case OPC_MULQ_RS_W:
12081             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12082             break;
12083         }
12084         break;
12085     case OPC_DPA_W_PH_DSP:
12086         switch (op2) {
12087         case OPC_DPAU_H_QBL:
12088             check_dsp(ctx);
12089             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env);
12090             break;
12091         case OPC_DPAU_H_QBR:
12092             check_dsp(ctx);
12093             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env);
12094             break;
12095         case OPC_DPSU_H_QBL:
12096             check_dsp(ctx);
12097             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env);
12098             break;
12099         case OPC_DPSU_H_QBR:
12100             check_dsp(ctx);
12101             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env);
12102             break;
12103         case OPC_DPA_W_PH:
12104             check_dsp_r2(ctx);
12105             gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env);
12106             break;
12107         case OPC_DPAX_W_PH:
12108             check_dsp_r2(ctx);
12109             gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env);
12110             break;
12111         case OPC_DPAQ_S_W_PH:
12112             check_dsp(ctx);
12113             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12114             break;
12115         case OPC_DPAQX_S_W_PH:
12116             check_dsp_r2(ctx);
12117             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12118             break;
12119         case OPC_DPAQX_SA_W_PH:
12120             check_dsp_r2(ctx);
12121             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12122             break;
12123         case OPC_DPS_W_PH:
12124             check_dsp_r2(ctx);
12125             gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env);
12126             break;
12127         case OPC_DPSX_W_PH:
12128             check_dsp_r2(ctx);
12129             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env);
12130             break;
12131         case OPC_DPSQ_S_W_PH:
12132             check_dsp(ctx);
12133             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12134             break;
12135         case OPC_DPSQX_S_W_PH:
12136             check_dsp_r2(ctx);
12137             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12138             break;
12139         case OPC_DPSQX_SA_W_PH:
12140             check_dsp_r2(ctx);
12141             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12142             break;
12143         case OPC_MULSAQ_S_W_PH:
12144             check_dsp(ctx);
12145             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12146             break;
12147         case OPC_DPAQ_SA_L_W:
12148             check_dsp(ctx);
12149             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12150             break;
12151         case OPC_DPSQ_SA_L_W:
12152             check_dsp(ctx);
12153             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12154             break;
12155         case OPC_MAQ_S_W_PHL:
12156             check_dsp(ctx);
12157             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env);
12158             break;
12159         case OPC_MAQ_S_W_PHR:
12160             check_dsp(ctx);
12161             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env);
12162             break;
12163         case OPC_MAQ_SA_W_PHL:
12164             check_dsp(ctx);
12165             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env);
12166             break;
12167         case OPC_MAQ_SA_W_PHR:
12168             check_dsp(ctx);
12169             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env);
12170             break;
12171         case OPC_MULSA_W_PH:
12172             check_dsp_r2(ctx);
12173             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env);
12174             break;
12175         }
12176         break;
12177 #ifdef TARGET_MIPS64
12178     case OPC_DPAQ_W_QH_DSP:
12179         {
12180             int ac = ret & 0x03;
12181             tcg_gen_movi_i32(t0, ac);
12182 
12183             switch (op2) {
12184             case OPC_DMADD:
12185                 check_dsp(ctx);
12186                 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env);
12187                 break;
12188             case OPC_DMADDU:
12189                 check_dsp(ctx);
12190                 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env);
12191                 break;
12192             case OPC_DMSUB:
12193                 check_dsp(ctx);
12194                 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env);
12195                 break;
12196             case OPC_DMSUBU:
12197                 check_dsp(ctx);
12198                 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env);
12199                 break;
12200             case OPC_DPA_W_QH:
12201                 check_dsp_r2(ctx);
12202                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env);
12203                 break;
12204             case OPC_DPAQ_S_W_QH:
12205                 check_dsp(ctx);
12206                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12207                 break;
12208             case OPC_DPAQ_SA_L_PW:
12209                 check_dsp(ctx);
12210                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12211                 break;
12212             case OPC_DPAU_H_OBL:
12213                 check_dsp(ctx);
12214                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env);
12215                 break;
12216             case OPC_DPAU_H_OBR:
12217                 check_dsp(ctx);
12218                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env);
12219                 break;
12220             case OPC_DPS_W_QH:
12221                 check_dsp_r2(ctx);
12222                 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env);
12223                 break;
12224             case OPC_DPSQ_S_W_QH:
12225                 check_dsp(ctx);
12226                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12227                 break;
12228             case OPC_DPSQ_SA_L_PW:
12229                 check_dsp(ctx);
12230                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12231                 break;
12232             case OPC_DPSU_H_OBL:
12233                 check_dsp(ctx);
12234                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env);
12235                 break;
12236             case OPC_DPSU_H_OBR:
12237                 check_dsp(ctx);
12238                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env);
12239                 break;
12240             case OPC_MAQ_S_L_PWL:
12241                 check_dsp(ctx);
12242                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env);
12243                 break;
12244             case OPC_MAQ_S_L_PWR:
12245                 check_dsp(ctx);
12246                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env);
12247                 break;
12248             case OPC_MAQ_S_W_QHLL:
12249                 check_dsp(ctx);
12250                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env);
12251                 break;
12252             case OPC_MAQ_SA_W_QHLL:
12253                 check_dsp(ctx);
12254                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env);
12255                 break;
12256             case OPC_MAQ_S_W_QHLR:
12257                 check_dsp(ctx);
12258                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env);
12259                 break;
12260             case OPC_MAQ_SA_W_QHLR:
12261                 check_dsp(ctx);
12262                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env);
12263                 break;
12264             case OPC_MAQ_S_W_QHRL:
12265                 check_dsp(ctx);
12266                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env);
12267                 break;
12268             case OPC_MAQ_SA_W_QHRL:
12269                 check_dsp(ctx);
12270                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env);
12271                 break;
12272             case OPC_MAQ_S_W_QHRR:
12273                 check_dsp(ctx);
12274                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env);
12275                 break;
12276             case OPC_MAQ_SA_W_QHRR:
12277                 check_dsp(ctx);
12278                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env);
12279                 break;
12280             case OPC_MULSAQ_S_L_PW:
12281                 check_dsp(ctx);
12282                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env);
12283                 break;
12284             case OPC_MULSAQ_S_W_QH:
12285                 check_dsp(ctx);
12286                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12287                 break;
12288             }
12289         }
12290         break;
12291 #endif
12292     case OPC_ADDU_QB_DSP:
12293         switch (op2) {
12294         case OPC_MULEU_S_PH_QBL:
12295             check_dsp(ctx);
12296             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12297             break;
12298         case OPC_MULEU_S_PH_QBR:
12299             check_dsp(ctx);
12300             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12301             break;
12302         case OPC_MULQ_RS_PH:
12303             check_dsp(ctx);
12304             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12305             break;
12306         case OPC_MULEQ_S_W_PHL:
12307             check_dsp(ctx);
12308             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12309             break;
12310         case OPC_MULEQ_S_W_PHR:
12311             check_dsp(ctx);
12312             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12313             break;
12314         case OPC_MULQ_S_PH:
12315             check_dsp_r2(ctx);
12316             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12317             break;
12318         }
12319         break;
12320 #ifdef TARGET_MIPS64
12321     case OPC_ADDU_OB_DSP:
12322         switch (op2) {
12323         case OPC_MULEQ_S_PW_QHL:
12324             check_dsp(ctx);
12325             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12326             break;
12327         case OPC_MULEQ_S_PW_QHR:
12328             check_dsp(ctx);
12329             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12330             break;
12331         case OPC_MULEU_S_QH_OBL:
12332             check_dsp(ctx);
12333             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12334             break;
12335         case OPC_MULEU_S_QH_OBR:
12336             check_dsp(ctx);
12337             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12338             break;
12339         case OPC_MULQ_RS_QH:
12340             check_dsp(ctx);
12341             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12342             break;
12343         }
12344         break;
12345 #endif
12346     }
12347 }
12348 
gen_mipsdsp_bitinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int val)12349 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12350                                 int ret, int val)
12351 {
12352     int16_t imm;
12353     TCGv t0;
12354     TCGv val_t;
12355 
12356     if (ret == 0) {
12357         /* Treat as NOP. */
12358         return;
12359     }
12360 
12361     t0 = tcg_temp_new();
12362     val_t = tcg_temp_new();
12363     gen_load_gpr(val_t, val);
12364 
12365     switch (op1) {
12366     case OPC_ABSQ_S_PH_DSP:
12367         switch (op2) {
12368         case OPC_BITREV:
12369             check_dsp(ctx);
12370             gen_helper_bitrev(cpu_gpr[ret], val_t);
12371             break;
12372         case OPC_REPL_QB:
12373             check_dsp(ctx);
12374             {
12375                 target_long result;
12376                 imm = (ctx->opcode >> 16) & 0xFF;
12377                 result = (uint32_t)imm << 24 |
12378                          (uint32_t)imm << 16 |
12379                          (uint32_t)imm << 8  |
12380                          (uint32_t)imm;
12381                 result = (int32_t)result;
12382                 tcg_gen_movi_tl(cpu_gpr[ret], result);
12383             }
12384             break;
12385         case OPC_REPLV_QB:
12386             check_dsp(ctx);
12387             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12388             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12389             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12390             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12391             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12392             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12393             break;
12394         case OPC_REPL_PH:
12395             check_dsp(ctx);
12396             {
12397                 imm = (ctx->opcode >> 16) & 0x03FF;
12398                 imm = (int16_t)(imm << 6) >> 6;
12399                 tcg_gen_movi_tl(cpu_gpr[ret], \
12400                                 (target_long)((int32_t)imm << 16 | \
12401                                 (uint16_t)imm));
12402             }
12403             break;
12404         case OPC_REPLV_PH:
12405             check_dsp(ctx);
12406             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12407             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12408             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12409             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12410             break;
12411         }
12412         break;
12413 #ifdef TARGET_MIPS64
12414     case OPC_ABSQ_S_QH_DSP:
12415         switch (op2) {
12416         case OPC_REPL_OB:
12417             check_dsp(ctx);
12418             {
12419                 target_long temp;
12420 
12421                 imm = (ctx->opcode >> 16) & 0xFF;
12422                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
12423                 temp = (temp << 16) | temp;
12424                 temp = (temp << 32) | temp;
12425                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12426                 break;
12427             }
12428         case OPC_REPL_PW:
12429             check_dsp(ctx);
12430             {
12431                 target_long temp;
12432 
12433                 imm = (ctx->opcode >> 16) & 0x03FF;
12434                 imm = (int16_t)(imm << 6) >> 6;
12435                 temp = ((target_long)imm << 32) \
12436                        | ((target_long)imm & 0xFFFFFFFF);
12437                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12438                 break;
12439             }
12440         case OPC_REPL_QH:
12441             check_dsp(ctx);
12442             {
12443                 target_long temp;
12444 
12445                 imm = (ctx->opcode >> 16) & 0x03FF;
12446                 imm = (int16_t)(imm << 6) >> 6;
12447 
12448                 temp = ((uint64_t)(uint16_t)imm << 48) |
12449                        ((uint64_t)(uint16_t)imm << 32) |
12450                        ((uint64_t)(uint16_t)imm << 16) |
12451                        (uint64_t)(uint16_t)imm;
12452                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12453                 break;
12454             }
12455         case OPC_REPLV_OB:
12456             check_dsp(ctx);
12457             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12458             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12459             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12460             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12461             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12462             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12463             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12464             break;
12465         case OPC_REPLV_PW:
12466             check_dsp(ctx);
12467             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
12468             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12469             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12470             break;
12471         case OPC_REPLV_QH:
12472             check_dsp(ctx);
12473             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12474             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12475             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12476             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12477             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12478             break;
12479         }
12480         break;
12481 #endif
12482     }
12483 }
12484 
gen_mipsdsp_add_cmp_pick(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12485 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
12486                                      uint32_t op1, uint32_t op2,
12487                                      int ret, int v1, int v2, int check_ret)
12488 {
12489     TCGv t1;
12490     TCGv v1_t;
12491     TCGv v2_t;
12492 
12493     if ((ret == 0) && (check_ret == 1)) {
12494         /* Treat as NOP. */
12495         return;
12496     }
12497 
12498     t1 = tcg_temp_new();
12499     v1_t = tcg_temp_new();
12500     v2_t = tcg_temp_new();
12501 
12502     gen_load_gpr(v1_t, v1);
12503     gen_load_gpr(v2_t, v2);
12504 
12505     switch (op1) {
12506     case OPC_CMPU_EQ_QB_DSP:
12507         switch (op2) {
12508         case OPC_CMPU_EQ_QB:
12509             check_dsp(ctx);
12510             gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env);
12511             break;
12512         case OPC_CMPU_LT_QB:
12513             check_dsp(ctx);
12514             gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env);
12515             break;
12516         case OPC_CMPU_LE_QB:
12517             check_dsp(ctx);
12518             gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env);
12519             break;
12520         case OPC_CMPGU_EQ_QB:
12521             check_dsp(ctx);
12522             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
12523             break;
12524         case OPC_CMPGU_LT_QB:
12525             check_dsp(ctx);
12526             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
12527             break;
12528         case OPC_CMPGU_LE_QB:
12529             check_dsp(ctx);
12530             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
12531             break;
12532         case OPC_CMPGDU_EQ_QB:
12533             check_dsp_r2(ctx);
12534             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
12535             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12536             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12537             tcg_gen_shli_tl(t1, t1, 24);
12538             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12539             break;
12540         case OPC_CMPGDU_LT_QB:
12541             check_dsp_r2(ctx);
12542             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
12543             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12544             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12545             tcg_gen_shli_tl(t1, t1, 24);
12546             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12547             break;
12548         case OPC_CMPGDU_LE_QB:
12549             check_dsp_r2(ctx);
12550             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
12551             tcg_gen_mov_tl(cpu_gpr[ret], t1);
12552             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12553             tcg_gen_shli_tl(t1, t1, 24);
12554             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12555             break;
12556         case OPC_CMP_EQ_PH:
12557             check_dsp(ctx);
12558             gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env);
12559             break;
12560         case OPC_CMP_LT_PH:
12561             check_dsp(ctx);
12562             gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env);
12563             break;
12564         case OPC_CMP_LE_PH:
12565             check_dsp(ctx);
12566             gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env);
12567             break;
12568         case OPC_PICK_QB:
12569             check_dsp(ctx);
12570             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12571             break;
12572         case OPC_PICK_PH:
12573             check_dsp(ctx);
12574             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12575             break;
12576         case OPC_PACKRL_PH:
12577             check_dsp(ctx);
12578             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
12579             break;
12580         }
12581         break;
12582 #ifdef TARGET_MIPS64
12583     case OPC_CMPU_EQ_OB_DSP:
12584         switch (op2) {
12585         case OPC_CMP_EQ_PW:
12586             check_dsp(ctx);
12587             gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env);
12588             break;
12589         case OPC_CMP_LT_PW:
12590             check_dsp(ctx);
12591             gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env);
12592             break;
12593         case OPC_CMP_LE_PW:
12594             check_dsp(ctx);
12595             gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env);
12596             break;
12597         case OPC_CMP_EQ_QH:
12598             check_dsp(ctx);
12599             gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env);
12600             break;
12601         case OPC_CMP_LT_QH:
12602             check_dsp(ctx);
12603             gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env);
12604             break;
12605         case OPC_CMP_LE_QH:
12606             check_dsp(ctx);
12607             gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env);
12608             break;
12609         case OPC_CMPGDU_EQ_OB:
12610             check_dsp_r2(ctx);
12611             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12612             break;
12613         case OPC_CMPGDU_LT_OB:
12614             check_dsp_r2(ctx);
12615             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12616             break;
12617         case OPC_CMPGDU_LE_OB:
12618             check_dsp_r2(ctx);
12619             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12620             break;
12621         case OPC_CMPGU_EQ_OB:
12622             check_dsp(ctx);
12623             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
12624             break;
12625         case OPC_CMPGU_LT_OB:
12626             check_dsp(ctx);
12627             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
12628             break;
12629         case OPC_CMPGU_LE_OB:
12630             check_dsp(ctx);
12631             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
12632             break;
12633         case OPC_CMPU_EQ_OB:
12634             check_dsp(ctx);
12635             gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env);
12636             break;
12637         case OPC_CMPU_LT_OB:
12638             check_dsp(ctx);
12639             gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env);
12640             break;
12641         case OPC_CMPU_LE_OB:
12642             check_dsp(ctx);
12643             gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env);
12644             break;
12645         case OPC_PACKRL_PW:
12646             check_dsp(ctx);
12647             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
12648             break;
12649         case OPC_PICK_OB:
12650             check_dsp(ctx);
12651             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12652             break;
12653         case OPC_PICK_PW:
12654             check_dsp(ctx);
12655             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12656             break;
12657         case OPC_PICK_QH:
12658             check_dsp(ctx);
12659             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12660             break;
12661         }
12662         break;
12663 #endif
12664     }
12665 }
12666 
gen_mipsdsp_append(CPUMIPSState * env,DisasContext * ctx,uint32_t op1,int rt,int rs,int sa)12667 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
12668                                uint32_t op1, int rt, int rs, int sa)
12669 {
12670     TCGv t0;
12671 
12672     check_dsp_r2(ctx);
12673 
12674     if (rt == 0) {
12675         /* Treat as NOP. */
12676         return;
12677     }
12678 
12679     t0 = tcg_temp_new();
12680     gen_load_gpr(t0, rs);
12681 
12682     switch (op1) {
12683     case OPC_APPEND_DSP:
12684         switch (MASK_APPEND(ctx->opcode)) {
12685         case OPC_APPEND:
12686             if (sa != 0) {
12687                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
12688             }
12689             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12690             break;
12691         case OPC_PREPEND:
12692             if (sa != 0) {
12693                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
12694                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12695                 tcg_gen_shli_tl(t0, t0, 32 - sa);
12696                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12697             }
12698             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12699             break;
12700         case OPC_BALIGN:
12701             sa &= 3;
12702             if (sa != 0 && sa != 2) {
12703                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12704                 tcg_gen_ext32u_tl(t0, t0);
12705                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
12706                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12707             }
12708             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12709             break;
12710         default:            /* Invalid */
12711             MIPS_INVAL("MASK APPEND");
12712             gen_reserved_instruction(ctx);
12713             break;
12714         }
12715         break;
12716 #ifdef TARGET_MIPS64
12717     case OPC_DAPPEND_DSP:
12718         switch (MASK_DAPPEND(ctx->opcode)) {
12719         case OPC_DAPPEND:
12720             if (sa != 0) {
12721                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
12722             }
12723             break;
12724         case OPC_PREPENDD:
12725             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
12726             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
12727             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
12728             break;
12729         case OPC_PREPENDW:
12730             if (sa != 0) {
12731                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12732                 tcg_gen_shli_tl(t0, t0, 64 - sa);
12733                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12734             }
12735             break;
12736         case OPC_DBALIGN:
12737             sa &= 7;
12738             if (sa != 0 && sa != 2 && sa != 4) {
12739                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12740                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
12741                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12742             }
12743             break;
12744         default:            /* Invalid */
12745             MIPS_INVAL("MASK DAPPEND");
12746             gen_reserved_instruction(ctx);
12747             break;
12748         }
12749         break;
12750 #endif
12751     }
12752 }
12753 
gen_mipsdsp_accinsn(DisasContext * ctx,uint32_t op1,uint32_t op2,int ret,int v1,int v2,int check_ret)12754 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12755                                 int ret, int v1, int v2, int check_ret)
12756 
12757 {
12758     TCGv t0;
12759     TCGv t1;
12760     TCGv v1_t;
12761     int16_t imm;
12762 
12763     if ((ret == 0) && (check_ret == 1)) {
12764         /* Treat as NOP. */
12765         return;
12766     }
12767 
12768     t0 = tcg_temp_new();
12769     t1 = tcg_temp_new();
12770     v1_t = tcg_temp_new();
12771 
12772     gen_load_gpr(v1_t, v1);
12773 
12774     switch (op1) {
12775     case OPC_EXTR_W_DSP:
12776         check_dsp(ctx);
12777         switch (op2) {
12778         case OPC_EXTR_W:
12779             tcg_gen_movi_tl(t0, v2);
12780             tcg_gen_movi_tl(t1, v1);
12781             gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env);
12782             break;
12783         case OPC_EXTR_R_W:
12784             tcg_gen_movi_tl(t0, v2);
12785             tcg_gen_movi_tl(t1, v1);
12786             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
12787             break;
12788         case OPC_EXTR_RS_W:
12789             tcg_gen_movi_tl(t0, v2);
12790             tcg_gen_movi_tl(t1, v1);
12791             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
12792             break;
12793         case OPC_EXTR_S_H:
12794             tcg_gen_movi_tl(t0, v2);
12795             tcg_gen_movi_tl(t1, v1);
12796             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
12797             break;
12798         case OPC_EXTRV_S_H:
12799             tcg_gen_movi_tl(t0, v2);
12800             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
12801             break;
12802         case OPC_EXTRV_W:
12803             tcg_gen_movi_tl(t0, v2);
12804             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12805             break;
12806         case OPC_EXTRV_R_W:
12807             tcg_gen_movi_tl(t0, v2);
12808             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12809             break;
12810         case OPC_EXTRV_RS_W:
12811             tcg_gen_movi_tl(t0, v2);
12812             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12813             break;
12814         case OPC_EXTP:
12815             tcg_gen_movi_tl(t0, v2);
12816             tcg_gen_movi_tl(t1, v1);
12817             gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env);
12818             break;
12819         case OPC_EXTPV:
12820             tcg_gen_movi_tl(t0, v2);
12821             gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env);
12822             break;
12823         case OPC_EXTPDP:
12824             tcg_gen_movi_tl(t0, v2);
12825             tcg_gen_movi_tl(t1, v1);
12826             gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env);
12827             break;
12828         case OPC_EXTPDPV:
12829             tcg_gen_movi_tl(t0, v2);
12830             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
12831             break;
12832         case OPC_SHILO:
12833             imm = (ctx->opcode >> 20) & 0x3F;
12834             tcg_gen_movi_tl(t0, ret);
12835             tcg_gen_movi_tl(t1, imm);
12836             gen_helper_shilo(t0, t1, tcg_env);
12837             break;
12838         case OPC_SHILOV:
12839             tcg_gen_movi_tl(t0, ret);
12840             gen_helper_shilo(t0, v1_t, tcg_env);
12841             break;
12842         case OPC_MTHLIP:
12843             tcg_gen_movi_tl(t0, ret);
12844             gen_helper_mthlip(t0, v1_t, tcg_env);
12845             break;
12846         case OPC_WRDSP:
12847             imm = (ctx->opcode >> 11) & 0x3FF;
12848             tcg_gen_movi_tl(t0, imm);
12849             gen_helper_wrdsp(v1_t, t0, tcg_env);
12850             break;
12851         case OPC_RDDSP:
12852             imm = (ctx->opcode >> 16) & 0x03FF;
12853             tcg_gen_movi_tl(t0, imm);
12854             gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env);
12855             break;
12856         }
12857         break;
12858 #ifdef TARGET_MIPS64
12859     case OPC_DEXTR_W_DSP:
12860         check_dsp(ctx);
12861         switch (op2) {
12862         case OPC_DMTHLIP:
12863             tcg_gen_movi_tl(t0, ret);
12864             gen_helper_dmthlip(v1_t, t0, tcg_env);
12865             break;
12866         case OPC_DSHILO:
12867             {
12868                 int shift = (ctx->opcode >> 19) & 0x7F;
12869                 int ac = (ctx->opcode >> 11) & 0x03;
12870                 tcg_gen_movi_tl(t0, shift);
12871                 tcg_gen_movi_tl(t1, ac);
12872                 gen_helper_dshilo(t0, t1, tcg_env);
12873                 break;
12874             }
12875         case OPC_DSHILOV:
12876             {
12877                 int ac = (ctx->opcode >> 11) & 0x03;
12878                 tcg_gen_movi_tl(t0, ac);
12879                 gen_helper_dshilo(v1_t, t0, tcg_env);
12880                 break;
12881             }
12882         case OPC_DEXTP:
12883             tcg_gen_movi_tl(t0, v2);
12884             tcg_gen_movi_tl(t1, v1);
12885 
12886             gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env);
12887             break;
12888         case OPC_DEXTPV:
12889             tcg_gen_movi_tl(t0, v2);
12890             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env);
12891             break;
12892         case OPC_DEXTPDP:
12893             tcg_gen_movi_tl(t0, v2);
12894             tcg_gen_movi_tl(t1, v1);
12895             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env);
12896             break;
12897         case OPC_DEXTPDPV:
12898             tcg_gen_movi_tl(t0, v2);
12899             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
12900             break;
12901         case OPC_DEXTR_L:
12902             tcg_gen_movi_tl(t0, v2);
12903             tcg_gen_movi_tl(t1, v1);
12904             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env);
12905             break;
12906         case OPC_DEXTR_R_L:
12907             tcg_gen_movi_tl(t0, v2);
12908             tcg_gen_movi_tl(t1, v1);
12909             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env);
12910             break;
12911         case OPC_DEXTR_RS_L:
12912             tcg_gen_movi_tl(t0, v2);
12913             tcg_gen_movi_tl(t1, v1);
12914             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env);
12915             break;
12916         case OPC_DEXTR_W:
12917             tcg_gen_movi_tl(t0, v2);
12918             tcg_gen_movi_tl(t1, v1);
12919             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env);
12920             break;
12921         case OPC_DEXTR_R_W:
12922             tcg_gen_movi_tl(t0, v2);
12923             tcg_gen_movi_tl(t1, v1);
12924             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
12925             break;
12926         case OPC_DEXTR_RS_W:
12927             tcg_gen_movi_tl(t0, v2);
12928             tcg_gen_movi_tl(t1, v1);
12929             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
12930             break;
12931         case OPC_DEXTR_S_H:
12932             tcg_gen_movi_tl(t0, v2);
12933             tcg_gen_movi_tl(t1, v1);
12934             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
12935             break;
12936         case OPC_DEXTRV_S_H:
12937             tcg_gen_movi_tl(t0, v2);
12938             gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
12939             break;
12940         case OPC_DEXTRV_L:
12941             tcg_gen_movi_tl(t0, v2);
12942             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12943             break;
12944         case OPC_DEXTRV_R_L:
12945             tcg_gen_movi_tl(t0, v2);
12946             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12947             break;
12948         case OPC_DEXTRV_RS_L:
12949             tcg_gen_movi_tl(t0, v2);
12950             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env);
12951             break;
12952         case OPC_DEXTRV_W:
12953             tcg_gen_movi_tl(t0, v2);
12954             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12955             break;
12956         case OPC_DEXTRV_R_W:
12957             tcg_gen_movi_tl(t0, v2);
12958             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12959             break;
12960         case OPC_DEXTRV_RS_W:
12961             tcg_gen_movi_tl(t0, v2);
12962             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
12963             break;
12964         }
12965         break;
12966 #endif
12967     }
12968 }
12969 
12970 /* End MIPSDSP functions. */
12971 
decode_opc_special_r6(CPUMIPSState * env,DisasContext * ctx)12972 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
12973 {
12974     int rs, rt, rd, sa;
12975     uint32_t op1, op2;
12976 
12977     rs = (ctx->opcode >> 21) & 0x1f;
12978     rt = (ctx->opcode >> 16) & 0x1f;
12979     rd = (ctx->opcode >> 11) & 0x1f;
12980     sa = (ctx->opcode >> 6) & 0x1f;
12981 
12982     op1 = MASK_SPECIAL(ctx->opcode);
12983     switch (op1) {
12984     case OPC_MULT:
12985     case OPC_MULTU:
12986     case OPC_DIV:
12987     case OPC_DIVU:
12988         op2 = MASK_R6_MULDIV(ctx->opcode);
12989         switch (op2) {
12990         case R6_OPC_MUL:
12991         case R6_OPC_MUH:
12992         case R6_OPC_MULU:
12993         case R6_OPC_MUHU:
12994         case R6_OPC_DIV:
12995         case R6_OPC_MOD:
12996         case R6_OPC_DIVU:
12997         case R6_OPC_MODU:
12998             gen_r6_muldiv(ctx, op2, rd, rs, rt);
12999             break;
13000         default:
13001             MIPS_INVAL("special_r6 muldiv");
13002             gen_reserved_instruction(ctx);
13003             break;
13004         }
13005         break;
13006     case OPC_SELEQZ:
13007     case OPC_SELNEZ:
13008         gen_cond_move(ctx, op1, rd, rs, rt);
13009         break;
13010     case R6_OPC_CLO:
13011     case R6_OPC_CLZ:
13012         if (rt == 0 && sa == 1) {
13013             /*
13014              * Major opcode and function field is shared with preR6 MFHI/MTHI.
13015              * We need additionally to check other fields.
13016              */
13017             gen_cl(ctx, op1, rd, rs);
13018         } else {
13019             gen_reserved_instruction(ctx);
13020         }
13021         break;
13022     case R6_OPC_SDBBP:
13023         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13024             ctx->base.is_jmp = DISAS_SEMIHOST;
13025         } else {
13026             if (ctx->hflags & MIPS_HFLAG_SBRI) {
13027                 gen_reserved_instruction(ctx);
13028             } else {
13029                 generate_exception_end(ctx, EXCP_DBp);
13030             }
13031         }
13032         break;
13033 #if defined(TARGET_MIPS64)
13034     case R6_OPC_DCLO:
13035     case R6_OPC_DCLZ:
13036         if (rt == 0 && sa == 1) {
13037             /*
13038              * Major opcode and function field is shared with preR6 MFHI/MTHI.
13039              * We need additionally to check other fields.
13040              */
13041             check_mips_64(ctx);
13042             gen_cl(ctx, op1, rd, rs);
13043         } else {
13044             gen_reserved_instruction(ctx);
13045         }
13046         break;
13047     case OPC_DMULT:
13048     case OPC_DMULTU:
13049     case OPC_DDIV:
13050     case OPC_DDIVU:
13051 
13052         op2 = MASK_R6_MULDIV(ctx->opcode);
13053         switch (op2) {
13054         case R6_OPC_DMUL:
13055         case R6_OPC_DMUH:
13056         case R6_OPC_DMULU:
13057         case R6_OPC_DMUHU:
13058         case R6_OPC_DDIV:
13059         case R6_OPC_DMOD:
13060         case R6_OPC_DDIVU:
13061         case R6_OPC_DMODU:
13062             check_mips_64(ctx);
13063             gen_r6_muldiv(ctx, op2, rd, rs, rt);
13064             break;
13065         default:
13066             MIPS_INVAL("special_r6 muldiv");
13067             gen_reserved_instruction(ctx);
13068             break;
13069         }
13070         break;
13071 #endif
13072     default:            /* Invalid */
13073         MIPS_INVAL("special_r6");
13074         gen_reserved_instruction(ctx);
13075         break;
13076     }
13077 }
13078 
decode_opc_special_tx79(CPUMIPSState * env,DisasContext * ctx)13079 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13080 {
13081     int rs = extract32(ctx->opcode, 21, 5);
13082     int rt = extract32(ctx->opcode, 16, 5);
13083     int rd = extract32(ctx->opcode, 11, 5);
13084     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13085 
13086     switch (op1) {
13087     case OPC_MOVN:         /* Conditional move */
13088     case OPC_MOVZ:
13089         gen_cond_move(ctx, op1, rd, rs, rt);
13090         break;
13091     case OPC_MFHI:          /* Move from HI/LO */
13092     case OPC_MFLO:
13093         gen_HILO(ctx, op1, 0, rd);
13094         break;
13095     case OPC_MTHI:
13096     case OPC_MTLO:          /* Move to HI/LO */
13097         gen_HILO(ctx, op1, 0, rs);
13098         break;
13099     case OPC_MULT:
13100     case OPC_MULTU:
13101         gen_mul_txx9(ctx, op1, rd, rs, rt);
13102         break;
13103     case OPC_DIV:
13104     case OPC_DIVU:
13105         gen_muldiv(ctx, op1, 0, rs, rt);
13106         break;
13107 #if defined(TARGET_MIPS64)
13108     case OPC_DMULT:
13109     case OPC_DMULTU:
13110     case OPC_DDIV:
13111     case OPC_DDIVU:
13112         check_insn_opc_user_only(ctx, INSN_R5900);
13113         gen_muldiv(ctx, op1, 0, rs, rt);
13114         break;
13115 #endif
13116     case OPC_JR:
13117         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13118         break;
13119     default:            /* Invalid */
13120         MIPS_INVAL("special_tx79");
13121         gen_reserved_instruction(ctx);
13122         break;
13123     }
13124 }
13125 
decode_opc_special_legacy(CPUMIPSState * env,DisasContext * ctx)13126 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13127 {
13128     int rs, rt, rd;
13129     uint32_t op1;
13130 
13131     rs = (ctx->opcode >> 21) & 0x1f;
13132     rt = (ctx->opcode >> 16) & 0x1f;
13133     rd = (ctx->opcode >> 11) & 0x1f;
13134 
13135     op1 = MASK_SPECIAL(ctx->opcode);
13136     switch (op1) {
13137     case OPC_MOVN:         /* Conditional move */
13138     case OPC_MOVZ:
13139         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
13140                    INSN_LOONGSON2E | INSN_LOONGSON2F);
13141         gen_cond_move(ctx, op1, rd, rs, rt);
13142         break;
13143     case OPC_MFHI:          /* Move from HI/LO */
13144     case OPC_MFLO:
13145         gen_HILO(ctx, op1, rs & 3, rd);
13146         break;
13147     case OPC_MTHI:
13148     case OPC_MTLO:          /* Move to HI/LO */
13149         gen_HILO(ctx, op1, rd & 3, rs);
13150         break;
13151     case OPC_MOVCI:
13152         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
13153         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13154             check_cp1_enabled(ctx);
13155             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
13156                       (ctx->opcode >> 16) & 1);
13157         } else {
13158             generate_exception_err(ctx, EXCP_CpU, 1);
13159         }
13160         break;
13161     case OPC_MULT:
13162     case OPC_MULTU:
13163         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13164         break;
13165     case OPC_DIV:
13166     case OPC_DIVU:
13167         gen_muldiv(ctx, op1, 0, rs, rt);
13168         break;
13169 #if defined(TARGET_MIPS64)
13170     case OPC_DMULT:
13171     case OPC_DMULTU:
13172     case OPC_DDIV:
13173     case OPC_DDIVU:
13174         check_insn(ctx, ISA_MIPS3);
13175         check_mips_64(ctx);
13176         gen_muldiv(ctx, op1, 0, rs, rt);
13177         break;
13178 #endif
13179     case OPC_JR:
13180         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13181         break;
13182     case OPC_SPIM:
13183 #ifdef MIPS_STRICT_STANDARD
13184         MIPS_INVAL("SPIM");
13185         gen_reserved_instruction(ctx);
13186 #else
13187         /* Implemented as RI exception for now. */
13188         MIPS_INVAL("spim (unofficial)");
13189         gen_reserved_instruction(ctx);
13190 #endif
13191         break;
13192     default:            /* Invalid */
13193         MIPS_INVAL("special_legacy");
13194         gen_reserved_instruction(ctx);
13195         break;
13196     }
13197 }
13198 
decode_opc_special(CPUMIPSState * env,DisasContext * ctx)13199 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
13200 {
13201     int rs, rt, rd, sa;
13202     uint32_t op1;
13203 
13204     rs = (ctx->opcode >> 21) & 0x1f;
13205     rt = (ctx->opcode >> 16) & 0x1f;
13206     rd = (ctx->opcode >> 11) & 0x1f;
13207     sa = (ctx->opcode >> 6) & 0x1f;
13208 
13209     op1 = MASK_SPECIAL(ctx->opcode);
13210     switch (op1) {
13211     case OPC_SLL:          /* Shift with immediate */
13212         if (sa == 5 && rd == 0 &&
13213             rs == 0 && rt == 0) { /* PAUSE */
13214             if ((ctx->insn_flags & ISA_MIPS_R6) &&
13215                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
13216                 gen_reserved_instruction(ctx);
13217                 break;
13218             }
13219         }
13220         /* Fallthrough */
13221     case OPC_SRA:
13222         gen_shift_imm(ctx, op1, rd, rt, sa);
13223         break;
13224     case OPC_SRL:
13225         switch ((ctx->opcode >> 21) & 0x1f) {
13226         case 1:
13227             /* rotr is decoded as srl on non-R2 CPUs */
13228             if (ctx->insn_flags & ISA_MIPS_R2) {
13229                 op1 = OPC_ROTR;
13230             }
13231             /* Fallthrough */
13232         case 0:
13233             gen_shift_imm(ctx, op1, rd, rt, sa);
13234             break;
13235         default:
13236             gen_reserved_instruction(ctx);
13237             break;
13238         }
13239         break;
13240     case OPC_ADD:
13241     case OPC_ADDU:
13242     case OPC_SUB:
13243     case OPC_SUBU:
13244         gen_arith(ctx, op1, rd, rs, rt);
13245         break;
13246     case OPC_SLLV:         /* Shifts */
13247     case OPC_SRAV:
13248         gen_shift(ctx, op1, rd, rs, rt);
13249         break;
13250     case OPC_SRLV:
13251         switch ((ctx->opcode >> 6) & 0x1f) {
13252         case 1:
13253             /* rotrv is decoded as srlv on non-R2 CPUs */
13254             if (ctx->insn_flags & ISA_MIPS_R2) {
13255                 op1 = OPC_ROTRV;
13256             }
13257             /* Fallthrough */
13258         case 0:
13259             gen_shift(ctx, op1, rd, rs, rt);
13260             break;
13261         default:
13262             gen_reserved_instruction(ctx);
13263             break;
13264         }
13265         break;
13266     case OPC_SLT:          /* Set on less than */
13267     case OPC_SLTU:
13268         gen_slt(ctx, op1, rd, rs, rt);
13269         break;
13270     case OPC_AND:          /* Logic*/
13271     case OPC_OR:
13272     case OPC_NOR:
13273     case OPC_XOR:
13274         gen_logic(ctx, op1, rd, rs, rt);
13275         break;
13276     case OPC_JALR:
13277         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
13278         break;
13279     case OPC_TGE: /* Traps */
13280     case OPC_TGEU:
13281     case OPC_TLT:
13282     case OPC_TLTU:
13283     case OPC_TEQ:
13284     case OPC_TNE:
13285         check_insn(ctx, ISA_MIPS2);
13286         gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
13287         break;
13288     case OPC_PMON:
13289         /* Pmon entry point, also R4010 selsl */
13290 #ifdef MIPS_STRICT_STANDARD
13291         MIPS_INVAL("PMON / selsl");
13292         gen_reserved_instruction(ctx);
13293 #else
13294         gen_helper_pmon(tcg_env, tcg_constant_i32(sa));
13295 #endif
13296         break;
13297     case OPC_SYSCALL:
13298         generate_exception_end(ctx, EXCP_SYSCALL);
13299         break;
13300     case OPC_BREAK:
13301         generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
13302         break;
13303     case OPC_SYNC:
13304         check_insn(ctx, ISA_MIPS2);
13305         gen_sync(extract32(ctx->opcode, 6, 5));
13306         break;
13307 
13308 #if defined(TARGET_MIPS64)
13309         /* MIPS64 specific opcodes */
13310     case OPC_DSLL:
13311     case OPC_DSRA:
13312     case OPC_DSLL32:
13313     case OPC_DSRA32:
13314         check_insn(ctx, ISA_MIPS3);
13315         check_mips_64(ctx);
13316         gen_shift_imm(ctx, op1, rd, rt, sa);
13317         break;
13318     case OPC_DSRL:
13319         switch ((ctx->opcode >> 21) & 0x1f) {
13320         case 1:
13321             /* drotr is decoded as dsrl on non-R2 CPUs */
13322             if (ctx->insn_flags & ISA_MIPS_R2) {
13323                 op1 = OPC_DROTR;
13324             }
13325             /* Fallthrough */
13326         case 0:
13327             check_insn(ctx, ISA_MIPS3);
13328             check_mips_64(ctx);
13329             gen_shift_imm(ctx, op1, rd, rt, sa);
13330             break;
13331         default:
13332             gen_reserved_instruction(ctx);
13333             break;
13334         }
13335         break;
13336     case OPC_DSRL32:
13337         switch ((ctx->opcode >> 21) & 0x1f) {
13338         case 1:
13339             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
13340             if (ctx->insn_flags & ISA_MIPS_R2) {
13341                 op1 = OPC_DROTR32;
13342             }
13343             /* Fallthrough */
13344         case 0:
13345             check_insn(ctx, ISA_MIPS3);
13346             check_mips_64(ctx);
13347             gen_shift_imm(ctx, op1, rd, rt, sa);
13348             break;
13349         default:
13350             gen_reserved_instruction(ctx);
13351             break;
13352         }
13353         break;
13354     case OPC_DADD:
13355     case OPC_DADDU:
13356     case OPC_DSUB:
13357     case OPC_DSUBU:
13358         check_insn(ctx, ISA_MIPS3);
13359         check_mips_64(ctx);
13360         gen_arith(ctx, op1, rd, rs, rt);
13361         break;
13362     case OPC_DSLLV:
13363     case OPC_DSRAV:
13364         check_insn(ctx, ISA_MIPS3);
13365         check_mips_64(ctx);
13366         gen_shift(ctx, op1, rd, rs, rt);
13367         break;
13368     case OPC_DSRLV:
13369         switch ((ctx->opcode >> 6) & 0x1f) {
13370         case 1:
13371             /* drotrv is decoded as dsrlv on non-R2 CPUs */
13372             if (ctx->insn_flags & ISA_MIPS_R2) {
13373                 op1 = OPC_DROTRV;
13374             }
13375             /* Fallthrough */
13376         case 0:
13377             check_insn(ctx, ISA_MIPS3);
13378             check_mips_64(ctx);
13379             gen_shift(ctx, op1, rd, rs, rt);
13380             break;
13381         default:
13382             gen_reserved_instruction(ctx);
13383             break;
13384         }
13385         break;
13386 #endif
13387     default:
13388         if (ctx->insn_flags & ISA_MIPS_R6) {
13389             decode_opc_special_r6(env, ctx);
13390         } else if (ctx->insn_flags & INSN_R5900) {
13391             decode_opc_special_tx79(env, ctx);
13392         } else {
13393             decode_opc_special_legacy(env, ctx);
13394         }
13395     }
13396 }
13397 
13398 
decode_opc_special2_legacy(CPUMIPSState * env,DisasContext * ctx)13399 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
13400 {
13401     int rs, rt, rd;
13402     uint32_t op1;
13403 
13404     rs = (ctx->opcode >> 21) & 0x1f;
13405     rt = (ctx->opcode >> 16) & 0x1f;
13406     rd = (ctx->opcode >> 11) & 0x1f;
13407 
13408     op1 = MASK_SPECIAL2(ctx->opcode);
13409     switch (op1) {
13410     case OPC_MADD: /* Multiply and add/sub */
13411     case OPC_MADDU:
13412     case OPC_MSUB:
13413     case OPC_MSUBU:
13414         check_insn(ctx, ISA_MIPS_R1);
13415         gen_muldiv(ctx, op1, rd & 3, rs, rt);
13416         break;
13417     case OPC_MUL:
13418         gen_arith(ctx, op1, rd, rs, rt);
13419         break;
13420     case OPC_CLO:
13421     case OPC_CLZ:
13422         check_insn(ctx, ISA_MIPS_R1);
13423         gen_cl(ctx, op1, rd, rs);
13424         break;
13425     case OPC_SDBBP:
13426         if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13427             ctx->base.is_jmp = DISAS_SEMIHOST;
13428         } else {
13429             /*
13430              * XXX: not clear which exception should be raised
13431              *      when in debug mode...
13432              */
13433             check_insn(ctx, ISA_MIPS_R1);
13434             generate_exception_end(ctx, EXCP_DBp);
13435         }
13436         break;
13437 #if defined(TARGET_MIPS64)
13438     case OPC_DCLO:
13439     case OPC_DCLZ:
13440         check_insn(ctx, ISA_MIPS_R1);
13441         check_mips_64(ctx);
13442         gen_cl(ctx, op1, rd, rs);
13443         break;
13444 #endif
13445     default:            /* Invalid */
13446         MIPS_INVAL("special2_legacy");
13447         gen_reserved_instruction(ctx);
13448         break;
13449     }
13450 }
13451 
decode_opc_special3_r6(CPUMIPSState * env,DisasContext * ctx)13452 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
13453 {
13454     int rs, rt, rd, sa;
13455     uint32_t op1, op2;
13456     int16_t imm;
13457 
13458     rs = (ctx->opcode >> 21) & 0x1f;
13459     rt = (ctx->opcode >> 16) & 0x1f;
13460     rd = (ctx->opcode >> 11) & 0x1f;
13461     sa = (ctx->opcode >> 6) & 0x1f;
13462     imm = (int16_t)ctx->opcode >> 7;
13463 
13464     op1 = MASK_SPECIAL3(ctx->opcode);
13465     switch (op1) {
13466     case R6_OPC_PREF:
13467         if (rt >= 24) {
13468             /* hint codes 24-31 are reserved and signal RI */
13469             gen_reserved_instruction(ctx);
13470         }
13471         /* Treat as NOP. */
13472         break;
13473     case R6_OPC_CACHE:
13474         check_cp0_enabled(ctx);
13475         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13476             gen_cache_operation(ctx, rt, rs, imm);
13477         }
13478         break;
13479     case R6_OPC_SC:
13480         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false);
13481         break;
13482     case R6_OPC_LL:
13483         gen_ld(ctx, op1, rt, rs, imm);
13484         break;
13485     case OPC_BSHFL:
13486         {
13487             if (rd == 0) {
13488                 /* Treat as NOP. */
13489                 break;
13490             }
13491             op2 = MASK_BSHFL(ctx->opcode);
13492             switch (op2) {
13493             case OPC_ALIGN:
13494             case OPC_ALIGN_1:
13495             case OPC_ALIGN_2:
13496             case OPC_ALIGN_3:
13497                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
13498                 break;
13499             case OPC_BITSWAP:
13500                 gen_bitswap(ctx, op2, rd, rt);
13501                 break;
13502             }
13503         }
13504         break;
13505 #ifndef CONFIG_USER_ONLY
13506     case OPC_GINV:
13507         if (unlikely(ctx->gi <= 1)) {
13508             gen_reserved_instruction(ctx);
13509         }
13510         check_cp0_enabled(ctx);
13511         switch ((ctx->opcode >> 6) & 3) {
13512         case 0:    /* GINVI */
13513             /* Treat as NOP. */
13514             break;
13515         case 2:    /* GINVT */
13516             gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
13517             break;
13518         default:
13519             gen_reserved_instruction(ctx);
13520             break;
13521         }
13522         break;
13523 #endif
13524 #if defined(TARGET_MIPS64)
13525     case R6_OPC_SCD:
13526         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false);
13527         break;
13528     case R6_OPC_LLD:
13529         gen_ld(ctx, op1, rt, rs, imm);
13530         break;
13531     case OPC_DBSHFL:
13532         check_mips_64(ctx);
13533         {
13534             if (rd == 0) {
13535                 /* Treat as NOP. */
13536                 break;
13537             }
13538             op2 = MASK_DBSHFL(ctx->opcode);
13539             switch (op2) {
13540             case OPC_DALIGN:
13541             case OPC_DALIGN_1:
13542             case OPC_DALIGN_2:
13543             case OPC_DALIGN_3:
13544             case OPC_DALIGN_4:
13545             case OPC_DALIGN_5:
13546             case OPC_DALIGN_6:
13547             case OPC_DALIGN_7:
13548                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
13549                 break;
13550             case OPC_DBITSWAP:
13551                 gen_bitswap(ctx, op2, rd, rt);
13552                 break;
13553             }
13554 
13555         }
13556         break;
13557 #endif
13558     default:            /* Invalid */
13559         MIPS_INVAL("special3_r6");
13560         gen_reserved_instruction(ctx);
13561         break;
13562     }
13563 }
13564 
decode_opc_special3_legacy(CPUMIPSState * env,DisasContext * ctx)13565 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
13566 {
13567     int rs, rt, rd;
13568     uint32_t op1, op2;
13569 
13570     rs = (ctx->opcode >> 21) & 0x1f;
13571     rt = (ctx->opcode >> 16) & 0x1f;
13572     rd = (ctx->opcode >> 11) & 0x1f;
13573 
13574     op1 = MASK_SPECIAL3(ctx->opcode);
13575     switch (op1) {
13576     case OPC_MUL_PH_DSP:
13577         /*
13578          * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13579          * the same mask and op1.
13580          */
13581         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) {
13582             op2 = MASK_ADDUH_QB(ctx->opcode);
13583             switch (op2) {
13584             case OPC_ADDUH_QB:
13585             case OPC_ADDUH_R_QB:
13586             case OPC_ADDQH_PH:
13587             case OPC_ADDQH_R_PH:
13588             case OPC_ADDQH_W:
13589             case OPC_ADDQH_R_W:
13590             case OPC_SUBUH_QB:
13591             case OPC_SUBUH_R_QB:
13592             case OPC_SUBQH_PH:
13593             case OPC_SUBQH_R_PH:
13594             case OPC_SUBQH_W:
13595             case OPC_SUBQH_R_W:
13596                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13597                 break;
13598             case OPC_MUL_PH:
13599             case OPC_MUL_S_PH:
13600             case OPC_MULQ_S_W:
13601             case OPC_MULQ_RS_W:
13602                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13603                 break;
13604             default:
13605                 MIPS_INVAL("MASK ADDUH.QB");
13606                 gen_reserved_instruction(ctx);
13607                 break;
13608             }
13609         } else {
13610             gen_reserved_instruction(ctx);
13611         }
13612         break;
13613     case OPC_LX_DSP:
13614         op2 = MASK_LX(ctx->opcode);
13615         switch (op2) {
13616 #if defined(TARGET_MIPS64)
13617         case OPC_LDX:
13618 #endif
13619         case OPC_LBUX:
13620         case OPC_LHX:
13621         case OPC_LWX:
13622             gen_mips_lx(ctx, op2, rd, rs, rt);
13623             break;
13624         default:            /* Invalid */
13625             MIPS_INVAL("MASK LX");
13626             gen_reserved_instruction(ctx);
13627             break;
13628         }
13629         break;
13630     case OPC_ABSQ_S_PH_DSP:
13631         op2 = MASK_ABSQ_S_PH(ctx->opcode);
13632         switch (op2) {
13633         case OPC_ABSQ_S_QB:
13634         case OPC_ABSQ_S_PH:
13635         case OPC_ABSQ_S_W:
13636         case OPC_PRECEQ_W_PHL:
13637         case OPC_PRECEQ_W_PHR:
13638         case OPC_PRECEQU_PH_QBL:
13639         case OPC_PRECEQU_PH_QBR:
13640         case OPC_PRECEQU_PH_QBLA:
13641         case OPC_PRECEQU_PH_QBRA:
13642         case OPC_PRECEU_PH_QBL:
13643         case OPC_PRECEU_PH_QBR:
13644         case OPC_PRECEU_PH_QBLA:
13645         case OPC_PRECEU_PH_QBRA:
13646             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13647             break;
13648         case OPC_BITREV:
13649         case OPC_REPL_QB:
13650         case OPC_REPLV_QB:
13651         case OPC_REPL_PH:
13652         case OPC_REPLV_PH:
13653             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13654             break;
13655         default:
13656             MIPS_INVAL("MASK ABSQ_S.PH");
13657             gen_reserved_instruction(ctx);
13658             break;
13659         }
13660         break;
13661     case OPC_ADDU_QB_DSP:
13662         op2 = MASK_ADDU_QB(ctx->opcode);
13663         switch (op2) {
13664         case OPC_ADDQ_PH:
13665         case OPC_ADDQ_S_PH:
13666         case OPC_ADDQ_S_W:
13667         case OPC_ADDU_QB:
13668         case OPC_ADDU_S_QB:
13669         case OPC_ADDU_PH:
13670         case OPC_ADDU_S_PH:
13671         case OPC_SUBQ_PH:
13672         case OPC_SUBQ_S_PH:
13673         case OPC_SUBQ_S_W:
13674         case OPC_SUBU_QB:
13675         case OPC_SUBU_S_QB:
13676         case OPC_SUBU_PH:
13677         case OPC_SUBU_S_PH:
13678         case OPC_ADDSC:
13679         case OPC_ADDWC:
13680         case OPC_MODSUB:
13681         case OPC_RADDU_W_QB:
13682             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13683             break;
13684         case OPC_MULEU_S_PH_QBL:
13685         case OPC_MULEU_S_PH_QBR:
13686         case OPC_MULQ_RS_PH:
13687         case OPC_MULEQ_S_W_PHL:
13688         case OPC_MULEQ_S_W_PHR:
13689         case OPC_MULQ_S_PH:
13690             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13691             break;
13692         default:            /* Invalid */
13693             MIPS_INVAL("MASK ADDU.QB");
13694             gen_reserved_instruction(ctx);
13695             break;
13696 
13697         }
13698         break;
13699     case OPC_CMPU_EQ_QB_DSP:
13700         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
13701         switch (op2) {
13702         case OPC_PRECR_SRA_PH_W:
13703         case OPC_PRECR_SRA_R_PH_W:
13704             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
13705             break;
13706         case OPC_PRECR_QB_PH:
13707         case OPC_PRECRQ_QB_PH:
13708         case OPC_PRECRQ_PH_W:
13709         case OPC_PRECRQ_RS_PH_W:
13710         case OPC_PRECRQU_S_QB_PH:
13711             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13712             break;
13713         case OPC_CMPU_EQ_QB:
13714         case OPC_CMPU_LT_QB:
13715         case OPC_CMPU_LE_QB:
13716         case OPC_CMP_EQ_PH:
13717         case OPC_CMP_LT_PH:
13718         case OPC_CMP_LE_PH:
13719             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
13720             break;
13721         case OPC_CMPGU_EQ_QB:
13722         case OPC_CMPGU_LT_QB:
13723         case OPC_CMPGU_LE_QB:
13724         case OPC_CMPGDU_EQ_QB:
13725         case OPC_CMPGDU_LT_QB:
13726         case OPC_CMPGDU_LE_QB:
13727         case OPC_PICK_QB:
13728         case OPC_PICK_PH:
13729         case OPC_PACKRL_PH:
13730             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
13731             break;
13732         default:            /* Invalid */
13733             MIPS_INVAL("MASK CMPU.EQ.QB");
13734             gen_reserved_instruction(ctx);
13735             break;
13736         }
13737         break;
13738     case OPC_SHLL_QB_DSP:
13739         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
13740         break;
13741     case OPC_DPA_W_PH_DSP:
13742         op2 = MASK_DPA_W_PH(ctx->opcode);
13743         switch (op2) {
13744         case OPC_DPAU_H_QBL:
13745         case OPC_DPAU_H_QBR:
13746         case OPC_DPSU_H_QBL:
13747         case OPC_DPSU_H_QBR:
13748         case OPC_DPA_W_PH:
13749         case OPC_DPAX_W_PH:
13750         case OPC_DPAQ_S_W_PH:
13751         case OPC_DPAQX_S_W_PH:
13752         case OPC_DPAQX_SA_W_PH:
13753         case OPC_DPS_W_PH:
13754         case OPC_DPSX_W_PH:
13755         case OPC_DPSQ_S_W_PH:
13756         case OPC_DPSQX_S_W_PH:
13757         case OPC_DPSQX_SA_W_PH:
13758         case OPC_MULSAQ_S_W_PH:
13759         case OPC_DPAQ_SA_L_W:
13760         case OPC_DPSQ_SA_L_W:
13761         case OPC_MAQ_S_W_PHL:
13762         case OPC_MAQ_S_W_PHR:
13763         case OPC_MAQ_SA_W_PHL:
13764         case OPC_MAQ_SA_W_PHR:
13765         case OPC_MULSA_W_PH:
13766             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
13767             break;
13768         default:            /* Invalid */
13769             MIPS_INVAL("MASK DPAW.PH");
13770             gen_reserved_instruction(ctx);
13771             break;
13772         }
13773         break;
13774     case OPC_INSV_DSP:
13775         op2 = MASK_INSV(ctx->opcode);
13776         switch (op2) {
13777         case OPC_INSV:
13778             check_dsp(ctx);
13779             {
13780                 TCGv t0, t1;
13781 
13782                 if (rt == 0) {
13783                     break;
13784                 }
13785 
13786                 t0 = tcg_temp_new();
13787                 t1 = tcg_temp_new();
13788 
13789                 gen_load_gpr(t0, rt);
13790                 gen_load_gpr(t1, rs);
13791 
13792                 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0);
13793                 break;
13794             }
13795         default:            /* Invalid */
13796             MIPS_INVAL("MASK INSV");
13797             gen_reserved_instruction(ctx);
13798             break;
13799         }
13800         break;
13801     case OPC_APPEND_DSP:
13802         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
13803         break;
13804     case OPC_EXTR_W_DSP:
13805         op2 = MASK_EXTR_W(ctx->opcode);
13806         switch (op2) {
13807         case OPC_EXTR_W:
13808         case OPC_EXTR_R_W:
13809         case OPC_EXTR_RS_W:
13810         case OPC_EXTR_S_H:
13811         case OPC_EXTRV_S_H:
13812         case OPC_EXTRV_W:
13813         case OPC_EXTRV_R_W:
13814         case OPC_EXTRV_RS_W:
13815         case OPC_EXTP:
13816         case OPC_EXTPV:
13817         case OPC_EXTPDP:
13818         case OPC_EXTPDPV:
13819             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
13820             break;
13821         case OPC_RDDSP:
13822             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
13823             break;
13824         case OPC_SHILO:
13825         case OPC_SHILOV:
13826         case OPC_MTHLIP:
13827         case OPC_WRDSP:
13828             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
13829             break;
13830         default:            /* Invalid */
13831             MIPS_INVAL("MASK EXTR.W");
13832             gen_reserved_instruction(ctx);
13833             break;
13834         }
13835         break;
13836 #if defined(TARGET_MIPS64)
13837     case OPC_ABSQ_S_QH_DSP:
13838         op2 = MASK_ABSQ_S_QH(ctx->opcode);
13839         switch (op2) {
13840         case OPC_PRECEQ_L_PWL:
13841         case OPC_PRECEQ_L_PWR:
13842         case OPC_PRECEQ_PW_QHL:
13843         case OPC_PRECEQ_PW_QHR:
13844         case OPC_PRECEQ_PW_QHLA:
13845         case OPC_PRECEQ_PW_QHRA:
13846         case OPC_PRECEQU_QH_OBL:
13847         case OPC_PRECEQU_QH_OBR:
13848         case OPC_PRECEQU_QH_OBLA:
13849         case OPC_PRECEQU_QH_OBRA:
13850         case OPC_PRECEU_QH_OBL:
13851         case OPC_PRECEU_QH_OBR:
13852         case OPC_PRECEU_QH_OBLA:
13853         case OPC_PRECEU_QH_OBRA:
13854         case OPC_ABSQ_S_OB:
13855         case OPC_ABSQ_S_PW:
13856         case OPC_ABSQ_S_QH:
13857             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13858             break;
13859         case OPC_REPL_OB:
13860         case OPC_REPL_PW:
13861         case OPC_REPL_QH:
13862         case OPC_REPLV_OB:
13863         case OPC_REPLV_PW:
13864         case OPC_REPLV_QH:
13865             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13866             break;
13867         default:            /* Invalid */
13868             MIPS_INVAL("MASK ABSQ_S.QH");
13869             gen_reserved_instruction(ctx);
13870             break;
13871         }
13872         break;
13873     case OPC_ADDU_OB_DSP:
13874         op2 = MASK_ADDU_OB(ctx->opcode);
13875         switch (op2) {
13876         case OPC_RADDU_L_OB:
13877         case OPC_SUBQ_PW:
13878         case OPC_SUBQ_S_PW:
13879         case OPC_SUBQ_QH:
13880         case OPC_SUBQ_S_QH:
13881         case OPC_SUBU_OB:
13882         case OPC_SUBU_S_OB:
13883         case OPC_SUBU_QH:
13884         case OPC_SUBU_S_QH:
13885         case OPC_SUBUH_OB:
13886         case OPC_SUBUH_R_OB:
13887         case OPC_ADDQ_PW:
13888         case OPC_ADDQ_S_PW:
13889         case OPC_ADDQ_QH:
13890         case OPC_ADDQ_S_QH:
13891         case OPC_ADDU_OB:
13892         case OPC_ADDU_S_OB:
13893         case OPC_ADDU_QH:
13894         case OPC_ADDU_S_QH:
13895         case OPC_ADDUH_OB:
13896         case OPC_ADDUH_R_OB:
13897             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13898             break;
13899         case OPC_MULEQ_S_PW_QHL:
13900         case OPC_MULEQ_S_PW_QHR:
13901         case OPC_MULEU_S_QH_OBL:
13902         case OPC_MULEU_S_QH_OBR:
13903         case OPC_MULQ_RS_QH:
13904             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13905             break;
13906         default:            /* Invalid */
13907             MIPS_INVAL("MASK ADDU.OB");
13908             gen_reserved_instruction(ctx);
13909             break;
13910         }
13911         break;
13912     case OPC_CMPU_EQ_OB_DSP:
13913         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
13914         switch (op2) {
13915         case OPC_PRECR_SRA_QH_PW:
13916         case OPC_PRECR_SRA_R_QH_PW:
13917             /* Return value is rt. */
13918             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
13919             break;
13920         case OPC_PRECR_OB_QH:
13921         case OPC_PRECRQ_OB_QH:
13922         case OPC_PRECRQ_PW_L:
13923         case OPC_PRECRQ_QH_PW:
13924         case OPC_PRECRQ_RS_QH_PW:
13925         case OPC_PRECRQU_S_OB_QH:
13926             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13927             break;
13928         case OPC_CMPU_EQ_OB:
13929         case OPC_CMPU_LT_OB:
13930         case OPC_CMPU_LE_OB:
13931         case OPC_CMP_EQ_QH:
13932         case OPC_CMP_LT_QH:
13933         case OPC_CMP_LE_QH:
13934         case OPC_CMP_EQ_PW:
13935         case OPC_CMP_LT_PW:
13936         case OPC_CMP_LE_PW:
13937             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
13938             break;
13939         case OPC_CMPGDU_EQ_OB:
13940         case OPC_CMPGDU_LT_OB:
13941         case OPC_CMPGDU_LE_OB:
13942         case OPC_CMPGU_EQ_OB:
13943         case OPC_CMPGU_LT_OB:
13944         case OPC_CMPGU_LE_OB:
13945         case OPC_PACKRL_PW:
13946         case OPC_PICK_OB:
13947         case OPC_PICK_PW:
13948         case OPC_PICK_QH:
13949             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
13950             break;
13951         default:            /* Invalid */
13952             MIPS_INVAL("MASK CMPU_EQ.OB");
13953             gen_reserved_instruction(ctx);
13954             break;
13955         }
13956         break;
13957     case OPC_DAPPEND_DSP:
13958         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
13959         break;
13960     case OPC_DEXTR_W_DSP:
13961         op2 = MASK_DEXTR_W(ctx->opcode);
13962         switch (op2) {
13963         case OPC_DEXTP:
13964         case OPC_DEXTPDP:
13965         case OPC_DEXTPDPV:
13966         case OPC_DEXTPV:
13967         case OPC_DEXTR_L:
13968         case OPC_DEXTR_R_L:
13969         case OPC_DEXTR_RS_L:
13970         case OPC_DEXTR_W:
13971         case OPC_DEXTR_R_W:
13972         case OPC_DEXTR_RS_W:
13973         case OPC_DEXTR_S_H:
13974         case OPC_DEXTRV_L:
13975         case OPC_DEXTRV_R_L:
13976         case OPC_DEXTRV_RS_L:
13977         case OPC_DEXTRV_S_H:
13978         case OPC_DEXTRV_W:
13979         case OPC_DEXTRV_R_W:
13980         case OPC_DEXTRV_RS_W:
13981             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
13982             break;
13983         case OPC_DMTHLIP:
13984         case OPC_DSHILO:
13985         case OPC_DSHILOV:
13986             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
13987             break;
13988         default:            /* Invalid */
13989             MIPS_INVAL("MASK EXTR.W");
13990             gen_reserved_instruction(ctx);
13991             break;
13992         }
13993         break;
13994     case OPC_DPAQ_W_QH_DSP:
13995         op2 = MASK_DPAQ_W_QH(ctx->opcode);
13996         switch (op2) {
13997         case OPC_DPAU_H_OBL:
13998         case OPC_DPAU_H_OBR:
13999         case OPC_DPSU_H_OBL:
14000         case OPC_DPSU_H_OBR:
14001         case OPC_DPA_W_QH:
14002         case OPC_DPAQ_S_W_QH:
14003         case OPC_DPS_W_QH:
14004         case OPC_DPSQ_S_W_QH:
14005         case OPC_MULSAQ_S_W_QH:
14006         case OPC_DPAQ_SA_L_PW:
14007         case OPC_DPSQ_SA_L_PW:
14008         case OPC_MULSAQ_S_L_PW:
14009             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14010             break;
14011         case OPC_MAQ_S_W_QHLL:
14012         case OPC_MAQ_S_W_QHLR:
14013         case OPC_MAQ_S_W_QHRL:
14014         case OPC_MAQ_S_W_QHRR:
14015         case OPC_MAQ_SA_W_QHLL:
14016         case OPC_MAQ_SA_W_QHLR:
14017         case OPC_MAQ_SA_W_QHRL:
14018         case OPC_MAQ_SA_W_QHRR:
14019         case OPC_MAQ_S_L_PWL:
14020         case OPC_MAQ_S_L_PWR:
14021         case OPC_DMADD:
14022         case OPC_DMADDU:
14023         case OPC_DMSUB:
14024         case OPC_DMSUBU:
14025             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14026             break;
14027         default:            /* Invalid */
14028             MIPS_INVAL("MASK DPAQ.W.QH");
14029             gen_reserved_instruction(ctx);
14030             break;
14031         }
14032         break;
14033     case OPC_DINSV_DSP:
14034         op2 = MASK_INSV(ctx->opcode);
14035         switch (op2) {
14036         case OPC_DINSV:
14037         {
14038             TCGv t0, t1;
14039 
14040             check_dsp(ctx);
14041 
14042             if (rt == 0) {
14043                 break;
14044             }
14045 
14046             t0 = tcg_temp_new();
14047             t1 = tcg_temp_new();
14048 
14049             gen_load_gpr(t0, rt);
14050             gen_load_gpr(t1, rs);
14051 
14052             gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0);
14053             break;
14054         }
14055         default:            /* Invalid */
14056             MIPS_INVAL("MASK DINSV");
14057             gen_reserved_instruction(ctx);
14058             break;
14059         }
14060         break;
14061     case OPC_SHLL_OB_DSP:
14062         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14063         break;
14064 #endif
14065     default:            /* Invalid */
14066         MIPS_INVAL("special3_legacy");
14067         gen_reserved_instruction(ctx);
14068         break;
14069     }
14070 }
14071 
14072 
14073 #if defined(TARGET_MIPS64)
14074 
decode_mmi(CPUMIPSState * env,DisasContext * ctx)14075 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14076 {
14077     uint32_t opc = MASK_MMI(ctx->opcode);
14078     int rs = extract32(ctx->opcode, 21, 5);
14079     int rt = extract32(ctx->opcode, 16, 5);
14080     int rd = extract32(ctx->opcode, 11, 5);
14081 
14082     switch (opc) {
14083     case MMI_OPC_MULT1:
14084     case MMI_OPC_MULTU1:
14085     case MMI_OPC_MADD:
14086     case MMI_OPC_MADDU:
14087     case MMI_OPC_MADD1:
14088     case MMI_OPC_MADDU1:
14089         gen_mul_txx9(ctx, opc, rd, rs, rt);
14090         break;
14091     case MMI_OPC_DIV1:
14092     case MMI_OPC_DIVU1:
14093         gen_div1_tx79(ctx, opc, rs, rt);
14094         break;
14095     default:
14096         MIPS_INVAL("TX79 MMI class");
14097         gen_reserved_instruction(ctx);
14098         break;
14099     }
14100 }
14101 
gen_mmi_sq(DisasContext * ctx,int base,int rt,int offset)14102 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
14103 {
14104     gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
14105 }
14106 
14107 /*
14108  * The TX79-specific instruction Store Quadword
14109  *
14110  * +--------+-------+-------+------------------------+
14111  * | 011111 |  base |   rt  |           offset       | SQ
14112  * +--------+-------+-------+------------------------+
14113  *      6       5       5                 16
14114  *
14115  * has the same opcode as the Read Hardware Register instruction
14116  *
14117  * +--------+-------+-------+-------+-------+--------+
14118  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
14119  * +--------+-------+-------+-------+-------+--------+
14120  *      6       5       5       5       5        6
14121  *
14122  * that is required, trapped and emulated by the Linux kernel. However, all
14123  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
14124  * offset is odd. Therefore all valid SQ instructions can execute normally.
14125  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
14126  * between SQ and RDHWR, as the Linux kernel does.
14127  */
decode_mmi_sq(CPUMIPSState * env,DisasContext * ctx)14128 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
14129 {
14130     int base = extract32(ctx->opcode, 21, 5);
14131     int rt = extract32(ctx->opcode, 16, 5);
14132     int offset = extract32(ctx->opcode, 0, 16);
14133 
14134 #ifdef CONFIG_USER_ONLY
14135     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
14136     uint32_t op2 = extract32(ctx->opcode, 6, 5);
14137 
14138     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
14139         int rd = extract32(ctx->opcode, 11, 5);
14140 
14141         gen_rdhwr(ctx, rt, rd, 0);
14142         return;
14143     }
14144 #endif
14145 
14146     gen_mmi_sq(ctx, base, rt, offset);
14147 }
14148 
14149 #endif
14150 
decode_opc_special3(CPUMIPSState * env,DisasContext * ctx)14151 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
14152 {
14153     int rs, rt, rd, sa;
14154     uint32_t op1, op2;
14155     int16_t imm;
14156 
14157     rs = (ctx->opcode >> 21) & 0x1f;
14158     rt = (ctx->opcode >> 16) & 0x1f;
14159     rd = (ctx->opcode >> 11) & 0x1f;
14160     sa = (ctx->opcode >> 6) & 0x1f;
14161     imm = sextract32(ctx->opcode, 7, 9);
14162 
14163     op1 = MASK_SPECIAL3(ctx->opcode);
14164 
14165     /*
14166      * EVA loads and stores overlap Loongson 2E instructions decoded by
14167      * decode_opc_special3_legacy(), so be careful to allow their decoding when
14168      * EVA is absent.
14169      */
14170     if (ctx->eva) {
14171         switch (op1) {
14172         case OPC_LWLE:
14173         case OPC_LWRE:
14174         case OPC_LBUE:
14175         case OPC_LHUE:
14176         case OPC_LBE:
14177         case OPC_LHE:
14178         case OPC_LLE:
14179         case OPC_LWE:
14180             check_cp0_enabled(ctx);
14181             gen_ld(ctx, op1, rt, rs, imm);
14182             return;
14183         case OPC_SWLE:
14184         case OPC_SWRE:
14185         case OPC_SBE:
14186         case OPC_SHE:
14187         case OPC_SWE:
14188             check_cp0_enabled(ctx);
14189             gen_st(ctx, op1, rt, rs, imm);
14190             return;
14191         case OPC_SCE:
14192             check_cp0_enabled(ctx);
14193             gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, true);
14194             return;
14195         case OPC_CACHEE:
14196             check_eva(ctx);
14197             check_cp0_enabled(ctx);
14198             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14199                 gen_cache_operation(ctx, rt, rs, imm);
14200             }
14201             return;
14202         case OPC_PREFE:
14203             check_cp0_enabled(ctx);
14204             /* Treat as NOP. */
14205             return;
14206         }
14207     }
14208 
14209     switch (op1) {
14210     case OPC_EXT:
14211     case OPC_INS:
14212         check_insn(ctx, ISA_MIPS_R2);
14213         gen_bitops(ctx, op1, rt, rs, sa, rd);
14214         break;
14215     case OPC_BSHFL:
14216         op2 = MASK_BSHFL(ctx->opcode);
14217         switch (op2) {
14218         case OPC_ALIGN:
14219         case OPC_ALIGN_1:
14220         case OPC_ALIGN_2:
14221         case OPC_ALIGN_3:
14222         case OPC_BITSWAP:
14223             check_insn(ctx, ISA_MIPS_R6);
14224             decode_opc_special3_r6(env, ctx);
14225             break;
14226         default:
14227             check_insn(ctx, ISA_MIPS_R2);
14228             gen_bshfl(ctx, op2, rt, rd);
14229             break;
14230         }
14231         break;
14232 #if defined(TARGET_MIPS64)
14233     case OPC_DEXTM:
14234     case OPC_DEXTU:
14235     case OPC_DEXT:
14236     case OPC_DINSM:
14237     case OPC_DINSU:
14238     case OPC_DINS:
14239         check_insn(ctx, ISA_MIPS_R2);
14240         check_mips_64(ctx);
14241         gen_bitops(ctx, op1, rt, rs, sa, rd);
14242         break;
14243     case OPC_DBSHFL:
14244         op2 = MASK_DBSHFL(ctx->opcode);
14245         switch (op2) {
14246         case OPC_DALIGN:
14247         case OPC_DALIGN_1:
14248         case OPC_DALIGN_2:
14249         case OPC_DALIGN_3:
14250         case OPC_DALIGN_4:
14251         case OPC_DALIGN_5:
14252         case OPC_DALIGN_6:
14253         case OPC_DALIGN_7:
14254         case OPC_DBITSWAP:
14255             check_insn(ctx, ISA_MIPS_R6);
14256             decode_opc_special3_r6(env, ctx);
14257             break;
14258         default:
14259             check_insn(ctx, ISA_MIPS_R2);
14260             check_mips_64(ctx);
14261             op2 = MASK_DBSHFL(ctx->opcode);
14262             gen_bshfl(ctx, op2, rt, rd);
14263             break;
14264         }
14265         break;
14266 #endif
14267     case OPC_RDHWR:
14268         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
14269         break;
14270     case OPC_FORK:
14271         check_mt(ctx);
14272         {
14273             TCGv t0 = tcg_temp_new();
14274             TCGv t1 = tcg_temp_new();
14275 
14276             gen_load_gpr(t0, rt);
14277             gen_load_gpr(t1, rs);
14278             gen_helper_fork(t0, t1);
14279         }
14280         break;
14281     case OPC_YIELD:
14282         check_mt(ctx);
14283         {
14284             TCGv t0 = tcg_temp_new();
14285 
14286             gen_load_gpr(t0, rs);
14287             gen_helper_yield(t0, tcg_env, t0);
14288             gen_store_gpr(t0, rd);
14289         }
14290         break;
14291     default:
14292         if (ctx->insn_flags & ISA_MIPS_R6) {
14293             decode_opc_special3_r6(env, ctx);
14294         } else {
14295             decode_opc_special3_legacy(env, ctx);
14296         }
14297     }
14298 }
14299 
decode_opc_legacy(CPUMIPSState * env,DisasContext * ctx)14300 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
14301 {
14302     int32_t offset;
14303     int rs, rt, rd, sa;
14304     uint32_t op, op1;
14305     int16_t imm;
14306 
14307     op = MASK_OP_MAJOR(ctx->opcode);
14308     rs = (ctx->opcode >> 21) & 0x1f;
14309     rt = (ctx->opcode >> 16) & 0x1f;
14310     rd = (ctx->opcode >> 11) & 0x1f;
14311     sa = (ctx->opcode >> 6) & 0x1f;
14312     imm = (int16_t)ctx->opcode;
14313     switch (op) {
14314     case OPC_SPECIAL:
14315         decode_opc_special(env, ctx);
14316         break;
14317     case OPC_SPECIAL2:
14318 #if defined(TARGET_MIPS64)
14319         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
14320             decode_mmi(env, ctx);
14321             break;
14322         }
14323 #endif
14324         if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
14325             if (decode_ase_mxu(ctx, ctx->opcode)) {
14326                 break;
14327             }
14328         }
14329         decode_opc_special2_legacy(env, ctx);
14330         break;
14331     case OPC_SPECIAL3:
14332 #if defined(TARGET_MIPS64)
14333         if (ctx->insn_flags & INSN_R5900) {
14334             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
14335         } else {
14336             decode_opc_special3(env, ctx);
14337         }
14338 #else
14339         decode_opc_special3(env, ctx);
14340 #endif
14341         break;
14342     case OPC_REGIMM:
14343         op1 = MASK_REGIMM(ctx->opcode);
14344         switch (op1) {
14345         case OPC_BLTZL: /* REGIMM branches */
14346         case OPC_BGEZL:
14347         case OPC_BLTZALL:
14348         case OPC_BGEZALL:
14349             check_insn(ctx, ISA_MIPS2);
14350             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14351             /* Fallthrough */
14352         case OPC_BLTZ:
14353         case OPC_BGEZ:
14354             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14355             break;
14356         case OPC_BLTZAL:
14357         case OPC_BGEZAL:
14358             if (ctx->insn_flags & ISA_MIPS_R6) {
14359                 if (rs == 0) {
14360                     /* OPC_NAL, OPC_BAL */
14361                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
14362                 } else {
14363                     gen_reserved_instruction(ctx);
14364                 }
14365             } else {
14366                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14367             }
14368             break;
14369         case OPC_TGEI: /* REGIMM traps */
14370         case OPC_TGEIU:
14371         case OPC_TLTI:
14372         case OPC_TLTIU:
14373         case OPC_TEQI:
14374         case OPC_TNEI:
14375             check_insn(ctx, ISA_MIPS2);
14376             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14377             gen_trap(ctx, op1, rs, -1, imm, 0);
14378             break;
14379         case OPC_SIGRIE:
14380             check_insn(ctx, ISA_MIPS_R6);
14381             gen_reserved_instruction(ctx);
14382             break;
14383         case OPC_SYNCI:
14384             check_insn(ctx, ISA_MIPS_R2);
14385             /*
14386              * Break the TB to be able to sync copied instructions
14387              * immediately.
14388              */
14389             ctx->base.is_jmp = DISAS_STOP;
14390             break;
14391         case OPC_BPOSGE32:    /* MIPS DSP branch */
14392 #if defined(TARGET_MIPS64)
14393         case OPC_BPOSGE64:
14394 #endif
14395             check_dsp(ctx);
14396             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
14397             break;
14398 #if defined(TARGET_MIPS64)
14399         case OPC_DAHI:
14400             check_insn(ctx, ISA_MIPS_R6);
14401             check_mips_64(ctx);
14402             if (rs != 0) {
14403                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
14404             }
14405             break;
14406         case OPC_DATI:
14407             check_insn(ctx, ISA_MIPS_R6);
14408             check_mips_64(ctx);
14409             if (rs != 0) {
14410                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
14411             }
14412             break;
14413 #endif
14414         default:            /* Invalid */
14415             MIPS_INVAL("regimm");
14416             gen_reserved_instruction(ctx);
14417             break;
14418         }
14419         break;
14420     case OPC_CP0:
14421         check_cp0_enabled(ctx);
14422         op1 = MASK_CP0(ctx->opcode);
14423         switch (op1) {
14424         case OPC_MFC0:
14425         case OPC_MTC0:
14426         case OPC_MFTR:
14427         case OPC_MTTR:
14428         case OPC_MFHC0:
14429         case OPC_MTHC0:
14430 #if defined(TARGET_MIPS64)
14431         case OPC_DMFC0:
14432         case OPC_DMTC0:
14433 #endif
14434 #ifndef CONFIG_USER_ONLY
14435             gen_cp0(env, ctx, op1, rt, rd);
14436 #endif /* !CONFIG_USER_ONLY */
14437             break;
14438         case OPC_C0:
14439         case OPC_C0_1:
14440         case OPC_C0_2:
14441         case OPC_C0_3:
14442         case OPC_C0_4:
14443         case OPC_C0_5:
14444         case OPC_C0_6:
14445         case OPC_C0_7:
14446         case OPC_C0_8:
14447         case OPC_C0_9:
14448         case OPC_C0_A:
14449         case OPC_C0_B:
14450         case OPC_C0_C:
14451         case OPC_C0_D:
14452         case OPC_C0_E:
14453         case OPC_C0_F:
14454 #ifndef CONFIG_USER_ONLY
14455             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
14456 #endif /* !CONFIG_USER_ONLY */
14457             break;
14458         case OPC_MFMC0:
14459 #ifndef CONFIG_USER_ONLY
14460             {
14461                 uint32_t op2;
14462                 TCGv t0 = tcg_temp_new();
14463 
14464                 op2 = MASK_MFMC0(ctx->opcode);
14465                 switch (op2) {
14466                 case OPC_DMT:
14467                     check_cp0_mt(ctx);
14468                     gen_helper_dmt(t0);
14469                     gen_store_gpr(t0, rt);
14470                     break;
14471                 case OPC_EMT:
14472                     check_cp0_mt(ctx);
14473                     gen_helper_emt(t0);
14474                     gen_store_gpr(t0, rt);
14475                     break;
14476                 case OPC_DVPE:
14477                     check_cp0_mt(ctx);
14478                     gen_helper_dvpe(t0, tcg_env);
14479                     gen_store_gpr(t0, rt);
14480                     break;
14481                 case OPC_EVPE:
14482                     check_cp0_mt(ctx);
14483                     gen_helper_evpe(t0, tcg_env);
14484                     gen_store_gpr(t0, rt);
14485                     break;
14486                 case OPC_DVP:
14487                     check_insn(ctx, ISA_MIPS_R6);
14488                     if (ctx->vp) {
14489                         gen_helper_dvp(t0, tcg_env);
14490                         gen_store_gpr(t0, rt);
14491                     }
14492                     break;
14493                 case OPC_EVP:
14494                     check_insn(ctx, ISA_MIPS_R6);
14495                     if (ctx->vp) {
14496                         gen_helper_evp(t0, tcg_env);
14497                         gen_store_gpr(t0, rt);
14498                     }
14499                     break;
14500                 case OPC_DI:
14501                     check_insn(ctx, ISA_MIPS_R2);
14502                     save_cpu_state(ctx, 1);
14503                     gen_helper_di(t0, tcg_env);
14504                     gen_store_gpr(t0, rt);
14505                     /*
14506                      * Stop translation as we may have switched
14507                      * the execution mode.
14508                      */
14509                     ctx->base.is_jmp = DISAS_STOP;
14510                     break;
14511                 case OPC_EI:
14512                     check_insn(ctx, ISA_MIPS_R2);
14513                     save_cpu_state(ctx, 1);
14514                     gen_helper_ei(t0, tcg_env);
14515                     gen_store_gpr(t0, rt);
14516                     /*
14517                      * DISAS_STOP isn't sufficient, we need to ensure we break
14518                      * out of translated code to check for pending interrupts.
14519                      */
14520                     gen_save_pc(ctx->base.pc_next + 4);
14521                     ctx->base.is_jmp = DISAS_EXIT;
14522                     break;
14523                 default:            /* Invalid */
14524                     MIPS_INVAL("mfmc0");
14525                     gen_reserved_instruction(ctx);
14526                     break;
14527                 }
14528             }
14529 #endif /* !CONFIG_USER_ONLY */
14530             break;
14531         case OPC_RDPGPR:
14532             check_insn(ctx, ISA_MIPS_R2);
14533             gen_load_srsgpr(rt, rd);
14534             break;
14535         case OPC_WRPGPR:
14536             check_insn(ctx, ISA_MIPS_R2);
14537             gen_store_srsgpr(rt, rd);
14538             break;
14539         default:
14540             MIPS_INVAL("cp0");
14541             gen_reserved_instruction(ctx);
14542             break;
14543         }
14544         break;
14545     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
14546         if (ctx->insn_flags & ISA_MIPS_R6) {
14547             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
14548             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14549         } else {
14550             /* OPC_ADDI */
14551             /* Arithmetic with immediate opcode */
14552             gen_arith_imm(ctx, op, rt, rs, imm);
14553         }
14554         break;
14555     case OPC_ADDIU:
14556          gen_arith_imm(ctx, op, rt, rs, imm);
14557          break;
14558     case OPC_SLTI: /* Set on less than with immediate opcode */
14559     case OPC_SLTIU:
14560          gen_slt_imm(ctx, op, rt, rs, imm);
14561          break;
14562     case OPC_ANDI: /* Arithmetic with immediate opcode */
14563     case OPC_LUI: /* OPC_AUI */
14564     case OPC_ORI:
14565     case OPC_XORI:
14566          gen_logic_imm(ctx, op, rt, rs, imm);
14567          break;
14568     case OPC_J: /* Jump */
14569     case OPC_JAL:
14570          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14571          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14572          break;
14573     /* Branch */
14574     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
14575         if (ctx->insn_flags & ISA_MIPS_R6) {
14576             if (rt == 0) {
14577                 gen_reserved_instruction(ctx);
14578                 break;
14579             }
14580             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
14581             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14582         } else {
14583             /* OPC_BLEZL */
14584             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14585         }
14586         break;
14587     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
14588         if (ctx->insn_flags & ISA_MIPS_R6) {
14589             if (rt == 0) {
14590                 gen_reserved_instruction(ctx);
14591                 break;
14592             }
14593             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
14594             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14595         } else {
14596             /* OPC_BGTZL */
14597             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14598         }
14599         break;
14600     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
14601         if (rt == 0) {
14602             /* OPC_BLEZ */
14603             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14604         } else {
14605             check_insn(ctx, ISA_MIPS_R6);
14606             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
14607             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14608         }
14609         break;
14610     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
14611         if (rt == 0) {
14612             /* OPC_BGTZ */
14613             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14614         } else {
14615             check_insn(ctx, ISA_MIPS_R6);
14616             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
14617             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14618         }
14619         break;
14620     case OPC_BEQL:
14621     case OPC_BNEL:
14622         check_insn(ctx, ISA_MIPS2);
14623          check_insn_opc_removed(ctx, ISA_MIPS_R6);
14624         /* Fallthrough */
14625     case OPC_BEQ:
14626     case OPC_BNE:
14627          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14628          break;
14629     case OPC_LL: /* Load and stores */
14630         check_insn(ctx, ISA_MIPS2);
14631         if (ctx->insn_flags & INSN_R5900) {
14632             check_insn_opc_user_only(ctx, INSN_R5900);
14633         }
14634         /* Fallthrough */
14635     case OPC_LWL:
14636     case OPC_LWR:
14637     case OPC_LB:
14638     case OPC_LH:
14639     case OPC_LW:
14640     case OPC_LWPC:
14641     case OPC_LBU:
14642     case OPC_LHU:
14643          gen_ld(ctx, op, rt, rs, imm);
14644          break;
14645     case OPC_SWL:
14646     case OPC_SWR:
14647     case OPC_SB:
14648     case OPC_SH:
14649     case OPC_SW:
14650          gen_st(ctx, op, rt, rs, imm);
14651          break;
14652     case OPC_SC:
14653         check_insn(ctx, ISA_MIPS2);
14654         if (ctx->insn_flags & INSN_R5900) {
14655             check_insn_opc_user_only(ctx, INSN_R5900);
14656         }
14657         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_SL, false);
14658         break;
14659     case OPC_CACHE:
14660         check_cp0_enabled(ctx);
14661         check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
14662         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14663             gen_cache_operation(ctx, rt, rs, imm);
14664         }
14665         /* Treat as NOP. */
14666         break;
14667     case OPC_PREF:
14668         check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
14669         /* Treat as NOP. */
14670         break;
14671 
14672     /* Floating point (COP1). */
14673     case OPC_LWC1:
14674     case OPC_LDC1:
14675     case OPC_SWC1:
14676     case OPC_SDC1:
14677         gen_cop1_ldst(ctx, op, rt, rs, imm);
14678         break;
14679 
14680     case OPC_CP1:
14681         op1 = MASK_CP1(ctx->opcode);
14682 
14683         switch (op1) {
14684         case OPC_MFHC1:
14685         case OPC_MTHC1:
14686             check_cp1_enabled(ctx);
14687             check_insn(ctx, ISA_MIPS_R2);
14688             /* fall through */
14689         case OPC_MFC1:
14690         case OPC_CFC1:
14691         case OPC_MTC1:
14692         case OPC_CTC1:
14693             check_cp1_enabled(ctx);
14694             gen_cp1(ctx, op1, rt, rd);
14695             break;
14696 #if defined(TARGET_MIPS64)
14697         case OPC_DMFC1:
14698         case OPC_DMTC1:
14699             check_cp1_enabled(ctx);
14700             check_insn(ctx, ISA_MIPS3);
14701             check_mips_64(ctx);
14702             gen_cp1(ctx, op1, rt, rd);
14703             break;
14704 #endif
14705         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
14706             check_cp1_enabled(ctx);
14707             if (ctx->insn_flags & ISA_MIPS_R6) {
14708                 /* OPC_BC1EQZ */
14709                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14710                                        rt, imm << 2, 4);
14711             } else {
14712                 /* OPC_BC1ANY2 */
14713                 check_cop1x(ctx);
14714                 if (!ase_3d_available(env)) {
14715                     return false;
14716                 }
14717                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14718                                     (rt >> 2) & 0x7, imm << 2);
14719             }
14720             break;
14721         case OPC_BC1NEZ:
14722             check_cp1_enabled(ctx);
14723             check_insn(ctx, ISA_MIPS_R6);
14724             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
14725                                    rt, imm << 2, 4);
14726             break;
14727         case OPC_BC1ANY4:
14728             check_cp1_enabled(ctx);
14729             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14730             check_cop1x(ctx);
14731             if (!ase_3d_available(env)) {
14732                 return false;
14733             }
14734             /* fall through */
14735         case OPC_BC1:
14736             check_cp1_enabled(ctx);
14737             check_insn_opc_removed(ctx, ISA_MIPS_R6);
14738             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
14739                                 (rt >> 2) & 0x7, imm << 2);
14740             break;
14741         case OPC_PS_FMT:
14742             check_ps(ctx);
14743             /* fall through */
14744         case OPC_S_FMT:
14745         case OPC_D_FMT:
14746             check_cp1_enabled(ctx);
14747             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
14748                        (imm >> 8) & 0x7);
14749             break;
14750         case OPC_W_FMT:
14751         case OPC_L_FMT:
14752         {
14753             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
14754             check_cp1_enabled(ctx);
14755             if (ctx->insn_flags & ISA_MIPS_R6) {
14756                 switch (r6_op) {
14757                 case R6_OPC_CMP_AF_S:
14758                 case R6_OPC_CMP_UN_S:
14759                 case R6_OPC_CMP_EQ_S:
14760                 case R6_OPC_CMP_UEQ_S:
14761                 case R6_OPC_CMP_LT_S:
14762                 case R6_OPC_CMP_ULT_S:
14763                 case R6_OPC_CMP_LE_S:
14764                 case R6_OPC_CMP_ULE_S:
14765                 case R6_OPC_CMP_SAF_S:
14766                 case R6_OPC_CMP_SUN_S:
14767                 case R6_OPC_CMP_SEQ_S:
14768                 case R6_OPC_CMP_SEUQ_S:
14769                 case R6_OPC_CMP_SLT_S:
14770                 case R6_OPC_CMP_SULT_S:
14771                 case R6_OPC_CMP_SLE_S:
14772                 case R6_OPC_CMP_SULE_S:
14773                 case R6_OPC_CMP_OR_S:
14774                 case R6_OPC_CMP_UNE_S:
14775                 case R6_OPC_CMP_NE_S:
14776                 case R6_OPC_CMP_SOR_S:
14777                 case R6_OPC_CMP_SUNE_S:
14778                 case R6_OPC_CMP_SNE_S:
14779                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
14780                     break;
14781                 case R6_OPC_CMP_AF_D:
14782                 case R6_OPC_CMP_UN_D:
14783                 case R6_OPC_CMP_EQ_D:
14784                 case R6_OPC_CMP_UEQ_D:
14785                 case R6_OPC_CMP_LT_D:
14786                 case R6_OPC_CMP_ULT_D:
14787                 case R6_OPC_CMP_LE_D:
14788                 case R6_OPC_CMP_ULE_D:
14789                 case R6_OPC_CMP_SAF_D:
14790                 case R6_OPC_CMP_SUN_D:
14791                 case R6_OPC_CMP_SEQ_D:
14792                 case R6_OPC_CMP_SEUQ_D:
14793                 case R6_OPC_CMP_SLT_D:
14794                 case R6_OPC_CMP_SULT_D:
14795                 case R6_OPC_CMP_SLE_D:
14796                 case R6_OPC_CMP_SULE_D:
14797                 case R6_OPC_CMP_OR_D:
14798                 case R6_OPC_CMP_UNE_D:
14799                 case R6_OPC_CMP_NE_D:
14800                 case R6_OPC_CMP_SOR_D:
14801                 case R6_OPC_CMP_SUNE_D:
14802                 case R6_OPC_CMP_SNE_D:
14803                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
14804                     break;
14805                 default:
14806                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
14807                                rt, rd, sa, (imm >> 8) & 0x7);
14808 
14809                     break;
14810                 }
14811             } else {
14812                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
14813                            (imm >> 8) & 0x7);
14814             }
14815             break;
14816         }
14817         default:
14818             MIPS_INVAL("cp1");
14819             gen_reserved_instruction(ctx);
14820             break;
14821         }
14822         break;
14823 
14824     /* Compact branches [R6] and COP2 [non-R6] */
14825     case OPC_BC: /* OPC_LWC2 */
14826     case OPC_BALC: /* OPC_SWC2 */
14827         if (ctx->insn_flags & ISA_MIPS_R6) {
14828             /* OPC_BC, OPC_BALC */
14829             gen_compute_compact_branch(ctx, op, 0, 0,
14830                                        sextract32(ctx->opcode << 2, 0, 28));
14831         } else if (ctx->insn_flags & ASE_LEXT) {
14832             gen_loongson_lswc2(ctx, rt, rs, rd);
14833         } else {
14834             /* OPC_LWC2, OPC_SWC2 */
14835             /* COP2: Not implemented. */
14836             generate_exception_err(ctx, EXCP_CpU, 2);
14837         }
14838         break;
14839     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
14840     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
14841         if (ctx->insn_flags & ISA_MIPS_R6) {
14842             if (rs != 0) {
14843                 /* OPC_BEQZC, OPC_BNEZC */
14844                 gen_compute_compact_branch(ctx, op, rs, 0,
14845                                            sextract32(ctx->opcode << 2, 0, 23));
14846             } else {
14847                 /* OPC_JIC, OPC_JIALC */
14848                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
14849             }
14850         } else if (ctx->insn_flags & ASE_LEXT) {
14851             gen_loongson_lsdc2(ctx, rt, rs, rd);
14852         } else {
14853             /* OPC_LWC2, OPC_SWC2 */
14854             /* COP2: Not implemented. */
14855             generate_exception_err(ctx, EXCP_CpU, 2);
14856         }
14857         break;
14858     case OPC_CP2:
14859         check_insn(ctx, ASE_LMMI);
14860         /* Note that these instructions use different fields.  */
14861         gen_loongson_multimedia(ctx, sa, rd, rt);
14862         break;
14863 
14864     case OPC_CP3:
14865         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14866             check_cp1_enabled(ctx);
14867             op1 = MASK_CP3(ctx->opcode);
14868             switch (op1) {
14869             case OPC_LUXC1:
14870             case OPC_SUXC1:
14871                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
14872                 /* Fallthrough */
14873             case OPC_LWXC1:
14874             case OPC_LDXC1:
14875             case OPC_SWXC1:
14876             case OPC_SDXC1:
14877                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14878                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
14879                 break;
14880             case OPC_PREFX:
14881                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14882                 /* Treat as NOP. */
14883                 break;
14884             case OPC_ALNV_PS:
14885                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
14886                 /* Fallthrough */
14887             case OPC_MADD_S:
14888             case OPC_MADD_D:
14889             case OPC_MADD_PS:
14890             case OPC_MSUB_S:
14891             case OPC_MSUB_D:
14892             case OPC_MSUB_PS:
14893             case OPC_NMADD_S:
14894             case OPC_NMADD_D:
14895             case OPC_NMADD_PS:
14896             case OPC_NMSUB_S:
14897             case OPC_NMSUB_D:
14898             case OPC_NMSUB_PS:
14899                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
14900                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
14901                 break;
14902             default:
14903                 MIPS_INVAL("cp3");
14904                 gen_reserved_instruction(ctx);
14905                 break;
14906             }
14907         } else {
14908             generate_exception_err(ctx, EXCP_CpU, 1);
14909         }
14910         break;
14911 
14912 #if defined(TARGET_MIPS64)
14913     /* MIPS64 opcodes */
14914     case OPC_LLD:
14915         if (ctx->insn_flags & INSN_R5900) {
14916             check_insn_opc_user_only(ctx, INSN_R5900);
14917         }
14918         /* fall through */
14919     case OPC_LDL:
14920     case OPC_LDR:
14921     case OPC_LWU:
14922     case OPC_LD:
14923         check_insn(ctx, ISA_MIPS3);
14924         check_mips_64(ctx);
14925         gen_ld(ctx, op, rt, rs, imm);
14926         break;
14927     case OPC_SDL:
14928     case OPC_SDR:
14929     case OPC_SD:
14930         check_insn(ctx, ISA_MIPS3);
14931         check_mips_64(ctx);
14932         gen_st(ctx, op, rt, rs, imm);
14933         break;
14934     case OPC_SCD:
14935         check_insn(ctx, ISA_MIPS3);
14936         if (ctx->insn_flags & INSN_R5900) {
14937             check_insn_opc_user_only(ctx, INSN_R5900);
14938         }
14939         check_mips_64(ctx);
14940         gen_st_cond(ctx, rt, rs, imm, mo_endian(ctx) | MO_UQ, false);
14941         break;
14942     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
14943         if (ctx->insn_flags & ISA_MIPS_R6) {
14944             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
14945             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14946         } else {
14947             /* OPC_DADDI */
14948             check_insn(ctx, ISA_MIPS3);
14949             check_mips_64(ctx);
14950             gen_arith_imm(ctx, op, rt, rs, imm);
14951         }
14952         break;
14953     case OPC_DADDIU:
14954         check_insn(ctx, ISA_MIPS3);
14955         check_mips_64(ctx);
14956         gen_arith_imm(ctx, op, rt, rs, imm);
14957         break;
14958 #else
14959     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
14960         if (ctx->insn_flags & ISA_MIPS_R6) {
14961             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14962         } else {
14963             MIPS_INVAL("major opcode");
14964             gen_reserved_instruction(ctx);
14965         }
14966         break;
14967 #endif
14968     case OPC_DAUI: /* OPC_JALX */
14969         if (ctx->insn_flags & ISA_MIPS_R6) {
14970 #if defined(TARGET_MIPS64)
14971             /* OPC_DAUI */
14972             check_mips_64(ctx);
14973             if (rs == 0) {
14974                 generate_exception(ctx, EXCP_RI);
14975             } else if (rt != 0) {
14976                 TCGv t0 = tcg_temp_new();
14977                 gen_load_gpr(t0, rs);
14978                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
14979             }
14980 #else
14981             gen_reserved_instruction(ctx);
14982             MIPS_INVAL("major opcode");
14983 #endif
14984         } else {
14985             /* OPC_JALX */
14986             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
14987             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14988             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14989         }
14990         break;
14991     case OPC_MDMX:
14992         /* MDMX: Not implemented. */
14993         break;
14994     case OPC_PCREL:
14995         check_insn(ctx, ISA_MIPS_R6);
14996         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
14997         break;
14998     default:            /* Invalid */
14999         MIPS_INVAL("major opcode");
15000         return false;
15001     }
15002     return true;
15003 }
15004 
decode_opc(CPUMIPSState * env,DisasContext * ctx)15005 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15006 {
15007     /* make sure instructions are on a word boundary */
15008     if (ctx->base.pc_next & 0x3) {
15009         env->CP0_BadVAddr = ctx->base.pc_next;
15010         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15011         return;
15012     }
15013 
15014     /* Handle blikely not taken case */
15015     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15016         TCGLabel *l1 = gen_new_label();
15017 
15018         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15019         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15020         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15021         gen_set_label(l1);
15022     }
15023 
15024     /* Transition to the auto-generated decoder.  */
15025 
15026     /* Vendor specific extensions */
15027     if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15028         return;
15029     }
15030     if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15031         return;
15032     }
15033     if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) {
15034         return;
15035     }
15036 #if defined(TARGET_MIPS64)
15037     if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
15038         return;
15039     }
15040     if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15041         return;
15042     }
15043 #endif
15044 
15045     /* ISA extensions */
15046     if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15047         return;
15048     }
15049 
15050     /* ISA (from latest to oldest) */
15051     if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15052         return;
15053     }
15054 
15055     if (decode_opc_legacy(env, ctx)) {
15056         return;
15057     }
15058 
15059     gen_reserved_instruction(ctx);
15060 }
15061 
mips_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)15062 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15063 {
15064     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15065     CPUMIPSState *env = cpu_env(cs);
15066 
15067     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15068     ctx->saved_pc = -1;
15069     ctx->insn_flags = env->insn_flags;
15070     ctx->CP0_Config0 = env->CP0_Config0;
15071     ctx->CP0_Config1 = env->CP0_Config1;
15072     ctx->CP0_Config2 = env->CP0_Config2;
15073     ctx->CP0_Config3 = env->CP0_Config3;
15074     ctx->CP0_Config5 = env->CP0_Config5;
15075     ctx->btarget = 0;
15076     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15077     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15078     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15079     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15080     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15081     ctx->PAMask = env->PAMask;
15082     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15083     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15084     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15085     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15086     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15087     /* Restore delay slot state from the tb context.  */
15088     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
15089     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15090     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15091              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15092     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15093     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15094     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15095     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15096     ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15097     ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15098     restore_cpu_state(env, ctx);
15099 #ifdef CONFIG_USER_ONLY
15100         ctx->mem_idx = MIPS_HFLAG_UM;
15101 #else
15102         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15103 #endif
15104     ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
15105                                   (ctx->insn_flags & (ISA_MIPS_R6 |
15106                                   INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
15107 
15108     /*
15109      * Execute a branch and its delay slot as a single instruction.
15110      * This is what GDB expects and is consistent with what the
15111      * hardware does (e.g. if a delay slot instruction faults, the
15112      * reported PC is the PC of the branch).
15113      */
15114     if ((tb_cflags(ctx->base.tb) & CF_SINGLE_STEP) &&
15115         (ctx->hflags & MIPS_HFLAG_BMASK)) {
15116         ctx->base.max_insns = 2;
15117     }
15118 
15119     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
15120               ctx->hflags);
15121 }
15122 
mips_tr_tb_start(DisasContextBase * dcbase,CPUState * cs)15123 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
15124 {
15125 }
15126 
mips_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)15127 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
15128 {
15129     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15130 
15131     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
15132                        ctx->btarget);
15133 }
15134 
mips_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)15135 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
15136 {
15137     CPUMIPSState *env = cpu_env(cs);
15138     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15139     int insn_bytes;
15140     int is_slot;
15141 
15142     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
15143     if (ctx->insn_flags & ISA_NANOMIPS32) {
15144         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15145         insn_bytes = decode_isa_nanomips(env, ctx);
15146     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
15147         ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
15148         insn_bytes = 4;
15149         decode_opc(env, ctx);
15150     } else if (ctx->insn_flags & ASE_MICROMIPS) {
15151         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15152         insn_bytes = decode_isa_micromips(env, ctx);
15153     } else if (ctx->insn_flags & ASE_MIPS16) {
15154         ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15155         insn_bytes = decode_ase_mips16e(env, ctx);
15156     } else {
15157         gen_reserved_instruction(ctx);
15158         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
15159         return;
15160     }
15161 
15162     if (ctx->hflags & MIPS_HFLAG_BMASK) {
15163         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
15164                              MIPS_HFLAG_FBNSLOT))) {
15165             /*
15166              * Force to generate branch as there is neither delay nor
15167              * forbidden slot.
15168              */
15169             is_slot = 1;
15170         }
15171         if ((ctx->hflags & MIPS_HFLAG_M16) &&
15172             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
15173             /*
15174              * Force to generate branch as microMIPS R6 doesn't restrict
15175              * branches in the forbidden slot.
15176              */
15177             is_slot = 1;
15178         }
15179     }
15180     if (is_slot) {
15181         gen_branch(ctx, insn_bytes);
15182     }
15183     if (ctx->base.is_jmp == DISAS_SEMIHOST) {
15184         generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
15185     }
15186     ctx->base.pc_next += insn_bytes;
15187 
15188     if (ctx->base.is_jmp != DISAS_NEXT) {
15189         return;
15190     }
15191 
15192     /*
15193      * End the TB on (most) page crossings.
15194      * See mips_tr_init_disas_context about single-stepping a branch
15195      * together with its delay slot.
15196      */
15197     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
15198         && !(tb_cflags(ctx->base.tb) & CF_SINGLE_STEP)) {
15199         ctx->base.is_jmp = DISAS_TOO_MANY;
15200     }
15201 }
15202 
mips_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)15203 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
15204 {
15205     DisasContext *ctx = container_of(dcbase, DisasContext, base);
15206 
15207     switch (ctx->base.is_jmp) {
15208     case DISAS_STOP:
15209         gen_save_pc(ctx->base.pc_next);
15210         tcg_gen_lookup_and_goto_ptr();
15211         break;
15212     case DISAS_NEXT:
15213     case DISAS_TOO_MANY:
15214         save_cpu_state(ctx, 0);
15215         gen_goto_tb(ctx, 0, ctx->base.pc_next);
15216         break;
15217     case DISAS_EXIT:
15218         tcg_gen_exit_tb(NULL, 0);
15219         break;
15220     case DISAS_NORETURN:
15221         break;
15222     default:
15223         g_assert_not_reached();
15224     }
15225 }
15226 
15227 static const TranslatorOps mips_tr_ops = {
15228     .init_disas_context = mips_tr_init_disas_context,
15229     .tb_start           = mips_tr_tb_start,
15230     .insn_start         = mips_tr_insn_start,
15231     .translate_insn     = mips_tr_translate_insn,
15232     .tb_stop            = mips_tr_tb_stop,
15233 };
15234 
mips_translate_code(CPUState * cs,TranslationBlock * tb,int * max_insns,vaddr pc,void * host_pc)15235 void mips_translate_code(CPUState *cs, TranslationBlock *tb,
15236                          int *max_insns, vaddr pc, void *host_pc)
15237 {
15238     DisasContext ctx;
15239 
15240     translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
15241 }
15242 
mips_tcg_init(void)15243 void mips_tcg_init(void)
15244 {
15245     cpu_gpr[0] = NULL;
15246     for (unsigned i = 1; i < 32; i++)
15247         cpu_gpr[i] = tcg_global_mem_new(tcg_env,
15248                                         offsetof(CPUMIPSState,
15249                                                  active_tc.gpr[i]),
15250                                         regnames[i]);
15251 #if defined(TARGET_MIPS64)
15252     cpu_gpr_hi[0] = NULL;
15253 
15254     for (unsigned i = 1; i < 32; i++) {
15255         g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
15256 
15257         cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env,
15258                                                offsetof(CPUMIPSState,
15259                                                         active_tc.gpr_hi[i]),
15260                                                rname);
15261     }
15262 #endif /* !TARGET_MIPS64 */
15263     for (unsigned i = 0; i < 32; i++) {
15264         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
15265 
15266         fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]);
15267     }
15268     msa_translate_init();
15269     cpu_PC = tcg_global_mem_new(tcg_env,
15270                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
15271     for (unsigned i = 0; i < MIPS_DSP_ACC; i++) {
15272         cpu_HI[i] = tcg_global_mem_new(tcg_env,
15273                                        offsetof(CPUMIPSState, active_tc.HI[i]),
15274                                        regnames_HI[i]);
15275         cpu_LO[i] = tcg_global_mem_new(tcg_env,
15276                                        offsetof(CPUMIPSState, active_tc.LO[i]),
15277                                        regnames_LO[i]);
15278     }
15279     cpu_dspctrl = tcg_global_mem_new(tcg_env,
15280                                      offsetof(CPUMIPSState,
15281                                               active_tc.DSPControl),
15282                                      "DSPControl");
15283     bcond = tcg_global_mem_new(tcg_env,
15284                                offsetof(CPUMIPSState, bcond), "bcond");
15285     btarget = tcg_global_mem_new(tcg_env,
15286                                  offsetof(CPUMIPSState, btarget), "btarget");
15287     hflags = tcg_global_mem_new_i32(tcg_env,
15288                                     offsetof(CPUMIPSState, hflags), "hflags");
15289 
15290     fpu_fcr0 = tcg_global_mem_new_i32(tcg_env,
15291                                       offsetof(CPUMIPSState, active_fpu.fcr0),
15292                                       "fcr0");
15293     fpu_fcr31 = tcg_global_mem_new_i32(tcg_env,
15294                                        offsetof(CPUMIPSState, active_fpu.fcr31),
15295                                        "fcr31");
15296     cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr),
15297                                     "lladdr");
15298     cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval),
15299                                    "llval");
15300 
15301     if (TARGET_LONG_BITS == 32) {
15302         mxu_translate_init();
15303     }
15304 }
15305 
mips_restore_state_to_opc(CPUState * cs,const TranslationBlock * tb,const uint64_t * data)15306 void mips_restore_state_to_opc(CPUState *cs,
15307                                const TranslationBlock *tb,
15308                                const uint64_t *data)
15309 {
15310     CPUMIPSState *env = cpu_env(cs);
15311 
15312     env->active_tc.PC = data[0];
15313     env->hflags &= ~MIPS_HFLAG_BMASK;
15314     env->hflags |= data[1];
15315     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15316     case MIPS_HFLAG_BR:
15317         break;
15318     case MIPS_HFLAG_BC:
15319     case MIPS_HFLAG_BL:
15320     case MIPS_HFLAG_B:
15321         env->btarget = data[2];
15322         break;
15323     }
15324 }
15325