1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu/osdep.h"
25#include "cpu.h"
26#include "disas/disas.h"
27#include "tcg-op.h"
28#include "exec/cpu_ldst.h"
29
30#include "exec/helper-proto.h"
31#include "exec/helper-gen.h"
32#include "sysemu/kvm.h"
33#include "exec/semihost.h"
34
35#include "trace-tcg.h"
36#include "exec/log.h"
37
38#define MIPS_DEBUG_DISAS 0
39
40
41#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
42
43enum {
44
45 OPC_SPECIAL = (0x00 << 26),
46 OPC_REGIMM = (0x01 << 26),
47 OPC_CP0 = (0x10 << 26),
48 OPC_CP1 = (0x11 << 26),
49 OPC_CP2 = (0x12 << 26),
50 OPC_CP3 = (0x13 << 26),
51 OPC_SPECIAL2 = (0x1C << 26),
52 OPC_SPECIAL3 = (0x1F << 26),
53
54 OPC_ADDI = (0x08 << 26),
55 OPC_ADDIU = (0x09 << 26),
56 OPC_SLTI = (0x0A << 26),
57 OPC_SLTIU = (0x0B << 26),
58
59 OPC_ANDI = (0x0C << 26),
60 OPC_ORI = (0x0D << 26),
61 OPC_XORI = (0x0E << 26),
62 OPC_LUI = (0x0F << 26),
63
64 OPC_DADDI = (0x18 << 26),
65 OPC_DADDIU = (0x19 << 26),
66
67 OPC_J = (0x02 << 26),
68 OPC_JAL = (0x03 << 26),
69 OPC_BEQ = (0x04 << 26),
70 OPC_BEQL = (0x14 << 26),
71 OPC_BNE = (0x05 << 26),
72 OPC_BNEL = (0x15 << 26),
73 OPC_BLEZ = (0x06 << 26),
74 OPC_BLEZL = (0x16 << 26),
75 OPC_BGTZ = (0x07 << 26),
76 OPC_BGTZL = (0x17 << 26),
77 OPC_JALX = (0x1D << 26),
78 OPC_DAUI = (0x1D << 26),
79
80 OPC_LDL = (0x1A << 26),
81 OPC_LDR = (0x1B << 26),
82 OPC_LB = (0x20 << 26),
83 OPC_LH = (0x21 << 26),
84 OPC_LWL = (0x22 << 26),
85 OPC_LW = (0x23 << 26),
86 OPC_LWPC = OPC_LW | 0x5,
87 OPC_LBU = (0x24 << 26),
88 OPC_LHU = (0x25 << 26),
89 OPC_LWR = (0x26 << 26),
90 OPC_LWU = (0x27 << 26),
91 OPC_SB = (0x28 << 26),
92 OPC_SH = (0x29 << 26),
93 OPC_SWL = (0x2A << 26),
94 OPC_SW = (0x2B << 26),
95 OPC_SDL = (0x2C << 26),
96 OPC_SDR = (0x2D << 26),
97 OPC_SWR = (0x2E << 26),
98 OPC_LL = (0x30 << 26),
99 OPC_LLD = (0x34 << 26),
100 OPC_LD = (0x37 << 26),
101 OPC_LDPC = OPC_LD | 0x5,
102 OPC_SC = (0x38 << 26),
103 OPC_SCD = (0x3C << 26),
104 OPC_SD = (0x3F << 26),
105
106 OPC_LWC1 = (0x31 << 26),
107 OPC_LWC2 = (0x32 << 26),
108 OPC_LDC1 = (0x35 << 26),
109 OPC_LDC2 = (0x36 << 26),
110 OPC_SWC1 = (0x39 << 26),
111 OPC_SWC2 = (0x3A << 26),
112 OPC_SDC1 = (0x3D << 26),
113 OPC_SDC2 = (0x3E << 26),
114
115 OPC_BLEZALC = (0x06 << 26),
116 OPC_BGEZALC = (0x06 << 26),
117 OPC_BGEUC = (0x06 << 26),
118 OPC_BGTZALC = (0x07 << 26),
119 OPC_BLTZALC = (0x07 << 26),
120 OPC_BLTUC = (0x07 << 26),
121 OPC_BOVC = (0x08 << 26),
122 OPC_BEQZALC = (0x08 << 26),
123 OPC_BEQC = (0x08 << 26),
124 OPC_BLEZC = (0x16 << 26),
125 OPC_BGEZC = (0x16 << 26),
126 OPC_BGEC = (0x16 << 26),
127 OPC_BGTZC = (0x17 << 26),
128 OPC_BLTZC = (0x17 << 26),
129 OPC_BLTC = (0x17 << 26),
130 OPC_BNVC = (0x18 << 26),
131 OPC_BNEZALC = (0x18 << 26),
132 OPC_BNEC = (0x18 << 26),
133 OPC_BC = (0x32 << 26),
134 OPC_BEQZC = (0x36 << 26),
135 OPC_JIC = (0x36 << 26),
136 OPC_BALC = (0x3A << 26),
137 OPC_BNEZC = (0x3E << 26),
138 OPC_JIALC = (0x3E << 26),
139
140 OPC_MDMX = (0x1E << 26),
141
142 OPC_MSA = OPC_MDMX,
143
144 OPC_CACHE = (0x2F << 26),
145 OPC_PREF = (0x33 << 26),
146
147 OPC_PCREL = (0x3B << 26),
148};
149
150
151#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
152#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
153enum {
154
155 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
156 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
157 OPC_LWUPC = OPC_PCREL | (2 << 19),
158
159
160 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
161 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
162
163
164 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
165};
166
167
168#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
169
170enum {
171
172 OPC_SLL = 0x00 | OPC_SPECIAL,
173
174
175
176 OPC_SRL = 0x02 | OPC_SPECIAL,
177 OPC_ROTR = OPC_SRL | (1 << 21),
178 OPC_SRA = 0x03 | OPC_SPECIAL,
179 OPC_SLLV = 0x04 | OPC_SPECIAL,
180 OPC_SRLV = 0x06 | OPC_SPECIAL,
181 OPC_ROTRV = OPC_SRLV | (1 << 6),
182 OPC_SRAV = 0x07 | OPC_SPECIAL,
183 OPC_DSLLV = 0x14 | OPC_SPECIAL,
184 OPC_DSRLV = 0x16 | OPC_SPECIAL,
185 OPC_DROTRV = OPC_DSRLV | (1 << 6),
186 OPC_DSRAV = 0x17 | OPC_SPECIAL,
187 OPC_DSLL = 0x38 | OPC_SPECIAL,
188 OPC_DSRL = 0x3A | OPC_SPECIAL,
189 OPC_DROTR = OPC_DSRL | (1 << 21),
190 OPC_DSRA = 0x3B | OPC_SPECIAL,
191 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
192 OPC_DSRL32 = 0x3E | OPC_SPECIAL,
193 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
194 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
195
196 OPC_MULT = 0x18 | OPC_SPECIAL,
197 OPC_MULTU = 0x19 | OPC_SPECIAL,
198 OPC_DIV = 0x1A | OPC_SPECIAL,
199 OPC_DIVU = 0x1B | OPC_SPECIAL,
200 OPC_DMULT = 0x1C | OPC_SPECIAL,
201 OPC_DMULTU = 0x1D | OPC_SPECIAL,
202 OPC_DDIV = 0x1E | OPC_SPECIAL,
203 OPC_DDIVU = 0x1F | OPC_SPECIAL,
204
205
206 OPC_ADD = 0x20 | OPC_SPECIAL,
207 OPC_ADDU = 0x21 | OPC_SPECIAL,
208 OPC_SUB = 0x22 | OPC_SPECIAL,
209 OPC_SUBU = 0x23 | OPC_SPECIAL,
210 OPC_AND = 0x24 | OPC_SPECIAL,
211 OPC_OR = 0x25 | OPC_SPECIAL,
212 OPC_XOR = 0x26 | OPC_SPECIAL,
213 OPC_NOR = 0x27 | OPC_SPECIAL,
214 OPC_SLT = 0x2A | OPC_SPECIAL,
215 OPC_SLTU = 0x2B | OPC_SPECIAL,
216 OPC_DADD = 0x2C | OPC_SPECIAL,
217 OPC_DADDU = 0x2D | OPC_SPECIAL,
218 OPC_DSUB = 0x2E | OPC_SPECIAL,
219 OPC_DSUBU = 0x2F | OPC_SPECIAL,
220
221 OPC_JR = 0x08 | OPC_SPECIAL,
222 OPC_JALR = 0x09 | OPC_SPECIAL,
223
224 OPC_TGE = 0x30 | OPC_SPECIAL,
225 OPC_TGEU = 0x31 | OPC_SPECIAL,
226 OPC_TLT = 0x32 | OPC_SPECIAL,
227 OPC_TLTU = 0x33 | OPC_SPECIAL,
228 OPC_TEQ = 0x34 | OPC_SPECIAL,
229 OPC_TNE = 0x36 | OPC_SPECIAL,
230
231 OPC_MFHI = 0x10 | OPC_SPECIAL,
232 OPC_MTHI = 0x11 | OPC_SPECIAL,
233 OPC_MFLO = 0x12 | OPC_SPECIAL,
234 OPC_MTLO = 0x13 | OPC_SPECIAL,
235
236 OPC_MOVZ = 0x0A | OPC_SPECIAL,
237 OPC_MOVN = 0x0B | OPC_SPECIAL,
238
239 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
240 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
241
242 OPC_MOVCI = 0x01 | OPC_SPECIAL,
243
244
245 OPC_PMON = 0x05 | OPC_SPECIAL,
246 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
247 OPC_BREAK = 0x0D | OPC_SPECIAL,
248 OPC_SPIM = 0x0E | OPC_SPECIAL,
249 OPC_SYNC = 0x0F | OPC_SPECIAL,
250
251 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
252 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
253 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
254 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
255};
256
257
258
259#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
260
261enum {
262 R6_OPC_MUL = OPC_MULT | (2 << 6),
263 R6_OPC_MUH = OPC_MULT | (3 << 6),
264 R6_OPC_MULU = OPC_MULTU | (2 << 6),
265 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
266 R6_OPC_DIV = OPC_DIV | (2 << 6),
267 R6_OPC_MOD = OPC_DIV | (3 << 6),
268 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
269 R6_OPC_MODU = OPC_DIVU | (3 << 6),
270
271 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
272 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
273 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
274 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
275 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
276 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
277 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
278 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
279
280 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
281 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
282 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
283 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
284 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
285
286 OPC_LSA = 0x05 | OPC_SPECIAL,
287 OPC_DLSA = 0x15 | OPC_SPECIAL,
288};
289
290
291#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
292
293enum {
294 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
295 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
296 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
297 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
298 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
299 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
301 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
302 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
303 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
304 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
305 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
306 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
307 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
308};
309
310
311#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
312
313enum {
314 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
315 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
316 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
317 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
318 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
319 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
320 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
321 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
322 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
323 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
324 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
325 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
326 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
327 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
328 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
329 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
330
331 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
332 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
333};
334
335
336#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
337
338enum {
339
340 OPC_MADD = 0x00 | OPC_SPECIAL2,
341 OPC_MADDU = 0x01 | OPC_SPECIAL2,
342 OPC_MUL = 0x02 | OPC_SPECIAL2,
343 OPC_MSUB = 0x04 | OPC_SPECIAL2,
344 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
345
346 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
347 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
348 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
349 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
350 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
351 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
352 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
353 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
354 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
355 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
356 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
357 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
358
359 OPC_CLZ = 0x20 | OPC_SPECIAL2,
360 OPC_CLO = 0x21 | OPC_SPECIAL2,
361 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
362 OPC_DCLO = 0x25 | OPC_SPECIAL2,
363
364 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
365};
366
367
368#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
369
370enum {
371 OPC_EXT = 0x00 | OPC_SPECIAL3,
372 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
373 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
374 OPC_DEXT = 0x03 | OPC_SPECIAL3,
375 OPC_INS = 0x04 | OPC_SPECIAL3,
376 OPC_DINSM = 0x05 | OPC_SPECIAL3,
377 OPC_DINSU = 0x06 | OPC_SPECIAL3,
378 OPC_DINS = 0x07 | OPC_SPECIAL3,
379 OPC_FORK = 0x08 | OPC_SPECIAL3,
380 OPC_YIELD = 0x09 | OPC_SPECIAL3,
381 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
382 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
383 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
384
385
386 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
387 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
388 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
389 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
390 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
391 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
392 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
393 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
394 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
395 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
396 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
397 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
398
399
400 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
401
402 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
403 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
404 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
405 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
406
407
408 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
409 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
410
411 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
412 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
413
414
415
416 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
417 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
418
419 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
420 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
421
422 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
423 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
424
425 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
426 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
427
428
429 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
430 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
431 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
432 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
433 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
434 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
435};
436
437
438#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
439
440enum {
441 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
442 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
443 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
444 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL,
445 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL,
446 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL
447};
448
449
450#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
451
452enum {
453 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
454 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
455 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL,
456 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL,
457 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL,
458};
459
460
461enum {
462 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
463 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
464};
465
466#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
467
468enum {
469 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
470 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
471 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
472 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
473};
474
475#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
476enum {
477
478 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
492 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
493 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
494 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
495 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
496
497 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
503};
504
505#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
506#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507enum {
508
509 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
521
522 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
524 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
526};
527
528#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529enum {
530
531 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
544
545 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
550};
551
552#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553enum {
554
555 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
562
563 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
578};
579
580#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
581enum {
582
583 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
605};
606
607#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
608enum {
609
610 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
626 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
632};
633
634#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635enum {
636
637 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
638};
639
640#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641enum {
642
643 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
644 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
645 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
646};
647
648#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
649enum {
650
651 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
663 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
664 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
665 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
666 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
667 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
668};
669
670#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671enum {
672
673 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
690
691 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
697};
698
699#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700enum {
701
702 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
707
708 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
729};
730
731#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
732enum {
733
734 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
753
754 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
762};
763
764#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765enum {
766
767 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
768 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
769 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
770 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
771};
772
773#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
774enum {
775
776 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
777 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
797};
798
799#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
800enum {
801
802 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
803};
804
805#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
806enum {
807
808 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
834};
835
836#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837enum {
838
839 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
865};
866
867
868#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
869
870enum {
871 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
872 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
873 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
874 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
875 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
876 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
877 OPC_MFTR = (0x08 << 21) | OPC_CP0,
878 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
879 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
880 OPC_MTTR = (0x0C << 21) | OPC_CP0,
881 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
882 OPC_C0 = (0x10 << 21) | OPC_CP0,
883 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
884 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
885};
886
887
888#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
889
890enum {
891 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
892 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
894 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
895 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
896 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
897 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
898 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
899};
900
901
902#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
903
904enum {
905 OPC_TLBR = 0x01 | OPC_C0,
906 OPC_TLBWI = 0x02 | OPC_C0,
907 OPC_TLBINV = 0x03 | OPC_C0,
908 OPC_TLBINVF = 0x04 | OPC_C0,
909 OPC_TLBWR = 0x06 | OPC_C0,
910 OPC_TLBP = 0x08 | OPC_C0,
911 OPC_RFE = 0x10 | OPC_C0,
912 OPC_ERET = 0x18 | OPC_C0,
913 OPC_DERET = 0x1F | OPC_C0,
914 OPC_WAIT = 0x20 | OPC_C0,
915};
916
917
918#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
919
920
921enum {
922
923 FMT_S = 16,
924 FMT_D = 17,
925 FMT_E = 18,
926 FMT_Q = 19,
927 FMT_W = 20,
928 FMT_L = 21,
929 FMT_PS = 22,
930
931};
932
933enum {
934 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
935 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
936 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
937 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
938 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
939 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
940 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
941 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
942 OPC_BC1 = (0x08 << 21) | OPC_CP1,
943 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
944 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
945 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
946 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
947 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
948 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
949 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
950 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
951 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
952 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
953 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
954 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
955 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
956 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
957 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
958 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
959 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
960 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
961 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
962 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
963 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
964};
965
966#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
967#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
968
969enum {
970 OPC_BC1F = (0x00 << 16) | OPC_BC1,
971 OPC_BC1T = (0x01 << 16) | OPC_BC1,
972 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
973 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
974};
975
976enum {
977 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
978 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
979};
980
981enum {
982 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
983 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
984};
985
986#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
987
988enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1000};
1001
1002#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1013
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1022
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1031
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1040
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1047
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
1099#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1100
1101enum {
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
1117 OPC_NMADD_D = 0x31 | OPC_CP3,
1118 OPC_NMADD_PS= 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1122};
1123
1124
1125#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1126enum {
1127 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1128 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1129 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1130 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1131 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1132 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1133 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1134 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1135 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1136 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1137 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1138 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1139 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1140 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1141 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1142 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1143 OPC_MSA_ELM = 0x19 | OPC_MSA,
1144 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1145 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1146 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1147 OPC_MSA_VEC = 0x1E | OPC_MSA,
1148
1149
1150 OPC_LD_B = (0x20) | OPC_MSA,
1151 OPC_LD_H = (0x21) | OPC_MSA,
1152 OPC_LD_W = (0x22) | OPC_MSA,
1153 OPC_LD_D = (0x23) | OPC_MSA,
1154 OPC_ST_B = (0x24) | OPC_MSA,
1155 OPC_ST_H = (0x25) | OPC_MSA,
1156 OPC_ST_W = (0x26) | OPC_MSA,
1157 OPC_ST_D = (0x27) | OPC_MSA,
1158};
1159
1160enum {
1161
1162 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1163 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1164 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1165 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1166 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1167 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1168 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1169 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1170 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1171 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1172 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1173 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1174
1175
1176 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1177 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1179 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1180 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1181 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1182 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1183 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1184 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1185 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1186
1187
1188 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1189 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1190 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1191 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1192 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1193 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1194 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1195
1196 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1197 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1198
1199
1200 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1201 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1202 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1203 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1204
1205
1206 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1207 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1208 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1209 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1210 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1211 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1212 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1213 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1214 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1215 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1216 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1217 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1218 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1219 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1220 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1221 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1222
1223
1224 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1225 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1226 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1227 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1228 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1229 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1230 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1231 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1232 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1233 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1234 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1235 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1236 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1237 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1238 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1239 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1240 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1241 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1242 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1243 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1244 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1245 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1246 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1247 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1248 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1249 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1250 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1251 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1252 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1253 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1254 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1255 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1256 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1257 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1258 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1259 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1260 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1261 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1262 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1263 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1264 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1265 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1266 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1267 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1268 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1269 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1270 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1271 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1272 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1273 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1274 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1276 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1281 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1282 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1283 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1284 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1285 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1286 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1287
1288
1289 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1291 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1293 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1295 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1296 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298
1299
1300 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1301 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1302 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1307 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1310 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1312 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1313 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1315 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1316 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1317 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1318 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1320 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1322 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1323 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1324 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1326 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1327 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1328 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1329 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1332 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1335 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1336 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1337 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1338 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1339 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1340 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1341
1342
1343 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1344 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1345 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1346 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1347 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1348 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1349 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1350 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1351 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1352 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1353 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1354 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1355};
1356
1357
1358static TCGv_env cpu_env;
1359static TCGv cpu_gpr[32], cpu_PC;
1360static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1361static TCGv cpu_dspctrl, btarget, bcond;
1362static TCGv_i32 hflags;
1363static TCGv_i32 fpu_fcr0, fpu_fcr31;
1364static TCGv_i64 fpu_f64[32];
1365static TCGv_i64 msa_wr_d[64];
1366
1367#include "exec/gen-icount.h"
1368
1369#define gen_helper_0e0i(name, arg) do { \
1370 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1371 gen_helper_##name(cpu_env, helper_tmp); \
1372 tcg_temp_free_i32(helper_tmp); \
1373 } while(0)
1374
1375#define gen_helper_0e1i(name, arg1, arg2) do { \
1376 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1377 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1378 tcg_temp_free_i32(helper_tmp); \
1379 } while(0)
1380
1381#define gen_helper_1e0i(name, ret, arg1) do { \
1382 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1383 gen_helper_##name(ret, cpu_env, helper_tmp); \
1384 tcg_temp_free_i32(helper_tmp); \
1385 } while(0)
1386
1387#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1388 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1389 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1390 tcg_temp_free_i32(helper_tmp); \
1391 } while(0)
1392
1393#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1394 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1395 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1396 tcg_temp_free_i32(helper_tmp); \
1397 } while(0)
1398
1399#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1400 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1401 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1402 tcg_temp_free_i32(helper_tmp); \
1403 } while(0)
1404
1405#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1406 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1407 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1408 tcg_temp_free_i32(helper_tmp); \
1409 } while(0)
1410
1411typedef struct DisasContext {
1412 struct TranslationBlock *tb;
1413 target_ulong pc, saved_pc;
1414 uint32_t opcode;
1415 int singlestep_enabled;
1416 int insn_flags;
1417 int32_t CP0_Config1;
1418
1419 int mem_idx;
1420 TCGMemOp default_tcg_memop_mask;
1421 uint32_t hflags, saved_hflags;
1422 int bstate;
1423 target_ulong btarget;
1424 bool ulri;
1425 int kscrexist;
1426 bool rxi;
1427 int ie;
1428 bool bi;
1429 bool bp;
1430 uint64_t PAMask;
1431 bool mvh;
1432 int CP0_LLAddr_shift;
1433 bool ps;
1434 bool vp;
1435 bool cmgcr;
1436 bool mrp;
1437} DisasContext;
1438
1439enum {
1440 BS_NONE = 0,
1441
1442 BS_STOP = 1,
1443 BS_BRANCH = 2,
1444 BS_EXCP = 3,
1445};
1446
1447static const char * const regnames[] = {
1448 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1449 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1450 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1451 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1452};
1453
1454static const char * const regnames_HI[] = {
1455 "HI0", "HI1", "HI2", "HI3",
1456};
1457
1458static const char * const regnames_LO[] = {
1459 "LO0", "LO1", "LO2", "LO3",
1460};
1461
1462static const char * const fregnames[] = {
1463 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1464 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1465 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1466 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1467};
1468
1469static const char * const msaregnames[] = {
1470 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1471 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1472 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1473 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1474 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1475 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1476 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1477 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1478 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1479 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1480 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1481 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1482 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1483 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1484 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1485 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1486};
1487
1488#define LOG_DISAS(...) \
1489 do { \
1490 if (MIPS_DEBUG_DISAS) { \
1491 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1492 } \
1493 } while (0)
1494
1495#define MIPS_INVAL(op) \
1496 do { \
1497 if (MIPS_DEBUG_DISAS) { \
1498 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1499 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1500 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1501 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1502 } \
1503 } while (0)
1504
1505
1506static inline void gen_load_gpr (TCGv t, int reg)
1507{
1508 if (reg == 0)
1509 tcg_gen_movi_tl(t, 0);
1510 else
1511 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1512}
1513
1514static inline void gen_store_gpr (TCGv t, int reg)
1515{
1516 if (reg != 0)
1517 tcg_gen_mov_tl(cpu_gpr[reg], t);
1518}
1519
1520
1521static inline void gen_load_srsgpr (int from, int to)
1522{
1523 TCGv t0 = tcg_temp_new();
1524
1525 if (from == 0)
1526 tcg_gen_movi_tl(t0, 0);
1527 else {
1528 TCGv_i32 t2 = tcg_temp_new_i32();
1529 TCGv_ptr addr = tcg_temp_new_ptr();
1530
1531 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1532 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1533 tcg_gen_andi_i32(t2, t2, 0xf);
1534 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1535 tcg_gen_ext_i32_ptr(addr, t2);
1536 tcg_gen_add_ptr(addr, cpu_env, addr);
1537
1538 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1539 tcg_temp_free_ptr(addr);
1540 tcg_temp_free_i32(t2);
1541 }
1542 gen_store_gpr(t0, to);
1543 tcg_temp_free(t0);
1544}
1545
1546static inline void gen_store_srsgpr (int from, int to)
1547{
1548 if (to != 0) {
1549 TCGv t0 = tcg_temp_new();
1550 TCGv_i32 t2 = tcg_temp_new_i32();
1551 TCGv_ptr addr = tcg_temp_new_ptr();
1552
1553 gen_load_gpr(t0, from);
1554 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1555 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1556 tcg_gen_andi_i32(t2, t2, 0xf);
1557 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1558 tcg_gen_ext_i32_ptr(addr, t2);
1559 tcg_gen_add_ptr(addr, cpu_env, addr);
1560
1561 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1562 tcg_temp_free_ptr(addr);
1563 tcg_temp_free_i32(t2);
1564 tcg_temp_free(t0);
1565 }
1566}
1567
1568
1569static inline void gen_save_pc(target_ulong pc)
1570{
1571 tcg_gen_movi_tl(cpu_PC, pc);
1572}
1573
1574static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1575{
1576 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1577 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1578 gen_save_pc(ctx->pc);
1579 ctx->saved_pc = ctx->pc;
1580 }
1581 if (ctx->hflags != ctx->saved_hflags) {
1582 tcg_gen_movi_i32(hflags, ctx->hflags);
1583 ctx->saved_hflags = ctx->hflags;
1584 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1585 case MIPS_HFLAG_BR:
1586 break;
1587 case MIPS_HFLAG_BC:
1588 case MIPS_HFLAG_BL:
1589 case MIPS_HFLAG_B:
1590 tcg_gen_movi_tl(btarget, ctx->btarget);
1591 break;
1592 }
1593 }
1594}
1595
1596static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1597{
1598 ctx->saved_hflags = ctx->hflags;
1599 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1600 case MIPS_HFLAG_BR:
1601 break;
1602 case MIPS_HFLAG_BC:
1603 case MIPS_HFLAG_BL:
1604 case MIPS_HFLAG_B:
1605 ctx->btarget = env->btarget;
1606 break;
1607 }
1608}
1609
1610static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1611{
1612 TCGv_i32 texcp = tcg_const_i32(excp);
1613 TCGv_i32 terr = tcg_const_i32(err);
1614 save_cpu_state(ctx, 1);
1615 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1616 tcg_temp_free_i32(terr);
1617 tcg_temp_free_i32(texcp);
1618 ctx->bstate = BS_EXCP;
1619}
1620
1621static inline void generate_exception(DisasContext *ctx, int excp)
1622{
1623 gen_helper_0e0i(raise_exception, excp);
1624}
1625
1626static inline void generate_exception_end(DisasContext *ctx, int excp)
1627{
1628 generate_exception_err(ctx, excp, 0);
1629}
1630
1631
1632static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1633{
1634 if (ctx->hflags & MIPS_HFLAG_FRE) {
1635 generate_exception(ctx, EXCP_RI);
1636 }
1637 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1638}
1639
1640static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1641{
1642 TCGv_i64 t64;
1643 if (ctx->hflags & MIPS_HFLAG_FRE) {
1644 generate_exception(ctx, EXCP_RI);
1645 }
1646 t64 = tcg_temp_new_i64();
1647 tcg_gen_extu_i32_i64(t64, t);
1648 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1649 tcg_temp_free_i64(t64);
1650}
1651
1652static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1653{
1654 if (ctx->hflags & MIPS_HFLAG_F64) {
1655 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1656 } else {
1657 gen_load_fpr32(ctx, t, reg | 1);
1658 }
1659}
1660
1661static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1662{
1663 if (ctx->hflags & MIPS_HFLAG_F64) {
1664 TCGv_i64 t64 = tcg_temp_new_i64();
1665 tcg_gen_extu_i32_i64(t64, t);
1666 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1667 tcg_temp_free_i64(t64);
1668 } else {
1669 gen_store_fpr32(ctx, t, reg | 1);
1670 }
1671}
1672
1673static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1674{
1675 if (ctx->hflags & MIPS_HFLAG_F64) {
1676 tcg_gen_mov_i64(t, fpu_f64[reg]);
1677 } else {
1678 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1679 }
1680}
1681
1682static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1683{
1684 if (ctx->hflags & MIPS_HFLAG_F64) {
1685 tcg_gen_mov_i64(fpu_f64[reg], t);
1686 } else {
1687 TCGv_i64 t0;
1688 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1689 t0 = tcg_temp_new_i64();
1690 tcg_gen_shri_i64(t0, t, 32);
1691 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1692 tcg_temp_free_i64(t0);
1693 }
1694}
1695
1696static inline int get_fp_bit (int cc)
1697{
1698 if (cc)
1699 return 24 + cc;
1700 else
1701 return 23;
1702}
1703
1704
1705static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1706{
1707 tcg_gen_add_tl(ret, arg0, arg1);
1708
1709#if defined(TARGET_MIPS64)
1710 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1711 tcg_gen_ext32s_i64(ret, ret);
1712 }
1713#endif
1714}
1715
1716
1717static target_long addr_add(DisasContext *ctx, target_long base,
1718 target_long offset)
1719{
1720 target_long sum = base + offset;
1721
1722#if defined(TARGET_MIPS64)
1723 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1724 sum = (int32_t)sum;
1725 }
1726#endif
1727 return sum;
1728}
1729
1730
1731static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1732{
1733#if defined(TARGET_MIPS64)
1734 tcg_gen_ext32s_i64(ret, arg);
1735#else
1736 tcg_gen_extrl_i64_i32(ret, arg);
1737#endif
1738}
1739
1740
1741static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1742{
1743#if defined(TARGET_MIPS64)
1744 tcg_gen_sari_i64(ret, arg, 32);
1745#else
1746 tcg_gen_extrh_i64_i32(ret, arg);
1747#endif
1748}
1749
1750static inline void check_cp0_enabled(DisasContext *ctx)
1751{
1752 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1753 generate_exception_err(ctx, EXCP_CpU, 0);
1754}
1755
1756static inline void check_cp1_enabled(DisasContext *ctx)
1757{
1758 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1759 generate_exception_err(ctx, EXCP_CpU, 1);
1760}
1761
1762
1763
1764
1765
1766static inline void check_cop1x(DisasContext *ctx)
1767{
1768 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1769 generate_exception_end(ctx, EXCP_RI);
1770}
1771
1772
1773
1774
1775static inline void check_cp1_64bitmode(DisasContext *ctx)
1776{
1777 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1778 generate_exception_end(ctx, EXCP_RI);
1779}
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792static inline void check_cp1_registers(DisasContext *ctx, int regs)
1793{
1794 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1795 generate_exception_end(ctx, EXCP_RI);
1796}
1797
1798
1799
1800
1801
1802static inline void check_dsp(DisasContext *ctx)
1803{
1804 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1805 if (ctx->insn_flags & ASE_DSP) {
1806 generate_exception_end(ctx, EXCP_DSPDIS);
1807 } else {
1808 generate_exception_end(ctx, EXCP_RI);
1809 }
1810 }
1811}
1812
1813static inline void check_dspr2(DisasContext *ctx)
1814{
1815 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1816 if (ctx->insn_flags & ASE_DSP) {
1817 generate_exception_end(ctx, EXCP_DSPDIS);
1818 } else {
1819 generate_exception_end(ctx, EXCP_RI);
1820 }
1821 }
1822}
1823
1824
1825
1826static inline void check_insn(DisasContext *ctx, int flags)
1827{
1828 if (unlikely(!(ctx->insn_flags & flags))) {
1829 generate_exception_end(ctx, EXCP_RI);
1830 }
1831}
1832
1833
1834
1835
1836static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1837{
1838 if (unlikely(ctx->insn_flags & flags)) {
1839 generate_exception_end(ctx, EXCP_RI);
1840 }
1841}
1842
1843
1844
1845static inline void check_ps(DisasContext *ctx)
1846{
1847 if (unlikely(!ctx->ps)) {
1848 generate_exception(ctx, EXCP_RI);
1849 }
1850 check_cp1_64bitmode(ctx);
1851}
1852
1853#ifdef TARGET_MIPS64
1854
1855
1856static inline void check_mips_64(DisasContext *ctx)
1857{
1858 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1859 generate_exception_end(ctx, EXCP_RI);
1860}
1861#endif
1862
1863#ifndef CONFIG_USER_ONLY
1864static inline void check_mvh(DisasContext *ctx)
1865{
1866 if (unlikely(!ctx->mvh)) {
1867 generate_exception(ctx, EXCP_RI);
1868 }
1869}
1870#endif
1871
1872
1873
1874
1875
1876#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1877#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1878#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1879static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1880 int ft, int fs, int cc) \
1881{ \
1882 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1883 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1884 switch (ifmt) { \
1885 case FMT_PS: \
1886 check_ps(ctx); \
1887 break; \
1888 case FMT_D: \
1889 if (abs) { \
1890 check_cop1x(ctx); \
1891 } \
1892 check_cp1_registers(ctx, fs | ft); \
1893 break; \
1894 case FMT_S: \
1895 if (abs) { \
1896 check_cop1x(ctx); \
1897 } \
1898 break; \
1899 } \
1900 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1901 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1902 switch (n) { \
1903 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1904 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1905 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1906 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1907 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1908 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1909 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1910 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1911 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1912 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1913 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1914 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1915 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1916 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1917 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1918 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1919 default: abort(); \
1920 } \
1921 tcg_temp_free_i##bits (fp0); \
1922 tcg_temp_free_i##bits (fp1); \
1923}
1924
1925FOP_CONDS(, 0, d, FMT_D, 64)
1926FOP_CONDS(abs, 1, d, FMT_D, 64)
1927FOP_CONDS(, 0, s, FMT_S, 32)
1928FOP_CONDS(abs, 1, s, FMT_S, 32)
1929FOP_CONDS(, 0, ps, FMT_PS, 64)
1930FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1931#undef FOP_CONDS
1932
1933#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1934static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1935 int ft, int fs, int fd) \
1936{ \
1937 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1938 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1939 if (ifmt == FMT_D) { \
1940 check_cp1_registers(ctx, fs | ft | fd); \
1941 } \
1942 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1943 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1944 switch (n) { \
1945 case 0: \
1946 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1947 break; \
1948 case 1: \
1949 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1950 break; \
1951 case 2: \
1952 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1953 break; \
1954 case 3: \
1955 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1956 break; \
1957 case 4: \
1958 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1959 break; \
1960 case 5: \
1961 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1962 break; \
1963 case 6: \
1964 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1965 break; \
1966 case 7: \
1967 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1968 break; \
1969 case 8: \
1970 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1971 break; \
1972 case 9: \
1973 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1974 break; \
1975 case 10: \
1976 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1977 break; \
1978 case 11: \
1979 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1980 break; \
1981 case 12: \
1982 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1983 break; \
1984 case 13: \
1985 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1986 break; \
1987 case 14: \
1988 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1989 break; \
1990 case 15: \
1991 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1992 break; \
1993 case 17: \
1994 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1995 break; \
1996 case 18: \
1997 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1998 break; \
1999 case 19: \
2000 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2001 break; \
2002 case 25: \
2003 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2004 break; \
2005 case 26: \
2006 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2007 break; \
2008 case 27: \
2009 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2010 break; \
2011 default: \
2012 abort(); \
2013 } \
2014 STORE; \
2015 tcg_temp_free_i ## bits (fp0); \
2016 tcg_temp_free_i ## bits (fp1); \
2017}
2018
2019FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2020FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2021#undef FOP_CONDNS
2022#undef gen_ldcmp_fpr32
2023#undef gen_ldcmp_fpr64
2024
2025
2026#ifdef CONFIG_USER_ONLY
2027#define OP_LD_ATOMIC(insn,fname) \
2028static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2029{ \
2030 TCGv t0 = tcg_temp_new(); \
2031 tcg_gen_mov_tl(t0, arg1); \
2032 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2033 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2034 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2035 tcg_temp_free(t0); \
2036}
2037#else
2038#define OP_LD_ATOMIC(insn,fname) \
2039static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2040{ \
2041 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2042}
2043#endif
2044OP_LD_ATOMIC(ll,ld32s);
2045#if defined(TARGET_MIPS64)
2046OP_LD_ATOMIC(lld,ld64);
2047#endif
2048#undef OP_LD_ATOMIC
2049
2050#ifdef CONFIG_USER_ONLY
2051#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2052static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2053{ \
2054 TCGv t0 = tcg_temp_new(); \
2055 TCGLabel *l1 = gen_new_label(); \
2056 TCGLabel *l2 = gen_new_label(); \
2057 \
2058 tcg_gen_andi_tl(t0, arg2, almask); \
2059 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2060 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2061 generate_exception(ctx, EXCP_AdES); \
2062 gen_set_label(l1); \
2063 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2064 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2065 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2066 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2067 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2068 generate_exception_end(ctx, EXCP_SC); \
2069 gen_set_label(l2); \
2070 tcg_gen_movi_tl(t0, 0); \
2071 gen_store_gpr(t0, rt); \
2072 tcg_temp_free(t0); \
2073}
2074#else
2075#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2076static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2077{ \
2078 TCGv t0 = tcg_temp_new(); \
2079 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2080 gen_store_gpr(t0, rt); \
2081 tcg_temp_free(t0); \
2082}
2083#endif
2084OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2085#if defined(TARGET_MIPS64)
2086OP_ST_ATOMIC(scd,st64,ld64,0x7);
2087#endif
2088#undef OP_ST_ATOMIC
2089
2090static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2091 int base, int16_t offset)
2092{
2093 if (base == 0) {
2094 tcg_gen_movi_tl(addr, offset);
2095 } else if (offset == 0) {
2096 gen_load_gpr(addr, base);
2097 } else {
2098 tcg_gen_movi_tl(addr, offset);
2099 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2100 }
2101}
2102
2103static target_ulong pc_relative_pc (DisasContext *ctx)
2104{
2105 target_ulong pc = ctx->pc;
2106
2107 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2108 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2109
2110 pc -= branch_bytes;
2111 }
2112
2113 pc &= ~(target_ulong)3;
2114 return pc;
2115}
2116
2117
2118static void gen_ld(DisasContext *ctx, uint32_t opc,
2119 int rt, int base, int16_t offset)
2120{
2121 TCGv t0, t1, t2;
2122
2123 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2124
2125
2126
2127 return;
2128 }
2129
2130 t0 = tcg_temp_new();
2131 gen_base_offset_addr(ctx, t0, base, offset);
2132
2133 switch (opc) {
2134#if defined(TARGET_MIPS64)
2135 case OPC_LWU:
2136 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2137 ctx->default_tcg_memop_mask);
2138 gen_store_gpr(t0, rt);
2139 break;
2140 case OPC_LD:
2141 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2142 ctx->default_tcg_memop_mask);
2143 gen_store_gpr(t0, rt);
2144 break;
2145 case OPC_LLD:
2146 case R6_OPC_LLD:
2147 op_ld_lld(t0, t0, ctx);
2148 gen_store_gpr(t0, rt);
2149 break;
2150 case OPC_LDL:
2151 t1 = tcg_temp_new();
2152
2153
2154 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2155 tcg_gen_andi_tl(t1, t0, 7);
2156#ifndef TARGET_WORDS_BIGENDIAN
2157 tcg_gen_xori_tl(t1, t1, 7);
2158#endif
2159 tcg_gen_shli_tl(t1, t1, 3);
2160 tcg_gen_andi_tl(t0, t0, ~7);
2161 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2162 tcg_gen_shl_tl(t0, t0, t1);
2163 t2 = tcg_const_tl(-1);
2164 tcg_gen_shl_tl(t2, t2, t1);
2165 gen_load_gpr(t1, rt);
2166 tcg_gen_andc_tl(t1, t1, t2);
2167 tcg_temp_free(t2);
2168 tcg_gen_or_tl(t0, t0, t1);
2169 tcg_temp_free(t1);
2170 gen_store_gpr(t0, rt);
2171 break;
2172 case OPC_LDR:
2173 t1 = tcg_temp_new();
2174
2175
2176 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2177 tcg_gen_andi_tl(t1, t0, 7);
2178#ifdef TARGET_WORDS_BIGENDIAN
2179 tcg_gen_xori_tl(t1, t1, 7);
2180#endif
2181 tcg_gen_shli_tl(t1, t1, 3);
2182 tcg_gen_andi_tl(t0, t0, ~7);
2183 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2184 tcg_gen_shr_tl(t0, t0, t1);
2185 tcg_gen_xori_tl(t1, t1, 63);
2186 t2 = tcg_const_tl(0xfffffffffffffffeull);
2187 tcg_gen_shl_tl(t2, t2, t1);
2188 gen_load_gpr(t1, rt);
2189 tcg_gen_and_tl(t1, t1, t2);
2190 tcg_temp_free(t2);
2191 tcg_gen_or_tl(t0, t0, t1);
2192 tcg_temp_free(t1);
2193 gen_store_gpr(t0, rt);
2194 break;
2195 case OPC_LDPC:
2196 t1 = tcg_const_tl(pc_relative_pc(ctx));
2197 gen_op_addr_add(ctx, t0, t0, t1);
2198 tcg_temp_free(t1);
2199 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2200 gen_store_gpr(t0, rt);
2201 break;
2202#endif
2203 case OPC_LWPC:
2204 t1 = tcg_const_tl(pc_relative_pc(ctx));
2205 gen_op_addr_add(ctx, t0, t0, t1);
2206 tcg_temp_free(t1);
2207 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2208 gen_store_gpr(t0, rt);
2209 break;
2210 case OPC_LW:
2211 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2212 ctx->default_tcg_memop_mask);
2213 gen_store_gpr(t0, rt);
2214 break;
2215 case OPC_LH:
2216 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2217 ctx->default_tcg_memop_mask);
2218 gen_store_gpr(t0, rt);
2219 break;
2220 case OPC_LHU:
2221 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2222 ctx->default_tcg_memop_mask);
2223 gen_store_gpr(t0, rt);
2224 break;
2225 case OPC_LB:
2226 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2227 gen_store_gpr(t0, rt);
2228 break;
2229 case OPC_LBU:
2230 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2231 gen_store_gpr(t0, rt);
2232 break;
2233 case OPC_LWL:
2234 t1 = tcg_temp_new();
2235
2236
2237 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2238 tcg_gen_andi_tl(t1, t0, 3);
2239#ifndef TARGET_WORDS_BIGENDIAN
2240 tcg_gen_xori_tl(t1, t1, 3);
2241#endif
2242 tcg_gen_shli_tl(t1, t1, 3);
2243 tcg_gen_andi_tl(t0, t0, ~3);
2244 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2245 tcg_gen_shl_tl(t0, t0, t1);
2246 t2 = tcg_const_tl(-1);
2247 tcg_gen_shl_tl(t2, t2, t1);
2248 gen_load_gpr(t1, rt);
2249 tcg_gen_andc_tl(t1, t1, t2);
2250 tcg_temp_free(t2);
2251 tcg_gen_or_tl(t0, t0, t1);
2252 tcg_temp_free(t1);
2253 tcg_gen_ext32s_tl(t0, t0);
2254 gen_store_gpr(t0, rt);
2255 break;
2256 case OPC_LWR:
2257 t1 = tcg_temp_new();
2258
2259
2260 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2261 tcg_gen_andi_tl(t1, t0, 3);
2262#ifdef TARGET_WORDS_BIGENDIAN
2263 tcg_gen_xori_tl(t1, t1, 3);
2264#endif
2265 tcg_gen_shli_tl(t1, t1, 3);
2266 tcg_gen_andi_tl(t0, t0, ~3);
2267 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2268 tcg_gen_shr_tl(t0, t0, t1);
2269 tcg_gen_xori_tl(t1, t1, 31);
2270 t2 = tcg_const_tl(0xfffffffeull);
2271 tcg_gen_shl_tl(t2, t2, t1);
2272 gen_load_gpr(t1, rt);
2273 tcg_gen_and_tl(t1, t1, t2);
2274 tcg_temp_free(t2);
2275 tcg_gen_or_tl(t0, t0, t1);
2276 tcg_temp_free(t1);
2277 tcg_gen_ext32s_tl(t0, t0);
2278 gen_store_gpr(t0, rt);
2279 break;
2280 case OPC_LL:
2281 case R6_OPC_LL:
2282 op_ld_ll(t0, t0, ctx);
2283 gen_store_gpr(t0, rt);
2284 break;
2285 }
2286 tcg_temp_free(t0);
2287}
2288
2289
2290static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2291 int base, int16_t offset)
2292{
2293 TCGv t0 = tcg_temp_new();
2294 TCGv t1 = tcg_temp_new();
2295
2296 gen_base_offset_addr(ctx, t0, base, offset);
2297 gen_load_gpr(t1, rt);
2298 switch (opc) {
2299#if defined(TARGET_MIPS64)
2300 case OPC_SD:
2301 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2302 ctx->default_tcg_memop_mask);
2303 break;
2304 case OPC_SDL:
2305 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2306 break;
2307 case OPC_SDR:
2308 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2309 break;
2310#endif
2311 case OPC_SW:
2312 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2313 ctx->default_tcg_memop_mask);
2314 break;
2315 case OPC_SH:
2316 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2317 ctx->default_tcg_memop_mask);
2318 break;
2319 case OPC_SB:
2320 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2321 break;
2322 case OPC_SWL:
2323 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2324 break;
2325 case OPC_SWR:
2326 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2327 break;
2328 }
2329 tcg_temp_free(t0);
2330 tcg_temp_free(t1);
2331}
2332
2333
2334
2335static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2336 int base, int16_t offset)
2337{
2338 TCGv t0, t1;
2339
2340#ifdef CONFIG_USER_ONLY
2341 t0 = tcg_temp_local_new();
2342 t1 = tcg_temp_local_new();
2343#else
2344 t0 = tcg_temp_new();
2345 t1 = tcg_temp_new();
2346#endif
2347 gen_base_offset_addr(ctx, t0, base, offset);
2348 gen_load_gpr(t1, rt);
2349 switch (opc) {
2350#if defined(TARGET_MIPS64)
2351 case OPC_SCD:
2352 case R6_OPC_SCD:
2353 op_st_scd(t1, t0, rt, ctx);
2354 break;
2355#endif
2356 case OPC_SC:
2357 case R6_OPC_SC:
2358 op_st_sc(t1, t0, rt, ctx);
2359 break;
2360 }
2361 tcg_temp_free(t1);
2362 tcg_temp_free(t0);
2363}
2364
2365
2366static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2367 int base, int16_t offset)
2368{
2369 TCGv t0 = tcg_temp_new();
2370
2371 gen_base_offset_addr(ctx, t0, base, offset);
2372
2373
2374 switch (opc) {
2375 case OPC_LWC1:
2376 {
2377 TCGv_i32 fp0 = tcg_temp_new_i32();
2378 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2379 ctx->default_tcg_memop_mask);
2380 gen_store_fpr32(ctx, fp0, ft);
2381 tcg_temp_free_i32(fp0);
2382 }
2383 break;
2384 case OPC_SWC1:
2385 {
2386 TCGv_i32 fp0 = tcg_temp_new_i32();
2387 gen_load_fpr32(ctx, fp0, ft);
2388 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2389 ctx->default_tcg_memop_mask);
2390 tcg_temp_free_i32(fp0);
2391 }
2392 break;
2393 case OPC_LDC1:
2394 {
2395 TCGv_i64 fp0 = tcg_temp_new_i64();
2396 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2397 ctx->default_tcg_memop_mask);
2398 gen_store_fpr64(ctx, fp0, ft);
2399 tcg_temp_free_i64(fp0);
2400 }
2401 break;
2402 case OPC_SDC1:
2403 {
2404 TCGv_i64 fp0 = tcg_temp_new_i64();
2405 gen_load_fpr64(ctx, fp0, ft);
2406 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2407 ctx->default_tcg_memop_mask);
2408 tcg_temp_free_i64(fp0);
2409 }
2410 break;
2411 default:
2412 MIPS_INVAL("flt_ldst");
2413 generate_exception_end(ctx, EXCP_RI);
2414 goto out;
2415 }
2416 out:
2417 tcg_temp_free(t0);
2418}
2419
2420static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2421 int rs, int16_t imm)
2422{
2423 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2424 check_cp1_enabled(ctx);
2425 switch (op) {
2426 case OPC_LDC1:
2427 case OPC_SDC1:
2428 check_insn(ctx, ISA_MIPS2);
2429
2430 default:
2431 gen_flt_ldst(ctx, op, rt, rs, imm);
2432 }
2433 } else {
2434 generate_exception_err(ctx, EXCP_CpU, 1);
2435 }
2436}
2437
2438
2439static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2440 int rt, int rs, int16_t imm)
2441{
2442 target_ulong uimm = (target_long)imm;
2443
2444 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2445
2446
2447 return;
2448 }
2449 switch (opc) {
2450 case OPC_ADDI:
2451 {
2452 TCGv t0 = tcg_temp_local_new();
2453 TCGv t1 = tcg_temp_new();
2454 TCGv t2 = tcg_temp_new();
2455 TCGLabel *l1 = gen_new_label();
2456
2457 gen_load_gpr(t1, rs);
2458 tcg_gen_addi_tl(t0, t1, uimm);
2459 tcg_gen_ext32s_tl(t0, t0);
2460
2461 tcg_gen_xori_tl(t1, t1, ~uimm);
2462 tcg_gen_xori_tl(t2, t0, uimm);
2463 tcg_gen_and_tl(t1, t1, t2);
2464 tcg_temp_free(t2);
2465 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2466 tcg_temp_free(t1);
2467
2468 generate_exception(ctx, EXCP_OVERFLOW);
2469 gen_set_label(l1);
2470 tcg_gen_ext32s_tl(t0, t0);
2471 gen_store_gpr(t0, rt);
2472 tcg_temp_free(t0);
2473 }
2474 break;
2475 case OPC_ADDIU:
2476 if (rs != 0) {
2477 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2478 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2479 } else {
2480 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2481 }
2482 break;
2483#if defined(TARGET_MIPS64)
2484 case OPC_DADDI:
2485 {
2486 TCGv t0 = tcg_temp_local_new();
2487 TCGv t1 = tcg_temp_new();
2488 TCGv t2 = tcg_temp_new();
2489 TCGLabel *l1 = gen_new_label();
2490
2491 gen_load_gpr(t1, rs);
2492 tcg_gen_addi_tl(t0, t1, uimm);
2493
2494 tcg_gen_xori_tl(t1, t1, ~uimm);
2495 tcg_gen_xori_tl(t2, t0, uimm);
2496 tcg_gen_and_tl(t1, t1, t2);
2497 tcg_temp_free(t2);
2498 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2499 tcg_temp_free(t1);
2500
2501 generate_exception(ctx, EXCP_OVERFLOW);
2502 gen_set_label(l1);
2503 gen_store_gpr(t0, rt);
2504 tcg_temp_free(t0);
2505 }
2506 break;
2507 case OPC_DADDIU:
2508 if (rs != 0) {
2509 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2510 } else {
2511 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2512 }
2513 break;
2514#endif
2515 }
2516}
2517
2518
2519static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2520 int rt, int rs, int16_t imm)
2521{
2522 target_ulong uimm;
2523
2524 if (rt == 0) {
2525
2526 return;
2527 }
2528 uimm = (uint16_t)imm;
2529 switch (opc) {
2530 case OPC_ANDI:
2531 if (likely(rs != 0))
2532 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2533 else
2534 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2535 break;
2536 case OPC_ORI:
2537 if (rs != 0)
2538 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2539 else
2540 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2541 break;
2542 case OPC_XORI:
2543 if (likely(rs != 0))
2544 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2545 else
2546 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2547 break;
2548 case OPC_LUI:
2549 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2550
2551 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2552 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2553 } else {
2554 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2555 }
2556 break;
2557
2558 default:
2559 break;
2560 }
2561}
2562
2563
2564static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2565 int rt, int rs, int16_t imm)
2566{
2567 target_ulong uimm = (target_long)imm;
2568 TCGv t0;
2569
2570 if (rt == 0) {
2571
2572 return;
2573 }
2574 t0 = tcg_temp_new();
2575 gen_load_gpr(t0, rs);
2576 switch (opc) {
2577 case OPC_SLTI:
2578 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2579 break;
2580 case OPC_SLTIU:
2581 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2582 break;
2583 }
2584 tcg_temp_free(t0);
2585}
2586
2587
2588static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2589 int rt, int rs, int16_t imm)
2590{
2591 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2592 TCGv t0;
2593
2594 if (rt == 0) {
2595
2596 return;
2597 }
2598
2599 t0 = tcg_temp_new();
2600 gen_load_gpr(t0, rs);
2601 switch (opc) {
2602 case OPC_SLL:
2603 tcg_gen_shli_tl(t0, t0, uimm);
2604 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2605 break;
2606 case OPC_SRA:
2607 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2608 break;
2609 case OPC_SRL:
2610 if (uimm != 0) {
2611 tcg_gen_ext32u_tl(t0, t0);
2612 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2613 } else {
2614 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2615 }
2616 break;
2617 case OPC_ROTR:
2618 if (uimm != 0) {
2619 TCGv_i32 t1 = tcg_temp_new_i32();
2620
2621 tcg_gen_trunc_tl_i32(t1, t0);
2622 tcg_gen_rotri_i32(t1, t1, uimm);
2623 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2624 tcg_temp_free_i32(t1);
2625 } else {
2626 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2627 }
2628 break;
2629#if defined(TARGET_MIPS64)
2630 case OPC_DSLL:
2631 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2632 break;
2633 case OPC_DSRA:
2634 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2635 break;
2636 case OPC_DSRL:
2637 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2638 break;
2639 case OPC_DROTR:
2640 if (uimm != 0) {
2641 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2642 } else {
2643 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2644 }
2645 break;
2646 case OPC_DSLL32:
2647 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2648 break;
2649 case OPC_DSRA32:
2650 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2651 break;
2652 case OPC_DSRL32:
2653 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2654 break;
2655 case OPC_DROTR32:
2656 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2657 break;
2658#endif
2659 }
2660 tcg_temp_free(t0);
2661}
2662
2663
2664static void gen_arith(DisasContext *ctx, uint32_t opc,
2665 int rd, int rs, int rt)
2666{
2667 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2668 && opc != OPC_DADD && opc != OPC_DSUB) {
2669
2670
2671 return;
2672 }
2673
2674 switch (opc) {
2675 case OPC_ADD:
2676 {
2677 TCGv t0 = tcg_temp_local_new();
2678 TCGv t1 = tcg_temp_new();
2679 TCGv t2 = tcg_temp_new();
2680 TCGLabel *l1 = gen_new_label();
2681
2682 gen_load_gpr(t1, rs);
2683 gen_load_gpr(t2, rt);
2684 tcg_gen_add_tl(t0, t1, t2);
2685 tcg_gen_ext32s_tl(t0, t0);
2686 tcg_gen_xor_tl(t1, t1, t2);
2687 tcg_gen_xor_tl(t2, t0, t2);
2688 tcg_gen_andc_tl(t1, t2, t1);
2689 tcg_temp_free(t2);
2690 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2691 tcg_temp_free(t1);
2692
2693 generate_exception(ctx, EXCP_OVERFLOW);
2694 gen_set_label(l1);
2695 gen_store_gpr(t0, rd);
2696 tcg_temp_free(t0);
2697 }
2698 break;
2699 case OPC_ADDU:
2700 if (rs != 0 && rt != 0) {
2701 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2702 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2703 } else if (rs == 0 && rt != 0) {
2704 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2705 } else if (rs != 0 && rt == 0) {
2706 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2707 } else {
2708 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2709 }
2710 break;
2711 case OPC_SUB:
2712 {
2713 TCGv t0 = tcg_temp_local_new();
2714 TCGv t1 = tcg_temp_new();
2715 TCGv t2 = tcg_temp_new();
2716 TCGLabel *l1 = gen_new_label();
2717
2718 gen_load_gpr(t1, rs);
2719 gen_load_gpr(t2, rt);
2720 tcg_gen_sub_tl(t0, t1, t2);
2721 tcg_gen_ext32s_tl(t0, t0);
2722 tcg_gen_xor_tl(t2, t1, t2);
2723 tcg_gen_xor_tl(t1, t0, t1);
2724 tcg_gen_and_tl(t1, t1, t2);
2725 tcg_temp_free(t2);
2726 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2727 tcg_temp_free(t1);
2728
2729 generate_exception(ctx, EXCP_OVERFLOW);
2730 gen_set_label(l1);
2731 gen_store_gpr(t0, rd);
2732 tcg_temp_free(t0);
2733 }
2734 break;
2735 case OPC_SUBU:
2736 if (rs != 0 && rt != 0) {
2737 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2739 } else if (rs == 0 && rt != 0) {
2740 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2741 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2742 } else if (rs != 0 && rt == 0) {
2743 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2744 } else {
2745 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2746 }
2747 break;
2748#if defined(TARGET_MIPS64)
2749 case OPC_DADD:
2750 {
2751 TCGv t0 = tcg_temp_local_new();
2752 TCGv t1 = tcg_temp_new();
2753 TCGv t2 = tcg_temp_new();
2754 TCGLabel *l1 = gen_new_label();
2755
2756 gen_load_gpr(t1, rs);
2757 gen_load_gpr(t2, rt);
2758 tcg_gen_add_tl(t0, t1, t2);
2759 tcg_gen_xor_tl(t1, t1, t2);
2760 tcg_gen_xor_tl(t2, t0, t2);
2761 tcg_gen_andc_tl(t1, t2, t1);
2762 tcg_temp_free(t2);
2763 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2764 tcg_temp_free(t1);
2765
2766 generate_exception(ctx, EXCP_OVERFLOW);
2767 gen_set_label(l1);
2768 gen_store_gpr(t0, rd);
2769 tcg_temp_free(t0);
2770 }
2771 break;
2772 case OPC_DADDU:
2773 if (rs != 0 && rt != 0) {
2774 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775 } else if (rs == 0 && rt != 0) {
2776 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2777 } else if (rs != 0 && rt == 0) {
2778 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2779 } else {
2780 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2781 }
2782 break;
2783 case OPC_DSUB:
2784 {
2785 TCGv t0 = tcg_temp_local_new();
2786 TCGv t1 = tcg_temp_new();
2787 TCGv t2 = tcg_temp_new();
2788 TCGLabel *l1 = gen_new_label();
2789
2790 gen_load_gpr(t1, rs);
2791 gen_load_gpr(t2, rt);
2792 tcg_gen_sub_tl(t0, t1, t2);
2793 tcg_gen_xor_tl(t2, t1, t2);
2794 tcg_gen_xor_tl(t1, t0, t1);
2795 tcg_gen_and_tl(t1, t1, t2);
2796 tcg_temp_free(t2);
2797 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2798 tcg_temp_free(t1);
2799
2800 generate_exception(ctx, EXCP_OVERFLOW);
2801 gen_set_label(l1);
2802 gen_store_gpr(t0, rd);
2803 tcg_temp_free(t0);
2804 }
2805 break;
2806 case OPC_DSUBU:
2807 if (rs != 0 && rt != 0) {
2808 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2809 } else if (rs == 0 && rt != 0) {
2810 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2811 } else if (rs != 0 && rt == 0) {
2812 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2813 } else {
2814 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2815 }
2816 break;
2817#endif
2818 case OPC_MUL:
2819 if (likely(rs != 0 && rt != 0)) {
2820 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2821 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2822 } else {
2823 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2824 }
2825 break;
2826 }
2827}
2828
2829
2830static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2831 int rd, int rs, int rt)
2832{
2833 TCGv t0, t1, t2;
2834
2835 if (rd == 0) {
2836
2837 return;
2838 }
2839
2840 t0 = tcg_temp_new();
2841 gen_load_gpr(t0, rt);
2842 t1 = tcg_const_tl(0);
2843 t2 = tcg_temp_new();
2844 gen_load_gpr(t2, rs);
2845 switch (opc) {
2846 case OPC_MOVN:
2847 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2848 break;
2849 case OPC_MOVZ:
2850 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2851 break;
2852 case OPC_SELNEZ:
2853 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2854 break;
2855 case OPC_SELEQZ:
2856 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2857 break;
2858 }
2859 tcg_temp_free(t2);
2860 tcg_temp_free(t1);
2861 tcg_temp_free(t0);
2862}
2863
2864
2865static void gen_logic(DisasContext *ctx, uint32_t opc,
2866 int rd, int rs, int rt)
2867{
2868 if (rd == 0) {
2869
2870 return;
2871 }
2872
2873 switch (opc) {
2874 case OPC_AND:
2875 if (likely(rs != 0 && rt != 0)) {
2876 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2877 } else {
2878 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2879 }
2880 break;
2881 case OPC_NOR:
2882 if (rs != 0 && rt != 0) {
2883 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2884 } else if (rs == 0 && rt != 0) {
2885 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2886 } else if (rs != 0 && rt == 0) {
2887 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2888 } else {
2889 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2890 }
2891 break;
2892 case OPC_OR:
2893 if (likely(rs != 0 && rt != 0)) {
2894 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2895 } else if (rs == 0 && rt != 0) {
2896 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2897 } else if (rs != 0 && rt == 0) {
2898 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2899 } else {
2900 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2901 }
2902 break;
2903 case OPC_XOR:
2904 if (likely(rs != 0 && rt != 0)) {
2905 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2906 } else if (rs == 0 && rt != 0) {
2907 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2908 } else if (rs != 0 && rt == 0) {
2909 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2910 } else {
2911 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2912 }
2913 break;
2914 }
2915}
2916
2917
2918static void gen_slt(DisasContext *ctx, uint32_t opc,
2919 int rd, int rs, int rt)
2920{
2921 TCGv t0, t1;
2922
2923 if (rd == 0) {
2924
2925 return;
2926 }
2927
2928 t0 = tcg_temp_new();
2929 t1 = tcg_temp_new();
2930 gen_load_gpr(t0, rs);
2931 gen_load_gpr(t1, rt);
2932 switch (opc) {
2933 case OPC_SLT:
2934 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2935 break;
2936 case OPC_SLTU:
2937 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2938 break;
2939 }
2940 tcg_temp_free(t0);
2941 tcg_temp_free(t1);
2942}
2943
2944
2945static void gen_shift(DisasContext *ctx, uint32_t opc,
2946 int rd, int rs, int rt)
2947{
2948 TCGv t0, t1;
2949
2950 if (rd == 0) {
2951
2952
2953 return;
2954 }
2955
2956 t0 = tcg_temp_new();
2957 t1 = tcg_temp_new();
2958 gen_load_gpr(t0, rs);
2959 gen_load_gpr(t1, rt);
2960 switch (opc) {
2961 case OPC_SLLV:
2962 tcg_gen_andi_tl(t0, t0, 0x1f);
2963 tcg_gen_shl_tl(t0, t1, t0);
2964 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2965 break;
2966 case OPC_SRAV:
2967 tcg_gen_andi_tl(t0, t0, 0x1f);
2968 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2969 break;
2970 case OPC_SRLV:
2971 tcg_gen_ext32u_tl(t1, t1);
2972 tcg_gen_andi_tl(t0, t0, 0x1f);
2973 tcg_gen_shr_tl(t0, t1, t0);
2974 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2975 break;
2976 case OPC_ROTRV:
2977 {
2978 TCGv_i32 t2 = tcg_temp_new_i32();
2979 TCGv_i32 t3 = tcg_temp_new_i32();
2980
2981 tcg_gen_trunc_tl_i32(t2, t0);
2982 tcg_gen_trunc_tl_i32(t3, t1);
2983 tcg_gen_andi_i32(t2, t2, 0x1f);
2984 tcg_gen_rotr_i32(t2, t3, t2);
2985 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2986 tcg_temp_free_i32(t2);
2987 tcg_temp_free_i32(t3);
2988 }
2989 break;
2990#if defined(TARGET_MIPS64)
2991 case OPC_DSLLV:
2992 tcg_gen_andi_tl(t0, t0, 0x3f);
2993 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2994 break;
2995 case OPC_DSRAV:
2996 tcg_gen_andi_tl(t0, t0, 0x3f);
2997 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2998 break;
2999 case OPC_DSRLV:
3000 tcg_gen_andi_tl(t0, t0, 0x3f);
3001 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3002 break;
3003 case OPC_DROTRV:
3004 tcg_gen_andi_tl(t0, t0, 0x3f);
3005 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3006 break;
3007#endif
3008 }
3009 tcg_temp_free(t0);
3010 tcg_temp_free(t1);
3011}
3012
3013
3014static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3015{
3016 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3017
3018 return;
3019 }
3020
3021 if (acc != 0) {
3022 check_dsp(ctx);
3023 }
3024
3025 switch (opc) {
3026 case OPC_MFHI:
3027#if defined(TARGET_MIPS64)
3028 if (acc != 0) {
3029 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3030 } else
3031#endif
3032 {
3033 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3034 }
3035 break;
3036 case OPC_MFLO:
3037#if defined(TARGET_MIPS64)
3038 if (acc != 0) {
3039 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3040 } else
3041#endif
3042 {
3043 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3044 }
3045 break;
3046 case OPC_MTHI:
3047 if (reg != 0) {
3048#if defined(TARGET_MIPS64)
3049 if (acc != 0) {
3050 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3051 } else
3052#endif
3053 {
3054 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3055 }
3056 } else {
3057 tcg_gen_movi_tl(cpu_HI[acc], 0);
3058 }
3059 break;
3060 case OPC_MTLO:
3061 if (reg != 0) {
3062#if defined(TARGET_MIPS64)
3063 if (acc != 0) {
3064 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3065 } else
3066#endif
3067 {
3068 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3069 }
3070 } else {
3071 tcg_gen_movi_tl(cpu_LO[acc], 0);
3072 }
3073 break;
3074 }
3075}
3076
3077static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3078 TCGMemOp memop)
3079{
3080 TCGv t0 = tcg_const_tl(addr);
3081 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3082 gen_store_gpr(t0, reg);
3083 tcg_temp_free(t0);
3084}
3085
3086static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3087 int rs)
3088{
3089 target_long offset;
3090 target_long addr;
3091
3092 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3093 case OPC_ADDIUPC:
3094 if (rs != 0) {
3095 offset = sextract32(ctx->opcode << 2, 0, 21);
3096 addr = addr_add(ctx, pc, offset);
3097 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3098 }
3099 break;
3100 case R6_OPC_LWPC:
3101 offset = sextract32(ctx->opcode << 2, 0, 21);
3102 addr = addr_add(ctx, pc, offset);
3103 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3104 break;
3105#if defined(TARGET_MIPS64)
3106 case OPC_LWUPC:
3107 check_mips_64(ctx);
3108 offset = sextract32(ctx->opcode << 2, 0, 21);
3109 addr = addr_add(ctx, pc, offset);
3110 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3111 break;
3112#endif
3113 default:
3114 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3115 case OPC_AUIPC:
3116 if (rs != 0) {
3117 offset = sextract32(ctx->opcode, 0, 16) << 16;
3118 addr = addr_add(ctx, pc, offset);
3119 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3120 }
3121 break;
3122 case OPC_ALUIPC:
3123 if (rs != 0) {
3124 offset = sextract32(ctx->opcode, 0, 16) << 16;
3125 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3126 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3127 }
3128 break;
3129#if defined(TARGET_MIPS64)
3130 case R6_OPC_LDPC:
3131 case R6_OPC_LDPC + (1 << 16):
3132 case R6_OPC_LDPC + (2 << 16):
3133 case R6_OPC_LDPC + (3 << 16):
3134 check_mips_64(ctx);
3135 offset = sextract32(ctx->opcode << 3, 0, 21);
3136 addr = addr_add(ctx, (pc & ~0x7), offset);
3137 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3138 break;
3139#endif
3140 default:
3141 MIPS_INVAL("OPC_PCREL");
3142 generate_exception_end(ctx, EXCP_RI);
3143 break;
3144 }
3145 break;
3146 }
3147}
3148
3149static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3150{
3151 TCGv t0, t1;
3152
3153 if (rd == 0) {
3154
3155 return;
3156 }
3157
3158 t0 = tcg_temp_new();
3159 t1 = tcg_temp_new();
3160
3161 gen_load_gpr(t0, rs);
3162 gen_load_gpr(t1, rt);
3163
3164 switch (opc) {
3165 case R6_OPC_DIV:
3166 {
3167 TCGv t2 = tcg_temp_new();
3168 TCGv t3 = tcg_temp_new();
3169 tcg_gen_ext32s_tl(t0, t0);
3170 tcg_gen_ext32s_tl(t1, t1);
3171 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3172 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3173 tcg_gen_and_tl(t2, t2, t3);
3174 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3175 tcg_gen_or_tl(t2, t2, t3);
3176 tcg_gen_movi_tl(t3, 0);
3177 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3178 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3179 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3180 tcg_temp_free(t3);
3181 tcg_temp_free(t2);
3182 }
3183 break;
3184 case R6_OPC_MOD:
3185 {
3186 TCGv t2 = tcg_temp_new();
3187 TCGv t3 = tcg_temp_new();
3188 tcg_gen_ext32s_tl(t0, t0);
3189 tcg_gen_ext32s_tl(t1, t1);
3190 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3191 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3192 tcg_gen_and_tl(t2, t2, t3);
3193 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3194 tcg_gen_or_tl(t2, t2, t3);
3195 tcg_gen_movi_tl(t3, 0);
3196 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3197 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3198 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3199 tcg_temp_free(t3);
3200 tcg_temp_free(t2);
3201 }
3202 break;
3203 case R6_OPC_DIVU:
3204 {
3205 TCGv t2 = tcg_const_tl(0);
3206 TCGv t3 = tcg_const_tl(1);
3207 tcg_gen_ext32u_tl(t0, t0);
3208 tcg_gen_ext32u_tl(t1, t1);
3209 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3210 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3211 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3212 tcg_temp_free(t3);
3213 tcg_temp_free(t2);
3214 }
3215 break;
3216 case R6_OPC_MODU:
3217 {
3218 TCGv t2 = tcg_const_tl(0);
3219 TCGv t3 = tcg_const_tl(1);
3220 tcg_gen_ext32u_tl(t0, t0);
3221 tcg_gen_ext32u_tl(t1, t1);
3222 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3223 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3224 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3225 tcg_temp_free(t3);
3226 tcg_temp_free(t2);
3227 }
3228 break;
3229 case R6_OPC_MUL:
3230 {
3231 TCGv_i32 t2 = tcg_temp_new_i32();
3232 TCGv_i32 t3 = tcg_temp_new_i32();
3233 tcg_gen_trunc_tl_i32(t2, t0);
3234 tcg_gen_trunc_tl_i32(t3, t1);
3235 tcg_gen_mul_i32(t2, t2, t3);
3236 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3237 tcg_temp_free_i32(t2);
3238 tcg_temp_free_i32(t3);
3239 }
3240 break;
3241 case R6_OPC_MUH:
3242 {
3243 TCGv_i32 t2 = tcg_temp_new_i32();
3244 TCGv_i32 t3 = tcg_temp_new_i32();
3245 tcg_gen_trunc_tl_i32(t2, t0);
3246 tcg_gen_trunc_tl_i32(t3, t1);
3247 tcg_gen_muls2_i32(t2, t3, t2, t3);
3248 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3249 tcg_temp_free_i32(t2);
3250 tcg_temp_free_i32(t3);
3251 }
3252 break;
3253 case R6_OPC_MULU:
3254 {
3255 TCGv_i32 t2 = tcg_temp_new_i32();
3256 TCGv_i32 t3 = tcg_temp_new_i32();
3257 tcg_gen_trunc_tl_i32(t2, t0);
3258 tcg_gen_trunc_tl_i32(t3, t1);
3259 tcg_gen_mul_i32(t2, t2, t3);
3260 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3261 tcg_temp_free_i32(t2);
3262 tcg_temp_free_i32(t3);
3263 }
3264 break;
3265 case R6_OPC_MUHU:
3266 {
3267 TCGv_i32 t2 = tcg_temp_new_i32();
3268 TCGv_i32 t3 = tcg_temp_new_i32();
3269 tcg_gen_trunc_tl_i32(t2, t0);
3270 tcg_gen_trunc_tl_i32(t3, t1);
3271 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3272 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3273 tcg_temp_free_i32(t2);
3274 tcg_temp_free_i32(t3);
3275 }
3276 break;
3277#if defined(TARGET_MIPS64)
3278 case R6_OPC_DDIV:
3279 {
3280 TCGv t2 = tcg_temp_new();
3281 TCGv t3 = tcg_temp_new();
3282 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3284 tcg_gen_and_tl(t2, t2, t3);
3285 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3286 tcg_gen_or_tl(t2, t2, t3);
3287 tcg_gen_movi_tl(t3, 0);
3288 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3289 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3290 tcg_temp_free(t3);
3291 tcg_temp_free(t2);
3292 }
3293 break;
3294 case R6_OPC_DMOD:
3295 {
3296 TCGv t2 = tcg_temp_new();
3297 TCGv t3 = tcg_temp_new();
3298 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3299 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3300 tcg_gen_and_tl(t2, t2, t3);
3301 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3302 tcg_gen_or_tl(t2, t2, t3);
3303 tcg_gen_movi_tl(t3, 0);
3304 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3305 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3306 tcg_temp_free(t3);
3307 tcg_temp_free(t2);
3308 }
3309 break;
3310 case R6_OPC_DDIVU:
3311 {
3312 TCGv t2 = tcg_const_tl(0);
3313 TCGv t3 = tcg_const_tl(1);
3314 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3315 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3316 tcg_temp_free(t3);
3317 tcg_temp_free(t2);
3318 }
3319 break;
3320 case R6_OPC_DMODU:
3321 {
3322 TCGv t2 = tcg_const_tl(0);
3323 TCGv t3 = tcg_const_tl(1);
3324 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3325 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3326 tcg_temp_free(t3);
3327 tcg_temp_free(t2);
3328 }
3329 break;
3330 case R6_OPC_DMUL:
3331 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3332 break;
3333 case R6_OPC_DMUH:
3334 {
3335 TCGv t2 = tcg_temp_new();
3336 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3337 tcg_temp_free(t2);
3338 }
3339 break;
3340 case R6_OPC_DMULU:
3341 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3342 break;
3343 case R6_OPC_DMUHU:
3344 {
3345 TCGv t2 = tcg_temp_new();
3346 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3347 tcg_temp_free(t2);
3348 }
3349 break;
3350#endif
3351 default:
3352 MIPS_INVAL("r6 mul/div");
3353 generate_exception_end(ctx, EXCP_RI);
3354 goto out;
3355 }
3356 out:
3357 tcg_temp_free(t0);
3358 tcg_temp_free(t1);
3359}
3360
3361static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3362 int acc, int rs, int rt)
3363{
3364 TCGv t0, t1;
3365
3366 t0 = tcg_temp_new();
3367 t1 = tcg_temp_new();
3368
3369 gen_load_gpr(t0, rs);
3370 gen_load_gpr(t1, rt);
3371
3372 if (acc != 0) {
3373 check_dsp(ctx);
3374 }
3375
3376 switch (opc) {
3377 case OPC_DIV:
3378 {
3379 TCGv t2 = tcg_temp_new();
3380 TCGv t3 = tcg_temp_new();
3381 tcg_gen_ext32s_tl(t0, t0);
3382 tcg_gen_ext32s_tl(t1, t1);
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3385 tcg_gen_and_tl(t2, t2, t3);
3386 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3387 tcg_gen_or_tl(t2, t2, t3);
3388 tcg_gen_movi_tl(t3, 0);
3389 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3390 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3391 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3392 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3393 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3394 tcg_temp_free(t3);
3395 tcg_temp_free(t2);
3396 }
3397 break;
3398 case OPC_DIVU:
3399 {
3400 TCGv t2 = tcg_const_tl(0);
3401 TCGv t3 = tcg_const_tl(1);
3402 tcg_gen_ext32u_tl(t0, t0);
3403 tcg_gen_ext32u_tl(t1, t1);
3404 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3405 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3406 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3407 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3408 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3409 tcg_temp_free(t3);
3410 tcg_temp_free(t2);
3411 }
3412 break;
3413 case OPC_MULT:
3414 {
3415 TCGv_i32 t2 = tcg_temp_new_i32();
3416 TCGv_i32 t3 = tcg_temp_new_i32();
3417 tcg_gen_trunc_tl_i32(t2, t0);
3418 tcg_gen_trunc_tl_i32(t3, t1);
3419 tcg_gen_muls2_i32(t2, t3, t2, t3);
3420 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3421 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3422 tcg_temp_free_i32(t2);
3423 tcg_temp_free_i32(t3);
3424 }
3425 break;
3426 case OPC_MULTU:
3427 {
3428 TCGv_i32 t2 = tcg_temp_new_i32();
3429 TCGv_i32 t3 = tcg_temp_new_i32();
3430 tcg_gen_trunc_tl_i32(t2, t0);
3431 tcg_gen_trunc_tl_i32(t3, t1);
3432 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3433 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3434 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3435 tcg_temp_free_i32(t2);
3436 tcg_temp_free_i32(t3);
3437 }
3438 break;
3439#if defined(TARGET_MIPS64)
3440 case OPC_DDIV:
3441 {
3442 TCGv t2 = tcg_temp_new();
3443 TCGv t3 = tcg_temp_new();
3444 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3445 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3446 tcg_gen_and_tl(t2, t2, t3);
3447 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3448 tcg_gen_or_tl(t2, t2, t3);
3449 tcg_gen_movi_tl(t3, 0);
3450 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3451 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3452 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3453 tcg_temp_free(t3);
3454 tcg_temp_free(t2);
3455 }
3456 break;
3457 case OPC_DDIVU:
3458 {
3459 TCGv t2 = tcg_const_tl(0);
3460 TCGv t3 = tcg_const_tl(1);
3461 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3462 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3463 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3464 tcg_temp_free(t3);
3465 tcg_temp_free(t2);
3466 }
3467 break;
3468 case OPC_DMULT:
3469 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3470 break;
3471 case OPC_DMULTU:
3472 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3473 break;
3474#endif
3475 case OPC_MADD:
3476 {
3477 TCGv_i64 t2 = tcg_temp_new_i64();
3478 TCGv_i64 t3 = tcg_temp_new_i64();
3479
3480 tcg_gen_ext_tl_i64(t2, t0);
3481 tcg_gen_ext_tl_i64(t3, t1);
3482 tcg_gen_mul_i64(t2, t2, t3);
3483 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3484 tcg_gen_add_i64(t2, t2, t3);
3485 tcg_temp_free_i64(t3);
3486 gen_move_low32(cpu_LO[acc], t2);
3487 gen_move_high32(cpu_HI[acc], t2);
3488 tcg_temp_free_i64(t2);
3489 }
3490 break;
3491 case OPC_MADDU:
3492 {
3493 TCGv_i64 t2 = tcg_temp_new_i64();
3494 TCGv_i64 t3 = tcg_temp_new_i64();
3495
3496 tcg_gen_ext32u_tl(t0, t0);
3497 tcg_gen_ext32u_tl(t1, t1);
3498 tcg_gen_extu_tl_i64(t2, t0);
3499 tcg_gen_extu_tl_i64(t3, t1);
3500 tcg_gen_mul_i64(t2, t2, t3);
3501 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3502 tcg_gen_add_i64(t2, t2, t3);
3503 tcg_temp_free_i64(t3);
3504 gen_move_low32(cpu_LO[acc], t2);
3505 gen_move_high32(cpu_HI[acc], t2);
3506 tcg_temp_free_i64(t2);
3507 }
3508 break;
3509 case OPC_MSUB:
3510 {
3511 TCGv_i64 t2 = tcg_temp_new_i64();
3512 TCGv_i64 t3 = tcg_temp_new_i64();
3513
3514 tcg_gen_ext_tl_i64(t2, t0);
3515 tcg_gen_ext_tl_i64(t3, t1);
3516 tcg_gen_mul_i64(t2, t2, t3);
3517 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3518 tcg_gen_sub_i64(t2, t3, t2);
3519 tcg_temp_free_i64(t3);
3520 gen_move_low32(cpu_LO[acc], t2);
3521 gen_move_high32(cpu_HI[acc], t2);
3522 tcg_temp_free_i64(t2);
3523 }
3524 break;
3525 case OPC_MSUBU:
3526 {
3527 TCGv_i64 t2 = tcg_temp_new_i64();
3528 TCGv_i64 t3 = tcg_temp_new_i64();
3529
3530 tcg_gen_ext32u_tl(t0, t0);
3531 tcg_gen_ext32u_tl(t1, t1);
3532 tcg_gen_extu_tl_i64(t2, t0);
3533 tcg_gen_extu_tl_i64(t3, t1);
3534 tcg_gen_mul_i64(t2, t2, t3);
3535 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3536 tcg_gen_sub_i64(t2, t3, t2);
3537 tcg_temp_free_i64(t3);
3538 gen_move_low32(cpu_LO[acc], t2);
3539 gen_move_high32(cpu_HI[acc], t2);
3540 tcg_temp_free_i64(t2);
3541 }
3542 break;
3543 default:
3544 MIPS_INVAL("mul/div");
3545 generate_exception_end(ctx, EXCP_RI);
3546 goto out;
3547 }
3548 out:
3549 tcg_temp_free(t0);
3550 tcg_temp_free(t1);
3551}
3552
3553static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3554 int rd, int rs, int rt)
3555{
3556 TCGv t0 = tcg_temp_new();
3557 TCGv t1 = tcg_temp_new();
3558
3559 gen_load_gpr(t0, rs);
3560 gen_load_gpr(t1, rt);
3561
3562 switch (opc) {
3563 case OPC_VR54XX_MULS:
3564 gen_helper_muls(t0, cpu_env, t0, t1);
3565 break;
3566 case OPC_VR54XX_MULSU:
3567 gen_helper_mulsu(t0, cpu_env, t0, t1);
3568 break;
3569 case OPC_VR54XX_MACC:
3570 gen_helper_macc(t0, cpu_env, t0, t1);
3571 break;
3572 case OPC_VR54XX_MACCU:
3573 gen_helper_maccu(t0, cpu_env, t0, t1);
3574 break;
3575 case OPC_VR54XX_MSAC:
3576 gen_helper_msac(t0, cpu_env, t0, t1);
3577 break;
3578 case OPC_VR54XX_MSACU:
3579 gen_helper_msacu(t0, cpu_env, t0, t1);
3580 break;
3581 case OPC_VR54XX_MULHI:
3582 gen_helper_mulhi(t0, cpu_env, t0, t1);
3583 break;
3584 case OPC_VR54XX_MULHIU:
3585 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3586 break;
3587 case OPC_VR54XX_MULSHI:
3588 gen_helper_mulshi(t0, cpu_env, t0, t1);
3589 break;
3590 case OPC_VR54XX_MULSHIU:
3591 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3592 break;
3593 case OPC_VR54XX_MACCHI:
3594 gen_helper_macchi(t0, cpu_env, t0, t1);
3595 break;
3596 case OPC_VR54XX_MACCHIU:
3597 gen_helper_macchiu(t0, cpu_env, t0, t1);
3598 break;
3599 case OPC_VR54XX_MSACHI:
3600 gen_helper_msachi(t0, cpu_env, t0, t1);
3601 break;
3602 case OPC_VR54XX_MSACHIU:
3603 gen_helper_msachiu(t0, cpu_env, t0, t1);
3604 break;
3605 default:
3606 MIPS_INVAL("mul vr54xx");
3607 generate_exception_end(ctx, EXCP_RI);
3608 goto out;
3609 }
3610 gen_store_gpr(t0, rd);
3611
3612 out:
3613 tcg_temp_free(t0);
3614 tcg_temp_free(t1);
3615}
3616
3617static void gen_cl (DisasContext *ctx, uint32_t opc,
3618 int rd, int rs)
3619{
3620 TCGv t0;
3621
3622 if (rd == 0) {
3623
3624 return;
3625 }
3626 t0 = tcg_temp_new();
3627 gen_load_gpr(t0, rs);
3628 switch (opc) {
3629 case OPC_CLO:
3630 case R6_OPC_CLO:
3631 gen_helper_clo(cpu_gpr[rd], t0);
3632 break;
3633 case OPC_CLZ:
3634 case R6_OPC_CLZ:
3635 gen_helper_clz(cpu_gpr[rd], t0);
3636 break;
3637#if defined(TARGET_MIPS64)
3638 case OPC_DCLO:
3639 case R6_OPC_DCLO:
3640 gen_helper_dclo(cpu_gpr[rd], t0);
3641 break;
3642 case OPC_DCLZ:
3643 case R6_OPC_DCLZ:
3644 gen_helper_dclz(cpu_gpr[rd], t0);
3645 break;
3646#endif
3647 }
3648 tcg_temp_free(t0);
3649}
3650
3651
3652static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3653 int rd, int rs, int rt)
3654{
3655 TCGv t0, t1;
3656
3657 if (rd == 0) {
3658
3659 return;
3660 }
3661
3662 switch (opc) {
3663 case OPC_MULT_G_2E:
3664 case OPC_MULT_G_2F:
3665 case OPC_MULTU_G_2E:
3666 case OPC_MULTU_G_2F:
3667#if defined(TARGET_MIPS64)
3668 case OPC_DMULT_G_2E:
3669 case OPC_DMULT_G_2F:
3670 case OPC_DMULTU_G_2E:
3671 case OPC_DMULTU_G_2F:
3672#endif
3673 t0 = tcg_temp_new();
3674 t1 = tcg_temp_new();
3675 break;
3676 default:
3677 t0 = tcg_temp_local_new();
3678 t1 = tcg_temp_local_new();
3679 break;
3680 }
3681
3682 gen_load_gpr(t0, rs);
3683 gen_load_gpr(t1, rt);
3684
3685 switch (opc) {
3686 case OPC_MULT_G_2E:
3687 case OPC_MULT_G_2F:
3688 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3689 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3690 break;
3691 case OPC_MULTU_G_2E:
3692 case OPC_MULTU_G_2F:
3693 tcg_gen_ext32u_tl(t0, t0);
3694 tcg_gen_ext32u_tl(t1, t1);
3695 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3696 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3697 break;
3698 case OPC_DIV_G_2E:
3699 case OPC_DIV_G_2F:
3700 {
3701 TCGLabel *l1 = gen_new_label();
3702 TCGLabel *l2 = gen_new_label();
3703 TCGLabel *l3 = gen_new_label();
3704 tcg_gen_ext32s_tl(t0, t0);
3705 tcg_gen_ext32s_tl(t1, t1);
3706 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3707 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3708 tcg_gen_br(l3);
3709 gen_set_label(l1);
3710 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3711 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3712 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3713 tcg_gen_br(l3);
3714 gen_set_label(l2);
3715 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3716 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3717 gen_set_label(l3);
3718 }
3719 break;
3720 case OPC_DIVU_G_2E:
3721 case OPC_DIVU_G_2F:
3722 {
3723 TCGLabel *l1 = gen_new_label();
3724 TCGLabel *l2 = gen_new_label();
3725 tcg_gen_ext32u_tl(t0, t0);
3726 tcg_gen_ext32u_tl(t1, t1);
3727 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3728 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3729 tcg_gen_br(l2);
3730 gen_set_label(l1);
3731 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3732 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3733 gen_set_label(l2);
3734 }
3735 break;
3736 case OPC_MOD_G_2E:
3737 case OPC_MOD_G_2F:
3738 {
3739 TCGLabel *l1 = gen_new_label();
3740 TCGLabel *l2 = gen_new_label();
3741 TCGLabel *l3 = gen_new_label();
3742 tcg_gen_ext32u_tl(t0, t0);
3743 tcg_gen_ext32u_tl(t1, t1);
3744 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3745 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3746 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3747 gen_set_label(l1);
3748 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3749 tcg_gen_br(l3);
3750 gen_set_label(l2);
3751 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3752 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3753 gen_set_label(l3);
3754 }
3755 break;
3756 case OPC_MODU_G_2E:
3757 case OPC_MODU_G_2F:
3758 {
3759 TCGLabel *l1 = gen_new_label();
3760 TCGLabel *l2 = gen_new_label();
3761 tcg_gen_ext32u_tl(t0, t0);
3762 tcg_gen_ext32u_tl(t1, t1);
3763 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3764 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3765 tcg_gen_br(l2);
3766 gen_set_label(l1);
3767 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3768 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3769 gen_set_label(l2);
3770 }
3771 break;
3772#if defined(TARGET_MIPS64)
3773 case OPC_DMULT_G_2E:
3774 case OPC_DMULT_G_2F:
3775 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3776 break;
3777 case OPC_DMULTU_G_2E:
3778 case OPC_DMULTU_G_2F:
3779 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3780 break;
3781 case OPC_DDIV_G_2E:
3782 case OPC_DDIV_G_2F:
3783 {
3784 TCGLabel *l1 = gen_new_label();
3785 TCGLabel *l2 = gen_new_label();
3786 TCGLabel *l3 = gen_new_label();
3787 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3788 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3789 tcg_gen_br(l3);
3790 gen_set_label(l1);
3791 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3792 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3793 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3794 tcg_gen_br(l3);
3795 gen_set_label(l2);
3796 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3797 gen_set_label(l3);
3798 }
3799 break;
3800 case OPC_DDIVU_G_2E:
3801 case OPC_DDIVU_G_2F:
3802 {
3803 TCGLabel *l1 = gen_new_label();
3804 TCGLabel *l2 = gen_new_label();
3805 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3806 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3807 tcg_gen_br(l2);
3808 gen_set_label(l1);
3809 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3810 gen_set_label(l2);
3811 }
3812 break;
3813 case OPC_DMOD_G_2E:
3814 case OPC_DMOD_G_2F:
3815 {
3816 TCGLabel *l1 = gen_new_label();
3817 TCGLabel *l2 = gen_new_label();
3818 TCGLabel *l3 = gen_new_label();
3819 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3820 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3821 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3822 gen_set_label(l1);
3823 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3824 tcg_gen_br(l3);
3825 gen_set_label(l2);
3826 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3827 gen_set_label(l3);
3828 }
3829 break;
3830 case OPC_DMODU_G_2E:
3831 case OPC_DMODU_G_2F:
3832 {
3833 TCGLabel *l1 = gen_new_label();
3834 TCGLabel *l2 = gen_new_label();
3835 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3836 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3837 tcg_gen_br(l2);
3838 gen_set_label(l1);
3839 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3840 gen_set_label(l2);
3841 }
3842 break;
3843#endif
3844 }
3845
3846 tcg_temp_free(t0);
3847 tcg_temp_free(t1);
3848}
3849
3850
3851static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3852{
3853 uint32_t opc, shift_max;
3854 TCGv_i64 t0, t1;
3855
3856 opc = MASK_LMI(ctx->opcode);
3857 switch (opc) {
3858 case OPC_ADD_CP2:
3859 case OPC_SUB_CP2:
3860 case OPC_DADD_CP2:
3861 case OPC_DSUB_CP2:
3862 t0 = tcg_temp_local_new_i64();
3863 t1 = tcg_temp_local_new_i64();
3864 break;
3865 default:
3866 t0 = tcg_temp_new_i64();
3867 t1 = tcg_temp_new_i64();
3868 break;
3869 }
3870
3871 gen_load_fpr64(ctx, t0, rs);
3872 gen_load_fpr64(ctx, t1, rt);
3873
3874#define LMI_HELPER(UP, LO) \
3875 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3876#define LMI_HELPER_1(UP, LO) \
3877 case OPC_##UP: gen_helper_##LO(t0, t0); break
3878#define LMI_DIRECT(UP, LO, OP) \
3879 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3880
3881 switch (opc) {
3882 LMI_HELPER(PADDSH, paddsh);
3883 LMI_HELPER(PADDUSH, paddush);
3884 LMI_HELPER(PADDH, paddh);
3885 LMI_HELPER(PADDW, paddw);
3886 LMI_HELPER(PADDSB, paddsb);
3887 LMI_HELPER(PADDUSB, paddusb);
3888 LMI_HELPER(PADDB, paddb);
3889
3890 LMI_HELPER(PSUBSH, psubsh);
3891 LMI_HELPER(PSUBUSH, psubush);
3892 LMI_HELPER(PSUBH, psubh);
3893 LMI_HELPER(PSUBW, psubw);
3894 LMI_HELPER(PSUBSB, psubsb);
3895 LMI_HELPER(PSUBUSB, psubusb);
3896 LMI_HELPER(PSUBB, psubb);
3897
3898 LMI_HELPER(PSHUFH, pshufh);
3899 LMI_HELPER(PACKSSWH, packsswh);
3900 LMI_HELPER(PACKSSHB, packsshb);
3901 LMI_HELPER(PACKUSHB, packushb);
3902
3903 LMI_HELPER(PUNPCKLHW, punpcklhw);
3904 LMI_HELPER(PUNPCKHHW, punpckhhw);
3905 LMI_HELPER(PUNPCKLBH, punpcklbh);
3906 LMI_HELPER(PUNPCKHBH, punpckhbh);
3907 LMI_HELPER(PUNPCKLWD, punpcklwd);
3908 LMI_HELPER(PUNPCKHWD, punpckhwd);
3909
3910 LMI_HELPER(PAVGH, pavgh);
3911 LMI_HELPER(PAVGB, pavgb);
3912 LMI_HELPER(PMAXSH, pmaxsh);
3913 LMI_HELPER(PMINSH, pminsh);
3914 LMI_HELPER(PMAXUB, pmaxub);
3915 LMI_HELPER(PMINUB, pminub);
3916
3917 LMI_HELPER(PCMPEQW, pcmpeqw);
3918 LMI_HELPER(PCMPGTW, pcmpgtw);
3919 LMI_HELPER(PCMPEQH, pcmpeqh);
3920 LMI_HELPER(PCMPGTH, pcmpgth);
3921 LMI_HELPER(PCMPEQB, pcmpeqb);
3922 LMI_HELPER(PCMPGTB, pcmpgtb);
3923
3924 LMI_HELPER(PSLLW, psllw);
3925 LMI_HELPER(PSLLH, psllh);
3926 LMI_HELPER(PSRLW, psrlw);
3927 LMI_HELPER(PSRLH, psrlh);
3928 LMI_HELPER(PSRAW, psraw);
3929 LMI_HELPER(PSRAH, psrah);
3930
3931 LMI_HELPER(PMULLH, pmullh);
3932 LMI_HELPER(PMULHH, pmulhh);
3933 LMI_HELPER(PMULHUH, pmulhuh);
3934 LMI_HELPER(PMADDHW, pmaddhw);
3935
3936 LMI_HELPER(PASUBUB, pasubub);
3937 LMI_HELPER_1(BIADD, biadd);
3938 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3939
3940 LMI_DIRECT(PADDD, paddd, add);
3941 LMI_DIRECT(PSUBD, psubd, sub);
3942 LMI_DIRECT(XOR_CP2, xor, xor);
3943 LMI_DIRECT(NOR_CP2, nor, nor);
3944 LMI_DIRECT(AND_CP2, and, and);
3945 LMI_DIRECT(PANDN, pandn, andc);
3946 LMI_DIRECT(OR, or, or);
3947
3948 case OPC_PINSRH_0:
3949 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3950 break;
3951 case OPC_PINSRH_1:
3952 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3953 break;
3954 case OPC_PINSRH_2:
3955 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3956 break;
3957 case OPC_PINSRH_3:
3958 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3959 break;
3960
3961 case OPC_PEXTRH:
3962 tcg_gen_andi_i64(t1, t1, 3);
3963 tcg_gen_shli_i64(t1, t1, 4);
3964 tcg_gen_shr_i64(t0, t0, t1);
3965 tcg_gen_ext16u_i64(t0, t0);
3966 break;
3967
3968 case OPC_ADDU_CP2:
3969 tcg_gen_add_i64(t0, t0, t1);
3970 tcg_gen_ext32s_i64(t0, t0);
3971 break;
3972 case OPC_SUBU_CP2:
3973 tcg_gen_sub_i64(t0, t0, t1);
3974 tcg_gen_ext32s_i64(t0, t0);
3975 break;
3976
3977 case OPC_SLL_CP2:
3978 shift_max = 32;
3979 goto do_shift;
3980 case OPC_SRL_CP2:
3981 shift_max = 32;
3982 goto do_shift;
3983 case OPC_SRA_CP2:
3984 shift_max = 32;
3985 goto do_shift;
3986 case OPC_DSLL_CP2:
3987 shift_max = 64;
3988 goto do_shift;
3989 case OPC_DSRL_CP2:
3990 shift_max = 64;
3991 goto do_shift;
3992 case OPC_DSRA_CP2:
3993 shift_max = 64;
3994 goto do_shift;
3995 do_shift:
3996
3997 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3998
3999 switch (opc) {
4000 case OPC_SLL_CP2:
4001 case OPC_DSLL_CP2:
4002 tcg_gen_shl_i64(t0, t0, t1);
4003 break;
4004 case OPC_SRA_CP2:
4005 case OPC_DSRA_CP2:
4006
4007
4008 tcg_gen_sar_i64(t0, t0, t1);
4009 break;
4010 case OPC_SRL_CP2:
4011
4012 tcg_gen_ext32u_i64(t0, t0);
4013
4014 case OPC_DSRL_CP2:
4015 tcg_gen_shr_i64(t0, t0, t1);
4016 break;
4017 }
4018
4019 if (shift_max == 32) {
4020 tcg_gen_ext32s_i64(t0, t0);
4021 }
4022
4023
4024 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4025 tcg_gen_neg_i64(t1, t1);
4026 tcg_gen_and_i64(t0, t0, t1);
4027 break;
4028
4029 case OPC_ADD_CP2:
4030 case OPC_DADD_CP2:
4031 {
4032 TCGv_i64 t2 = tcg_temp_new_i64();
4033 TCGLabel *lab = gen_new_label();
4034
4035 tcg_gen_mov_i64(t2, t0);
4036 tcg_gen_add_i64(t0, t1, t2);
4037 if (opc == OPC_ADD_CP2) {
4038 tcg_gen_ext32s_i64(t0, t0);
4039 }
4040 tcg_gen_xor_i64(t1, t1, t2);
4041 tcg_gen_xor_i64(t2, t2, t0);
4042 tcg_gen_andc_i64(t1, t2, t1);
4043 tcg_temp_free_i64(t2);
4044 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4045 generate_exception(ctx, EXCP_OVERFLOW);
4046 gen_set_label(lab);
4047 break;
4048 }
4049
4050 case OPC_SUB_CP2:
4051 case OPC_DSUB_CP2:
4052 {
4053 TCGv_i64 t2 = tcg_temp_new_i64();
4054 TCGLabel *lab = gen_new_label();
4055
4056 tcg_gen_mov_i64(t2, t0);
4057 tcg_gen_sub_i64(t0, t1, t2);
4058 if (opc == OPC_SUB_CP2) {
4059 tcg_gen_ext32s_i64(t0, t0);
4060 }
4061 tcg_gen_xor_i64(t1, t1, t2);
4062 tcg_gen_xor_i64(t2, t2, t0);
4063 tcg_gen_and_i64(t1, t1, t2);
4064 tcg_temp_free_i64(t2);
4065 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4066 generate_exception(ctx, EXCP_OVERFLOW);
4067 gen_set_label(lab);
4068 break;
4069 }
4070
4071 case OPC_PMULUW:
4072 tcg_gen_ext32u_i64(t0, t0);
4073 tcg_gen_ext32u_i64(t1, t1);
4074 tcg_gen_mul_i64(t0, t0, t1);
4075 break;
4076
4077 case OPC_SEQU_CP2:
4078 case OPC_SEQ_CP2:
4079 case OPC_SLTU_CP2:
4080 case OPC_SLT_CP2:
4081 case OPC_SLEU_CP2:
4082 case OPC_SLE_CP2:
4083
4084
4085 default:
4086 MIPS_INVAL("loongson_cp2");
4087 generate_exception_end(ctx, EXCP_RI);
4088 return;
4089 }
4090
4091#undef LMI_HELPER
4092#undef LMI_DIRECT
4093
4094 gen_store_fpr64(ctx, t0, rd);
4095
4096 tcg_temp_free_i64(t0);
4097 tcg_temp_free_i64(t1);
4098}
4099
4100
4101static void gen_trap (DisasContext *ctx, uint32_t opc,
4102 int rs, int rt, int16_t imm)
4103{
4104 int cond;
4105 TCGv t0 = tcg_temp_new();
4106 TCGv t1 = tcg_temp_new();
4107
4108 cond = 0;
4109
4110 switch (opc) {
4111 case OPC_TEQ:
4112 case OPC_TGE:
4113 case OPC_TGEU:
4114 case OPC_TLT:
4115 case OPC_TLTU:
4116 case OPC_TNE:
4117
4118 if (rs != rt) {
4119 gen_load_gpr(t0, rs);
4120 gen_load_gpr(t1, rt);
4121 cond = 1;
4122 }
4123 break;
4124 case OPC_TEQI:
4125 case OPC_TGEI:
4126 case OPC_TGEIU:
4127 case OPC_TLTI:
4128 case OPC_TLTIU:
4129 case OPC_TNEI:
4130
4131 if (rs != 0 || imm != 0) {
4132 gen_load_gpr(t0, rs);
4133 tcg_gen_movi_tl(t1, (int32_t)imm);
4134 cond = 1;
4135 }
4136 break;
4137 }
4138 if (cond == 0) {
4139 switch (opc) {
4140 case OPC_TEQ:
4141 case OPC_TEQI:
4142 case OPC_TGE:
4143 case OPC_TGEI:
4144 case OPC_TGEU:
4145 case OPC_TGEIU:
4146
4147 generate_exception_end(ctx, EXCP_TRAP);
4148 break;
4149 case OPC_TLT:
4150 case OPC_TLTI:
4151 case OPC_TLTU:
4152 case OPC_TLTIU:
4153 case OPC_TNE:
4154 case OPC_TNEI:
4155
4156 break;
4157 }
4158 } else {
4159 TCGLabel *l1 = gen_new_label();
4160
4161 switch (opc) {
4162 case OPC_TEQ:
4163 case OPC_TEQI:
4164 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4165 break;
4166 case OPC_TGE:
4167 case OPC_TGEI:
4168 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4169 break;
4170 case OPC_TGEU:
4171 case OPC_TGEIU:
4172 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4173 break;
4174 case OPC_TLT:
4175 case OPC_TLTI:
4176 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4177 break;
4178 case OPC_TLTU:
4179 case OPC_TLTIU:
4180 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4181 break;
4182 case OPC_TNE:
4183 case OPC_TNEI:
4184 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4185 break;
4186 }
4187 generate_exception(ctx, EXCP_TRAP);
4188 gen_set_label(l1);
4189 }
4190 tcg_temp_free(t0);
4191 tcg_temp_free(t1);
4192}
4193
4194static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4195{
4196 TranslationBlock *tb;
4197 tb = ctx->tb;
4198 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4199 likely(!ctx->singlestep_enabled)) {
4200 tcg_gen_goto_tb(n);
4201 gen_save_pc(dest);
4202 tcg_gen_exit_tb((uintptr_t)tb + n);
4203 } else {
4204 gen_save_pc(dest);
4205 if (ctx->singlestep_enabled) {
4206 save_cpu_state(ctx, 0);
4207 gen_helper_raise_exception_debug(cpu_env);
4208 }
4209 tcg_gen_exit_tb(0);
4210 }
4211}
4212
4213
4214static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4215 int insn_bytes,
4216 int rs, int rt, int32_t offset,
4217 int delayslot_size)
4218{
4219 target_ulong btgt = -1;
4220 int blink = 0;
4221 int bcond_compute = 0;
4222 TCGv t0 = tcg_temp_new();
4223 TCGv t1 = tcg_temp_new();
4224
4225 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4226#ifdef MIPS_DEBUG_DISAS
4227 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4228 TARGET_FMT_lx "\n", ctx->pc);
4229#endif
4230 generate_exception_end(ctx, EXCP_RI);
4231 goto out;
4232 }
4233
4234
4235 switch (opc) {
4236 case OPC_BEQ:
4237 case OPC_BEQL:
4238 case OPC_BNE:
4239 case OPC_BNEL:
4240
4241 if (rs != rt) {
4242 gen_load_gpr(t0, rs);
4243 gen_load_gpr(t1, rt);
4244 bcond_compute = 1;
4245 }
4246 btgt = ctx->pc + insn_bytes + offset;
4247 break;
4248 case OPC_BGEZ:
4249 case OPC_BGEZAL:
4250 case OPC_BGEZALL:
4251 case OPC_BGEZL:
4252 case OPC_BGTZ:
4253 case OPC_BGTZL:
4254 case OPC_BLEZ:
4255 case OPC_BLEZL:
4256 case OPC_BLTZ:
4257 case OPC_BLTZAL:
4258 case OPC_BLTZALL:
4259 case OPC_BLTZL:
4260
4261 if (rs != 0) {
4262 gen_load_gpr(t0, rs);
4263 bcond_compute = 1;
4264 }
4265 btgt = ctx->pc + insn_bytes + offset;
4266 break;
4267 case OPC_BPOSGE32:
4268#if defined(TARGET_MIPS64)
4269 case OPC_BPOSGE64:
4270 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4271#else
4272 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4273#endif
4274 bcond_compute = 1;
4275 btgt = ctx->pc + insn_bytes + offset;
4276 break;
4277 case OPC_J:
4278 case OPC_JAL:
4279 case OPC_JALX:
4280
4281 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4282 break;
4283 case OPC_JR:
4284 case OPC_JALR:
4285
4286 if (offset != 0 && offset != 16) {
4287
4288
4289 MIPS_INVAL("jump hint");
4290 generate_exception_end(ctx, EXCP_RI);
4291 goto out;
4292 }
4293 gen_load_gpr(btarget, rs);
4294 break;
4295 default:
4296 MIPS_INVAL("branch/jump");
4297 generate_exception_end(ctx, EXCP_RI);
4298 goto out;
4299 }
4300 if (bcond_compute == 0) {
4301
4302 switch (opc) {
4303 case OPC_BEQ:
4304 case OPC_BEQL:
4305 case OPC_BGEZ:
4306 case OPC_BGEZL:
4307 case OPC_BLEZ:
4308 case OPC_BLEZL:
4309
4310 ctx->hflags |= MIPS_HFLAG_B;
4311 break;
4312 case OPC_BGEZAL:
4313 case OPC_BGEZALL:
4314
4315 blink = 31;
4316 ctx->hflags |= MIPS_HFLAG_B;
4317 break;
4318 case OPC_BNE:
4319 case OPC_BGTZ:
4320 case OPC_BLTZ:
4321
4322 goto out;
4323 case OPC_BLTZAL:
4324
4325
4326 blink = 31;
4327 btgt = ctx->pc + insn_bytes + delayslot_size;
4328 ctx->hflags |= MIPS_HFLAG_B;
4329 break;
4330 case OPC_BLTZALL:
4331 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4332
4333 ctx->pc += 4;
4334 goto out;
4335 case OPC_BNEL:
4336 case OPC_BGTZL:
4337 case OPC_BLTZL:
4338
4339 ctx->pc += 4;
4340 goto out;
4341 case OPC_J:
4342 ctx->hflags |= MIPS_HFLAG_B;
4343 break;
4344 case OPC_JALX:
4345 ctx->hflags |= MIPS_HFLAG_BX;
4346
4347 case OPC_JAL:
4348 blink = 31;
4349 ctx->hflags |= MIPS_HFLAG_B;
4350 break;
4351 case OPC_JR:
4352 ctx->hflags |= MIPS_HFLAG_BR;
4353 break;
4354 case OPC_JALR:
4355 blink = rt;
4356 ctx->hflags |= MIPS_HFLAG_BR;
4357 break;
4358 default:
4359 MIPS_INVAL("branch/jump");
4360 generate_exception_end(ctx, EXCP_RI);
4361 goto out;
4362 }
4363 } else {
4364 switch (opc) {
4365 case OPC_BEQ:
4366 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4367 goto not_likely;
4368 case OPC_BEQL:
4369 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4370 goto likely;
4371 case OPC_BNE:
4372 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4373 goto not_likely;
4374 case OPC_BNEL:
4375 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4376 goto likely;
4377 case OPC_BGEZ:
4378 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4379 goto not_likely;
4380 case OPC_BGEZL:
4381 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4382 goto likely;
4383 case OPC_BGEZAL:
4384 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4385 blink = 31;
4386 goto not_likely;
4387 case OPC_BGEZALL:
4388 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4389 blink = 31;
4390 goto likely;
4391 case OPC_BGTZ:
4392 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4393 goto not_likely;
4394 case OPC_BGTZL:
4395 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4396 goto likely;
4397 case OPC_BLEZ:
4398 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4399 goto not_likely;
4400 case OPC_BLEZL:
4401 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4402 goto likely;
4403 case OPC_BLTZ:
4404 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4405 goto not_likely;
4406 case OPC_BLTZL:
4407 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4408 goto likely;
4409 case OPC_BPOSGE32:
4410 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4411 goto not_likely;
4412#if defined(TARGET_MIPS64)
4413 case OPC_BPOSGE64:
4414 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4415 goto not_likely;
4416#endif
4417 case OPC_BLTZAL:
4418 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4419 blink = 31;
4420 not_likely:
4421 ctx->hflags |= MIPS_HFLAG_BC;
4422 break;
4423 case OPC_BLTZALL:
4424 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4425 blink = 31;
4426 likely:
4427 ctx->hflags |= MIPS_HFLAG_BL;
4428 break;
4429 default:
4430 MIPS_INVAL("conditional branch/jump");
4431 generate_exception_end(ctx, EXCP_RI);
4432 goto out;
4433 }
4434 }
4435
4436 ctx->btarget = btgt;
4437
4438 switch (delayslot_size) {
4439 case 2:
4440 ctx->hflags |= MIPS_HFLAG_BDS16;
4441 break;
4442 case 4:
4443 ctx->hflags |= MIPS_HFLAG_BDS32;
4444 break;
4445 }
4446
4447 if (blink > 0) {
4448 int post_delay = insn_bytes + delayslot_size;
4449 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4450
4451 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4452 }
4453
4454 out:
4455 if (insn_bytes == 2)
4456 ctx->hflags |= MIPS_HFLAG_B16;
4457 tcg_temp_free(t0);
4458 tcg_temp_free(t1);
4459}
4460
4461
4462static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4463 int rs, int lsb, int msb)
4464{
4465 TCGv t0 = tcg_temp_new();
4466 TCGv t1 = tcg_temp_new();
4467
4468 gen_load_gpr(t1, rs);
4469 switch (opc) {
4470 case OPC_EXT:
4471 if (lsb + msb > 31) {
4472 goto fail;
4473 }
4474 tcg_gen_shri_tl(t0, t1, lsb);
4475 if (msb != 31) {
4476 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4477 } else {
4478 tcg_gen_ext32s_tl(t0, t0);
4479 }
4480 break;
4481#if defined(TARGET_MIPS64)
4482 case OPC_DEXTU:
4483 lsb += 32;
4484 goto do_dext;
4485 case OPC_DEXTM:
4486 msb += 32;
4487 goto do_dext;
4488 case OPC_DEXT:
4489 do_dext:
4490 if (lsb + msb > 63) {
4491 goto fail;
4492 }
4493 tcg_gen_shri_tl(t0, t1, lsb);
4494 if (msb != 63) {
4495 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4496 }
4497 break;
4498#endif
4499 case OPC_INS:
4500 if (lsb > msb) {
4501 goto fail;
4502 }
4503 gen_load_gpr(t0, rt);
4504 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4505 tcg_gen_ext32s_tl(t0, t0);
4506 break;
4507#if defined(TARGET_MIPS64)
4508 case OPC_DINSU:
4509 lsb += 32;
4510
4511 case OPC_DINSM:
4512 msb += 32;
4513
4514 case OPC_DINS:
4515 if (lsb > msb) {
4516 goto fail;
4517 }
4518 gen_load_gpr(t0, rt);
4519 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4520 break;
4521#endif
4522 default:
4523fail:
4524 MIPS_INVAL("bitops");
4525 generate_exception_end(ctx, EXCP_RI);
4526 tcg_temp_free(t0);
4527 tcg_temp_free(t1);
4528 return;
4529 }
4530 gen_store_gpr(t0, rt);
4531 tcg_temp_free(t0);
4532 tcg_temp_free(t1);
4533}
4534
4535static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4536{
4537 TCGv t0;
4538
4539 if (rd == 0) {
4540
4541 return;
4542 }
4543
4544 t0 = tcg_temp_new();
4545 gen_load_gpr(t0, rt);
4546 switch (op2) {
4547 case OPC_WSBH:
4548 {
4549 TCGv t1 = tcg_temp_new();
4550
4551 tcg_gen_shri_tl(t1, t0, 8);
4552 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4553 tcg_gen_shli_tl(t0, t0, 8);
4554 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4555 tcg_gen_or_tl(t0, t0, t1);
4556 tcg_temp_free(t1);
4557 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4558 }
4559 break;
4560 case OPC_SEB:
4561 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4562 break;
4563 case OPC_SEH:
4564 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4565 break;
4566#if defined(TARGET_MIPS64)
4567 case OPC_DSBH:
4568 {
4569 TCGv t1 = tcg_temp_new();
4570
4571 tcg_gen_shri_tl(t1, t0, 8);
4572 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4573 tcg_gen_shli_tl(t0, t0, 8);
4574 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4575 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4576 tcg_temp_free(t1);
4577 }
4578 break;
4579 case OPC_DSHD:
4580 {
4581 TCGv t1 = tcg_temp_new();
4582
4583 tcg_gen_shri_tl(t1, t0, 16);
4584 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4585 tcg_gen_shli_tl(t0, t0, 16);
4586 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4587 tcg_gen_or_tl(t0, t0, t1);
4588 tcg_gen_shri_tl(t1, t0, 32);
4589 tcg_gen_shli_tl(t0, t0, 32);
4590 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4591 tcg_temp_free(t1);
4592 }
4593 break;
4594#endif
4595 default:
4596 MIPS_INVAL("bsfhl");
4597 generate_exception_end(ctx, EXCP_RI);
4598 tcg_temp_free(t0);
4599 return;
4600 }
4601 tcg_temp_free(t0);
4602}
4603
4604static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4605 int imm2)
4606{
4607 TCGv t0;
4608 TCGv t1;
4609 if (rd == 0) {
4610
4611 return;
4612 }
4613 t0 = tcg_temp_new();
4614 t1 = tcg_temp_new();
4615 gen_load_gpr(t0, rs);
4616 gen_load_gpr(t1, rt);
4617 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4618 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4619 if (opc == OPC_LSA) {
4620 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4621 }
4622
4623 tcg_temp_free(t1);
4624 tcg_temp_free(t0);
4625
4626 return;
4627}
4628
4629static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4630 int bp)
4631{
4632 TCGv t0;
4633 if (rd == 0) {
4634
4635 return;
4636 }
4637 t0 = tcg_temp_new();
4638 gen_load_gpr(t0, rt);
4639 if (bp == 0) {
4640 switch (opc) {
4641 case OPC_ALIGN:
4642 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4643 break;
4644#if defined(TARGET_MIPS64)
4645 case OPC_DALIGN:
4646 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4647 break;
4648#endif
4649 }
4650 } else {
4651 TCGv t1 = tcg_temp_new();
4652 gen_load_gpr(t1, rs);
4653 switch (opc) {
4654 case OPC_ALIGN:
4655 {
4656 TCGv_i64 t2 = tcg_temp_new_i64();
4657 tcg_gen_concat_tl_i64(t2, t1, t0);
4658 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4659 gen_move_low32(cpu_gpr[rd], t2);
4660 tcg_temp_free_i64(t2);
4661 }
4662 break;
4663#if defined(TARGET_MIPS64)
4664 case OPC_DALIGN:
4665 tcg_gen_shli_tl(t0, t0, 8 * bp);
4666 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4667 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4668 break;
4669#endif
4670 }
4671 tcg_temp_free(t1);
4672 }
4673
4674 tcg_temp_free(t0);
4675}
4676
4677static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4678{
4679 TCGv t0;
4680 if (rd == 0) {
4681
4682 return;
4683 }
4684 t0 = tcg_temp_new();
4685 gen_load_gpr(t0, rt);
4686 switch (opc) {
4687 case OPC_BITSWAP:
4688 gen_helper_bitswap(cpu_gpr[rd], t0);
4689 break;
4690#if defined(TARGET_MIPS64)
4691 case OPC_DBITSWAP:
4692 gen_helper_dbitswap(cpu_gpr[rd], t0);
4693 break;
4694#endif
4695 }
4696 tcg_temp_free(t0);
4697}
4698
4699#ifndef CONFIG_USER_ONLY
4700
4701static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4702{
4703 TCGv_i64 t0 = tcg_temp_new_i64();
4704 TCGv_i64 t1 = tcg_temp_new_i64();
4705
4706 tcg_gen_ext_tl_i64(t0, arg);
4707 tcg_gen_ld_i64(t1, cpu_env, off);
4708#if defined(TARGET_MIPS64)
4709 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4710#else
4711 tcg_gen_concat32_i64(t1, t1, t0);
4712#endif
4713 tcg_gen_st_i64(t1, cpu_env, off);
4714 tcg_temp_free_i64(t1);
4715 tcg_temp_free_i64(t0);
4716}
4717
4718static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4719{
4720 TCGv_i64 t0 = tcg_temp_new_i64();
4721 TCGv_i64 t1 = tcg_temp_new_i64();
4722
4723 tcg_gen_ext_tl_i64(t0, arg);
4724 tcg_gen_ld_i64(t1, cpu_env, off);
4725 tcg_gen_concat32_i64(t1, t1, t0);
4726 tcg_gen_st_i64(t1, cpu_env, off);
4727 tcg_temp_free_i64(t1);
4728 tcg_temp_free_i64(t0);
4729}
4730
4731static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4732{
4733 TCGv_i64 t0 = tcg_temp_new_i64();
4734
4735 tcg_gen_ld_i64(t0, cpu_env, off);
4736#if defined(TARGET_MIPS64)
4737 tcg_gen_shri_i64(t0, t0, 30);
4738#else
4739 tcg_gen_shri_i64(t0, t0, 32);
4740#endif
4741 gen_move_low32(arg, t0);
4742 tcg_temp_free_i64(t0);
4743}
4744
4745static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4746{
4747 TCGv_i64 t0 = tcg_temp_new_i64();
4748
4749 tcg_gen_ld_i64(t0, cpu_env, off);
4750 tcg_gen_shri_i64(t0, t0, 32 + shift);
4751 gen_move_low32(arg, t0);
4752 tcg_temp_free_i64(t0);
4753}
4754
4755static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4756{
4757 TCGv_i32 t0 = tcg_temp_new_i32();
4758
4759 tcg_gen_ld_i32(t0, cpu_env, off);
4760 tcg_gen_ext_i32_tl(arg, t0);
4761 tcg_temp_free_i32(t0);
4762}
4763
4764static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4765{
4766 tcg_gen_ld_tl(arg, cpu_env, off);
4767 tcg_gen_ext32s_tl(arg, arg);
4768}
4769
4770static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4771{
4772 TCGv_i32 t0 = tcg_temp_new_i32();
4773
4774 tcg_gen_trunc_tl_i32(t0, arg);
4775 tcg_gen_st_i32(t0, cpu_env, off);
4776 tcg_temp_free_i32(t0);
4777}
4778
4779#define CP0_CHECK(c) \
4780 do { \
4781 if (!(c)) { \
4782 goto cp0_unimplemented; \
4783 } \
4784 } while (0)
4785
4786static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4787{
4788 const char *rn = "invalid";
4789
4790 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4791
4792 switch (reg) {
4793 case 2:
4794 switch (sel) {
4795 case 0:
4796 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4797 rn = "EntryLo0";
4798 break;
4799 default:
4800 goto cp0_unimplemented;
4801 }
4802 break;
4803 case 3:
4804 switch (sel) {
4805 case 0:
4806 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4807 rn = "EntryLo1";
4808 break;
4809 default:
4810 goto cp0_unimplemented;
4811 }
4812 break;
4813 case 17:
4814 switch (sel) {
4815 case 0:
4816 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4817 ctx->CP0_LLAddr_shift);
4818 rn = "LLAddr";
4819 break;
4820 case 1:
4821 CP0_CHECK(ctx->mrp);
4822 gen_helper_mfhc0_maar(arg, cpu_env);
4823 rn = "MAAR";
4824 break;
4825 default:
4826 goto cp0_unimplemented;
4827 }
4828 break;
4829 case 28:
4830 switch (sel) {
4831 case 0:
4832 case 2:
4833 case 4:
4834 case 6:
4835 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4836 rn = "TagLo";
4837 break;
4838 default:
4839 goto cp0_unimplemented;
4840 }
4841 break;
4842 default:
4843 goto cp0_unimplemented;
4844 }
4845
4846 (void)rn;
4847 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4848 return;
4849
4850cp0_unimplemented:
4851 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4852 tcg_gen_movi_tl(arg, 0);
4853}
4854
4855static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4856{
4857 const char *rn = "invalid";
4858 uint64_t mask = ctx->PAMask >> 36;
4859
4860 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4861
4862 switch (reg) {
4863 case 2:
4864 switch (sel) {
4865 case 0:
4866 tcg_gen_andi_tl(arg, arg, mask);
4867 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4868 rn = "EntryLo0";
4869 break;
4870 default:
4871 goto cp0_unimplemented;
4872 }
4873 break;
4874 case 3:
4875 switch (sel) {
4876 case 0:
4877 tcg_gen_andi_tl(arg, arg, mask);
4878 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4879 rn = "EntryLo1";
4880 break;
4881 default:
4882 goto cp0_unimplemented;
4883 }
4884 break;
4885 case 17:
4886 switch (sel) {
4887 case 0:
4888
4889
4890
4891
4892 rn = "LLAddr";
4893 break;
4894 case 1:
4895 CP0_CHECK(ctx->mrp);
4896 gen_helper_mthc0_maar(cpu_env, arg);
4897 rn = "MAAR";
4898 break;
4899 default:
4900 goto cp0_unimplemented;
4901 }
4902 break;
4903 case 28:
4904 switch (sel) {
4905 case 0:
4906 case 2:
4907 case 4:
4908 case 6:
4909 tcg_gen_andi_tl(arg, arg, mask);
4910 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4911 rn = "TagLo";
4912 break;
4913 default:
4914 goto cp0_unimplemented;
4915 }
4916 break;
4917 default:
4918 goto cp0_unimplemented;
4919 }
4920
4921 (void)rn;
4922cp0_unimplemented:
4923 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4924}
4925
4926static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4927{
4928 if (ctx->insn_flags & ISA_MIPS32R6) {
4929 tcg_gen_movi_tl(arg, 0);
4930 } else {
4931 tcg_gen_movi_tl(arg, ~0);
4932 }
4933}
4934
4935static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4936{
4937 const char *rn = "invalid";
4938
4939 if (sel != 0)
4940 check_insn(ctx, ISA_MIPS32);
4941
4942 switch (reg) {
4943 case 0:
4944 switch (sel) {
4945 case 0:
4946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4947 rn = "Index";
4948 break;
4949 case 1:
4950 CP0_CHECK(ctx->insn_flags & ASE_MT);
4951 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4952 rn = "MVPControl";
4953 break;
4954 case 2:
4955 CP0_CHECK(ctx->insn_flags & ASE_MT);
4956 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4957 rn = "MVPConf0";
4958 break;
4959 case 3:
4960 CP0_CHECK(ctx->insn_flags & ASE_MT);
4961 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4962 rn = "MVPConf1";
4963 break;
4964 case 4:
4965 CP0_CHECK(ctx->vp);
4966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4967 rn = "VPControl";
4968 break;
4969 default:
4970 goto cp0_unimplemented;
4971 }
4972 break;
4973 case 1:
4974 switch (sel) {
4975 case 0:
4976 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4977 gen_helper_mfc0_random(arg, cpu_env);
4978 rn = "Random";
4979 break;
4980 case 1:
4981 CP0_CHECK(ctx->insn_flags & ASE_MT);
4982 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4983 rn = "VPEControl";
4984 break;
4985 case 2:
4986 CP0_CHECK(ctx->insn_flags & ASE_MT);
4987 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4988 rn = "VPEConf0";
4989 break;
4990 case 3:
4991 CP0_CHECK(ctx->insn_flags & ASE_MT);
4992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4993 rn = "VPEConf1";
4994 break;
4995 case 4:
4996 CP0_CHECK(ctx->insn_flags & ASE_MT);
4997 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4998 rn = "YQMask";
4999 break;
5000 case 5:
5001 CP0_CHECK(ctx->insn_flags & ASE_MT);
5002 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5003 rn = "VPESchedule";
5004 break;
5005 case 6:
5006 CP0_CHECK(ctx->insn_flags & ASE_MT);
5007 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5008 rn = "VPEScheFBack";
5009 break;
5010 case 7:
5011 CP0_CHECK(ctx->insn_flags & ASE_MT);
5012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5013 rn = "VPEOpt";
5014 break;
5015 default:
5016 goto cp0_unimplemented;
5017 }
5018 break;
5019 case 2:
5020 switch (sel) {
5021 case 0:
5022 {
5023 TCGv_i64 tmp = tcg_temp_new_i64();
5024 tcg_gen_ld_i64(tmp, cpu_env,
5025 offsetof(CPUMIPSState, CP0_EntryLo0));
5026#if defined(TARGET_MIPS64)
5027 if (ctx->rxi) {
5028
5029 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5030 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5031 }
5032#endif
5033 gen_move_low32(arg, tmp);
5034 tcg_temp_free_i64(tmp);
5035 }
5036 rn = "EntryLo0";
5037 break;
5038 case 1:
5039 CP0_CHECK(ctx->insn_flags & ASE_MT);
5040 gen_helper_mfc0_tcstatus(arg, cpu_env);
5041 rn = "TCStatus";
5042 break;
5043 case 2:
5044 CP0_CHECK(ctx->insn_flags & ASE_MT);
5045 gen_helper_mfc0_tcbind(arg, cpu_env);
5046 rn = "TCBind";
5047 break;
5048 case 3:
5049 CP0_CHECK(ctx->insn_flags & ASE_MT);
5050 gen_helper_mfc0_tcrestart(arg, cpu_env);
5051 rn = "TCRestart";
5052 break;
5053 case 4:
5054 CP0_CHECK(ctx->insn_flags & ASE_MT);
5055 gen_helper_mfc0_tchalt(arg, cpu_env);
5056 rn = "TCHalt";
5057 break;
5058 case 5:
5059 CP0_CHECK(ctx->insn_flags & ASE_MT);
5060 gen_helper_mfc0_tccontext(arg, cpu_env);
5061 rn = "TCContext";
5062 break;
5063 case 6:
5064 CP0_CHECK(ctx->insn_flags & ASE_MT);
5065 gen_helper_mfc0_tcschedule(arg, cpu_env);
5066 rn = "TCSchedule";
5067 break;
5068 case 7:
5069 CP0_CHECK(ctx->insn_flags & ASE_MT);
5070 gen_helper_mfc0_tcschefback(arg, cpu_env);
5071 rn = "TCScheFBack";
5072 break;
5073 default:
5074 goto cp0_unimplemented;
5075 }
5076 break;
5077 case 3:
5078 switch (sel) {
5079 case 0:
5080 {
5081 TCGv_i64 tmp = tcg_temp_new_i64();
5082 tcg_gen_ld_i64(tmp, cpu_env,
5083 offsetof(CPUMIPSState, CP0_EntryLo1));
5084#if defined(TARGET_MIPS64)
5085 if (ctx->rxi) {
5086
5087 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5088 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5089 }
5090#endif
5091 gen_move_low32(arg, tmp);
5092 tcg_temp_free_i64(tmp);
5093 }
5094 rn = "EntryLo1";
5095 break;
5096 case 1:
5097 CP0_CHECK(ctx->vp);
5098 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5099 rn = "GlobalNumber";
5100 break;
5101 default:
5102 goto cp0_unimplemented;
5103 }
5104 break;
5105 case 4:
5106 switch (sel) {
5107 case 0:
5108 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5109 tcg_gen_ext32s_tl(arg, arg);
5110 rn = "Context";
5111 break;
5112 case 1:
5113
5114 rn = "ContextConfig";
5115 goto cp0_unimplemented;
5116
5117 case 2:
5118 CP0_CHECK(ctx->ulri);
5119 tcg_gen_ld32s_tl(arg, cpu_env,
5120 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5121 rn = "UserLocal";
5122 break;
5123 default:
5124 goto cp0_unimplemented;
5125 }
5126 break;
5127 case 5:
5128 switch (sel) {
5129 case 0:
5130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5131 rn = "PageMask";
5132 break;
5133 case 1:
5134 check_insn(ctx, ISA_MIPS32R2);
5135 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5136 rn = "PageGrain";
5137 break;
5138 default:
5139 goto cp0_unimplemented;
5140 }
5141 break;
5142 case 6:
5143 switch (sel) {
5144 case 0:
5145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5146 rn = "Wired";
5147 break;
5148 case 1:
5149 check_insn(ctx, ISA_MIPS32R2);
5150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5151 rn = "SRSConf0";
5152 break;
5153 case 2:
5154 check_insn(ctx, ISA_MIPS32R2);
5155 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5156 rn = "SRSConf1";
5157 break;
5158 case 3:
5159 check_insn(ctx, ISA_MIPS32R2);
5160 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5161 rn = "SRSConf2";
5162 break;
5163 case 4:
5164 check_insn(ctx, ISA_MIPS32R2);
5165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5166 rn = "SRSConf3";
5167 break;
5168 case 5:
5169 check_insn(ctx, ISA_MIPS32R2);
5170 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5171 rn = "SRSConf4";
5172 break;
5173 default:
5174 goto cp0_unimplemented;
5175 }
5176 break;
5177 case 7:
5178 switch (sel) {
5179 case 0:
5180 check_insn(ctx, ISA_MIPS32R2);
5181 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5182 rn = "HWREna";
5183 break;
5184 default:
5185 goto cp0_unimplemented;
5186 }
5187 break;
5188 case 8:
5189 switch (sel) {
5190 case 0:
5191 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5192 tcg_gen_ext32s_tl(arg, arg);
5193 rn = "BadVAddr";
5194 break;
5195 case 1:
5196 CP0_CHECK(ctx->bi);
5197 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5198 rn = "BadInstr";
5199 break;
5200 case 2:
5201 CP0_CHECK(ctx->bp);
5202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5203 rn = "BadInstrP";
5204 break;
5205 default:
5206 goto cp0_unimplemented;
5207 }
5208 break;
5209 case 9:
5210 switch (sel) {
5211 case 0:
5212
5213 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5214 gen_io_start();
5215 }
5216 gen_helper_mfc0_count(arg, cpu_env);
5217 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5218 gen_io_end();
5219 }
5220
5221
5222 ctx->bstate = BS_STOP;
5223 rn = "Count";
5224 break;
5225
5226 default:
5227 goto cp0_unimplemented;
5228 }
5229 break;
5230 case 10:
5231 switch (sel) {
5232 case 0:
5233 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5234 tcg_gen_ext32s_tl(arg, arg);
5235 rn = "EntryHi";
5236 break;
5237 default:
5238 goto cp0_unimplemented;
5239 }
5240 break;
5241 case 11:
5242 switch (sel) {
5243 case 0: