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