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 "internal.h"
27#include "disas/disas.h"
28#include "exec/exec-all.h"
29#include "tcg-op.h"
30#include "exec/cpu_ldst.h"
31#include "hw/mips/cpudevs.h"
32
33#include "exec/helper-proto.h"
34#include "exec/helper-gen.h"
35#include "hw/semihosting/semihost.h"
36
37#include "target/mips/trace.h"
38#include "trace-tcg.h"
39#include "exec/translator.h"
40#include "exec/log.h"
41#include "qemu/qemu-print.h"
42
43#define MIPS_DEBUG_DISAS 0
44
45
46#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
47
48enum {
49
50 OPC_SPECIAL = (0x00 << 26),
51 OPC_REGIMM = (0x01 << 26),
52 OPC_CP0 = (0x10 << 26),
53 OPC_CP1 = (0x11 << 26),
54 OPC_CP2 = (0x12 << 26),
55 OPC_CP3 = (0x13 << 26),
56 OPC_SPECIAL2 = (0x1C << 26),
57 OPC_SPECIAL3 = (0x1F << 26),
58
59 OPC_ADDI = (0x08 << 26),
60 OPC_ADDIU = (0x09 << 26),
61 OPC_SLTI = (0x0A << 26),
62 OPC_SLTIU = (0x0B << 26),
63
64 OPC_ANDI = (0x0C << 26),
65 OPC_ORI = (0x0D << 26),
66 OPC_XORI = (0x0E << 26),
67 OPC_LUI = (0x0F << 26),
68
69 OPC_DADDI = (0x18 << 26),
70 OPC_DADDIU = (0x19 << 26),
71
72 OPC_J = (0x02 << 26),
73 OPC_JAL = (0x03 << 26),
74 OPC_BEQ = (0x04 << 26),
75 OPC_BEQL = (0x14 << 26),
76 OPC_BNE = (0x05 << 26),
77 OPC_BNEL = (0x15 << 26),
78 OPC_BLEZ = (0x06 << 26),
79 OPC_BLEZL = (0x16 << 26),
80 OPC_BGTZ = (0x07 << 26),
81 OPC_BGTZL = (0x17 << 26),
82 OPC_JALX = (0x1D << 26),
83 OPC_DAUI = (0x1D << 26),
84
85 OPC_LDL = (0x1A << 26),
86 OPC_LDR = (0x1B << 26),
87 OPC_LB = (0x20 << 26),
88 OPC_LH = (0x21 << 26),
89 OPC_LWL = (0x22 << 26),
90 OPC_LW = (0x23 << 26),
91 OPC_LWPC = OPC_LW | 0x5,
92 OPC_LBU = (0x24 << 26),
93 OPC_LHU = (0x25 << 26),
94 OPC_LWR = (0x26 << 26),
95 OPC_LWU = (0x27 << 26),
96 OPC_SB = (0x28 << 26),
97 OPC_SH = (0x29 << 26),
98 OPC_SWL = (0x2A << 26),
99 OPC_SW = (0x2B << 26),
100 OPC_SDL = (0x2C << 26),
101 OPC_SDR = (0x2D << 26),
102 OPC_SWR = (0x2E << 26),
103 OPC_LL = (0x30 << 26),
104 OPC_LLD = (0x34 << 26),
105 OPC_LD = (0x37 << 26),
106 OPC_LDPC = OPC_LD | 0x5,
107 OPC_SC = (0x38 << 26),
108 OPC_SCD = (0x3C << 26),
109 OPC_SD = (0x3F << 26),
110
111 OPC_LWC1 = (0x31 << 26),
112 OPC_LWC2 = (0x32 << 26),
113 OPC_LDC1 = (0x35 << 26),
114 OPC_LDC2 = (0x36 << 26),
115 OPC_SWC1 = (0x39 << 26),
116 OPC_SWC2 = (0x3A << 26),
117 OPC_SDC1 = (0x3D << 26),
118 OPC_SDC2 = (0x3E << 26),
119
120 OPC_BLEZALC = (0x06 << 26),
121 OPC_BGEZALC = (0x06 << 26),
122 OPC_BGEUC = (0x06 << 26),
123 OPC_BGTZALC = (0x07 << 26),
124 OPC_BLTZALC = (0x07 << 26),
125 OPC_BLTUC = (0x07 << 26),
126 OPC_BOVC = (0x08 << 26),
127 OPC_BEQZALC = (0x08 << 26),
128 OPC_BEQC = (0x08 << 26),
129 OPC_BLEZC = (0x16 << 26),
130 OPC_BGEZC = (0x16 << 26),
131 OPC_BGEC = (0x16 << 26),
132 OPC_BGTZC = (0x17 << 26),
133 OPC_BLTZC = (0x17 << 26),
134 OPC_BLTC = (0x17 << 26),
135 OPC_BNVC = (0x18 << 26),
136 OPC_BNEZALC = (0x18 << 26),
137 OPC_BNEC = (0x18 << 26),
138 OPC_BC = (0x32 << 26),
139 OPC_BEQZC = (0x36 << 26),
140 OPC_JIC = (0x36 << 26),
141 OPC_BALC = (0x3A << 26),
142 OPC_BNEZC = (0x3E << 26),
143 OPC_JIALC = (0x3E << 26),
144
145 OPC_MDMX = (0x1E << 26),
146
147 OPC_MSA = OPC_MDMX,
148
149 OPC_CACHE = (0x2F << 26),
150 OPC_PREF = (0x33 << 26),
151
152 OPC_PCREL = (0x3B << 26),
153};
154
155
156#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
157#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
158enum {
159
160 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
161 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
162 OPC_LWUPC = OPC_PCREL | (2 << 19),
163
164
165 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
166 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
167
168
169 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
170};
171
172
173#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
174
175enum {
176
177 OPC_SLL = 0x00 | OPC_SPECIAL,
178
179
180
181 OPC_SRL = 0x02 | OPC_SPECIAL,
182 OPC_ROTR = OPC_SRL | (1 << 21),
183 OPC_SRA = 0x03 | OPC_SPECIAL,
184 OPC_SLLV = 0x04 | OPC_SPECIAL,
185 OPC_SRLV = 0x06 | OPC_SPECIAL,
186 OPC_ROTRV = OPC_SRLV | (1 << 6),
187 OPC_SRAV = 0x07 | OPC_SPECIAL,
188 OPC_DSLLV = 0x14 | OPC_SPECIAL,
189 OPC_DSRLV = 0x16 | OPC_SPECIAL,
190 OPC_DROTRV = OPC_DSRLV | (1 << 6),
191 OPC_DSRAV = 0x17 | OPC_SPECIAL,
192 OPC_DSLL = 0x38 | OPC_SPECIAL,
193 OPC_DSRL = 0x3A | OPC_SPECIAL,
194 OPC_DROTR = OPC_DSRL | (1 << 21),
195 OPC_DSRA = 0x3B | OPC_SPECIAL,
196 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
197 OPC_DSRL32 = 0x3E | OPC_SPECIAL,
198 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
199 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
200
201 OPC_MULT = 0x18 | OPC_SPECIAL,
202 OPC_MULTU = 0x19 | OPC_SPECIAL,
203 OPC_DIV = 0x1A | OPC_SPECIAL,
204 OPC_DIVU = 0x1B | OPC_SPECIAL,
205 OPC_DMULT = 0x1C | OPC_SPECIAL,
206 OPC_DMULTU = 0x1D | OPC_SPECIAL,
207 OPC_DDIV = 0x1E | OPC_SPECIAL,
208 OPC_DDIVU = 0x1F | OPC_SPECIAL,
209
210
211 OPC_ADD = 0x20 | OPC_SPECIAL,
212 OPC_ADDU = 0x21 | OPC_SPECIAL,
213 OPC_SUB = 0x22 | OPC_SPECIAL,
214 OPC_SUBU = 0x23 | OPC_SPECIAL,
215 OPC_AND = 0x24 | OPC_SPECIAL,
216 OPC_OR = 0x25 | OPC_SPECIAL,
217 OPC_XOR = 0x26 | OPC_SPECIAL,
218 OPC_NOR = 0x27 | OPC_SPECIAL,
219 OPC_SLT = 0x2A | OPC_SPECIAL,
220 OPC_SLTU = 0x2B | OPC_SPECIAL,
221 OPC_DADD = 0x2C | OPC_SPECIAL,
222 OPC_DADDU = 0x2D | OPC_SPECIAL,
223 OPC_DSUB = 0x2E | OPC_SPECIAL,
224 OPC_DSUBU = 0x2F | OPC_SPECIAL,
225
226 OPC_JR = 0x08 | OPC_SPECIAL,
227 OPC_JALR = 0x09 | OPC_SPECIAL,
228
229 OPC_TGE = 0x30 | OPC_SPECIAL,
230 OPC_TGEU = 0x31 | OPC_SPECIAL,
231 OPC_TLT = 0x32 | OPC_SPECIAL,
232 OPC_TLTU = 0x33 | OPC_SPECIAL,
233 OPC_TEQ = 0x34 | OPC_SPECIAL,
234 OPC_TNE = 0x36 | OPC_SPECIAL,
235
236 OPC_MFHI = 0x10 | OPC_SPECIAL,
237 OPC_MTHI = 0x11 | OPC_SPECIAL,
238 OPC_MFLO = 0x12 | OPC_SPECIAL,
239 OPC_MTLO = 0x13 | OPC_SPECIAL,
240
241 OPC_MOVZ = 0x0A | OPC_SPECIAL,
242 OPC_MOVN = 0x0B | OPC_SPECIAL,
243
244 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
245 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
246
247 OPC_MOVCI = 0x01 | OPC_SPECIAL,
248
249
250 OPC_PMON = 0x05 | OPC_SPECIAL,
251 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
252 OPC_BREAK = 0x0D | OPC_SPECIAL,
253 OPC_SPIM = 0x0E | OPC_SPECIAL,
254 OPC_SYNC = 0x0F | OPC_SPECIAL,
255
256 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
257 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
258 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
259 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
260};
261
262
263
264
265
266#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
267
268enum {
269 R6_OPC_MUL = OPC_MULT | (2 << 6),
270 R6_OPC_MUH = OPC_MULT | (3 << 6),
271 R6_OPC_MULU = OPC_MULTU | (2 << 6),
272 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
273 R6_OPC_DIV = OPC_DIV | (2 << 6),
274 R6_OPC_MOD = OPC_DIV | (3 << 6),
275 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
276 R6_OPC_MODU = OPC_DIVU | (3 << 6),
277
278 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
279 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
280 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
281 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
282 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
283 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
284 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
285 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
286
287 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
288 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
289 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
290 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
291 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
292
293 OPC_LSA = 0x05 | OPC_SPECIAL,
294 OPC_DLSA = 0x15 | OPC_SPECIAL,
295};
296
297
298#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
299
300enum {
301 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
302 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
303 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
304 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
305 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
306 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
307 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
308 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
309 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
310 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
311 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
312 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
313 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
314 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
315};
316
317
318#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
319
320enum {
321 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
322 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
323 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
324 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
325 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
326 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
327 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
328 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
329 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
330 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
331 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
332 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
333 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
334 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
335 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
336 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
337
338 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
339 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
340};
341
342
343#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
344
345enum {
346
347 OPC_MADD = 0x00 | OPC_SPECIAL2,
348 OPC_MADDU = 0x01 | OPC_SPECIAL2,
349 OPC_MUL = 0x02 | OPC_SPECIAL2,
350 OPC_MSUB = 0x04 | OPC_SPECIAL2,
351 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
352
353 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
354 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
355 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
356 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
357 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
358 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
359 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
360 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
361 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
362 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
363 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
364 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
365
366 OPC_CLZ = 0x20 | OPC_SPECIAL2,
367 OPC_CLO = 0x21 | OPC_SPECIAL2,
368 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
369 OPC_DCLO = 0x25 | OPC_SPECIAL2,
370
371 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
372};
373
374
375#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
376
377enum {
378 OPC_EXT = 0x00 | OPC_SPECIAL3,
379 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
380 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
381 OPC_DEXT = 0x03 | OPC_SPECIAL3,
382 OPC_INS = 0x04 | OPC_SPECIAL3,
383 OPC_DINSM = 0x05 | OPC_SPECIAL3,
384 OPC_DINSU = 0x06 | OPC_SPECIAL3,
385 OPC_DINS = 0x07 | OPC_SPECIAL3,
386 OPC_FORK = 0x08 | OPC_SPECIAL3,
387 OPC_YIELD = 0x09 | OPC_SPECIAL3,
388 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
389 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
390 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
391
392
393 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
394 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
395 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
396 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
397 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
398 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
399 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
400 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
401 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
402 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
403 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
404 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
405
406
407 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
408
409 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
410 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
411 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
412 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
413
414
415 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
416 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
417
418 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
419 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
420
421
422
423 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
424 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
425
426 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
427 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
428
429 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
430 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
431
432 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
433 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
434
435
436 OPC_LWLE = 0x19 | OPC_SPECIAL3,
437 OPC_LWRE = 0x1A | OPC_SPECIAL3,
438 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
439 OPC_SBE = 0x1C | OPC_SPECIAL3,
440 OPC_SHE = 0x1D | OPC_SPECIAL3,
441 OPC_SCE = 0x1E | OPC_SPECIAL3,
442 OPC_SWE = 0x1F | OPC_SPECIAL3,
443 OPC_SWLE = 0x21 | OPC_SPECIAL3,
444 OPC_SWRE = 0x22 | OPC_SPECIAL3,
445 OPC_PREFE = 0x23 | OPC_SPECIAL3,
446 OPC_LBUE = 0x28 | OPC_SPECIAL3,
447 OPC_LHUE = 0x29 | OPC_SPECIAL3,
448 OPC_LBE = 0x2C | OPC_SPECIAL3,
449 OPC_LHE = 0x2D | OPC_SPECIAL3,
450 OPC_LLE = 0x2E | OPC_SPECIAL3,
451 OPC_LWE = 0x2F | OPC_SPECIAL3,
452
453
454 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
455 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
456 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
457 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
458 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
459 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
460};
461
462
463#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
464
465enum {
466 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
467 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
468 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
469 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL,
470 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
471 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
472 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
473 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL
474};
475
476
477#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
478
479enum {
480 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
481 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
482 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL,
483 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
484 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
485 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
486 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
487 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
488 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
489 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
490 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL,
491};
492
493
494enum {
495 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
496 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
497};
498
499#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
500
501enum {
502 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
503 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
504 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
505 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
506};
507
508#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509enum {
510
511 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
515 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
516 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
517 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
518 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
519 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
520 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
521 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
522 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
523 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
524 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
525 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
526 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
527 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
528 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
529
530 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
531 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
532 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
533 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
534 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
535 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
536};
537
538#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
539#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540enum {
541
542 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
543 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
544 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
546 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
548 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
549 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
550 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
551 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
552 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
553 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
554
555 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
556 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
557 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
558 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
559};
560
561#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
562enum {
563
564 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
574 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
575 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
576 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
577
578 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
579 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
580 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
581 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
582 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
583};
584
585#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
586enum {
587
588 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
595
596 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
603 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
604 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
605 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
606 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
607 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
608 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
609 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
610 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
611};
612
613#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
614enum {
615
616 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
630 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
631 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
632 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
633 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
634 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
635 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
636 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
637 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
638};
639
640#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641enum {
642
643 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
649 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
652 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
654 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
655 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
656 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
657 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
658 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
659 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
660 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
661 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
662 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
663 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
664 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
665};
666
667#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
668enum {
669
670 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
671};
672
673#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
674enum {
675
676 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
677 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
678 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
679};
680
681#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
682enum {
683
684 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
688 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
689 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
690 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
691 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
692 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
693 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
694 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
695 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
696 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
697 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
698 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
699 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
700 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
701};
702
703#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704enum {
705
706 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
720 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
721 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
722 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
723
724 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
725 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
726 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
727 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
728 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
729 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
730};
731
732#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
733enum {
734
735 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
736 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
737 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
738 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
739 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
740
741 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
744 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
745 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
746 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
747 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
748 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
749 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
750 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
751 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
754 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
755 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
756 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
757 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
758 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
759 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
760 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
761 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
762};
763
764#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765enum {
766
767 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
784 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
785 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
786
787 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
788 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
789 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
793 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
794 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
795};
796
797#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
798enum {
799
800 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
801 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
802 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
803 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
804};
805
806#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
807enum {
808
809 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
810 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
822 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
823 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
824 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
825 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
826 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
827 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
828 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
829 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
830};
831
832#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
833enum {
834
835 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
836};
837
838#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839enum {
840
841 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
859 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
860 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
861 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
862 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
863 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
864 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
865 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
866 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
867};
868
869#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
870enum {
871
872 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
890 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
891 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
892 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
893 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
894 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
895 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
896 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
897 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
898};
899
900
901#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
902
903enum {
904 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
905 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
906 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
907 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
908 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
909 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
910 OPC_MFTR = (0x08 << 21) | OPC_CP0,
911 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
912 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
913 OPC_MTTR = (0x0C << 21) | OPC_CP0,
914 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
915 OPC_C0 = (0x10 << 21) | OPC_CP0,
916 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
917 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
918 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
919 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
920 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
921 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
922 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
923 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
924 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
925 OPC_C0_A = (0x1A << 21) | OPC_CP0,
926 OPC_C0_B = (0x1B << 21) | OPC_CP0,
927 OPC_C0_C = (0x1C << 21) | OPC_CP0,
928 OPC_C0_D = (0x1D << 21) | OPC_CP0,
929 OPC_C0_E = (0x1E << 21) | OPC_CP0,
930 OPC_C0_F = (0x1F << 21) | OPC_CP0,
931};
932
933
934#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
935
936enum {
937 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
938 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
939 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
940 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
941 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
942 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
943 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
944 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
945};
946
947
948#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
949
950enum {
951 OPC_TLBR = 0x01 | OPC_C0,
952 OPC_TLBWI = 0x02 | OPC_C0,
953 OPC_TLBINV = 0x03 | OPC_C0,
954 OPC_TLBINVF = 0x04 | OPC_C0,
955 OPC_TLBWR = 0x06 | OPC_C0,
956 OPC_TLBP = 0x08 | OPC_C0,
957 OPC_RFE = 0x10 | OPC_C0,
958 OPC_ERET = 0x18 | OPC_C0,
959 OPC_DERET = 0x1F | OPC_C0,
960 OPC_WAIT = 0x20 | OPC_C0,
961};
962
963
964#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
965
966
967enum {
968
969 FMT_S = 16,
970 FMT_D = 17,
971 FMT_E = 18,
972 FMT_Q = 19,
973 FMT_W = 20,
974 FMT_L = 21,
975 FMT_PS = 22,
976
977};
978
979enum {
980 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
981 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
982 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
983 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
984 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
985 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
986 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
987 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
988 OPC_BC1 = (0x08 << 21) | OPC_CP1,
989 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
990 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
991 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
992 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
993 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
994 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
995 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
996 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
997 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
998 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
999 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
1000 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
1001 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
1002 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
1003 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
1004 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
1005 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
1006 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
1007 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
1008 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
1009 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
1010};
1011
1012#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1013#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1014
1015enum {
1016 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1017 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1018 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1019 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1020};
1021
1022enum {
1023 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1024 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1025};
1026
1027enum {
1028 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1029 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1030};
1031
1032#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1033
1034enum {
1035 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1036 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1037 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1038 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1039 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1040 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1041 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1042 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1043 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1044 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1045 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1046};
1047
1048#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1049
1050enum {
1051 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1052 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1053 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1054 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1055 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1056 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1057 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1058 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1059
1060 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1061 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1062 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1063 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1064 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1065 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1066 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1067 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1068
1069 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1070 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1071 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1072 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1073 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1074 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1075 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1076 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1077
1078 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1079 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1080 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1081 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1082 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1083 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1084 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1085 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1086
1087 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1088 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1089 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1090 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1091 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1092 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1093
1094 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1095 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1096 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1097 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1098 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1099 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1100
1101 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1102 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1103 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1104 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1105 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1106 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1107
1108 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1109 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1110 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1111 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1112 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1113 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1114
1115 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1116 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1117 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1118 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1119 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1120 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1121
1122 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1123 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1124 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1125 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1126 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1127 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1128
1129 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1130 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1131 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1132 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1133 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1134 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1135
1136 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1137 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1138 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1139 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1140 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1141 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1142};
1143
1144
1145#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1146
1147enum {
1148 OPC_LWXC1 = 0x00 | OPC_CP3,
1149 OPC_LDXC1 = 0x01 | OPC_CP3,
1150 OPC_LUXC1 = 0x05 | OPC_CP3,
1151 OPC_SWXC1 = 0x08 | OPC_CP3,
1152 OPC_SDXC1 = 0x09 | OPC_CP3,
1153 OPC_SUXC1 = 0x0D | OPC_CP3,
1154 OPC_PREFX = 0x0F | OPC_CP3,
1155 OPC_ALNV_PS = 0x1E | OPC_CP3,
1156 OPC_MADD_S = 0x20 | OPC_CP3,
1157 OPC_MADD_D = 0x21 | OPC_CP3,
1158 OPC_MADD_PS = 0x26 | OPC_CP3,
1159 OPC_MSUB_S = 0x28 | OPC_CP3,
1160 OPC_MSUB_D = 0x29 | OPC_CP3,
1161 OPC_MSUB_PS = 0x2E | OPC_CP3,
1162 OPC_NMADD_S = 0x30 | OPC_CP3,
1163 OPC_NMADD_D = 0x31 | OPC_CP3,
1164 OPC_NMADD_PS= 0x36 | OPC_CP3,
1165 OPC_NMSUB_S = 0x38 | OPC_CP3,
1166 OPC_NMSUB_D = 0x39 | OPC_CP3,
1167 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1168};
1169
1170
1171#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1172enum {
1173 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1174 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1175 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1176 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1177 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1178 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1179 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1180 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1181 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1182 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1183 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1184 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1185 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1186 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1187 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1188 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1189 OPC_MSA_ELM = 0x19 | OPC_MSA,
1190 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1191 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1192 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1193 OPC_MSA_VEC = 0x1E | OPC_MSA,
1194
1195
1196 OPC_LD_B = (0x20) | OPC_MSA,
1197 OPC_LD_H = (0x21) | OPC_MSA,
1198 OPC_LD_W = (0x22) | OPC_MSA,
1199 OPC_LD_D = (0x23) | OPC_MSA,
1200 OPC_ST_B = (0x24) | OPC_MSA,
1201 OPC_ST_H = (0x25) | OPC_MSA,
1202 OPC_ST_W = (0x26) | OPC_MSA,
1203 OPC_ST_D = (0x27) | OPC_MSA,
1204};
1205
1206enum {
1207
1208 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1209 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1210 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1211 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1212 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1213 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1214 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1215 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1216 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1217 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1218 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1219 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1220
1221
1222 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1223 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1224 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1225 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1226 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1227 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1228 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1229 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1230 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1231 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1232
1233
1234 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1235 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1236 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1237 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1238 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1239 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1240 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1241
1242 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1243 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1244
1245
1246 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1247 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1248 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1249 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1250
1251
1252 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1253 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1254 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1255 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1256 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1257 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1258 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1259 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1260 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1261 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1262 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1263 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1264 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1265 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1266 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1267 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1268
1269
1270 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1271 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1272 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1273 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1274 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1275 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1276 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1277 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1278 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1279 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1280 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1281 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1282 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1283 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1284 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1285 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1286 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1287 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1288 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1289 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1290 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1291 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1292 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1293 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1294 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1295 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1296 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1297 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1298 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1299 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1300 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1301 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1302 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1303 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1304 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1305 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1306 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1307 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1308 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1309 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1310 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1311 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1312 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1313 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1314 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1315 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1316 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1317 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1318 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1319 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1320 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1321 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1322 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1323 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1324 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1325 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1326 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1327 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1328 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1329 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1330 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1331 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1332 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1333
1334
1335 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1336 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1337 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1338 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1339 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1341 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1342 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1343 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1344
1345
1346 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1348 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1349 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1350 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1351 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1352 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1353 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1356 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1357 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1358 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1359 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1361 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1362 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1363 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1364 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1365 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1366 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1367 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1368 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1369 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1370 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1372 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1373 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1375 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1376 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1377 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1378 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1379 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1380 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1381 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1382 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1383 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1384 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1385 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1386 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1387
1388
1389 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1390 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1391 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1392 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1393 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1394 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1395 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1396 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1397 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1398 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1399 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1400 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1401};
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738enum {
1739 OPC_MXU_S32MADD = 0x00,
1740 OPC_MXU_S32MADDU = 0x01,
1741 OPC__MXU_MUL = 0x02,
1742 OPC_MXU__POOL00 = 0x03,
1743 OPC_MXU_S32MSUB = 0x04,
1744 OPC_MXU_S32MSUBU = 0x05,
1745 OPC_MXU__POOL01 = 0x06,
1746 OPC_MXU__POOL02 = 0x07,
1747 OPC_MXU_D16MUL = 0x08,
1748 OPC_MXU__POOL03 = 0x09,
1749 OPC_MXU_D16MAC = 0x0A,
1750 OPC_MXU_D16MACF = 0x0B,
1751 OPC_MXU_D16MADL = 0x0C,
1752 OPC_MXU_S16MAD = 0x0D,
1753 OPC_MXU_Q16ADD = 0x0E,
1754 OPC_MXU_D16MACE = 0x0F,
1755 OPC_MXU__POOL04 = 0x10,
1756 OPC_MXU__POOL05 = 0x11,
1757 OPC_MXU__POOL06 = 0x12,
1758 OPC_MXU__POOL07 = 0x13,
1759 OPC_MXU__POOL08 = 0x14,
1760 OPC_MXU__POOL09 = 0x15,
1761 OPC_MXU__POOL10 = 0x16,
1762 OPC_MXU__POOL11 = 0x17,
1763 OPC_MXU_D32ADD = 0x18,
1764 OPC_MXU__POOL12 = 0x19,
1765
1766 OPC_MXU__POOL13 = 0x1B,
1767 OPC_MXU__POOL14 = 0x1C,
1768 OPC_MXU_Q8ACCE = 0x1D,
1769
1770
1771
1772
1773 OPC_MXU_S8LDD = 0x22,
1774 OPC_MXU_S8STD = 0x23,
1775 OPC_MXU_S8LDI = 0x24,
1776 OPC_MXU_S8SDI = 0x25,
1777 OPC_MXU__POOL15 = 0x26,
1778 OPC_MXU__POOL16 = 0x27,
1779 OPC_MXU__POOL17 = 0x28,
1780
1781 OPC_MXU_S16LDD = 0x2A,
1782 OPC_MXU_S16STD = 0x2B,
1783 OPC_MXU_S16LDI = 0x2C,
1784 OPC_MXU_S16SDI = 0x2D,
1785 OPC_MXU_S32M2I = 0x2E,
1786 OPC_MXU_S32I2M = 0x2F,
1787 OPC_MXU_D32SLL = 0x30,
1788 OPC_MXU_D32SLR = 0x31,
1789 OPC_MXU_D32SARL = 0x32,
1790 OPC_MXU_D32SAR = 0x33,
1791 OPC_MXU_Q16SLL = 0x34,
1792 OPC_MXU_Q16SLR = 0x35,
1793 OPC_MXU__POOL18 = 0x36,
1794 OPC_MXU_Q16SAR = 0x37,
1795 OPC_MXU__POOL19 = 0x38,
1796 OPC_MXU__POOL20 = 0x39,
1797 OPC_MXU__POOL21 = 0x3A,
1798 OPC_MXU_Q16SCOP = 0x3B,
1799 OPC_MXU_Q8MADL = 0x3C,
1800 OPC_MXU_S32SFL = 0x3D,
1801 OPC_MXU_Q8SAD = 0x3E,
1802
1803};
1804
1805
1806
1807
1808
1809enum {
1810 OPC_MXU_S32MAX = 0x00,
1811 OPC_MXU_S32MIN = 0x01,
1812 OPC_MXU_D16MAX = 0x02,
1813 OPC_MXU_D16MIN = 0x03,
1814 OPC_MXU_Q8MAX = 0x04,
1815 OPC_MXU_Q8MIN = 0x05,
1816 OPC_MXU_Q8SLT = 0x06,
1817 OPC_MXU_Q8SLTU = 0x07,
1818};
1819
1820
1821
1822
1823enum {
1824 OPC_MXU_S32SLT = 0x00,
1825 OPC_MXU_D16SLT = 0x01,
1826 OPC_MXU_D16AVG = 0x02,
1827 OPC_MXU_D16AVGR = 0x03,
1828 OPC_MXU_Q8AVG = 0x04,
1829 OPC_MXU_Q8AVGR = 0x05,
1830 OPC_MXU_Q8ADD = 0x07,
1831};
1832
1833
1834
1835
1836enum {
1837 OPC_MXU_S32CPS = 0x00,
1838 OPC_MXU_D16CPS = 0x02,
1839 OPC_MXU_Q8ABD = 0x04,
1840 OPC_MXU_Q16SAT = 0x06,
1841};
1842
1843
1844
1845
1846enum {
1847 OPC_MXU_D16MULF = 0x00,
1848 OPC_MXU_D16MULE = 0x01,
1849};
1850
1851
1852
1853
1854enum {
1855 OPC_MXU_S32LDD = 0x00,
1856 OPC_MXU_S32LDDR = 0x01,
1857};
1858
1859
1860
1861
1862enum {
1863 OPC_MXU_S32STD = 0x00,
1864 OPC_MXU_S32STDR = 0x01,
1865};
1866
1867
1868
1869
1870enum {
1871 OPC_MXU_S32LDDV = 0x00,
1872 OPC_MXU_S32LDDVR = 0x01,
1873};
1874
1875
1876
1877
1878enum {
1879 OPC_MXU_S32STDV = 0x00,
1880 OPC_MXU_S32STDVR = 0x01,
1881};
1882
1883
1884
1885
1886enum {
1887 OPC_MXU_S32LDI = 0x00,
1888 OPC_MXU_S32LDIR = 0x01,
1889};
1890
1891
1892
1893
1894enum {
1895 OPC_MXU_S32SDI = 0x00,
1896 OPC_MXU_S32SDIR = 0x01,
1897};
1898
1899
1900
1901
1902enum {
1903 OPC_MXU_S32LDIV = 0x00,
1904 OPC_MXU_S32LDIVR = 0x01,
1905};
1906
1907
1908
1909
1910enum {
1911 OPC_MXU_S32SDIV = 0x00,
1912 OPC_MXU_S32SDIVR = 0x01,
1913};
1914
1915
1916
1917
1918enum {
1919 OPC_MXU_D32ACC = 0x00,
1920 OPC_MXU_D32ACCM = 0x01,
1921 OPC_MXU_D32ASUM = 0x02,
1922};
1923
1924
1925
1926
1927enum {
1928 OPC_MXU_Q16ACC = 0x00,
1929 OPC_MXU_Q16ACCM = 0x01,
1930 OPC_MXU_Q16ASUM = 0x02,
1931};
1932
1933
1934
1935
1936enum {
1937 OPC_MXU_Q8ADDE = 0x00,
1938 OPC_MXU_D8SUM = 0x01,
1939 OPC_MXU_D8SUMC = 0x02,
1940};
1941
1942
1943
1944
1945enum {
1946 OPC_MXU_S32MUL = 0x00,
1947 OPC_MXU_S32MULU = 0x01,
1948 OPC_MXU_S32EXTR = 0x02,
1949 OPC_MXU_S32EXTRV = 0x03,
1950};
1951
1952
1953
1954
1955enum {
1956 OPC_MXU_D32SARW = 0x00,
1957 OPC_MXU_S32ALN = 0x01,
1958 OPC_MXU_S32ALNI = 0x02,
1959 OPC_MXU_S32LUI = 0x03,
1960 OPC_MXU_S32NOR = 0x04,
1961 OPC_MXU_S32AND = 0x05,
1962 OPC_MXU_S32OR = 0x06,
1963 OPC_MXU_S32XOR = 0x07,
1964};
1965
1966
1967
1968
1969enum {
1970 OPC_MXU_LXB = 0x00,
1971 OPC_MXU_LXH = 0x01,
1972 OPC_MXU_LXW = 0x03,
1973 OPC_MXU_LXBU = 0x04,
1974 OPC_MXU_LXHU = 0x05,
1975};
1976
1977
1978
1979
1980enum {
1981 OPC_MXU_D32SLLV = 0x00,
1982 OPC_MXU_D32SLRV = 0x01,
1983 OPC_MXU_D32SARV = 0x03,
1984 OPC_MXU_Q16SLLV = 0x04,
1985 OPC_MXU_Q16SLRV = 0x05,
1986 OPC_MXU_Q16SARV = 0x07,
1987};
1988
1989
1990
1991
1992enum {
1993 OPC_MXU_Q8MUL = 0x00,
1994 OPC_MXU_Q8MULSU = 0x01,
1995};
1996
1997
1998
1999
2000enum {
2001 OPC_MXU_Q8MOVZ = 0x00,
2002 OPC_MXU_Q8MOVN = 0x01,
2003 OPC_MXU_D16MOVZ = 0x02,
2004 OPC_MXU_D16MOVN = 0x03,
2005 OPC_MXU_S32MOVZ = 0x04,
2006 OPC_MXU_S32MOVN = 0x05,
2007};
2008
2009
2010
2011
2012enum {
2013 OPC_MXU_Q8MAC = 0x00,
2014 OPC_MXU_Q8MACSU = 0x01,
2015};
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213enum {
2214 MMI_OPC_CLASS_MMI = 0x1C << 26,
2215 MMI_OPC_LQ = 0x1E << 26,
2216 MMI_OPC_SQ = 0x1F << 26,
2217};
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2242enum {
2243 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI,
2244 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI,
2245 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
2246 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2247 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2248 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI,
2249 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI,
2250 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI,
2251 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI,
2252 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI,
2253 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI,
2254 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI,
2255 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI,
2256 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
2257 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
2258 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2259 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2260 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
2261 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
2262 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
2263 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
2264 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
2265 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
2266 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
2267 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
2268};
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2293enum {
2294 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2295 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2296 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2297 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2298 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2299 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2300 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2301 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2302 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2303 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2304 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2305 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2306 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2307 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2308 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2309 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2310 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2311 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2312 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2313 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2314 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2315 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2316 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2317 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2318 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2319};
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2344enum {
2345 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2346 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2347 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2348 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2349 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2350 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2351 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2352 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2353 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2354 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2355 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2356 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2357 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2358 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2359 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2360 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2361 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2362 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2363};
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2388enum {
2389 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2390 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2391 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2392 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2393 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2394 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2395 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2396 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2397 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2398 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2399 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2400 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2401 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2402 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2403 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2404 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2405 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2406 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2407 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2408 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2409 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2410 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2411};
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2436enum {
2437 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2438 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2439 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2440 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2441 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2442 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2443 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2444 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2445 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2446 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2447 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2448 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2449 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2450};
2451
2452
2453static TCGv cpu_gpr[32], cpu_PC;
2454static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2455static TCGv cpu_dspctrl, btarget, bcond;
2456static TCGv cpu_lladdr, cpu_llval;
2457static TCGv_i32 hflags;
2458static TCGv_i32 fpu_fcr0, fpu_fcr31;
2459static TCGv_i64 fpu_f64[32];
2460static TCGv_i64 msa_wr_d[64];
2461
2462#if defined(TARGET_MIPS64)
2463
2464static TCGv_i64 cpu_mmr[32];
2465#endif
2466
2467#if !defined(TARGET_MIPS64)
2468
2469static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2470static TCGv mxu_CR;
2471#endif
2472
2473#include "exec/gen-icount.h"
2474
2475#define gen_helper_0e0i(name, arg) do { \
2476 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2477 gen_helper_##name(cpu_env, helper_tmp); \
2478 tcg_temp_free_i32(helper_tmp); \
2479 } while(0)
2480
2481#define gen_helper_0e1i(name, arg1, arg2) do { \
2482 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2483 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2484 tcg_temp_free_i32(helper_tmp); \
2485 } while(0)
2486
2487#define gen_helper_1e0i(name, ret, arg1) do { \
2488 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2489 gen_helper_##name(ret, cpu_env, helper_tmp); \
2490 tcg_temp_free_i32(helper_tmp); \
2491 } while(0)
2492
2493#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2494 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2495 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2496 tcg_temp_free_i32(helper_tmp); \
2497 } while(0)
2498
2499#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2500 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2501 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2502 tcg_temp_free_i32(helper_tmp); \
2503 } while(0)
2504
2505#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2506 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2507 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2508 tcg_temp_free_i32(helper_tmp); \
2509 } while(0)
2510
2511#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2512 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2513 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2514 tcg_temp_free_i32(helper_tmp); \
2515 } while(0)
2516
2517typedef struct DisasContext {
2518 DisasContextBase base;
2519 target_ulong saved_pc;
2520 target_ulong page_start;
2521 uint32_t opcode;
2522 uint64_t insn_flags;
2523 int32_t CP0_Config1;
2524 int32_t CP0_Config2;
2525 int32_t CP0_Config3;
2526 int32_t CP0_Config5;
2527
2528 int mem_idx;
2529 TCGMemOp default_tcg_memop_mask;
2530 uint32_t hflags, saved_hflags;
2531 target_ulong btarget;
2532 bool ulri;
2533 int kscrexist;
2534 bool rxi;
2535 int ie;
2536 bool bi;
2537 bool bp;
2538 uint64_t PAMask;
2539 bool mvh;
2540 bool eva;
2541 bool sc;
2542 int CP0_LLAddr_shift;
2543 bool ps;
2544 bool vp;
2545 bool cmgcr;
2546 bool mrp;
2547 bool nan2008;
2548 bool abs2008;
2549 bool saar;
2550} DisasContext;
2551
2552#define DISAS_STOP DISAS_TARGET_0
2553#define DISAS_EXIT DISAS_TARGET_1
2554
2555static const char * const regnames[] = {
2556 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2557 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2558 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2559 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2560};
2561
2562static const char * const regnames_HI[] = {
2563 "HI0", "HI1", "HI2", "HI3",
2564};
2565
2566static const char * const regnames_LO[] = {
2567 "LO0", "LO1", "LO2", "LO3",
2568};
2569
2570static const char * const fregnames[] = {
2571 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2572 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2573 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2574 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2575};
2576
2577static const char * const msaregnames[] = {
2578 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2579 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2580 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2581 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2582 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2583 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2584 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2585 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2586 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2587 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2588 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2589 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2590 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2591 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2592 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2593 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2594};
2595
2596#if !defined(TARGET_MIPS64)
2597static const char * const mxuregnames[] = {
2598 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2599 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2600};
2601#endif
2602
2603#define LOG_DISAS(...) \
2604 do { \
2605 if (MIPS_DEBUG_DISAS) { \
2606 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2607 } \
2608 } while (0)
2609
2610#define MIPS_INVAL(op) \
2611 do { \
2612 if (MIPS_DEBUG_DISAS) { \
2613 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2614 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2615 ctx->base.pc_next, ctx->opcode, op, \
2616 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2617 ((ctx->opcode >> 16) & 0x1F)); \
2618 } \
2619 } while (0)
2620
2621
2622static inline void gen_load_gpr(TCGv t, int reg)
2623{
2624 if (reg == 0) {
2625 tcg_gen_movi_tl(t, 0);
2626 } else {
2627 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2628 }
2629}
2630
2631static inline void gen_store_gpr(TCGv t, int reg)
2632{
2633 if (reg != 0) {
2634 tcg_gen_mov_tl(cpu_gpr[reg], t);
2635 }
2636}
2637
2638
2639static inline void gen_load_srsgpr(int from, int to)
2640{
2641 TCGv t0 = tcg_temp_new();
2642
2643 if (from == 0) {
2644 tcg_gen_movi_tl(t0, 0);
2645 } else {
2646 TCGv_i32 t2 = tcg_temp_new_i32();
2647 TCGv_ptr addr = tcg_temp_new_ptr();
2648
2649 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2650 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2651 tcg_gen_andi_i32(t2, t2, 0xf);
2652 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2653 tcg_gen_ext_i32_ptr(addr, t2);
2654 tcg_gen_add_ptr(addr, cpu_env, addr);
2655
2656 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2657 tcg_temp_free_ptr(addr);
2658 tcg_temp_free_i32(t2);
2659 }
2660 gen_store_gpr(t0, to);
2661 tcg_temp_free(t0);
2662}
2663
2664static inline void gen_store_srsgpr (int from, int to)
2665{
2666 if (to != 0) {
2667 TCGv t0 = tcg_temp_new();
2668 TCGv_i32 t2 = tcg_temp_new_i32();
2669 TCGv_ptr addr = tcg_temp_new_ptr();
2670
2671 gen_load_gpr(t0, from);
2672 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2673 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2674 tcg_gen_andi_i32(t2, t2, 0xf);
2675 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2676 tcg_gen_ext_i32_ptr(addr, t2);
2677 tcg_gen_add_ptr(addr, cpu_env, addr);
2678
2679 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2680 tcg_temp_free_ptr(addr);
2681 tcg_temp_free_i32(t2);
2682 tcg_temp_free(t0);
2683 }
2684}
2685
2686#if !defined(TARGET_MIPS64)
2687
2688static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2689{
2690 if (reg == 0) {
2691 tcg_gen_movi_tl(t, 0);
2692 } else if (reg <= 15) {
2693 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2694 }
2695}
2696
2697static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2698{
2699 if (reg > 0 && reg <= 15) {
2700 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2701 }
2702}
2703
2704
2705static inline void gen_load_mxu_cr(TCGv t)
2706{
2707 tcg_gen_mov_tl(t, mxu_CR);
2708}
2709
2710static inline void gen_store_mxu_cr(TCGv t)
2711{
2712
2713 tcg_gen_mov_tl(mxu_CR, t);
2714}
2715#endif
2716
2717
2718
2719static inline void gen_save_pc(target_ulong pc)
2720{
2721 tcg_gen_movi_tl(cpu_PC, pc);
2722}
2723
2724static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2725{
2726 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2727 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2728 gen_save_pc(ctx->base.pc_next);
2729 ctx->saved_pc = ctx->base.pc_next;
2730 }
2731 if (ctx->hflags != ctx->saved_hflags) {
2732 tcg_gen_movi_i32(hflags, ctx->hflags);
2733 ctx->saved_hflags = ctx->hflags;
2734 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2735 case MIPS_HFLAG_BR:
2736 break;
2737 case MIPS_HFLAG_BC:
2738 case MIPS_HFLAG_BL:
2739 case MIPS_HFLAG_B:
2740 tcg_gen_movi_tl(btarget, ctx->btarget);
2741 break;
2742 }
2743 }
2744}
2745
2746static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2747{
2748 ctx->saved_hflags = ctx->hflags;
2749 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2750 case MIPS_HFLAG_BR:
2751 break;
2752 case MIPS_HFLAG_BC:
2753 case MIPS_HFLAG_BL:
2754 case MIPS_HFLAG_B:
2755 ctx->btarget = env->btarget;
2756 break;
2757 }
2758}
2759
2760static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2761{
2762 TCGv_i32 texcp = tcg_const_i32(excp);
2763 TCGv_i32 terr = tcg_const_i32(err);
2764 save_cpu_state(ctx, 1);
2765 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2766 tcg_temp_free_i32(terr);
2767 tcg_temp_free_i32(texcp);
2768 ctx->base.is_jmp = DISAS_NORETURN;
2769}
2770
2771static inline void generate_exception(DisasContext *ctx, int excp)
2772{
2773 gen_helper_0e0i(raise_exception, excp);
2774}
2775
2776static inline void generate_exception_end(DisasContext *ctx, int excp)
2777{
2778 generate_exception_err(ctx, excp, 0);
2779}
2780
2781
2782static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2783{
2784 if (ctx->hflags & MIPS_HFLAG_FRE) {
2785 generate_exception(ctx, EXCP_RI);
2786 }
2787 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2788}
2789
2790static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2791{
2792 TCGv_i64 t64;
2793 if (ctx->hflags & MIPS_HFLAG_FRE) {
2794 generate_exception(ctx, EXCP_RI);
2795 }
2796 t64 = tcg_temp_new_i64();
2797 tcg_gen_extu_i32_i64(t64, t);
2798 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2799 tcg_temp_free_i64(t64);
2800}
2801
2802static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2803{
2804 if (ctx->hflags & MIPS_HFLAG_F64) {
2805 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2806 } else {
2807 gen_load_fpr32(ctx, t, reg | 1);
2808 }
2809}
2810
2811static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2812{
2813 if (ctx->hflags & MIPS_HFLAG_F64) {
2814 TCGv_i64 t64 = tcg_temp_new_i64();
2815 tcg_gen_extu_i32_i64(t64, t);
2816 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2817 tcg_temp_free_i64(t64);
2818 } else {
2819 gen_store_fpr32(ctx, t, reg | 1);
2820 }
2821}
2822
2823static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2824{
2825 if (ctx->hflags & MIPS_HFLAG_F64) {
2826 tcg_gen_mov_i64(t, fpu_f64[reg]);
2827 } else {
2828 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2829 }
2830}
2831
2832static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2833{
2834 if (ctx->hflags & MIPS_HFLAG_F64) {
2835 tcg_gen_mov_i64(fpu_f64[reg], t);
2836 } else {
2837 TCGv_i64 t0;
2838 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2839 t0 = tcg_temp_new_i64();
2840 tcg_gen_shri_i64(t0, t, 32);
2841 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2842 tcg_temp_free_i64(t0);
2843 }
2844}
2845
2846static inline int get_fp_bit(int cc)
2847{
2848 if (cc) {
2849 return 24 + cc;
2850 } else {
2851 return 23;
2852 }
2853}
2854
2855
2856static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0,
2857 TCGv arg1)
2858{
2859 tcg_gen_add_tl(ret, arg0, arg1);
2860
2861#if defined(TARGET_MIPS64)
2862 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2863 tcg_gen_ext32s_i64(ret, ret);
2864 }
2865#endif
2866}
2867
2868static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2869 target_long ofs)
2870{
2871 tcg_gen_addi_tl(ret, base, ofs);
2872
2873#if defined(TARGET_MIPS64)
2874 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2875 tcg_gen_ext32s_i64(ret, ret);
2876 }
2877#endif
2878}
2879
2880
2881static target_long addr_add(DisasContext *ctx, target_long base,
2882 target_long offset)
2883{
2884 target_long sum = base + offset;
2885
2886#if defined(TARGET_MIPS64)
2887 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2888 sum = (int32_t)sum;
2889 }
2890#endif
2891 return sum;
2892}
2893
2894
2895static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2896{
2897#if defined(TARGET_MIPS64)
2898 tcg_gen_ext32s_i64(ret, arg);
2899#else
2900 tcg_gen_extrl_i64_i32(ret, arg);
2901#endif
2902}
2903
2904
2905static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2906{
2907#if defined(TARGET_MIPS64)
2908 tcg_gen_sari_i64(ret, arg, 32);
2909#else
2910 tcg_gen_extrh_i64_i32(ret, arg);
2911#endif
2912}
2913
2914static inline void check_cp0_enabled(DisasContext *ctx)
2915{
2916 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2917 generate_exception_err(ctx, EXCP_CpU, 0);
2918 }
2919}
2920
2921static inline void check_cp1_enabled(DisasContext *ctx)
2922{
2923 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
2924 generate_exception_err(ctx, EXCP_CpU, 1);
2925 }
2926}
2927
2928
2929
2930
2931
2932
2933static inline void check_cop1x(DisasContext *ctx)
2934{
2935 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
2936 generate_exception_end(ctx, EXCP_RI);
2937 }
2938}
2939
2940
2941
2942
2943
2944static inline void check_cp1_64bitmode(DisasContext *ctx)
2945{
2946 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
2947 generate_exception_end(ctx, EXCP_RI);
2948 }
2949}
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962static inline void check_cp1_registers(DisasContext *ctx, int regs)
2963{
2964 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
2965 generate_exception_end(ctx, EXCP_RI);
2966 }
2967}
2968
2969
2970
2971
2972
2973static inline void check_dsp(DisasContext *ctx)
2974{
2975 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2976 if (ctx->insn_flags & ASE_DSP) {
2977 generate_exception_end(ctx, EXCP_DSPDIS);
2978 } else {
2979 generate_exception_end(ctx, EXCP_RI);
2980 }
2981 }
2982}
2983
2984static inline void check_dsp_r2(DisasContext *ctx)
2985{
2986 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2987 if (ctx->insn_flags & ASE_DSP) {
2988 generate_exception_end(ctx, EXCP_DSPDIS);
2989 } else {
2990 generate_exception_end(ctx, EXCP_RI);
2991 }
2992 }
2993}
2994
2995static inline void check_dsp_r3(DisasContext *ctx)
2996{
2997 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2998 if (ctx->insn_flags & ASE_DSP) {
2999 generate_exception_end(ctx, EXCP_DSPDIS);
3000 } else {
3001 generate_exception_end(ctx, EXCP_RI);
3002 }
3003 }
3004}
3005
3006
3007
3008
3009
3010static inline void check_insn(DisasContext *ctx, uint64_t flags)
3011{
3012 if (unlikely(!(ctx->insn_flags & flags))) {
3013 generate_exception_end(ctx, EXCP_RI);
3014 }
3015}
3016
3017
3018
3019
3020
3021
3022static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3023{
3024 if (unlikely(ctx->insn_flags & flags)) {
3025 generate_exception_end(ctx, EXCP_RI);
3026 }
3027}
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3038{
3039#ifndef CONFIG_USER_ONLY
3040 check_insn_opc_removed(ctx, flags);
3041#endif
3042}
3043
3044
3045
3046
3047
3048static inline void check_ps(DisasContext *ctx)
3049{
3050 if (unlikely(!ctx->ps)) {
3051 generate_exception(ctx, EXCP_RI);
3052 }
3053 check_cp1_64bitmode(ctx);
3054}
3055
3056#ifdef TARGET_MIPS64
3057
3058
3059
3060
3061static inline void check_mips_64(DisasContext *ctx)
3062{
3063 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
3064 generate_exception_end(ctx, EXCP_RI);
3065 }
3066}
3067#endif
3068
3069#ifndef CONFIG_USER_ONLY
3070static inline void check_mvh(DisasContext *ctx)
3071{
3072 if (unlikely(!ctx->mvh)) {
3073 generate_exception(ctx, EXCP_RI);
3074 }
3075}
3076#endif
3077
3078
3079
3080
3081
3082static inline void check_xnp(DisasContext *ctx)
3083{
3084 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3085 generate_exception_end(ctx, EXCP_RI);
3086 }
3087}
3088
3089#ifndef CONFIG_USER_ONLY
3090
3091
3092
3093
3094static inline void check_pw(DisasContext *ctx)
3095{
3096 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3097 generate_exception_end(ctx, EXCP_RI);
3098 }
3099}
3100#endif
3101
3102
3103
3104
3105
3106static inline void check_mt(DisasContext *ctx)
3107{
3108 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3109 generate_exception_end(ctx, EXCP_RI);
3110 }
3111}
3112
3113#ifndef CONFIG_USER_ONLY
3114
3115
3116
3117
3118
3119
3120static inline void check_cp0_mt(DisasContext *ctx)
3121{
3122 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3123 generate_exception_err(ctx, EXCP_CpU, 0);
3124 } else {
3125 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3126 generate_exception_err(ctx, EXCP_RI, 0);
3127 }
3128 }
3129}
3130#endif
3131
3132
3133
3134
3135
3136static inline void check_nms(DisasContext *ctx)
3137{
3138 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3139 generate_exception_end(ctx, EXCP_RI);
3140 }
3141}
3142
3143
3144
3145
3146
3147
3148static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3149{
3150 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3151 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3152 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3153 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3154 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3155 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3156 generate_exception_end(ctx, EXCP_RI);
3157 }
3158}
3159
3160
3161
3162
3163
3164static inline void check_eva(DisasContext *ctx)
3165{
3166 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3167 generate_exception_end(ctx, EXCP_RI);
3168 }
3169}
3170
3171
3172
3173
3174
3175
3176
3177
3178#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3179#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3180#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3181static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3182 int ft, int fs, int cc) \
3183{ \
3184 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3185 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3186 switch (ifmt) { \
3187 case FMT_PS: \
3188 check_ps(ctx); \
3189 break; \
3190 case FMT_D: \
3191 if (abs) { \
3192 check_cop1x(ctx); \
3193 } \
3194 check_cp1_registers(ctx, fs | ft); \
3195 break; \
3196 case FMT_S: \
3197 if (abs) { \
3198 check_cop1x(ctx); \
3199 } \
3200 break; \
3201 } \
3202 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3203 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3204 switch (n) { \
3205 case 0: \
3206 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3207 break; \
3208 case 1: \
3209 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3210 break; \
3211 case 2: \
3212 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3213 break; \
3214 case 3: \
3215 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3216 break; \
3217 case 4: \
3218 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3219 break; \
3220 case 5: \
3221 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3222 break; \
3223 case 6: \
3224 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3225 break; \
3226 case 7: \
3227 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3228 break; \
3229 case 8: \
3230 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3231 break; \
3232 case 9: \
3233 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3234 break; \
3235 case 10: \
3236 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3237 break; \
3238 case 11: \
3239 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3240 break; \
3241 case 12: \
3242 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3243 break; \
3244 case 13: \
3245 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3246 break; \
3247 case 14: \
3248 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3249 break; \
3250 case 15: \
3251 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3252 break; \
3253 default: \
3254 abort(); \
3255 } \
3256 tcg_temp_free_i##bits (fp0); \
3257 tcg_temp_free_i##bits (fp1); \
3258}
3259
3260FOP_CONDS(, 0, d, FMT_D, 64)
3261FOP_CONDS(abs, 1, d, FMT_D, 64)
3262FOP_CONDS(, 0, s, FMT_S, 32)
3263FOP_CONDS(abs, 1, s, FMT_S, 32)
3264FOP_CONDS(, 0, ps, FMT_PS, 64)
3265FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3266#undef FOP_CONDS
3267
3268#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3269static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3270 int ft, int fs, int fd) \
3271{ \
3272 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3273 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3274 if (ifmt == FMT_D) { \
3275 check_cp1_registers(ctx, fs | ft | fd); \
3276 } \
3277 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3278 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3279 switch (n) { \
3280 case 0: \
3281 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3282 break; \
3283 case 1: \
3284 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3285 break; \
3286 case 2: \
3287 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3288 break; \
3289 case 3: \
3290 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3291 break; \
3292 case 4: \
3293 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3294 break; \
3295 case 5: \
3296 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3297 break; \
3298 case 6: \
3299 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3300 break; \
3301 case 7: \
3302 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3303 break; \
3304 case 8: \
3305 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3306 break; \
3307 case 9: \
3308 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3309 break; \
3310 case 10: \
3311 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3312 break; \
3313 case 11: \
3314 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3315 break; \
3316 case 12: \
3317 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3318 break; \
3319 case 13: \
3320 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3321 break; \
3322 case 14: \
3323 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3324 break; \
3325 case 15: \
3326 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3327 break; \
3328 case 17: \
3329 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3330 break; \
3331 case 18: \
3332 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3333 break; \
3334 case 19: \
3335 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3336 break; \
3337 case 25: \
3338 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3339 break; \
3340 case 26: \
3341 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3342 break; \
3343 case 27: \
3344 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3345 break; \
3346 default: \
3347 abort(); \
3348 } \
3349 STORE; \
3350 tcg_temp_free_i ## bits (fp0); \
3351 tcg_temp_free_i ## bits (fp1); \
3352}
3353
3354FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3355FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3356#undef FOP_CONDNS
3357#undef gen_ldcmp_fpr32
3358#undef gen_ldcmp_fpr64
3359
3360
3361#ifdef CONFIG_USER_ONLY
3362#define OP_LD_ATOMIC(insn,fname) \
3363static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3364 DisasContext *ctx) \
3365{ \
3366 TCGv t0 = tcg_temp_new(); \
3367 tcg_gen_mov_tl(t0, arg1); \
3368 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3369 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3370 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3371 tcg_temp_free(t0); \
3372}
3373#else
3374#define OP_LD_ATOMIC(insn,fname) \
3375static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3376 DisasContext *ctx) \
3377{ \
3378 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3379}
3380#endif
3381OP_LD_ATOMIC(ll,ld32s);
3382#if defined(TARGET_MIPS64)
3383OP_LD_ATOMIC(lld,ld64);
3384#endif
3385#undef OP_LD_ATOMIC
3386
3387static void gen_base_offset_addr(DisasContext *ctx, TCGv addr,
3388 int base, int offset)
3389{
3390 if (base == 0) {
3391 tcg_gen_movi_tl(addr, offset);
3392 } else if (offset == 0) {
3393 gen_load_gpr(addr, base);
3394 } else {
3395 tcg_gen_movi_tl(addr, offset);
3396 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3397 }
3398}
3399
3400static target_ulong pc_relative_pc(DisasContext *ctx)
3401{
3402 target_ulong pc = ctx->base.pc_next;
3403
3404 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3405 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3406
3407 pc -= branch_bytes;
3408 }
3409
3410 pc &= ~(target_ulong)3;
3411 return pc;
3412}
3413
3414
3415static void gen_ld(DisasContext *ctx, uint32_t opc,
3416 int rt, int base, int offset)
3417{
3418 TCGv t0, t1, t2;
3419 int mem_idx = ctx->mem_idx;
3420
3421 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3422
3423
3424
3425
3426
3427 return;
3428 }
3429
3430 t0 = tcg_temp_new();
3431 gen_base_offset_addr(ctx, t0, base, offset);
3432
3433 switch (opc) {
3434#if defined(TARGET_MIPS64)
3435 case OPC_LWU:
3436 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3437 ctx->default_tcg_memop_mask);
3438 gen_store_gpr(t0, rt);
3439 break;
3440 case OPC_LD:
3441 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3442 ctx->default_tcg_memop_mask);
3443 gen_store_gpr(t0, rt);
3444 break;
3445 case OPC_LLD:
3446 case R6_OPC_LLD:
3447 op_ld_lld(t0, t0, mem_idx, ctx);
3448 gen_store_gpr(t0, rt);
3449 break;
3450 case OPC_LDL:
3451 t1 = tcg_temp_new();
3452
3453
3454
3455
3456 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3457 tcg_gen_andi_tl(t1, t0, 7);
3458#ifndef TARGET_WORDS_BIGENDIAN
3459 tcg_gen_xori_tl(t1, t1, 7);
3460#endif
3461 tcg_gen_shli_tl(t1, t1, 3);
3462 tcg_gen_andi_tl(t0, t0, ~7);
3463 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3464 tcg_gen_shl_tl(t0, t0, t1);
3465 t2 = tcg_const_tl(-1);
3466 tcg_gen_shl_tl(t2, t2, t1);
3467 gen_load_gpr(t1, rt);
3468 tcg_gen_andc_tl(t1, t1, t2);
3469 tcg_temp_free(t2);
3470 tcg_gen_or_tl(t0, t0, t1);
3471 tcg_temp_free(t1);
3472 gen_store_gpr(t0, rt);
3473 break;
3474 case OPC_LDR:
3475 t1 = tcg_temp_new();
3476
3477
3478
3479
3480 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3481 tcg_gen_andi_tl(t1, t0, 7);
3482#ifdef TARGET_WORDS_BIGENDIAN
3483 tcg_gen_xori_tl(t1, t1, 7);
3484#endif
3485 tcg_gen_shli_tl(t1, t1, 3);
3486 tcg_gen_andi_tl(t0, t0, ~7);
3487 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3488 tcg_gen_shr_tl(t0, t0, t1);
3489 tcg_gen_xori_tl(t1, t1, 63);
3490 t2 = tcg_const_tl(0xfffffffffffffffeull);
3491 tcg_gen_shl_tl(t2, t2, t1);
3492 gen_load_gpr(t1, rt);
3493 tcg_gen_and_tl(t1, t1, t2);
3494 tcg_temp_free(t2);
3495 tcg_gen_or_tl(t0, t0, t1);
3496 tcg_temp_free(t1);
3497 gen_store_gpr(t0, rt);
3498 break;
3499 case OPC_LDPC:
3500 t1 = tcg_const_tl(pc_relative_pc(ctx));
3501 gen_op_addr_add(ctx, t0, t0, t1);
3502 tcg_temp_free(t1);
3503 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3504 gen_store_gpr(t0, rt);
3505 break;
3506#endif
3507 case OPC_LWPC:
3508 t1 = tcg_const_tl(pc_relative_pc(ctx));
3509 gen_op_addr_add(ctx, t0, t0, t1);
3510 tcg_temp_free(t1);
3511 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3512 gen_store_gpr(t0, rt);
3513 break;
3514 case OPC_LWE:
3515 mem_idx = MIPS_HFLAG_UM;
3516
3517 case OPC_LW:
3518 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3519 ctx->default_tcg_memop_mask);
3520 gen_store_gpr(t0, rt);
3521 break;
3522 case OPC_LHE:
3523 mem_idx = MIPS_HFLAG_UM;
3524
3525 case OPC_LH:
3526 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3527 ctx->default_tcg_memop_mask);
3528 gen_store_gpr(t0, rt);
3529 break;
3530 case OPC_LHUE:
3531 mem_idx = MIPS_HFLAG_UM;
3532
3533 case OPC_LHU:
3534 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3535 ctx->default_tcg_memop_mask);
3536 gen_store_gpr(t0, rt);
3537 break;
3538 case OPC_LBE:
3539 mem_idx = MIPS_HFLAG_UM;
3540
3541 case OPC_LB:
3542 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3543 gen_store_gpr(t0, rt);
3544 break;
3545 case OPC_LBUE:
3546 mem_idx = MIPS_HFLAG_UM;
3547
3548 case OPC_LBU:
3549 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3550 gen_store_gpr(t0, rt);
3551 break;
3552 case OPC_LWLE:
3553 mem_idx = MIPS_HFLAG_UM;
3554
3555 case OPC_LWL:
3556 t1 = tcg_temp_new();
3557
3558
3559
3560
3561 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3562 tcg_gen_andi_tl(t1, t0, 3);
3563#ifndef TARGET_WORDS_BIGENDIAN
3564 tcg_gen_xori_tl(t1, t1, 3);
3565#endif
3566 tcg_gen_shli_tl(t1, t1, 3);
3567 tcg_gen_andi_tl(t0, t0, ~3);
3568 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3569 tcg_gen_shl_tl(t0, t0, t1);
3570 t2 = tcg_const_tl(-1);
3571 tcg_gen_shl_tl(t2, t2, t1);
3572 gen_load_gpr(t1, rt);
3573 tcg_gen_andc_tl(t1, t1, t2);
3574 tcg_temp_free(t2);
3575 tcg_gen_or_tl(t0, t0, t1);
3576 tcg_temp_free(t1);
3577 tcg_gen_ext32s_tl(t0, t0);
3578 gen_store_gpr(t0, rt);
3579 break;
3580 case OPC_LWRE:
3581 mem_idx = MIPS_HFLAG_UM;
3582
3583 case OPC_LWR:
3584 t1 = tcg_temp_new();
3585
3586
3587
3588
3589 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3590 tcg_gen_andi_tl(t1, t0, 3);
3591#ifdef TARGET_WORDS_BIGENDIAN
3592 tcg_gen_xori_tl(t1, t1, 3);
3593#endif
3594 tcg_gen_shli_tl(t1, t1, 3);
3595 tcg_gen_andi_tl(t0, t0, ~3);
3596 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3597 tcg_gen_shr_tl(t0, t0, t1);
3598 tcg_gen_xori_tl(t1, t1, 31);
3599 t2 = tcg_const_tl(0xfffffffeull);
3600 tcg_gen_shl_tl(t2, t2, t1);
3601 gen_load_gpr(t1, rt);
3602 tcg_gen_and_tl(t1, t1, t2);
3603 tcg_temp_free(t2);
3604 tcg_gen_or_tl(t0, t0, t1);
3605 tcg_temp_free(t1);
3606 tcg_gen_ext32s_tl(t0, t0);
3607 gen_store_gpr(t0, rt);
3608 break;
3609 case OPC_LLE:
3610 mem_idx = MIPS_HFLAG_UM;
3611
3612 case OPC_LL:
3613 case R6_OPC_LL:
3614 op_ld_ll(t0, t0, mem_idx, ctx);
3615 gen_store_gpr(t0, rt);
3616 break;
3617 }
3618 tcg_temp_free(t0);
3619}
3620
3621static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3622 uint32_t reg1, uint32_t reg2)
3623{
3624 TCGv taddr = tcg_temp_new();
3625 TCGv_i64 tval = tcg_temp_new_i64();
3626 TCGv tmp1 = tcg_temp_new();
3627 TCGv tmp2 = tcg_temp_new();
3628
3629 gen_base_offset_addr(ctx, taddr, base, offset);
3630 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3631#ifdef TARGET_WORDS_BIGENDIAN
3632 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3633#else
3634 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3635#endif
3636 gen_store_gpr(tmp1, reg1);
3637 tcg_temp_free(tmp1);
3638 gen_store_gpr(tmp2, reg2);
3639 tcg_temp_free(tmp2);
3640 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3641 tcg_temp_free_i64(tval);
3642 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3643 tcg_temp_free(taddr);
3644}
3645
3646
3647static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3648 int base, int offset)
3649{
3650 TCGv t0 = tcg_temp_new();
3651 TCGv t1 = tcg_temp_new();
3652 int mem_idx = ctx->mem_idx;
3653
3654 gen_base_offset_addr(ctx, t0, base, offset);
3655 gen_load_gpr(t1, rt);
3656 switch (opc) {
3657#if defined(TARGET_MIPS64)
3658 case OPC_SD:
3659 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3660 ctx->default_tcg_memop_mask);
3661 break;
3662 case OPC_SDL:
3663 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3664 break;
3665 case OPC_SDR:
3666 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3667 break;
3668#endif
3669 case OPC_SWE:
3670 mem_idx = MIPS_HFLAG_UM;
3671
3672 case OPC_SW:
3673 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3674 ctx->default_tcg_memop_mask);
3675 break;
3676 case OPC_SHE:
3677 mem_idx = MIPS_HFLAG_UM;
3678
3679 case OPC_SH:
3680 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3681 ctx->default_tcg_memop_mask);
3682 break;
3683 case OPC_SBE:
3684 mem_idx = MIPS_HFLAG_UM;
3685
3686 case OPC_SB:
3687 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3688 break;
3689 case OPC_SWLE:
3690 mem_idx = MIPS_HFLAG_UM;
3691
3692 case OPC_SWL:
3693 gen_helper_0e2i(swl, t1, t0, mem_idx);
3694 break;
3695 case OPC_SWRE:
3696 mem_idx = MIPS_HFLAG_UM;
3697
3698 case OPC_SWR:
3699 gen_helper_0e2i(swr, t1, t0, mem_idx);
3700 break;
3701 }
3702 tcg_temp_free(t0);
3703 tcg_temp_free(t1);
3704}
3705
3706
3707
3708static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3709 TCGMemOp tcg_mo, bool eva)
3710{
3711 TCGv addr, t0, val;
3712 TCGLabel *l1 = gen_new_label();
3713 TCGLabel *done = gen_new_label();
3714
3715 t0 = tcg_temp_new();
3716 addr = tcg_temp_new();
3717
3718 gen_base_offset_addr(ctx, addr, base, offset);
3719 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3720 tcg_temp_free(addr);
3721 tcg_gen_movi_tl(t0, 0);
3722 gen_store_gpr(t0, rt);
3723 tcg_gen_br(done);
3724
3725 gen_set_label(l1);
3726
3727 val = tcg_temp_new();
3728 gen_load_gpr(val, rt);
3729 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3730 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3731 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3732 gen_store_gpr(t0, rt);
3733 tcg_temp_free(val);
3734
3735 gen_set_label(done);
3736 tcg_temp_free(t0);
3737}
3738
3739
3740static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3741 uint32_t reg1, uint32_t reg2, bool eva)
3742{
3743 TCGv taddr = tcg_temp_local_new();
3744 TCGv lladdr = tcg_temp_local_new();
3745 TCGv_i64 tval = tcg_temp_new_i64();
3746 TCGv_i64 llval = tcg_temp_new_i64();
3747 TCGv_i64 val = tcg_temp_new_i64();
3748 TCGv tmp1 = tcg_temp_new();
3749 TCGv tmp2 = tcg_temp_new();
3750 TCGLabel *lab_fail = gen_new_label();
3751 TCGLabel *lab_done = gen_new_label();
3752
3753 gen_base_offset_addr(ctx, taddr, base, offset);
3754
3755 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3756 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3757
3758 gen_load_gpr(tmp1, reg1);
3759 gen_load_gpr(tmp2, reg2);
3760
3761#ifdef TARGET_WORDS_BIGENDIAN
3762 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3763#else
3764 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3765#endif
3766
3767 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3768 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3769 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3770 if (reg1 != 0) {
3771 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3772 }
3773 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3774
3775 gen_set_label(lab_fail);
3776
3777 if (reg1 != 0) {
3778 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3779 }
3780 gen_set_label(lab_done);
3781 tcg_gen_movi_tl(lladdr, -1);
3782 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3783}
3784
3785
3786static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3787 TCGv t0)
3788{
3789
3790
3791
3792
3793 switch (opc) {
3794 case OPC_LWC1:
3795 {
3796 TCGv_i32 fp0 = tcg_temp_new_i32();
3797 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3798 ctx->default_tcg_memop_mask);
3799 gen_store_fpr32(ctx, fp0, ft);
3800 tcg_temp_free_i32(fp0);
3801 }
3802 break;
3803 case OPC_SWC1:
3804 {
3805 TCGv_i32 fp0 = tcg_temp_new_i32();
3806 gen_load_fpr32(ctx, fp0, ft);
3807 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3808 ctx->default_tcg_memop_mask);
3809 tcg_temp_free_i32(fp0);
3810 }
3811 break;
3812 case OPC_LDC1:
3813 {
3814 TCGv_i64 fp0 = tcg_temp_new_i64();
3815 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3816 ctx->default_tcg_memop_mask);
3817 gen_store_fpr64(ctx, fp0, ft);
3818 tcg_temp_free_i64(fp0);
3819 }
3820 break;
3821 case OPC_SDC1:
3822 {
3823 TCGv_i64 fp0 = tcg_temp_new_i64();
3824 gen_load_fpr64(ctx, fp0, ft);
3825 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3826 ctx->default_tcg_memop_mask);
3827 tcg_temp_free_i64(fp0);
3828 }
3829 break;
3830 default:
3831 MIPS_INVAL("flt_ldst");
3832 generate_exception_end(ctx, EXCP_RI);
3833 break;
3834 }
3835}
3836
3837static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3838 int rs, int16_t imm)
3839{
3840 TCGv t0 = tcg_temp_new();
3841
3842 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3843 check_cp1_enabled(ctx);
3844 switch (op) {
3845 case OPC_LDC1:
3846 case OPC_SDC1:
3847 check_insn(ctx, ISA_MIPS2);
3848
3849 default:
3850 gen_base_offset_addr(ctx, t0, rs, imm);
3851 gen_flt_ldst(ctx, op, rt, t0);
3852 }
3853 } else {
3854 generate_exception_err(ctx, EXCP_CpU, 1);
3855 }
3856 tcg_temp_free(t0);
3857}
3858
3859
3860static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3861 int rt, int rs, int imm)
3862{
3863 target_ulong uimm = (target_long)imm;
3864
3865 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3866
3867
3868
3869
3870 return;
3871 }
3872 switch (opc) {
3873 case OPC_ADDI:
3874 {
3875 TCGv t0 = tcg_temp_local_new();
3876 TCGv t1 = tcg_temp_new();
3877 TCGv t2 = tcg_temp_new();
3878 TCGLabel *l1 = gen_new_label();
3879
3880 gen_load_gpr(t1, rs);
3881 tcg_gen_addi_tl(t0, t1, uimm);
3882 tcg_gen_ext32s_tl(t0, t0);
3883
3884 tcg_gen_xori_tl(t1, t1, ~uimm);
3885 tcg_gen_xori_tl(t2, t0, uimm);
3886 tcg_gen_and_tl(t1, t1, t2);
3887 tcg_temp_free(t2);
3888 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3889 tcg_temp_free(t1);
3890
3891 generate_exception(ctx, EXCP_OVERFLOW);
3892 gen_set_label(l1);
3893 tcg_gen_ext32s_tl(t0, t0);
3894 gen_store_gpr(t0, rt);
3895 tcg_temp_free(t0);
3896 }
3897 break;
3898 case OPC_ADDIU:
3899 if (rs != 0) {
3900 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3901 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3902 } else {
3903 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3904 }
3905 break;
3906#if defined(TARGET_MIPS64)
3907 case OPC_DADDI:
3908 {
3909 TCGv t0 = tcg_temp_local_new();
3910 TCGv t1 = tcg_temp_new();
3911 TCGv t2 = tcg_temp_new();
3912 TCGLabel *l1 = gen_new_label();
3913
3914 gen_load_gpr(t1, rs);
3915 tcg_gen_addi_tl(t0, t1, uimm);
3916
3917 tcg_gen_xori_tl(t1, t1, ~uimm);
3918 tcg_gen_xori_tl(t2, t0, uimm);
3919 tcg_gen_and_tl(t1, t1, t2);
3920 tcg_temp_free(t2);
3921 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3922 tcg_temp_free(t1);
3923
3924 generate_exception(ctx, EXCP_OVERFLOW);
3925 gen_set_label(l1);
3926 gen_store_gpr(t0, rt);
3927 tcg_temp_free(t0);
3928 }
3929 break;
3930 case OPC_DADDIU:
3931 if (rs != 0) {
3932 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3933 } else {
3934 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3935 }
3936 break;
3937#endif
3938 }
3939}
3940
3941
3942static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3943 int rt, int rs, int16_t imm)
3944{
3945 target_ulong uimm;
3946
3947 if (rt == 0) {
3948
3949 return;
3950 }
3951 uimm = (uint16_t)imm;
3952 switch (opc) {
3953 case OPC_ANDI:
3954 if (likely(rs != 0)) {
3955 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3956 } else {
3957 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3958 }
3959 break;
3960 case OPC_ORI:
3961 if (rs != 0) {
3962 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3963 } else {
3964 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3965 }
3966 break;
3967 case OPC_XORI:
3968 if (likely(rs != 0)) {
3969 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3970 } else {
3971 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3972 }
3973 break;
3974 case OPC_LUI:
3975 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3976
3977 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3978 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3979 } else {
3980 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3981 }
3982 break;
3983
3984 default:
3985 break;
3986 }
3987}
3988
3989
3990static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3991 int rt, int rs, int16_t imm)
3992{
3993 target_ulong uimm = (target_long)imm;
3994 TCGv t0;
3995
3996 if (rt == 0) {
3997
3998 return;
3999 }
4000 t0 = tcg_temp_new();
4001 gen_load_gpr(t0, rs);
4002 switch (opc) {
4003 case OPC_SLTI:
4004 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
4005 break;
4006 case OPC_SLTIU:
4007 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
4008 break;
4009 }
4010 tcg_temp_free(t0);
4011}
4012
4013
4014static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
4015 int rt, int rs, int16_t imm)
4016{
4017 target_ulong uimm = ((uint16_t)imm) & 0x1f;
4018 TCGv t0;
4019
4020 if (rt == 0) {
4021
4022 return;
4023 }
4024
4025 t0 = tcg_temp_new();
4026 gen_load_gpr(t0, rs);
4027 switch (opc) {
4028 case OPC_SLL:
4029 tcg_gen_shli_tl(t0, t0, uimm);
4030 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4031 break;
4032 case OPC_SRA:
4033 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4034 break;
4035 case OPC_SRL:
4036 if (uimm != 0) {
4037 tcg_gen_ext32u_tl(t0, t0);
4038 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4039 } else {
4040 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4041 }
4042 break;
4043 case OPC_ROTR:
4044 if (uimm != 0) {
4045 TCGv_i32 t1 = tcg_temp_new_i32();
4046
4047 tcg_gen_trunc_tl_i32(t1, t0);
4048 tcg_gen_rotri_i32(t1, t1, uimm);
4049 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4050 tcg_temp_free_i32(t1);
4051 } else {
4052 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4053 }
4054 break;
4055#if defined(TARGET_MIPS64)
4056 case OPC_DSLL:
4057 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4058 break;
4059 case OPC_DSRA:
4060 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4061 break;
4062 case OPC_DSRL:
4063 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4064 break;
4065 case OPC_DROTR:
4066 if (uimm != 0) {
4067 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4068 } else {
4069 tcg_gen_mov_tl(cpu_gpr[rt], t0);
4070 }
4071 break;
4072 case OPC_DSLL32:
4073 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4074 break;
4075 case OPC_DSRA32:
4076 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4077 break;
4078 case OPC_DSRL32:
4079 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4080 break;
4081 case OPC_DROTR32:
4082 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4083 break;
4084#endif
4085 }
4086 tcg_temp_free(t0);
4087}
4088
4089
4090static void gen_arith(DisasContext *ctx, uint32_t opc,
4091 int rd, int rs, int rt)
4092{
4093 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4094 && opc != OPC_DADD && opc != OPC_DSUB) {
4095
4096
4097
4098
4099 return;
4100 }
4101
4102 switch (opc) {
4103 case OPC_ADD:
4104 {
4105 TCGv t0 = tcg_temp_local_new();
4106 TCGv t1 = tcg_temp_new();
4107 TCGv t2 = tcg_temp_new();
4108 TCGLabel *l1 = gen_new_label();
4109
4110 gen_load_gpr(t1, rs);
4111 gen_load_gpr(t2, rt);
4112 tcg_gen_add_tl(t0, t1, t2);
4113 tcg_gen_ext32s_tl(t0, t0);
4114 tcg_gen_xor_tl(t1, t1, t2);
4115 tcg_gen_xor_tl(t2, t0, t2);
4116 tcg_gen_andc_tl(t1, t2, t1);
4117 tcg_temp_free(t2);
4118 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4119 tcg_temp_free(t1);
4120
4121 generate_exception(ctx, EXCP_OVERFLOW);
4122 gen_set_label(l1);
4123 gen_store_gpr(t0, rd);
4124 tcg_temp_free(t0);
4125 }
4126 break;
4127 case OPC_ADDU:
4128 if (rs != 0 && rt != 0) {
4129 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4130 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4131 } else if (rs == 0 && rt != 0) {
4132 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4133 } else if (rs != 0 && rt == 0) {
4134 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4135 } else {
4136 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4137 }
4138 break;
4139 case OPC_SUB:
4140 {
4141 TCGv t0 = tcg_temp_local_new();
4142 TCGv t1 = tcg_temp_new();
4143 TCGv t2 = tcg_temp_new();
4144 TCGLabel *l1 = gen_new_label();
4145
4146 gen_load_gpr(t1, rs);
4147 gen_load_gpr(t2, rt);
4148 tcg_gen_sub_tl(t0, t1, t2);
4149 tcg_gen_ext32s_tl(t0, t0);
4150 tcg_gen_xor_tl(t2, t1, t2);
4151 tcg_gen_xor_tl(t1, t0, t1);
4152 tcg_gen_and_tl(t1, t1, t2);
4153 tcg_temp_free(t2);
4154 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4155 tcg_temp_free(t1);
4156
4157
4158
4159
4160 generate_exception(ctx, EXCP_OVERFLOW);
4161 gen_set_label(l1);
4162 gen_store_gpr(t0, rd);
4163 tcg_temp_free(t0);
4164 }
4165 break;
4166 case OPC_SUBU:
4167 if (rs != 0 && rt != 0) {
4168 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4169 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4170 } else if (rs == 0 && rt != 0) {
4171 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4172 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4173 } else if (rs != 0 && rt == 0) {
4174 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4175 } else {
4176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4177 }
4178 break;
4179#if defined(TARGET_MIPS64)
4180 case OPC_DADD:
4181 {
4182 TCGv t0 = tcg_temp_local_new();
4183 TCGv t1 = tcg_temp_new();
4184 TCGv t2 = tcg_temp_new();
4185 TCGLabel *l1 = gen_new_label();
4186
4187 gen_load_gpr(t1, rs);
4188 gen_load_gpr(t2, rt);
4189 tcg_gen_add_tl(t0, t1, t2);
4190 tcg_gen_xor_tl(t1, t1, t2);
4191 tcg_gen_xor_tl(t2, t0, t2);
4192 tcg_gen_andc_tl(t1, t2, t1);
4193 tcg_temp_free(t2);
4194 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4195 tcg_temp_free(t1);
4196
4197 generate_exception(ctx, EXCP_OVERFLOW);
4198 gen_set_label(l1);
4199 gen_store_gpr(t0, rd);
4200 tcg_temp_free(t0);
4201 }
4202 break;
4203 case OPC_DADDU:
4204 if (rs != 0 && rt != 0) {
4205 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4206 } else if (rs == 0 && rt != 0) {
4207 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4208 } else if (rs != 0 && rt == 0) {
4209 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4210 } else {
4211 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4212 }
4213 break;
4214 case OPC_DSUB:
4215 {
4216 TCGv t0 = tcg_temp_local_new();
4217 TCGv t1 = tcg_temp_new();
4218 TCGv t2 = tcg_temp_new();
4219 TCGLabel *l1 = gen_new_label();
4220
4221 gen_load_gpr(t1, rs);
4222 gen_load_gpr(t2, rt);
4223 tcg_gen_sub_tl(t0, t1, t2);
4224 tcg_gen_xor_tl(t2, t1, t2);
4225 tcg_gen_xor_tl(t1, t0, t1);
4226 tcg_gen_and_tl(t1, t1, t2);
4227 tcg_temp_free(t2);
4228 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4229 tcg_temp_free(t1);
4230
4231 generate_exception(ctx, EXCP_OVERFLOW);
4232 gen_set_label(l1);
4233 gen_store_gpr(t0, rd);
4234 tcg_temp_free(t0);
4235 }
4236 break;
4237 case OPC_DSUBU:
4238 if (rs != 0 && rt != 0) {
4239 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4240 } else if (rs == 0 && rt != 0) {
4241 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4242 } else if (rs != 0 && rt == 0) {
4243 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4244 } else {
4245 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4246 }
4247 break;
4248#endif
4249 case OPC_MUL:
4250 if (likely(rs != 0 && rt != 0)) {
4251 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4252 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4253 } else {
4254 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4255 }
4256 break;
4257 }
4258}
4259
4260
4261static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4262 int rd, int rs, int rt)
4263{
4264 TCGv t0, t1, t2;
4265
4266 if (rd == 0) {
4267
4268 return;
4269 }
4270
4271 t0 = tcg_temp_new();
4272 gen_load_gpr(t0, rt);
4273 t1 = tcg_const_tl(0);
4274 t2 = tcg_temp_new();
4275 gen_load_gpr(t2, rs);
4276 switch (opc) {
4277 case OPC_MOVN:
4278 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4279 break;
4280 case OPC_MOVZ:
4281 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4282 break;
4283 case OPC_SELNEZ:
4284 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4285 break;
4286 case OPC_SELEQZ:
4287 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4288 break;
4289 }
4290 tcg_temp_free(t2);
4291 tcg_temp_free(t1);
4292 tcg_temp_free(t0);
4293}
4294
4295
4296static void gen_logic(DisasContext *ctx, uint32_t opc,
4297 int rd, int rs, int rt)
4298{
4299 if (rd == 0) {
4300
4301 return;
4302 }
4303
4304 switch (opc) {
4305 case OPC_AND:
4306 if (likely(rs != 0 && rt != 0)) {
4307 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4308 } else {
4309 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4310 }
4311 break;
4312 case OPC_NOR:
4313 if (rs != 0 && rt != 0) {
4314 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4315 } else if (rs == 0 && rt != 0) {
4316 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4317 } else if (rs != 0 && rt == 0) {
4318 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4319 } else {
4320 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4321 }
4322 break;
4323 case OPC_OR:
4324 if (likely(rs != 0 && rt != 0)) {
4325 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4326 } else if (rs == 0 && rt != 0) {
4327 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4328 } else if (rs != 0 && rt == 0) {
4329 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4330 } else {
4331 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4332 }
4333 break;
4334 case OPC_XOR:
4335 if (likely(rs != 0 && rt != 0)) {
4336 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4337 } else if (rs == 0 && rt != 0) {
4338 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4339 } else if (rs != 0 && rt == 0) {
4340 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4341 } else {
4342 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4343 }
4344 break;
4345 }
4346}
4347
4348
4349static void gen_slt(DisasContext *ctx, uint32_t opc,
4350 int rd, int rs, int rt)
4351{
4352 TCGv t0, t1;
4353
4354 if (rd == 0) {
4355
4356 return;
4357 }
4358
4359 t0 = tcg_temp_new();
4360 t1 = tcg_temp_new();
4361 gen_load_gpr(t0, rs);
4362 gen_load_gpr(t1, rt);
4363 switch (opc) {
4364 case OPC_SLT:
4365 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4366 break;
4367 case OPC_SLTU:
4368 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4369 break;
4370 }
4371 tcg_temp_free(t0);
4372 tcg_temp_free(t1);
4373}
4374
4375
4376static void gen_shift(DisasContext *ctx, uint32_t opc,
4377 int rd, int rs, int rt)
4378{
4379 TCGv t0, t1;
4380
4381 if (rd == 0) {
4382
4383
4384
4385
4386 return;
4387 }
4388
4389 t0 = tcg_temp_new();
4390 t1 = tcg_temp_new();
4391 gen_load_gpr(t0, rs);
4392 gen_load_gpr(t1, rt);
4393 switch (opc) {
4394 case OPC_SLLV:
4395 tcg_gen_andi_tl(t0, t0, 0x1f);
4396 tcg_gen_shl_tl(t0, t1, t0);
4397 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4398 break;
4399 case OPC_SRAV:
4400 tcg_gen_andi_tl(t0, t0, 0x1f);
4401 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4402 break;
4403 case OPC_SRLV:
4404 tcg_gen_ext32u_tl(t1, t1);
4405 tcg_gen_andi_tl(t0, t0, 0x1f);
4406 tcg_gen_shr_tl(t0, t1, t0);
4407 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4408 break;
4409 case OPC_ROTRV:
4410 {
4411 TCGv_i32 t2 = tcg_temp_new_i32();
4412 TCGv_i32 t3 = tcg_temp_new_i32();
4413
4414 tcg_gen_trunc_tl_i32(t2, t0);
4415 tcg_gen_trunc_tl_i32(t3, t1);
4416 tcg_gen_andi_i32(t2, t2, 0x1f);
4417 tcg_gen_rotr_i32(t2, t3, t2);
4418 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4419 tcg_temp_free_i32(t2);
4420 tcg_temp_free_i32(t3);
4421 }
4422 break;
4423#if defined(TARGET_MIPS64)
4424 case OPC_DSLLV:
4425 tcg_gen_andi_tl(t0, t0, 0x3f);
4426 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4427 break;
4428 case OPC_DSRAV:
4429 tcg_gen_andi_tl(t0, t0, 0x3f);
4430 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4431 break;
4432 case OPC_DSRLV:
4433 tcg_gen_andi_tl(t0, t0, 0x3f);
4434 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4435 break;
4436 case OPC_DROTRV:
4437 tcg_gen_andi_tl(t0, t0, 0x3f);
4438 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4439 break;
4440#endif
4441 }
4442 tcg_temp_free(t0);
4443 tcg_temp_free(t1);
4444}
4445
4446#if defined(TARGET_MIPS64)
4447
4448static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4449{
4450 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4451
4452 return;
4453 }
4454
4455 switch (opc) {
4456 case MMI_OPC_MFHI1:
4457 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4458 break;
4459 case MMI_OPC_MFLO1:
4460 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4461 break;
4462 case MMI_OPC_MTHI1:
4463 if (reg != 0) {
4464 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4465 } else {
4466 tcg_gen_movi_tl(cpu_HI[1], 0);
4467 }
4468 break;
4469 case MMI_OPC_MTLO1:
4470 if (reg != 0) {
4471 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4472 } else {
4473 tcg_gen_movi_tl(cpu_LO[1], 0);
4474 }
4475 break;
4476 default:
4477 MIPS_INVAL("mfthilo1 TX79");
4478 generate_exception_end(ctx, EXCP_RI);
4479 break;
4480 }
4481}
4482#endif
4483
4484
4485static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4486{
4487 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4488
4489 return;
4490 }
4491
4492 if (acc != 0) {
4493 check_dsp(ctx);
4494 }
4495
4496 switch (opc) {
4497 case OPC_MFHI:
4498#if defined(TARGET_MIPS64)
4499 if (acc != 0) {
4500 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4501 } else
4502#endif
4503 {
4504 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4505 }
4506 break;
4507 case OPC_MFLO:
4508#if defined(TARGET_MIPS64)
4509 if (acc != 0) {
4510 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4511 } else
4512#endif
4513 {
4514 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4515 }
4516 break;
4517 case OPC_MTHI:
4518 if (reg != 0) {
4519#if defined(TARGET_MIPS64)
4520 if (acc != 0) {
4521 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4522 } else
4523#endif
4524 {
4525 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4526 }
4527 } else {
4528 tcg_gen_movi_tl(cpu_HI[acc], 0);
4529 }
4530 break;
4531 case OPC_MTLO:
4532 if (reg != 0) {
4533#if defined(TARGET_MIPS64)
4534 if (acc != 0) {
4535 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4536 } else
4537#endif
4538 {
4539 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4540 }
4541 } else {
4542 tcg_gen_movi_tl(cpu_LO[acc], 0);
4543 }
4544 break;
4545 }
4546}
4547
4548static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4549 TCGMemOp memop)
4550{
4551 TCGv t0 = tcg_const_tl(addr);
4552 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4553 gen_store_gpr(t0, reg);
4554 tcg_temp_free(t0);
4555}
4556
4557static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4558 int rs)
4559{
4560 target_long offset;
4561 target_long addr;
4562
4563 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4564 case OPC_ADDIUPC:
4565 if (rs != 0) {
4566 offset = sextract32(ctx->opcode << 2, 0, 21);
4567 addr = addr_add(ctx, pc, offset);
4568 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4569 }
4570 break;
4571 case R6_OPC_LWPC:
4572 offset = sextract32(ctx->opcode << 2, 0, 21);
4573 addr = addr_add(ctx, pc, offset);
4574 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4575 break;
4576#if defined(TARGET_MIPS64)
4577 case OPC_LWUPC:
4578 check_mips_64(ctx);
4579 offset = sextract32(ctx->opcode << 2, 0, 21);
4580 addr = addr_add(ctx, pc, offset);
4581 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4582 break;
4583#endif
4584 default:
4585 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4586 case OPC_AUIPC:
4587 if (rs != 0) {
4588 offset = sextract32(ctx->opcode, 0, 16) << 16;
4589 addr = addr_add(ctx, pc, offset);
4590 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4591 }
4592 break;
4593 case OPC_ALUIPC:
4594 if (rs != 0) {
4595 offset = sextract32(ctx->opcode, 0, 16) << 16;
4596 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4597 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4598 }
4599 break;
4600#if defined(TARGET_MIPS64)
4601 case R6_OPC_LDPC:
4602 case R6_OPC_LDPC + (1 << 16):
4603 case R6_OPC_LDPC + (2 << 16):
4604 case R6_OPC_LDPC + (3 << 16):
4605 check_mips_64(ctx);
4606 offset = sextract32(ctx->opcode << 3, 0, 21);
4607 addr = addr_add(ctx, (pc & ~0x7), offset);
4608 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4609 break;
4610#endif
4611 default:
4612 MIPS_INVAL("OPC_PCREL");
4613 generate_exception_end(ctx, EXCP_RI);
4614 break;
4615 }
4616 break;
4617 }
4618}
4619
4620static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4621{
4622 TCGv t0, t1;
4623
4624 if (rd == 0) {
4625
4626 return;
4627 }
4628
4629 t0 = tcg_temp_new();
4630 t1 = tcg_temp_new();
4631
4632 gen_load_gpr(t0, rs);
4633 gen_load_gpr(t1, rt);
4634
4635 switch (opc) {
4636 case R6_OPC_DIV:
4637 {
4638 TCGv t2 = tcg_temp_new();
4639 TCGv t3 = tcg_temp_new();
4640 tcg_gen_ext32s_tl(t0, t0);
4641 tcg_gen_ext32s_tl(t1, t1);
4642 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4643 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4644 tcg_gen_and_tl(t2, t2, t3);
4645 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4646 tcg_gen_or_tl(t2, t2, t3);
4647 tcg_gen_movi_tl(t3, 0);
4648 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4649 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4650 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4651 tcg_temp_free(t3);
4652 tcg_temp_free(t2);
4653 }
4654 break;
4655 case R6_OPC_MOD:
4656 {
4657 TCGv t2 = tcg_temp_new();
4658 TCGv t3 = tcg_temp_new();
4659 tcg_gen_ext32s_tl(t0, t0);
4660 tcg_gen_ext32s_tl(t1, t1);
4661 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4662 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4663 tcg_gen_and_tl(t2, t2, t3);
4664 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4665 tcg_gen_or_tl(t2, t2, t3);
4666 tcg_gen_movi_tl(t3, 0);
4667 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4668 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4669 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4670 tcg_temp_free(t3);
4671 tcg_temp_free(t2);
4672 }
4673 break;
4674 case R6_OPC_DIVU:
4675 {
4676 TCGv t2 = tcg_const_tl(0);
4677 TCGv t3 = tcg_const_tl(1);
4678 tcg_gen_ext32u_tl(t0, t0);
4679 tcg_gen_ext32u_tl(t1, t1);
4680 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4681 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4682 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4683 tcg_temp_free(t3);
4684 tcg_temp_free(t2);
4685 }
4686 break;
4687 case R6_OPC_MODU:
4688 {
4689 TCGv t2 = tcg_const_tl(0);
4690 TCGv t3 = tcg_const_tl(1);
4691 tcg_gen_ext32u_tl(t0, t0);
4692 tcg_gen_ext32u_tl(t1, t1);
4693 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4694 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4695 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4696 tcg_temp_free(t3);
4697 tcg_temp_free(t2);
4698 }
4699 break;
4700 case R6_OPC_MUL:
4701 {
4702 TCGv_i32 t2 = tcg_temp_new_i32();
4703 TCGv_i32 t3 = tcg_temp_new_i32();
4704 tcg_gen_trunc_tl_i32(t2, t0);
4705 tcg_gen_trunc_tl_i32(t3, t1);
4706 tcg_gen_mul_i32(t2, t2, t3);
4707 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4708 tcg_temp_free_i32(t2);
4709 tcg_temp_free_i32(t3);
4710 }
4711 break;
4712 case R6_OPC_MUH:
4713 {
4714 TCGv_i32 t2 = tcg_temp_new_i32();
4715 TCGv_i32 t3 = tcg_temp_new_i32();
4716 tcg_gen_trunc_tl_i32(t2, t0);
4717 tcg_gen_trunc_tl_i32(t3, t1);
4718 tcg_gen_muls2_i32(t2, t3, t2, t3);
4719 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4720 tcg_temp_free_i32(t2);
4721 tcg_temp_free_i32(t3);
4722 }
4723 break;
4724 case R6_OPC_MULU:
4725 {
4726 TCGv_i32 t2 = tcg_temp_new_i32();
4727 TCGv_i32 t3 = tcg_temp_new_i32();
4728 tcg_gen_trunc_tl_i32(t2, t0);
4729 tcg_gen_trunc_tl_i32(t3, t1);
4730 tcg_gen_mul_i32(t2, t2, t3);
4731 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4732 tcg_temp_free_i32(t2);
4733 tcg_temp_free_i32(t3);
4734 }
4735 break;
4736 case R6_OPC_MUHU:
4737 {
4738 TCGv_i32 t2 = tcg_temp_new_i32();
4739 TCGv_i32 t3 = tcg_temp_new_i32();
4740 tcg_gen_trunc_tl_i32(t2, t0);
4741 tcg_gen_trunc_tl_i32(t3, t1);
4742 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4743 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4744 tcg_temp_free_i32(t2);
4745 tcg_temp_free_i32(t3);
4746 }
4747 break;
4748#if defined(TARGET_MIPS64)
4749 case R6_OPC_DDIV:
4750 {
4751 TCGv t2 = tcg_temp_new();
4752 TCGv t3 = tcg_temp_new();
4753 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4754 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4755 tcg_gen_and_tl(t2, t2, t3);
4756 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4757 tcg_gen_or_tl(t2, t2, t3);
4758 tcg_gen_movi_tl(t3, 0);
4759 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4760 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4761 tcg_temp_free(t3);
4762 tcg_temp_free(t2);
4763 }
4764 break;
4765 case R6_OPC_DMOD:
4766 {
4767 TCGv t2 = tcg_temp_new();
4768 TCGv t3 = tcg_temp_new();
4769 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4770 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4771 tcg_gen_and_tl(t2, t2, t3);
4772 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4773 tcg_gen_or_tl(t2, t2, t3);
4774 tcg_gen_movi_tl(t3, 0);
4775 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4776 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4777 tcg_temp_free(t3);
4778 tcg_temp_free(t2);
4779 }
4780 break;
4781 case R6_OPC_DDIVU:
4782 {
4783 TCGv t2 = tcg_const_tl(0);
4784 TCGv t3 = tcg_const_tl(1);
4785 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4786 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4787 tcg_temp_free(t3);
4788 tcg_temp_free(t2);
4789 }
4790 break;
4791 case R6_OPC_DMODU:
4792 {
4793 TCGv t2 = tcg_const_tl(0);
4794 TCGv t3 = tcg_const_tl(1);
4795 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4796 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4797 tcg_temp_free(t3);
4798 tcg_temp_free(t2);
4799 }
4800 break;
4801 case R6_OPC_DMUL:
4802 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4803 break;
4804 case R6_OPC_DMUH:
4805 {
4806 TCGv t2 = tcg_temp_new();
4807 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4808 tcg_temp_free(t2);
4809 }
4810 break;
4811 case R6_OPC_DMULU:
4812 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4813 break;
4814 case R6_OPC_DMUHU:
4815 {
4816 TCGv t2 = tcg_temp_new();
4817 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4818 tcg_temp_free(t2);
4819 }
4820 break;
4821#endif
4822 default:
4823 MIPS_INVAL("r6 mul/div");
4824 generate_exception_end(ctx, EXCP_RI);
4825 goto out;
4826 }
4827 out:
4828 tcg_temp_free(t0);
4829 tcg_temp_free(t1);
4830}
4831
4832#if defined(TARGET_MIPS64)
4833static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4834{
4835 TCGv t0, t1;
4836
4837 t0 = tcg_temp_new();
4838 t1 = tcg_temp_new();
4839
4840 gen_load_gpr(t0, rs);
4841 gen_load_gpr(t1, rt);
4842
4843 switch (opc) {
4844 case MMI_OPC_DIV1:
4845 {
4846 TCGv t2 = tcg_temp_new();
4847 TCGv t3 = tcg_temp_new();
4848 tcg_gen_ext32s_tl(t0, t0);
4849 tcg_gen_ext32s_tl(t1, t1);
4850 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4851 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4852 tcg_gen_and_tl(t2, t2, t3);
4853 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4854 tcg_gen_or_tl(t2, t2, t3);
4855 tcg_gen_movi_tl(t3, 0);
4856 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4857 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4858 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4859 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4860 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4861 tcg_temp_free(t3);
4862 tcg_temp_free(t2);
4863 }
4864 break;
4865 case MMI_OPC_DIVU1:
4866 {
4867 TCGv t2 = tcg_const_tl(0);
4868 TCGv t3 = tcg_const_tl(1);
4869 tcg_gen_ext32u_tl(t0, t0);
4870 tcg_gen_ext32u_tl(t1, t1);
4871 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4872 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4873 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4874 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4875 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4876 tcg_temp_free(t3);
4877 tcg_temp_free(t2);
4878 }
4879 break;
4880 default:
4881 MIPS_INVAL("div1 TX79");
4882 generate_exception_end(ctx, EXCP_RI);
4883 goto out;
4884 }
4885 out:
4886 tcg_temp_free(t0);
4887 tcg_temp_free(t1);
4888}
4889#endif
4890
4891static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4892 int acc, int rs, int rt)
4893{
4894 TCGv t0, t1;
4895
4896 t0 = tcg_temp_new();
4897 t1 = tcg_temp_new();
4898
4899 gen_load_gpr(t0, rs);
4900 gen_load_gpr(t1, rt);
4901
4902 if (acc != 0) {
4903 check_dsp(ctx);
4904 }
4905
4906 switch (opc) {
4907 case OPC_DIV:
4908 {
4909 TCGv t2 = tcg_temp_new();
4910 TCGv t3 = tcg_temp_new();
4911 tcg_gen_ext32s_tl(t0, t0);
4912 tcg_gen_ext32s_tl(t1, t1);
4913 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4914 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4915 tcg_gen_and_tl(t2, t2, t3);
4916 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4917 tcg_gen_or_tl(t2, t2, t3);
4918 tcg_gen_movi_tl(t3, 0);
4919 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4920 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4921 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4922 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4923 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4924 tcg_temp_free(t3);
4925 tcg_temp_free(t2);
4926 }
4927 break;
4928 case OPC_DIVU:
4929 {
4930 TCGv t2 = tcg_const_tl(0);
4931 TCGv t3 = tcg_const_tl(1);
4932 tcg_gen_ext32u_tl(t0, t0);
4933 tcg_gen_ext32u_tl(t1, t1);
4934 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4935 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4936 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4937 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4938 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4939 tcg_temp_free(t3);
4940 tcg_temp_free(t2);
4941 }
4942 break;
4943 case OPC_MULT:
4944 {
4945 TCGv_i32 t2 = tcg_temp_new_i32();
4946 TCGv_i32 t3 = tcg_temp_new_i32();
4947 tcg_gen_trunc_tl_i32(t2, t0);
4948 tcg_gen_trunc_tl_i32(t3, t1);
4949 tcg_gen_muls2_i32(t2, t3, t2, t3);
4950 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4951 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4952 tcg_temp_free_i32(t2);
4953 tcg_temp_free_i32(t3);
4954 }
4955 break;
4956 case OPC_MULTU:
4957 {
4958 TCGv_i32 t2 = tcg_temp_new_i32();
4959 TCGv_i32 t3 = tcg_temp_new_i32();
4960 tcg_gen_trunc_tl_i32(t2, t0);
4961 tcg_gen_trunc_tl_i32(t3, t1);
4962 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4963 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4964 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4965 tcg_temp_free_i32(t2);
4966 tcg_temp_free_i32(t3);
4967 }
4968 break;
4969#if defined(TARGET_MIPS64)
4970 case OPC_DDIV:
4971 {
4972 TCGv t2 = tcg_temp_new();
4973 TCGv t3 = tcg_temp_new();
4974 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4975 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4976 tcg_gen_and_tl(t2, t2, t3);
4977 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4978 tcg_gen_or_tl(t2, t2, t3);
4979 tcg_gen_movi_tl(t3, 0);
4980 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4981 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4982 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4983 tcg_temp_free(t3);
4984 tcg_temp_free(t2);
4985 }
4986 break;
4987 case OPC_DDIVU:
4988 {
4989 TCGv t2 = tcg_const_tl(0);
4990 TCGv t3 = tcg_const_tl(1);
4991 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4992 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4993 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4994 tcg_temp_free(t3);
4995 tcg_temp_free(t2);
4996 }
4997 break;
4998 case OPC_DMULT:
4999 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5000 break;
5001 case OPC_DMULTU:
5002 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5003 break;
5004#endif
5005 case OPC_MADD:
5006 {
5007 TCGv_i64 t2 = tcg_temp_new_i64();
5008 TCGv_i64 t3 = tcg_temp_new_i64();
5009
5010 tcg_gen_ext_tl_i64(t2, t0);
5011 tcg_gen_ext_tl_i64(t3, t1);
5012 tcg_gen_mul_i64(t2, t2, t3);
5013 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5014 tcg_gen_add_i64(t2, t2, t3);
5015 tcg_temp_free_i64(t3);
5016 gen_move_low32(cpu_LO[acc], t2);
5017 gen_move_high32(cpu_HI[acc], t2);
5018 tcg_temp_free_i64(t2);
5019 }
5020 break;
5021 case OPC_MADDU:
5022 {
5023 TCGv_i64 t2 = tcg_temp_new_i64();
5024 TCGv_i64 t3 = tcg_temp_new_i64();
5025
5026 tcg_gen_ext32u_tl(t0, t0);
5027 tcg_gen_ext32u_tl(t1, t1);
5028 tcg_gen_extu_tl_i64(t2, t0);
5029 tcg_gen_extu_tl_i64(t3, t1);
5030 tcg_gen_mul_i64(t2, t2, t3);
5031 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5032 tcg_gen_add_i64(t2, t2, t3);
5033 tcg_temp_free_i64(t3);
5034 gen_move_low32(cpu_LO[acc], t2);
5035 gen_move_high32(cpu_HI[acc], t2);
5036 tcg_temp_free_i64(t2);
5037 }
5038 break;
5039 case OPC_MSUB:
5040 {
5041 TCGv_i64 t2 = tcg_temp_new_i64();
5042 TCGv_i64 t3 = tcg_temp_new_i64();
5043
5044 tcg_gen_ext_tl_i64(t2, t0);
5045 tcg_gen_ext_tl_i64(t3, t1);
5046 tcg_gen_mul_i64(t2, t2, t3);
5047 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5048 tcg_gen_sub_i64(t2, t3, t2);
5049 tcg_temp_free_i64(t3);
5050 gen_move_low32(cpu_LO[acc], t2);
5051 gen_move_high32(cpu_HI[acc], t2);
5052 tcg_temp_free_i64(t2);
5053 }
5054 break;
5055 case OPC_MSUBU:
5056 {
5057 TCGv_i64 t2 = tcg_temp_new_i64();
5058 TCGv_i64 t3 = tcg_temp_new_i64();
5059
5060 tcg_gen_ext32u_tl(t0, t0);
5061 tcg_gen_ext32u_tl(t1, t1);
5062 tcg_gen_extu_tl_i64(t2, t0);
5063 tcg_gen_extu_tl_i64(t3, t1);
5064 tcg_gen_mul_i64(t2, t2, t3);
5065 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5066 tcg_gen_sub_i64(t2, t3, t2);
5067 tcg_temp_free_i64(t3);
5068 gen_move_low32(cpu_LO[acc], t2);
5069 gen_move_high32(cpu_HI[acc], t2);
5070 tcg_temp_free_i64(t2);
5071 }
5072 break;
5073 default:
5074 MIPS_INVAL("mul/div");
5075 generate_exception_end(ctx, EXCP_RI);
5076 goto out;
5077 }
5078 out:
5079 tcg_temp_free(t0);
5080 tcg_temp_free(t1);
5081}
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5110 int rd, int rs, int rt)
5111{
5112 TCGv t0 = tcg_temp_new();
5113 TCGv t1 = tcg_temp_new();
5114 int acc = 0;
5115
5116 gen_load_gpr(t0, rs);
5117 gen_load_gpr(t1, rt);
5118
5119 switch (opc) {
5120 case MMI_OPC_MULT1:
5121 acc = 1;
5122
5123 case OPC_MULT:
5124 {
5125 TCGv_i32 t2 = tcg_temp_new_i32();
5126 TCGv_i32 t3 = tcg_temp_new_i32();
5127 tcg_gen_trunc_tl_i32(t2, t0);
5128 tcg_gen_trunc_tl_i32(t3, t1);
5129 tcg_gen_muls2_i32(t2, t3, t2, t3);
5130 if (rd) {
5131 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5132 }
5133 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5134 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5135 tcg_temp_free_i32(t2);
5136 tcg_temp_free_i32(t3);
5137 }
5138 break;
5139 case MMI_OPC_MULTU1:
5140 acc = 1;
5141
5142 case OPC_MULTU:
5143 {
5144 TCGv_i32 t2 = tcg_temp_new_i32();
5145 TCGv_i32 t3 = tcg_temp_new_i32();
5146 tcg_gen_trunc_tl_i32(t2, t0);
5147 tcg_gen_trunc_tl_i32(t3, t1);
5148 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5149 if (rd) {
5150 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5151 }
5152 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5153 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5154 tcg_temp_free_i32(t2);
5155 tcg_temp_free_i32(t3);
5156 }
5157 break;
5158 case MMI_OPC_MADD1:
5159 acc = 1;
5160
5161 case MMI_OPC_MADD:
5162 {
5163 TCGv_i64 t2 = tcg_temp_new_i64();
5164 TCGv_i64 t3 = tcg_temp_new_i64();
5165
5166 tcg_gen_ext_tl_i64(t2, t0);
5167 tcg_gen_ext_tl_i64(t3, t1);
5168 tcg_gen_mul_i64(t2, t2, t3);
5169 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5170 tcg_gen_add_i64(t2, t2, t3);
5171 tcg_temp_free_i64(t3);
5172 gen_move_low32(cpu_LO[acc], t2);
5173 gen_move_high32(cpu_HI[acc], t2);
5174 if (rd) {
5175 gen_move_low32(cpu_gpr[rd], t2);
5176 }
5177 tcg_temp_free_i64(t2);
5178 }
5179 break;
5180 case MMI_OPC_MADDU1:
5181 acc = 1;
5182
5183 case MMI_OPC_MADDU:
5184 {
5185 TCGv_i64 t2 = tcg_temp_new_i64();
5186 TCGv_i64 t3 = tcg_temp_new_i64();
5187
5188 tcg_gen_ext32u_tl(t0, t0);
5189 tcg_gen_ext32u_tl(t1, t1);
5190 tcg_gen_extu_tl_i64(t2, t0);
5191 tcg_gen_extu_tl_i64(t3, t1);
5192 tcg_gen_mul_i64(t2, t2, t3);
5193 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5194 tcg_gen_add_i64(t2, t2, t3);
5195 tcg_temp_free_i64(t3);
5196 gen_move_low32(cpu_LO[acc], t2);
5197 gen_move_high32(cpu_HI[acc], t2);
5198 if (rd) {
5199 gen_move_low32(cpu_gpr[rd], t2);
5200 }
5201 tcg_temp_free_i64(t2);
5202 }
5203 break;
5204 default:
5205 MIPS_INVAL("mul/madd TXx9");
5206 generate_exception_end(ctx, EXCP_RI);
5207 goto out;
5208 }
5209
5210 out:
5211 tcg_temp_free(t0);
5212 tcg_temp_free(t1);
5213}
5214
5215static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
5216 int rd, int rs, int rt)
5217{
5218 TCGv t0 = tcg_temp_new();
5219 TCGv t1 = tcg_temp_new();
5220
5221 gen_load_gpr(t0, rs);
5222 gen_load_gpr(t1, rt);
5223
5224 switch (opc) {
5225 case OPC_VR54XX_MULS:
5226 gen_helper_muls(t0, cpu_env, t0, t1);
5227 break;
5228 case OPC_VR54XX_MULSU:
5229 gen_helper_mulsu(t0, cpu_env, t0, t1);
5230 break;
5231 case OPC_VR54XX_MACC:
5232 gen_helper_macc(t0, cpu_env, t0, t1);
5233 break;
5234 case OPC_VR54XX_MACCU:
5235 gen_helper_maccu(t0, cpu_env, t0, t1);
5236 break;
5237 case OPC_VR54XX_MSAC:
5238 gen_helper_msac(t0, cpu_env, t0, t1);
5239 break;
5240 case OPC_VR54XX_MSACU:
5241 gen_helper_msacu(t0, cpu_env, t0, t1);
5242 break;
5243 case OPC_VR54XX_MULHI:
5244 gen_helper_mulhi(t0, cpu_env, t0, t1);
5245 break;
5246 case OPC_VR54XX_MULHIU:
5247 gen_helper_mulhiu(t0, cpu_env, t0, t1);
5248 break;
5249 case OPC_VR54XX_MULSHI:
5250 gen_helper_mulshi(t0, cpu_env, t0, t1);
5251 break;
5252 case OPC_VR54XX_MULSHIU:
5253 gen_helper_mulshiu(t0, cpu_env, t0, t1);
5254 break;
5255 case OPC_VR54XX_MACCHI:
5256 gen_helper_macchi(t0, cpu_env, t0, t1);
5257 break;
5258 case OPC_VR54XX_MACCHIU:
5259 gen_helper_macchiu(t0, cpu_env, t0, t1);
5260 break;
5261 case OPC_VR54XX_MSACHI:
5262 gen_helper_msachi(t0, cpu_env, t0, t1);
5263 break;
5264 case OPC_VR54XX_MSACHIU:
5265 gen_helper_msachiu(t0, cpu_env, t0, t1);
5266 break;
5267 default:
5268 MIPS_INVAL("mul vr54xx");
5269 generate_exception_end(ctx, EXCP_RI);
5270 goto out;
5271 }
5272 gen_store_gpr(t0, rd);
5273
5274 out:
5275 tcg_temp_free(t0);
5276 tcg_temp_free(t1);
5277}
5278
5279static void gen_cl(DisasContext *ctx, uint32_t opc,
5280 int rd, int rs)
5281{
5282 TCGv t0;
5283
5284 if (rd == 0) {
5285
5286 return;
5287 }
5288 t0 = cpu_gpr[rd];
5289 gen_load_gpr(t0, rs);
5290
5291 switch (opc) {
5292 case OPC_CLO:
5293 case R6_OPC_CLO:
5294#if defined(TARGET_MIPS64)
5295 case OPC_DCLO:
5296 case R6_OPC_DCLO:
5297#endif
5298 tcg_gen_not_tl(t0, t0);
5299 break;
5300 }
5301
5302 switch (opc) {
5303 case OPC_CLO:
5304 case R6_OPC_CLO:
5305 case OPC_CLZ:
5306 case R6_OPC_CLZ:
5307 tcg_gen_ext32u_tl(t0, t0);
5308 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5309 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5310 break;
5311#if defined(TARGET_MIPS64)
5312 case OPC_DCLO:
5313 case R6_OPC_DCLO:
5314 case OPC_DCLZ:
5315 case R6_OPC_DCLZ:
5316 tcg_gen_clzi_i64(t0, t0, 64);
5317 break;
5318#endif
5319 }
5320}
5321
5322
5323static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5324 int rd, int rs, int rt)
5325{
5326 TCGv t0, t1;
5327
5328 if (rd == 0) {
5329
5330 return;
5331 }
5332
5333 switch (opc) {
5334 case OPC_MULT_G_2E:
5335 case OPC_MULT_G_2F:
5336 case OPC_MULTU_G_2E:
5337 case OPC_MULTU_G_2F:
5338#if defined(TARGET_MIPS64)
5339 case OPC_DMULT_G_2E:
5340 case OPC_DMULT_G_2F:
5341 case OPC_DMULTU_G_2E:
5342 case OPC_DMULTU_G_2F:
5343#endif
5344 t0 = tcg_temp_new();
5345 t1 = tcg_temp_new();
5346 break;
5347 default:
5348 t0 = tcg_temp_local_new();
5349 t1 = tcg_temp_local_new();
5350 break;
5351 }
5352
5353 gen_load_gpr(t0, rs);
5354 gen_load_gpr(t1, rt);
5355
5356 switch (opc) {
5357 case OPC_MULT_G_2E:
5358 case OPC_MULT_G_2F:
5359 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5360 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5361 break;
5362 case OPC_MULTU_G_2E:
5363 case OPC_MULTU_G_2F:
5364 tcg_gen_ext32u_tl(t0, t0);
5365 tcg_gen_ext32u_tl(t1, t1);
5366 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5367 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5368 break;
5369 case OPC_DIV_G_2E:
5370 case OPC_DIV_G_2F:
5371 {
5372 TCGLabel *l1 = gen_new_label();
5373 TCGLabel *l2 = gen_new_label();
5374 TCGLabel *l3 = gen_new_label();
5375 tcg_gen_ext32s_tl(t0, t0);
5376 tcg_gen_ext32s_tl(t1, t1);
5377 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5378 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5379 tcg_gen_br(l3);
5380 gen_set_label(l1);
5381 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5382 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5383 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5384 tcg_gen_br(l3);
5385 gen_set_label(l2);
5386 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5387 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5388 gen_set_label(l3);
5389 }
5390 break;
5391 case OPC_DIVU_G_2E:
5392 case OPC_DIVU_G_2F:
5393 {
5394 TCGLabel *l1 = gen_new_label();
5395 TCGLabel *l2 = gen_new_label();
5396 tcg_gen_ext32u_tl(t0, t0);
5397 tcg_gen_ext32u_tl(t1, t1);
5398 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5399 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5400 tcg_gen_br(l2);
5401 gen_set_label(l1);
5402 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5403 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5404 gen_set_label(l2);
5405 }
5406 break;
5407 case OPC_MOD_G_2E:
5408 case OPC_MOD_G_2F:
5409 {
5410 TCGLabel *l1 = gen_new_label();
5411 TCGLabel *l2 = gen_new_label();
5412 TCGLabel *l3 = gen_new_label();
5413 tcg_gen_ext32u_tl(t0, t0);
5414 tcg_gen_ext32u_tl(t1, t1);
5415 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5416 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5417 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5418 gen_set_label(l1);
5419 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5420 tcg_gen_br(l3);
5421 gen_set_label(l2);
5422 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5423 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5424 gen_set_label(l3);
5425 }
5426 break;
5427 case OPC_MODU_G_2E:
5428 case OPC_MODU_G_2F:
5429 {
5430 TCGLabel *l1 = gen_new_label();
5431 TCGLabel *l2 = gen_new_label();
5432 tcg_gen_ext32u_tl(t0, t0);
5433 tcg_gen_ext32u_tl(t1, t1);
5434 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5435 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5436 tcg_gen_br(l2);
5437 gen_set_label(l1);
5438 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5439 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5440 gen_set_label(l2);
5441 }
5442 break;
5443#if defined(TARGET_MIPS64)
5444 case OPC_DMULT_G_2E:
5445 case OPC_DMULT_G_2F:
5446 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5447 break;
5448 case OPC_DMULTU_G_2E:
5449 case OPC_DMULTU_G_2F:
5450 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5451 break;
5452 case OPC_DDIV_G_2E:
5453 case OPC_DDIV_G_2F:
5454 {
5455 TCGLabel *l1 = gen_new_label();
5456 TCGLabel *l2 = gen_new_label();
5457 TCGLabel *l3 = gen_new_label();
5458 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5459 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5460 tcg_gen_br(l3);
5461 gen_set_label(l1);
5462 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5463 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5464 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5465 tcg_gen_br(l3);
5466 gen_set_label(l2);
5467 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5468 gen_set_label(l3);
5469 }
5470 break;
5471 case OPC_DDIVU_G_2E:
5472 case OPC_DDIVU_G_2F:
5473 {
5474 TCGLabel *l1 = gen_new_label();
5475 TCGLabel *l2 = gen_new_label();
5476 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5477 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5478 tcg_gen_br(l2);
5479 gen_set_label(l1);
5480 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5481 gen_set_label(l2);
5482 }
5483 break;
5484 case OPC_DMOD_G_2E:
5485 case OPC_DMOD_G_2F:
5486 {
5487 TCGLabel *l1 = gen_new_label();
5488 TCGLabel *l2 = gen_new_label();
5489 TCGLabel *l3 = gen_new_label();
5490 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5491 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5492 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5493 gen_set_label(l1);
5494 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5495 tcg_gen_br(l3);
5496 gen_set_label(l2);
5497 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5498 gen_set_label(l3);
5499 }
5500 break;
5501 case OPC_DMODU_G_2E:
5502 case OPC_DMODU_G_2F:
5503 {
5504 TCGLabel *l1 = gen_new_label();
5505 TCGLabel *l2 = gen_new_label();
5506 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5507 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5508 tcg_gen_br(l2);
5509 gen_set_label(l1);
5510 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5511 gen_set_label(l2);
5512 }
5513 break;
5514#endif
5515 }
5516
5517 tcg_temp_free(t0);
5518 tcg_temp_free(t1);
5519}
5520
5521
5522static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5523{
5524 uint32_t opc, shift_max;
5525 TCGv_i64 t0, t1;
5526
5527 opc = MASK_LMI(ctx->opcode);
5528 switch (opc) {
5529 case OPC_ADD_CP2:
5530 case OPC_SUB_CP2:
5531 case OPC_DADD_CP2:
5532 case OPC_DSUB_CP2:
5533 t0 = tcg_temp_local_new_i64();
5534 t1 = tcg_temp_local_new_i64();
5535 break;
5536 default:
5537 t0 = tcg_temp_new_i64();
5538 t1 = tcg_temp_new_i64();
5539 break;
5540 }
5541
5542 check_cp1_enabled(ctx);
5543 gen_load_fpr64(ctx, t0, rs);
5544 gen_load_fpr64(ctx, t1, rt);
5545
5546#define LMI_HELPER(UP, LO) \
5547 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5548#define LMI_HELPER_1(UP, LO) \
5549 case OPC_##UP: gen_helper_##LO(t0, t0); break
5550#define LMI_DIRECT(UP, LO, OP) \
5551 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5552
5553 switch (opc) {
5554 LMI_HELPER(PADDSH, paddsh);
5555 LMI_HELPER(PADDUSH, paddush);
5556 LMI_HELPER(PADDH, paddh);
5557 LMI_HELPER(PADDW, paddw);
5558 LMI_HELPER(PADDSB, paddsb);
5559 LMI_HELPER(PADDUSB, paddusb);
5560 LMI_HELPER(PADDB, paddb);
5561
5562 LMI_HELPER(PSUBSH, psubsh);
5563 LMI_HELPER(PSUBUSH, psubush);
5564 LMI_HELPER(PSUBH, psubh);
5565 LMI_HELPER(PSUBW, psubw);
5566 LMI_HELPER(PSUBSB, psubsb);
5567 LMI_HELPER(PSUBUSB, psubusb);
5568 LMI_HELPER(PSUBB, psubb);
5569
5570 LMI_HELPER(PSHUFH, pshufh);
5571 LMI_HELPER(PACKSSWH, packsswh);
5572 LMI_HELPER(PACKSSHB, packsshb);
5573 LMI_HELPER(PACKUSHB, packushb);
5574
5575 LMI_HELPER(PUNPCKLHW, punpcklhw);
5576 LMI_HELPER(PUNPCKHHW, punpckhhw);
5577 LMI_HELPER(PUNPCKLBH, punpcklbh);
5578 LMI_HELPER(PUNPCKHBH, punpckhbh);
5579 LMI_HELPER(PUNPCKLWD, punpcklwd);
5580 LMI_HELPER(PUNPCKHWD, punpckhwd);
5581
5582 LMI_HELPER(PAVGH, pavgh);
5583 LMI_HELPER(PAVGB, pavgb);
5584 LMI_HELPER(PMAXSH, pmaxsh);
5585 LMI_HELPER(PMINSH, pminsh);
5586 LMI_HELPER(PMAXUB, pmaxub);
5587 LMI_HELPER(PMINUB, pminub);
5588
5589 LMI_HELPER(PCMPEQW, pcmpeqw);
5590 LMI_HELPER(PCMPGTW, pcmpgtw);
5591 LMI_HELPER(PCMPEQH, pcmpeqh);
5592 LMI_HELPER(PCMPGTH, pcmpgth);
5593 LMI_HELPER(PCMPEQB, pcmpeqb);
5594 LMI_HELPER(PCMPGTB, pcmpgtb);
5595
5596 LMI_HELPER(PSLLW, psllw);
5597 LMI_HELPER(PSLLH, psllh);
5598 LMI_HELPER(PSRLW, psrlw);
5599 LMI_HELPER(PSRLH, psrlh);
5600 LMI_HELPER(PSRAW, psraw);
5601 LMI_HELPER(PSRAH, psrah);
5602
5603 LMI_HELPER(PMULLH, pmullh);
5604 LMI_HELPER(PMULHH, pmulhh);
5605 LMI_HELPER(PMULHUH, pmulhuh);
5606 LMI_HELPER(PMADDHW, pmaddhw);
5607
5608 LMI_HELPER(PASUBUB, pasubub);
5609 LMI_HELPER_1(BIADD, biadd);
5610 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5611
5612 LMI_DIRECT(PADDD, paddd, add);
5613 LMI_DIRECT(PSUBD, psubd, sub);
5614 LMI_DIRECT(XOR_CP2, xor, xor);
5615 LMI_DIRECT(NOR_CP2, nor, nor);
5616 LMI_DIRECT(AND_CP2, and, and);
5617 LMI_DIRECT(OR_CP2, or, or);
5618
5619 case OPC_PANDN:
5620 tcg_gen_andc_i64(t0, t1, t0);
5621 break;
5622
5623 case OPC_PINSRH_0:
5624 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5625 break;
5626 case OPC_PINSRH_1:
5627 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5628 break;
5629 case OPC_PINSRH_2:
5630 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5631 break;
5632 case OPC_PINSRH_3:
5633 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5634 break;
5635
5636 case OPC_PEXTRH:
5637 tcg_gen_andi_i64(t1, t1, 3);
5638 tcg_gen_shli_i64(t1, t1, 4);
5639 tcg_gen_shr_i64(t0, t0, t1);
5640 tcg_gen_ext16u_i64(t0, t0);
5641 break;
5642
5643 case OPC_ADDU_CP2:
5644 tcg_gen_add_i64(t0, t0, t1);
5645 tcg_gen_ext32s_i64(t0, t0);
5646 break;
5647 case OPC_SUBU_CP2:
5648 tcg_gen_sub_i64(t0, t0, t1);
5649 tcg_gen_ext32s_i64(t0, t0);
5650 break;
5651
5652 case OPC_SLL_CP2:
5653 shift_max = 32;
5654 goto do_shift;
5655 case OPC_SRL_CP2:
5656 shift_max = 32;
5657 goto do_shift;
5658 case OPC_SRA_CP2:
5659 shift_max = 32;
5660 goto do_shift;
5661 case OPC_DSLL_CP2:
5662 shift_max = 64;
5663 goto do_shift;
5664 case OPC_DSRL_CP2:
5665 shift_max = 64;
5666 goto do_shift;
5667 case OPC_DSRA_CP2:
5668 shift_max = 64;
5669 goto do_shift;
5670 do_shift:
5671
5672 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5673
5674 switch (opc) {
5675 case OPC_SLL_CP2:
5676 case OPC_DSLL_CP2:
5677 tcg_gen_shl_i64(t0, t0, t1);
5678 break;
5679 case OPC_SRA_CP2:
5680 case OPC_DSRA_CP2:
5681
5682
5683
5684
5685 tcg_gen_sar_i64(t0, t0, t1);
5686 break;
5687 case OPC_SRL_CP2:
5688
5689 tcg_gen_ext32u_i64(t0, t0);
5690
5691 case OPC_DSRL_CP2:
5692 tcg_gen_shr_i64(t0, t0, t1);
5693 break;
5694 }
5695
5696 if (shift_max == 32) {
5697 tcg_gen_ext32s_i64(t0, t0);
5698 }
5699
5700
5701 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5702 tcg_gen_neg_i64(t1, t1);
5703 tcg_gen_and_i64(t0, t0, t1);
5704 break;
5705
5706 case OPC_ADD_CP2:
5707 case OPC_DADD_CP2:
5708 {
5709 TCGv_i64 t2 = tcg_temp_new_i64();
5710 TCGLabel *lab = gen_new_label();
5711
5712 tcg_gen_mov_i64(t2, t0);
5713 tcg_gen_add_i64(t0, t1, t2);
5714 if (opc == OPC_ADD_CP2) {
5715 tcg_gen_ext32s_i64(t0, t0);
5716 }
5717 tcg_gen_xor_i64(t1, t1, t2);
5718 tcg_gen_xor_i64(t2, t2, t0);
5719 tcg_gen_andc_i64(t1, t2, t1);
5720 tcg_temp_free_i64(t2);
5721 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5722 generate_exception(ctx, EXCP_OVERFLOW);
5723 gen_set_label(lab);
5724 break;
5725 }
5726
5727 case OPC_SUB_CP2:
5728 case OPC_DSUB_CP2:
5729 {
5730 TCGv_i64 t2 = tcg_temp_new_i64();
5731 TCGLabel *lab = gen_new_label();
5732
5733 tcg_gen_mov_i64(t2, t0);
5734 tcg_gen_sub_i64(t0, t1, t2);
5735 if (opc == OPC_SUB_CP2) {
5736 tcg_gen_ext32s_i64(t0, t0);
5737 }
5738 tcg_gen_xor_i64(t1, t1, t2);
5739 tcg_gen_xor_i64(t2, t2, t0);
5740 tcg_gen_and_i64(t1, t1, t2);
5741 tcg_temp_free_i64(t2);
5742 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5743 generate_exception(ctx, EXCP_OVERFLOW);
5744 gen_set_label(lab);
5745 break;
5746 }
5747
5748 case OPC_PMULUW:
5749 tcg_gen_ext32u_i64(t0, t0);
5750 tcg_gen_ext32u_i64(t1, t1);
5751 tcg_gen_mul_i64(t0, t0, t1);
5752 break;
5753
5754 case OPC_SEQU_CP2:
5755 case OPC_SEQ_CP2:
5756 case OPC_SLTU_CP2:
5757 case OPC_SLT_CP2:
5758 case OPC_SLEU_CP2:
5759 case OPC_SLE_CP2:
5760
5761
5762
5763
5764 default:
5765 MIPS_INVAL("loongson_cp2");
5766 generate_exception_end(ctx, EXCP_RI);
5767 return;
5768 }
5769
5770#undef LMI_HELPER
5771#undef LMI_DIRECT
5772
5773 gen_store_fpr64(ctx, t0, rd);
5774
5775 tcg_temp_free_i64(t0);
5776 tcg_temp_free_i64(t1);
5777}
5778
5779
5780static void gen_trap (DisasContext *ctx, uint32_t opc,
5781 int rs, int rt, int16_t imm)
5782{
5783 int cond;
5784 TCGv t0 = tcg_temp_new();
5785 TCGv t1 = tcg_temp_new();
5786
5787 cond = 0;
5788
5789 switch (opc) {
5790 case OPC_TEQ:
5791 case OPC_TGE:
5792 case OPC_TGEU:
5793 case OPC_TLT:
5794 case OPC_TLTU:
5795 case OPC_TNE:
5796
5797 if (rs != rt) {
5798 gen_load_gpr(t0, rs);
5799 gen_load_gpr(t1, rt);
5800 cond = 1;
5801 }
5802 break;
5803 case OPC_TEQI:
5804 case OPC_TGEI:
5805 case OPC_TGEIU:
5806 case OPC_TLTI:
5807 case OPC_TLTIU:
5808 case OPC_TNEI:
5809
5810 if (rs != 0 || imm != 0) {
5811 gen_load_gpr(t0, rs);
5812 tcg_gen_movi_tl(t1, (int32_t)imm);
5813 cond = 1;
5814 }
5815 break;
5816 }
5817 if (cond == 0) {
5818 switch (opc) {
5819 case OPC_TEQ:
5820 case OPC_TEQI:
5821 case OPC_TGE:
5822 case OPC_TGEI:
5823 case OPC_TGEU:
5824 case OPC_TGEIU:
5825
5826 generate_exception_end(ctx, EXCP_TRAP);
5827 break;
5828 case OPC_TLT:
5829 case OPC_TLTI:
5830 case OPC_TLTU:
5831 case OPC_TLTIU:
5832 case OPC_TNE:
5833 case OPC_TNEI:
5834
5835 break;
5836 }
5837 } else {
5838 TCGLabel *l1 = gen_new_label();
5839
5840 switch (opc) {
5841 case OPC_TEQ:
5842 case OPC_TEQI:
5843 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5844 break;
5845 case OPC_TGE:
5846 case OPC_TGEI:
5847 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5848 break;
5849 case OPC_TGEU:
5850 case OPC_TGEIU:
5851 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5852 break;
5853 case OPC_TLT:
5854 case OPC_TLTI:
5855 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5856 break;
5857 case OPC_TLTU:
5858 case OPC_TLTIU:
5859 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5860 break;
5861 case OPC_TNE:
5862 case OPC_TNEI:
5863 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5864 break;
5865 }
5866 generate_exception(ctx, EXCP_TRAP);
5867 gen_set_label(l1);
5868 }
5869 tcg_temp_free(t0);
5870 tcg_temp_free(t1);
5871}
5872
5873static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5874{
5875 if (unlikely(ctx->base.singlestep_enabled)) {
5876 return false;
5877 }
5878
5879#ifndef CONFIG_USER_ONLY
5880 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5881#else
5882 return true;
5883#endif
5884}
5885
5886static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5887{
5888 if (use_goto_tb(ctx, dest)) {
5889 tcg_gen_goto_tb(n);
5890 gen_save_pc(dest);
5891 tcg_gen_exit_tb(ctx->base.tb, n);
5892 } else {
5893 gen_save_pc(dest);
5894 if (ctx->base.singlestep_enabled) {
5895 save_cpu_state(ctx, 0);
5896 gen_helper_raise_exception_debug(cpu_env);
5897 }
5898 tcg_gen_lookup_and_goto_ptr();
5899 }
5900}
5901
5902
5903static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5904 int insn_bytes,
5905 int rs, int rt, int32_t offset,
5906 int delayslot_size)
5907{
5908 target_ulong btgt = -1;
5909 int blink = 0;
5910 int bcond_compute = 0;
5911 TCGv t0 = tcg_temp_new();
5912 TCGv t1 = tcg_temp_new();
5913
5914 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5915#ifdef MIPS_DEBUG_DISAS
5916 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5917 TARGET_FMT_lx "\n", ctx->base.pc_next);
5918#endif
5919 generate_exception_end(ctx, EXCP_RI);
5920 goto out;
5921 }
5922
5923
5924 switch (opc) {
5925 case OPC_BEQ:
5926 case OPC_BEQL:
5927 case OPC_BNE:
5928 case OPC_BNEL:
5929
5930 if (rs != rt) {
5931 gen_load_gpr(t0, rs);
5932 gen_load_gpr(t1, rt);
5933 bcond_compute = 1;
5934 }
5935 btgt = ctx->base.pc_next + insn_bytes + offset;
5936 break;
5937 case OPC_BGEZ:
5938 case OPC_BGEZAL:
5939 case OPC_BGEZALL:
5940 case OPC_BGEZL:
5941 case OPC_BGTZ:
5942 case OPC_BGTZL:
5943 case OPC_BLEZ:
5944 case OPC_BLEZL:
5945 case OPC_BLTZ:
5946 case OPC_BLTZAL:
5947 case OPC_BLTZALL:
5948 case OPC_BLTZL:
5949
5950 if (rs != 0) {
5951 gen_load_gpr(t0, rs);
5952 bcond_compute = 1;
5953 }
5954 btgt = ctx->base.pc_next + insn_bytes + offset;
5955 break;
5956 case OPC_BPOSGE32:
5957#if defined(TARGET_MIPS64)
5958 case OPC_BPOSGE64:
5959 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5960#else
5961 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5962#endif
5963 bcond_compute = 1;
5964 btgt = ctx->base.pc_next + insn_bytes + offset;
5965 break;
5966 case OPC_J:
5967 case OPC_JAL:
5968 case OPC_JALX:
5969
5970 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5971 (uint32_t)offset;
5972 break;
5973 case OPC_JR:
5974 case OPC_JALR:
5975
5976 if (offset != 0 && offset != 16) {
5977
5978
5979
5980
5981 MIPS_INVAL("jump hint");
5982 generate_exception_end(ctx, EXCP_RI);
5983 goto out;
5984 }
5985 gen_load_gpr(btarget, rs);
5986 break;
5987 default:
5988 MIPS_INVAL("branch/jump");
5989 generate_exception_end(ctx, EXCP_RI);
5990 goto out;
5991 }
5992 if (bcond_compute == 0) {
5993
5994 switch (opc) {
5995 case OPC_BEQ:
5996 case OPC_BEQL:
5997 case OPC_BGEZ:
5998 case OPC_BGEZL:
5999 case OPC_BLEZ:
6000 case OPC_BLEZL:
6001
6002 ctx->hflags |= MIPS_HFLAG_B;
6003 break;
6004 case OPC_BGEZAL:
6005 case OPC_BGEZALL:
6006
6007 blink = 31;
6008 ctx->hflags |= MIPS_HFLAG_B;
6009 break;
6010 case OPC_BNE:
6011 case OPC_BGTZ:
6012 case OPC_BLTZ:
6013
6014 goto out;
6015 case OPC_BLTZAL:
6016
6017
6018
6019
6020 blink = 31;
6021 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
6022 ctx->hflags |= MIPS_HFLAG_B;
6023 break;
6024 case OPC_BLTZALL:
6025 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6026
6027 ctx->base.pc_next += 4;
6028 goto out;
6029 case OPC_BNEL:
6030 case OPC_BGTZL:
6031 case OPC_BLTZL:
6032
6033 ctx->base.pc_next += 4;
6034 goto out;
6035 case OPC_J:
6036 ctx->hflags |= MIPS_HFLAG_B;
6037 break;
6038 case OPC_JALX:
6039 ctx->hflags |= MIPS_HFLAG_BX;
6040
6041 case OPC_JAL:
6042 blink = 31;
6043 ctx->hflags |= MIPS_HFLAG_B;
6044 break;
6045 case OPC_JR:
6046 ctx->hflags |= MIPS_HFLAG_BR;
6047 break;
6048 case OPC_JALR:
6049 blink = rt;
6050 ctx->hflags |= MIPS_HFLAG_BR;
6051 break;
6052 default:
6053 MIPS_INVAL("branch/jump");
6054 generate_exception_end(ctx, EXCP_RI);
6055 goto out;
6056 }
6057 } else {
6058 switch (opc) {
6059 case OPC_BEQ:
6060 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6061 goto not_likely;
6062 case OPC_BEQL:
6063 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6064 goto likely;
6065 case OPC_BNE:
6066 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6067 goto not_likely;
6068 case OPC_BNEL:
6069 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6070 goto likely;
6071 case OPC_BGEZ:
6072 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6073 goto not_likely;
6074 case OPC_BGEZL:
6075 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6076 goto likely;
6077 case OPC_BGEZAL:
6078 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6079 blink = 31;
6080 goto not_likely;
6081 case OPC_BGEZALL:
6082 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6083 blink = 31;
6084 goto likely;
6085 case OPC_BGTZ:
6086 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6087 goto not_likely;
6088 case OPC_BGTZL:
6089 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6090 goto likely;
6091 case OPC_BLEZ:
6092 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6093 goto not_likely;
6094 case OPC_BLEZL:
6095 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6096 goto likely;
6097 case OPC_BLTZ:
6098 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6099 goto not_likely;
6100 case OPC_BLTZL:
6101 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6102 goto likely;
6103 case OPC_BPOSGE32:
6104 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6105 goto not_likely;
6106#if defined(TARGET_MIPS64)
6107 case OPC_BPOSGE64:
6108 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6109 goto not_likely;
6110#endif
6111 case OPC_BLTZAL:
6112 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6113 blink = 31;
6114 not_likely:
6115 ctx->hflags |= MIPS_HFLAG_BC;
6116 break;
6117 case OPC_BLTZALL:
6118 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6119 blink = 31;
6120 likely:
6121 ctx->hflags |= MIPS_HFLAG_BL;
6122 break;
6123 default:
6124 MIPS_INVAL("conditional branch/jump");
6125 generate_exception_end(ctx, EXCP_RI);
6126 goto out;
6127 }
6128 }
6129
6130 ctx->btarget = btgt;
6131
6132 switch (delayslot_size) {
6133 case 2:
6134 ctx->hflags |= MIPS_HFLAG_BDS16;
6135 break;
6136 case 4:
6137 ctx->hflags |= MIPS_HFLAG_BDS32;
6138 break;
6139 }
6140
6141 if (blink > 0) {
6142 int post_delay = insn_bytes + delayslot_size;
6143 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6144
6145 tcg_gen_movi_tl(cpu_gpr[blink],
6146 ctx->base.pc_next + post_delay + lowbit);
6147 }
6148
6149 out:
6150 if (insn_bytes == 2) {
6151 ctx->hflags |= MIPS_HFLAG_B16;
6152 }
6153 tcg_temp_free(t0);
6154 tcg_temp_free(t1);
6155}
6156
6157
6158
6159static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6160 int insn_bytes,
6161 int rs, int rt, int32_t offset)
6162{
6163 target_ulong btgt = -1;
6164 int bcond_compute = 0;
6165 TCGv t0 = tcg_temp_new();
6166 TCGv t1 = tcg_temp_new();
6167
6168
6169 switch (opc) {
6170 case OPC_BEQ:
6171 case OPC_BNE:
6172
6173 if (rs != rt) {
6174 gen_load_gpr(t0, rs);
6175 gen_load_gpr(t1, rt);
6176 bcond_compute = 1;
6177 }
6178 btgt = ctx->base.pc_next + insn_bytes + offset;
6179 break;
6180 case OPC_BGEZAL:
6181
6182 if (rs != 0) {
6183 gen_load_gpr(t0, rs);
6184 bcond_compute = 1;
6185 }
6186 btgt = ctx->base.pc_next + insn_bytes + offset;
6187 break;
6188 case OPC_BPOSGE32:
6189 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6190 bcond_compute = 1;
6191 btgt = ctx->base.pc_next + insn_bytes + offset;
6192 break;
6193 case OPC_JR:
6194 case OPC_JALR:
6195
6196 if (offset != 0 && offset != 16) {
6197
6198
6199
6200
6201 MIPS_INVAL("jump hint");
6202 generate_exception_end(ctx, EXCP_RI);
6203 goto out;
6204 }
6205 gen_load_gpr(btarget, rs);
6206 break;
6207 default:
6208 MIPS_INVAL("branch/jump");
6209 generate_exception_end(ctx, EXCP_RI);
6210 goto out;
6211 }
6212 if (bcond_compute == 0) {
6213
6214 switch (opc) {
6215 case OPC_BEQ:
6216
6217 ctx->hflags |= MIPS_HFLAG_B;
6218 break;
6219 case OPC_BGEZAL:
6220
6221 tcg_gen_movi_tl(cpu_gpr[31],
6222 ctx->base.pc_next + insn_bytes);
6223 ctx->hflags |= MIPS_HFLAG_B;
6224 break;
6225 case OPC_BNE:
6226 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6227
6228 ctx->base.pc_next += 4;
6229 goto out;
6230 case OPC_JR:
6231 ctx->hflags |= MIPS_HFLAG_BR;
6232 break;
6233 case OPC_JALR:
6234 if (rt > 0) {
6235 tcg_gen_movi_tl(cpu_gpr[rt],
6236 ctx->base.pc_next + insn_bytes);
6237 }
6238 ctx->hflags |= MIPS_HFLAG_BR;
6239 break;
6240 default:
6241 MIPS_INVAL("branch/jump");
6242 generate_exception_end(ctx, EXCP_RI);
6243 goto out;
6244 }
6245 } else {
6246 switch (opc) {
6247 case OPC_BEQ:
6248 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6249 goto not_likely;
6250 case OPC_BNE:
6251 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6252 goto not_likely;
6253 case OPC_BGEZAL:
6254 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6255 tcg_gen_movi_tl(cpu_gpr[31],
6256 ctx->base.pc_next + insn_bytes);
6257 goto not_likely;
6258 case OPC_BPOSGE32:
6259 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6260 not_likely:
6261 ctx->hflags |= MIPS_HFLAG_BC;
6262 break;
6263 default:
6264 MIPS_INVAL("conditional branch/jump");
6265 generate_exception_end(ctx, EXCP_RI);
6266 goto out;
6267 }
6268 }
6269
6270 ctx->btarget = btgt;
6271
6272 out:
6273 if (insn_bytes == 2) {
6274 ctx->hflags |= MIPS_HFLAG_B16;
6275 }
6276 tcg_temp_free(t0);
6277 tcg_temp_free(t1);
6278}
6279
6280
6281
6282static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
6283 int rs, int lsb, int msb)
6284{
6285 TCGv t0 = tcg_temp_new();
6286 TCGv t1 = tcg_temp_new();
6287
6288 gen_load_gpr(t1, rs);
6289 switch (opc) {
6290 case OPC_EXT:
6291 if (lsb + msb > 31) {
6292 goto fail;
6293 }
6294 if (msb != 31) {
6295 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6296 } else {
6297
6298
6299
6300
6301 tcg_gen_ext32s_tl(t0, t1);
6302 }
6303 break;
6304#if defined(TARGET_MIPS64)
6305 case OPC_DEXTU:
6306 lsb += 32;
6307 goto do_dext;
6308 case OPC_DEXTM:
6309 msb += 32;
6310 goto do_dext;
6311 case OPC_DEXT:
6312 do_dext:
6313 if (lsb + msb > 63) {
6314 goto fail;
6315 }
6316 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6317 break;
6318#endif
6319 case OPC_INS:
6320 if (lsb > msb) {
6321 goto fail;
6322 }
6323 gen_load_gpr(t0, rt);
6324 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6325 tcg_gen_ext32s_tl(t0, t0);
6326 break;
6327#if defined(TARGET_MIPS64)
6328 case OPC_DINSU:
6329 lsb += 32;
6330
6331 case OPC_DINSM:
6332 msb += 32;
6333
6334 case OPC_DINS:
6335 if (lsb > msb) {
6336 goto fail;
6337 }
6338 gen_load_gpr(t0, rt);
6339 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6340 break;
6341#endif
6342 default:
6343fail:
6344 MIPS_INVAL("bitops");
6345 generate_exception_end(ctx, EXCP_RI);
6346 tcg_temp_free(t0);
6347 tcg_temp_free(t1);
6348 return;
6349 }
6350 gen_store_gpr(t0, rt);
6351 tcg_temp_free(t0);
6352 tcg_temp_free(t1);
6353}
6354
6355static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
6356{
6357 TCGv t0;
6358
6359 if (rd == 0) {
6360
6361 return;
6362 }
6363
6364 t0 = tcg_temp_new();
6365 gen_load_gpr(t0, rt);
6366 switch (op2) {
6367 case OPC_WSBH:
6368 {
6369 TCGv t1 = tcg_temp_new();
6370 TCGv t2 = tcg_const_tl(0x00FF00FF);
6371
6372 tcg_gen_shri_tl(t1, t0, 8);
6373 tcg_gen_and_tl(t1, t1, t2);
6374 tcg_gen_and_tl(t0, t0, t2);
6375 tcg_gen_shli_tl(t0, t0, 8);
6376 tcg_gen_or_tl(t0, t0, t1);
6377 tcg_temp_free(t2);
6378 tcg_temp_free(t1);
6379 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6380 }
6381 break;
6382 case OPC_SEB:
6383 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6384 break;
6385 case OPC_SEH:
6386 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6387 break;
6388#if defined(TARGET_MIPS64)
6389 case OPC_DSBH:
6390 {
6391 TCGv t1 = tcg_temp_new();
6392 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6393
6394 tcg_gen_shri_tl(t1, t0, 8);
6395 tcg_gen_and_tl(t1, t1, t2);
6396 tcg_gen_and_tl(t0, t0, t2);
6397 tcg_gen_shli_tl(t0, t0, 8);
6398 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6399 tcg_temp_free(t2);
6400 tcg_temp_free(t1);
6401 }
6402 break;
6403 case OPC_DSHD:
6404 {
6405 TCGv t1 = tcg_temp_new();
6406 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6407
6408 tcg_gen_shri_tl(t1, t0, 16);
6409 tcg_gen_and_tl(t1, t1, t2);
6410 tcg_gen_and_tl(t0, t0, t2);
6411 tcg_gen_shli_tl(t0, t0, 16);
6412 tcg_gen_or_tl(t0, t0, t1);
6413 tcg_gen_shri_tl(t1, t0, 32);
6414 tcg_gen_shli_tl(t0, t0, 32);
6415 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6416 tcg_temp_free(t2);
6417 tcg_temp_free(t1);
6418 }
6419 break;
6420#endif
6421 default:
6422 MIPS_INVAL("bsfhl");
6423 generate_exception_end(ctx, EXCP_RI);
6424 tcg_temp_free(t0);
6425 return;
6426 }
6427 tcg_temp_free(t0);
6428}
6429
6430static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6431 int imm2)
6432{
6433 TCGv t0;
6434 TCGv t1;
6435 if (rd == 0) {
6436
6437 return;
6438 }
6439 t0 = tcg_temp_new();
6440 t1 = tcg_temp_new();
6441 gen_load_gpr(t0, rs);
6442 gen_load_gpr(t1, rt);
6443 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6444 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6445 if (opc == OPC_LSA) {
6446 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6447 }
6448
6449 tcg_temp_free(t1);
6450 tcg_temp_free(t0);
6451
6452 return;
6453}
6454
6455static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6456 int rt, int bits)
6457{
6458 TCGv t0;
6459 if (rd == 0) {
6460
6461 return;
6462 }
6463 t0 = tcg_temp_new();
6464 if (bits == 0 || bits == wordsz) {
6465 if (bits == 0) {
6466 gen_load_gpr(t0, rt);
6467 } else {
6468 gen_load_gpr(t0, rs);
6469 }
6470 switch (wordsz) {
6471 case 32:
6472 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6473 break;
6474#if defined(TARGET_MIPS64)
6475 case 64:
6476 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6477 break;
6478#endif
6479 }
6480 } else {
6481 TCGv t1 = tcg_temp_new();
6482 gen_load_gpr(t0, rt);
6483 gen_load_gpr(t1, rs);
6484 switch (wordsz) {
6485 case 32:
6486 {
6487 TCGv_i64 t2 = tcg_temp_new_i64();
6488 tcg_gen_concat_tl_i64(t2, t1, t0);
6489 tcg_gen_shri_i64(t2, t2, 32 - bits);
6490 gen_move_low32(cpu_gpr[rd], t2);
6491 tcg_temp_free_i64(t2);
6492 }
6493 break;
6494#if defined(TARGET_MIPS64)
6495 case 64:
6496 tcg_gen_shli_tl(t0, t0, bits);
6497 tcg_gen_shri_tl(t1, t1, 64 - bits);
6498 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6499 break;
6500#endif
6501 }
6502 tcg_temp_free(t1);
6503 }
6504
6505 tcg_temp_free(t0);
6506}
6507
6508static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6509 int bp)
6510{
6511 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6512}
6513
6514static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6515 int shift)
6516{
6517 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6518}
6519
6520static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6521{
6522 TCGv t0;
6523 if (rd == 0) {
6524
6525 return;
6526 }
6527 t0 = tcg_temp_new();
6528 gen_load_gpr(t0, rt);
6529 switch (opc) {
6530 case OPC_BITSWAP:
6531 gen_helper_bitswap(cpu_gpr[rd], t0);
6532 break;
6533#if defined(TARGET_MIPS64)
6534 case OPC_DBITSWAP:
6535 gen_helper_dbitswap(cpu_gpr[rd], t0);
6536 break;
6537#endif
6538 }
6539 tcg_temp_free(t0);
6540}
6541
6542#ifndef CONFIG_USER_ONLY
6543
6544static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6545{
6546 TCGv_i64 t0 = tcg_temp_new_i64();
6547 TCGv_i64 t1 = tcg_temp_new_i64();
6548
6549 tcg_gen_ext_tl_i64(t0, arg);
6550 tcg_gen_ld_i64(t1, cpu_env, off);
6551#if defined(TARGET_MIPS64)
6552 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6553#else
6554 tcg_gen_concat32_i64(t1, t1, t0);
6555#endif
6556 tcg_gen_st_i64(t1, cpu_env, off);
6557 tcg_temp_free_i64(t1);
6558 tcg_temp_free_i64(t0);
6559}
6560
6561static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6562{
6563 TCGv_i64 t0 = tcg_temp_new_i64();
6564 TCGv_i64 t1 = tcg_temp_new_i64();
6565
6566 tcg_gen_ext_tl_i64(t0, arg);
6567 tcg_gen_ld_i64(t1, cpu_env, off);
6568 tcg_gen_concat32_i64(t1, t1, t0);
6569 tcg_gen_st_i64(t1, cpu_env, off);
6570 tcg_temp_free_i64(t1);
6571 tcg_temp_free_i64(t0);
6572}
6573
6574static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6575{
6576 TCGv_i64 t0 = tcg_temp_new_i64();
6577
6578 tcg_gen_ld_i64(t0, cpu_env, off);
6579#if defined(TARGET_MIPS64)
6580 tcg_gen_shri_i64(t0, t0, 30);
6581#else
6582 tcg_gen_shri_i64(t0, t0, 32);
6583#endif
6584 gen_move_low32(arg, t0);
6585 tcg_temp_free_i64(t0);
6586}
6587
6588static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6589{
6590 TCGv_i64 t0 = tcg_temp_new_i64();
6591
6592 tcg_gen_ld_i64(t0, cpu_env, off);
6593 tcg_gen_shri_i64(t0, t0, 32 + shift);
6594 gen_move_low32(arg, t0);
6595 tcg_temp_free_i64(t0);
6596}
6597
6598static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
6599{
6600 TCGv_i32 t0 = tcg_temp_new_i32();
6601
6602 tcg_gen_ld_i32(t0, cpu_env, off);
6603 tcg_gen_ext_i32_tl(arg, t0);
6604 tcg_temp_free_i32(t0);
6605}
6606
6607static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
6608{
6609 tcg_gen_ld_tl(arg, cpu_env, off);
6610 tcg_gen_ext32s_tl(arg, arg);
6611}
6612
6613static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
6614{
6615 TCGv_i32 t0 = tcg_temp_new_i32();
6616
6617 tcg_gen_trunc_tl_i32(t0, arg);
6618 tcg_gen_st_i32(t0, cpu_env, off);
6619 tcg_temp_free_i32(t0);
6620}
6621
6622#define CP0_CHECK(c) \
6623 do { \
6624 if (!(c)) { \
6625 goto cp0_unimplemented; \
6626 } \
6627 } while (0)
6628
6629static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6630{
6631 const char *register_name = "invalid";
6632
6633 switch (reg) {
6634 case CP0_REGISTER_02:
6635 switch (sel) {
6636 case 0:
6637 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6638 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6639 register_name = "EntryLo0";
6640 break;
6641 default:
6642 goto cp0_unimplemented;
6643 }
6644 break;
6645 case CP0_REGISTER_03:
6646 switch (sel) {
6647 case 0:
6648 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6649 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6650 register_name = "EntryLo1";
6651 break;
6652 default:
6653 goto cp0_unimplemented;
6654 }
6655 break;
6656 case CP0_REGISTER_09:
6657 switch (sel) {
6658 case 7:
6659 CP0_CHECK(ctx->saar);
6660 gen_helper_mfhc0_saar(arg, cpu_env);
6661 register_name = "SAAR";
6662 break;
6663 default:
6664 goto cp0_unimplemented;
6665 }
6666 break;
6667 case CP0_REGISTER_17:
6668 switch (sel) {
6669 case 0:
6670 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6671 ctx->CP0_LLAddr_shift);
6672 register_name = "LLAddr";
6673 break;
6674 case 1:
6675 CP0_CHECK(ctx->mrp);
6676 gen_helper_mfhc0_maar(arg, cpu_env);
6677 register_name = "MAAR";
6678 break;
6679 default:
6680 goto cp0_unimplemented;
6681 }
6682 break;
6683 case CP0_REGISTER_28:
6684 switch (sel) {
6685 case 0:
6686 case 2:
6687 case 4:
6688 case 6:
6689 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6690 register_name = "TagLo";
6691 break;
6692 default:
6693 goto cp0_unimplemented;
6694 }
6695 break;
6696 default:
6697 goto cp0_unimplemented;
6698 }
6699 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6700 return;
6701
6702cp0_unimplemented:
6703 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6704 register_name, reg, sel);
6705 tcg_gen_movi_tl(arg, 0);
6706}
6707
6708static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6709{
6710 const char *register_name = "invalid";
6711 uint64_t mask = ctx->PAMask >> 36;
6712
6713 switch (reg) {
6714 case CP0_REGISTER_02:
6715 switch (sel) {
6716 case 0:
6717 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6718 tcg_gen_andi_tl(arg, arg, mask);
6719 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6720 register_name = "EntryLo0";
6721 break;
6722 default:
6723 goto cp0_unimplemented;
6724 }
6725 break;
6726 case CP0_REGISTER_03:
6727 switch (sel) {
6728 case 0:
6729 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6730 tcg_gen_andi_tl(arg, arg, mask);
6731 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6732 register_name = "EntryLo1";
6733 break;
6734 default:
6735 goto cp0_unimplemented;
6736 }
6737 break;
6738 case CP0_REGISTER_09:
6739 switch (sel) {
6740 case 7:
6741 CP0_CHECK(ctx->saar);
6742 gen_helper_mthc0_saar(cpu_env, arg);
6743 register_name = "SAAR";
6744 break;
6745 default:
6746 goto cp0_unimplemented;
6747 }
6748 break;
6749 case CP0_REGISTER_17:
6750 switch (sel) {
6751 case 0:
6752
6753
6754
6755
6756
6757
6758 register_name = "LLAddr";
6759 break;
6760 case 1:
6761 CP0_CHECK(ctx->mrp);
6762 gen_helper_mthc0_maar(cpu_env, arg);
6763 register_name = "MAAR";
6764 break;
6765 default:
6766 goto cp0_unimplemented;
6767 }
6768 break;
6769 case CP0_REGISTER_28:
6770 switch (sel) {
6771 case 0:
6772 case 2:
6773 case 4:
6774 case 6:
6775 tcg_gen_andi_tl(arg, arg, mask);
6776 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6777 register_name = "TagLo";
6778 break;
6779 default:
6780 goto cp0_unimplemented;
6781 }
6782 break;
6783 default:
6784 goto cp0_unimplemented;
6785 }
6786 trace_mips_translate_c0("mthc0", register_name, reg, sel);
6787
6788cp0_unimplemented:
6789 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6790 register_name, reg, sel);
6791}
6792
6793static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6794{
6795 if (ctx->insn_flags & ISA_MIPS32R6) {
6796 tcg_gen_movi_tl(arg, 0);
6797 } else {
6798 tcg_gen_movi_tl(arg, ~0);
6799 }
6800}
6801
6802static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6803{
6804 const char *register_name = "invalid";
6805
6806 if (sel != 0) {
6807 check_insn(ctx, ISA_MIPS32);
6808 }
6809
6810 switch (reg) {
6811 case CP0_REGISTER_00:
6812 switch (sel) {
6813 case 0:
6814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6815 register_name = "Index";
6816 break;
6817 case 1:
6818 CP0_CHECK(ctx->insn_flags & ASE_MT);
6819 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6820 register_name = "MVPControl";
6821 break;
6822 case 2:
6823 CP0_CHECK(ctx->insn_flags & ASE_MT);
6824 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6825 register_name = "MVPConf0";
6826 break;
6827 case 3:
6828 CP0_CHECK(ctx->insn_flags & ASE_MT);
6829 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6830 register_name = "MVPConf1";
6831 break;
6832 case 4:
6833 CP0_CHECK(ctx->vp);
6834 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6835 register_name = "VPControl";
6836 break;
6837 default:
6838 goto cp0_unimplemented;
6839 }
6840 break;
6841 case CP0_REGISTER_01:
6842 switch (sel) {
6843 case 0:
6844 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6845 gen_helper_mfc0_random(arg, cpu_env);
6846 register_name = "Random";
6847 break;
6848 case 1:
6849 CP0_CHECK(ctx->insn_flags & ASE_MT);
6850 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6851 register_name = "VPEControl";
6852 break;
6853 case 2:
6854 CP0_CHECK(ctx->insn_flags & ASE_MT);
6855 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6856 register_name = "VPEConf0";
6857 break;
6858 case 3:
6859 CP0_CHECK(ctx->insn_flags & ASE_MT);
6860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6861 register_name = "VPEConf1";
6862 break;
6863 case 4:
6864 CP0_CHECK(ctx->insn_flags & ASE_MT);
6865 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6866 register_name = "YQMask";
6867 break;
6868 case 5:
6869 CP0_CHECK(ctx->insn_flags & ASE_MT);
6870 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6871 register_name = "VPESchedule";
6872 break;
6873 case 6:
6874 CP0_CHECK(ctx->insn_flags & ASE_MT);
6875 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6876 register_name = "VPEScheFBack";
6877 break;
6878 case 7:
6879 CP0_CHECK(ctx->insn_flags & ASE_MT);
6880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6881 register_name = "VPEOpt";
6882 break;
6883 default:
6884 goto cp0_unimplemented;
6885 }
6886 break;
6887 case CP0_REGISTER_02:
6888 switch (sel) {
6889 case 0:
6890 {
6891 TCGv_i64 tmp = tcg_temp_new_i64();
6892 tcg_gen_ld_i64(tmp, cpu_env,
6893 offsetof(CPUMIPSState, CP0_EntryLo0));
6894#if defined(TARGET_MIPS64)
6895 if (ctx->rxi) {
6896
6897 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6898 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6899 }
6900#endif
6901 gen_move_low32(arg, tmp);
6902 tcg_temp_free_i64(tmp);
6903 }
6904 register_name = "EntryLo0";
6905 break;
6906 case 1:
6907 CP0_CHECK(ctx->insn_flags & ASE_MT);
6908 gen_helper_mfc0_tcstatus(arg, cpu_env);
6909 register_name = "TCStatus";
6910 break;
6911 case 2:
6912 CP0_CHECK(ctx->insn_flags & ASE_MT);
6913 gen_helper_mfc0_tcbind(arg, cpu_env);
6914 register_name = "TCBind";
6915 break;
6916 case 3:
6917 CP0_CHECK(ctx->insn_flags & ASE_MT);
6918 gen_helper_mfc0_tcrestart(arg, cpu_env);
6919 register_name = "TCRestart";
6920 break;
6921 case 4:
6922 CP0_CHECK(ctx->insn_flags & ASE_MT);
6923 gen_helper_mfc0_tchalt(arg, cpu_env);
6924 register_name = "TCHalt";
6925 break;
6926 case 5:
6927 CP0_CHECK(ctx->insn_flags & ASE_MT);
6928 gen_helper_mfc0_tccontext(arg, cpu_env);
6929 register_name = "TCContext";
6930 break;
6931 case 6:
6932 CP0_CHECK(ctx->insn_flags & ASE_MT);
6933 gen_helper_mfc0_tcschedule(arg, cpu_env);
6934 register_name = "TCSchedule";
6935 break;
6936 case 7:
6937 CP0_CHECK(ctx->insn_flags & ASE_MT);
6938 gen_helper_mfc0_tcschefback(arg, cpu_env);
6939 register_name = "TCScheFBack";
6940 break;
6941 default:
6942 goto cp0_unimplemented;
6943 }
6944 break;
6945 case CP0_REGISTER_03:
6946 switch (sel) {
6947 case 0:
6948 {
6949 TCGv_i64 tmp = tcg_temp_new_i64();
6950 tcg_gen_ld_i64(tmp, cpu_env,
6951 offsetof(CPUMIPSState, CP0_EntryLo1));
6952#if defined(TARGET_MIPS64)
6953 if (ctx->rxi) {
6954
6955 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6956 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6957 }
6958#endif
6959 gen_move_low32(arg, tmp);
6960 tcg_temp_free_i64(tmp);
6961 }
6962 register_name = "EntryLo1";
6963 break;
6964 case 1:
6965 CP0_CHECK(ctx->vp);
6966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6967 register_name = "GlobalNumber";
6968 break;
6969 default:
6970 goto cp0_unimplemented;
6971 }
6972 break;
6973 case CP0_REGISTER_04:
6974 switch (sel) {
6975 case 0:
6976 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6977 tcg_gen_ext32s_tl(arg, arg);
6978 register_name = "Context";
6979 break;
6980 case 1:
6981
6982 register_name = "ContextConfig";
6983 goto cp0_unimplemented;
6984 case 2:
6985 CP0_CHECK(ctx->ulri);
6986 tcg_gen_ld_tl(arg, cpu_env,
6987 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6988 tcg_gen_ext32s_tl(arg, arg);
6989 register_name = "UserLocal";
6990 break;
6991 default:
6992 goto cp0_unimplemented;
6993 }
6994 break;
6995 case CP0_REGISTER_05:
6996 switch (sel) {
6997 case 0:
6998 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6999 register_name = "PageMask";
7000 break;
7001 case 1:
7002 check_insn(ctx, ISA_MIPS32R2);
7003 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7004 register_name = "PageGrain";
7005 break;
7006 case 2:
7007 CP0_CHECK(ctx->sc);
7008 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7009 tcg_gen_ext32s_tl(arg, arg);
7010 register_name = "SegCtl0";
7011 break;
7012 case 3:
7013 CP0_CHECK(ctx->sc);
7014 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7015 tcg_gen_ext32s_tl(arg, arg);
7016 register_name = "SegCtl1";
7017 break;
7018 case 4:
7019 CP0_CHECK(ctx->sc);
7020 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7021 tcg_gen_ext32s_tl(arg, arg);
7022 register_name = "SegCtl2";
7023 break;
7024 case 5:
7025 check_pw(ctx);
7026 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7027 register_name = "PWBase";
7028 break;
7029 case 6:
7030 check_pw(ctx);
7031 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
7032 register_name = "PWField";
7033 break;
7034 case 7:
7035 check_pw(ctx);
7036 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
7037 register_name = "PWSize";
7038 break;
7039 default:
7040 goto cp0_unimplemented;
7041 }
7042 break;
7043 case CP0_REGISTER_06:
7044 switch (sel) {
7045 case 0:
7046 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7047 register_name = "Wired";
7048 break;
7049 case 1:
7050 check_insn(ctx, ISA_MIPS32R2);
7051 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7052 register_name = "SRSConf0";
7053 break;
7054 case 2:
7055 check_insn(ctx, ISA_MIPS32R2);
7056 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7057 register_name = "SRSConf1";
7058 break;
7059 case 3:
7060 check_insn(ctx, ISA_MIPS32R2);
7061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7062 register_name = "SRSConf2";
7063 break;
7064 case 4:
7065 check_insn(ctx, ISA_MIPS32R2);
7066 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7067 register_name = "SRSConf3";
7068 break;
7069 case 5:
7070 check_insn(ctx, ISA_MIPS32R2);
7071 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7072 register_name = "SRSConf4";
7073 break;
7074 case 6:
7075 check_pw(ctx);
7076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7077 register_name = "PWCtl";
7078 break;
7079 default:
7080 goto cp0_unimplemented;
7081 }
7082 break;
7083 case CP0_REGISTER_07:
7084 switch (sel) {
7085 case 0:
7086 check_insn(ctx, ISA_MIPS32R2);
7087 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7088 register_name = "HWREna";
7089 break;
7090 default:
7091 goto cp0_unimplemented;
7092 }
7093 break;
7094 case CP0_REGISTER_08:
7095 switch (sel) {
7096 case 0:
7097 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7098 tcg_gen_ext32s_tl(arg, arg);
7099 register_name = "BadVAddr";
7100 break;
7101 case 1:
7102 CP0_CHECK(ctx->bi);
7103 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7104 register_name = "BadInstr";
7105 break;
7106 case 2:
7107 CP0_CHECK(ctx->bp);
7108 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7109 register_name = "BadInstrP";
7110 break;
7111 case 3:
7112 CP0_CHECK(ctx->bi);
7113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7114 tcg_gen_andi_tl(arg, arg, ~0xffff);
7115 register_name = "BadInstrX";
7116 break;
7117 default:
7118 goto cp0_unimplemented;
7119 }
7120 break;
7121 case CP0_REGISTER_09:
7122 switch (sel) {
7123 case 0:
7124
7125 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7126 gen_io_start();
7127 }
7128 gen_helper_mfc0_count(arg, cpu_env);
7129 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7130 gen_io_end();
7131 }
7132
7133
7134
7135
7136
7137 gen_save_pc(ctx->base.pc_next + 4);
7138 ctx->base.is_jmp = DISAS_EXIT;
7139 register_name = "Count";
7140 break;
7141 case 6:
7142 CP0_CHECK(ctx->saar);
7143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7144 register_name = "SAARI";
7145 break;
7146 case 7:
7147 CP0_CHECK(ctx->saar);
7148 gen_helper_mfc0_saar(arg, cpu_env);
7149 register_name = "SAAR";
7150 break;
7151 default:
7152 goto cp0_unimplemented;
7153 }
7154 break;
7155 case CP0_REGISTER_10:
7156 switch (sel) {
7157 case 0:
7158 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7159 tcg_gen_ext32s_tl(arg, arg);
7160 register_name = "EntryHi";
7161 break;
7162 default:
7163 goto cp0_unimplemented;
7164 }
7165 break;
7166 case CP0_REGISTER_11:
7167 switch (sel) {
7168 case 0:
7169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7170 register_name = "Compare";
7171 break;
7172
7173 default:
7174 goto cp0_unimplemented;
7175 }
7176 break;
7177 case CP0_REGISTER_12:
7178 switch (sel) {
7179 case 0:
7180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7181 register_name = "Status";
7182 break;
7183 case 1:
7184 check_insn(ctx, ISA_MIPS32R2);
7185 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7186 register_name = "IntCtl";
7187 break;
7188 case 2:
7189 check_insn(ctx, ISA_MIPS32R2);
7190 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7191 register_name = "SRSCtl";
7192 break;
7193 case 3:
7194 check_insn(ctx, ISA_MIPS32R2);
7195 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7196 register_name = "SRSMap";
7197 break;
7198 default:
7199 goto cp0_unimplemented;
7200 }
7201 break;
7202 case CP0_REGISTER_13:
7203 switch (sel) {
7204 case 0:
7205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7206 register_name = "Cause";
7207 break;
7208 default:
7209 goto cp0_unimplemented;
7210 }
7211 break;
7212 case CP0_REGISTER_14:
7213 switch (sel) {
7214 case 0:
7215 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7216 tcg_gen_ext32s_tl(arg, arg);
7217 register_name = "EPC";
7218 break;
7219 default:
7220 goto cp0_unimplemented;
7221 }
7222 break;
7223 case CP0_REGISTER_15:
7224 switch (sel) {
7225 case 0:
7226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7227 register_name = "PRid";
7228 break;
7229 case 1:
7230 check_insn(ctx, ISA_MIPS32R2);
7231 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7232 tcg_gen_ext32s_tl(arg, arg);
7233 register_name = "EBase";
7234 break;
7235 case 3:
7236 check_insn(ctx, ISA_MIPS32R2);
7237 CP0_CHECK(ctx->cmgcr);
7238 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7239 tcg_gen_ext32s_tl(arg, arg);
7240 register_name = "CMGCRBase";
7241 break;
7242 default:
7243 goto cp0_unimplemented;
7244 }
7245 break;
7246 case CP0_REGISTER_16:
7247 switch (sel) {
7248 case 0:
7249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7250 register_name = "Config";
7251 break;
7252 case 1:
7253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7254 register_name = "Config1";
7255 break;
7256 case 2:
7257 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7258 register_name = "Config2";
7259 break;
7260 case 3:
7261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7262 register_name = "Config3";
7263 break;
7264 case 4:
7265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7266 register_name = "Config4";
7267 break;
7268 case 5:
7269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7270 register_name = "Config5";
7271 break;
7272
7273 case 6:
7274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7275 register_name = "Config6";
7276 break;
7277 case 7:
7278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7279 register_name = "Config7";
7280 break;
7281 default:
7282 goto cp0_unimplemented;
7283 }
7284 break;
7285 case CP0_REGISTER_17:
7286 switch (sel) {
7287 case 0:
7288 gen_helper_mfc0_lladdr(arg, cpu_env);
7289 register_name = "LLAddr";
7290 break;
7291 case 1:
7292 CP0_CHECK(ctx->mrp);
7293 gen_helper_mfc0_maar(arg, cpu_env);
7294 register_name = "MAAR";
7295 break;
7296 case 2:
7297 CP0_CHECK(ctx->mrp);
7298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7299 register_name = "MAARI";
7300 break;
7301 default:
7302 goto cp0_unimplemented;
7303 }
7304 break;
7305 case CP0_REGISTER_18:
7306 switch (sel) {
7307 case 0:
7308 case 1:
7309 case 2:
7310 case 3:
7311 case 4:
7312 case 5:
7313 case 6:
7314 case 7:
7315 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7316 gen_helper_1e0i(mfc0_watchlo, arg, sel);
7317 register_name = "WatchLo";
7318 break;
7319 default:
7320 goto cp0_unimplemented;
7321 }
7322 break;
7323 case CP0_REGISTER_19:
7324 switch (sel) {
7325 case 0:
7326 case 1:
7327 case 2:
7328 case 3:
7329 case 4:
7330 case 5:
7331 case 6:
7332 case 7:
7333 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7334 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7335 register_name = "WatchHi";
7336 break;
7337 default:
7338 goto cp0_unimplemented;
7339 }
7340 break;
7341 case CP0_REGISTER_20:
7342 switch (sel) {
7343 case 0:
7344#if defined(TARGET_MIPS64)
7345 check_insn(ctx, ISA_MIPS3);
7346 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7347 tcg_gen_ext32s_tl(arg, arg);
7348 register_name = "XContext";
7349 break;
7350#endif
7351 default:
7352 goto cp0_unimplemented;
7353 }
7354 break;
7355 case CP0_REGISTER_21:
7356
7357 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7358 switch (sel) {
7359 case 0:
7360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7361 register_name = "Framemask";
7362 break;
7363 default:
7364 goto cp0_unimplemented;
7365 }
7366 break;
7367 case CP0_REGISTER_22:
7368 tcg_gen_movi_tl(arg, 0);
7369 register_name = "'Diagnostic";
7370 break;
7371 case CP0_REGISTER_23:
7372 switch (sel) {
7373 case 0:
7374 gen_helper_mfc0_debug(arg, cpu_env);
7375 register_name = "Debug";
7376 break;
7377 case 1:
7378
7379 register_name = "TraceControl";
7380 goto cp0_unimplemented;
7381 case 2:
7382
7383 register_name = "TraceControl2";
7384 goto cp0_unimplemented;
7385 case 3:
7386
7387 register_name = "UserTraceData";
7388 goto cp0_unimplemented;
7389 case 4:
7390
7391 register_name = "TraceBPC";
7392 goto cp0_unimplemented;
7393 default:
7394 goto cp0_unimplemented;
7395 }
7396 break;
7397 case CP0_REGISTER_24:
7398 switch (sel) {
7399 case 0:
7400
7401 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7402 tcg_gen_ext32s_tl(arg, arg);
7403 register_name = "DEPC";
7404 break;
7405 default:
7406 goto cp0_unimplemented;
7407 }
7408 break;
7409 case CP0_REGISTER_25:
7410 switch (sel) {
7411 case 0:
7412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7413 register_name = "Performance0";
7414 break;
7415 case 1:
7416
7417 register_name = "Performance1";
7418 goto cp0_unimplemented;
7419 case 2:
7420
7421 register_name = "Performance2";
7422 goto cp0_unimplemented;
7423 case 3:
7424
7425 register_name = "Performance3";
7426 goto cp0_unimplemented;
7427 case 4:
7428
7429 register_name = "Performance4";
7430 goto cp0_unimplemented;
7431 case 5:
7432
7433 register_name = "Performance5";
7434 goto cp0_unimplemented;
7435 case 6:
7436
7437 register_name = "Performance6";
7438 goto cp0_unimplemented;
7439 case 7:
7440
7441 register_name = "Performance7";
7442 goto cp0_unimplemented;
7443 default:
7444 goto cp0_unimplemented;
7445 }
7446 break;
7447 case CP0_REGISTER_26:
7448 switch (sel) {
7449 case 0:
7450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7451 register_name = "ErrCtl";
7452 break;
7453 default:
7454 goto cp0_unimplemented;
7455 }
7456 break;
7457 case CP0_REGISTER_27:
7458 switch (sel) {
7459 case 0:
7460 case 1:
7461 case 2:
7462 case 3:
7463 tcg_gen_movi_tl(arg, 0);
7464 register_name = "CacheErr";
7465 break;
7466 default:
7467 goto cp0_unimplemented;
7468 }
7469 break;
7470 case CP0_REGISTER_28:
7471 switch (sel) {
7472 case 0:
7473 case 2:
7474 case 4:
7475 case 6:
7476 {
7477 TCGv_i64 tmp = tcg_temp_new_i64();
7478 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7479 gen_move_low32(arg, tmp);
7480 tcg_temp_free_i64(tmp);
7481 }
7482 register_name = "TagLo";
7483 break;
7484 case 1:
7485 case 3:
7486 case 5:
7487 case 7:
7488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7489 register_name = "DataLo";
7490 break;
7491 default:
7492 goto cp0_unimplemented;
7493 }
7494 break;
7495 case CP0_REGISTER_29:
7496 switch (sel) {
7497 case 0:
7498 case 2:
7499 case 4:
7500 case 6:
7501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7502 register_name = "TagHi";
7503 break;
7504 case 1:
7505 case 3:
7506 case 5:
7507 case 7:
7508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7509 register_name = "DataHi";
7510 break;
7511 default:
7512 goto cp0_unimplemented;
7513 }
7514 break;
7515 case CP0_REGISTER_30:
7516 switch (sel) {
7517 case 0:
7518 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7519 tcg_gen_ext32s_tl(arg, arg);
7520 register_name = "ErrorEPC";
7521 break;
7522 default:
7523 goto cp0_unimplemented;
7524 }
7525 break;
7526 case CP0_REGISTER_31:
7527 switch (sel) {
7528 case 0:
7529
7530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7531 register_name = "DESAVE";
7532 break;
7533 case 2:
7534 case 3:
7535 case 4:
7536 case 5:
7537 case 6:
7538 case 7:
7539 CP0_CHECK(ctx->kscrexist & (1 << sel));
7540 tcg_gen_ld_tl(arg, cpu_env,
7541 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7542 tcg_gen_ext32s_tl(arg, arg);
7543 register_name = "KScratch";
7544 break;
7545 default:
7546 goto cp0_unimplemented;
7547 }
7548 break;
7549 default:
7550 goto cp0_unimplemented;
7551 }
7552 trace_mips_translate_c0("mfc0", register_name, reg, sel);
7553 return;
7554
7555cp0_unimplemented:
7556 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7557 register_name, reg, sel);
7558 gen_mfc0_unimplemented(ctx, arg);
7559}
7560
7561static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7562{
7563 const char *register_name = "invalid";
7564
7565 if (sel != 0) {
7566 check_insn(ctx, ISA_MIPS32);
7567 }
7568
7569 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7570 gen_io_start();
7571 }
7572
7573 switch (reg) {
7574 case CP0_REGISTER_00:
7575 switch (sel) {
7576 case 0:
7577 gen_helper_mtc0_index(cpu_env, arg);
7578 register_name = "Index";
7579 break;
7580 case 1:
7581 CP0_CHECK(ctx->insn_flags & ASE_MT);
7582 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7583 register_name = "MVPControl";
7584 break;
7585 case 2:
7586 CP0_CHECK(ctx->insn_flags & ASE_MT);
7587
7588 register_name = "MVPConf0";
7589 break;
7590 case 3:
7591 CP0_CHECK(ctx->insn_flags & ASE_MT);
7592
7593 register_name = "MVPConf1";
7594 break;
7595 case 4:
7596 CP0_CHECK(ctx->vp);
7597
7598 register_name = "VPControl";
7599 break;
7600 default:
7601 goto cp0_unimplemented;
7602 }
7603 break;
7604 case CP0_REGISTER_01:
7605 switch (sel) {
7606 case 0:
7607
7608 register_name = "Random";
7609 break;
7610 case 1:
7611 CP0_CHECK(ctx->insn_flags & ASE_MT);
7612 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7613 register_name = "VPEControl";
7614 break;
7615 case 2:
7616 CP0_CHECK(ctx->insn_flags & ASE_MT);
7617 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7618 register_name = "VPEConf0";
7619 break;
7620 case 3:
7621 CP0_CHECK(ctx->insn_flags & ASE_MT);
7622 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7623 register_name = "VPEConf1";
7624 break;
7625 case 4:
7626 CP0_CHECK(ctx->insn_flags & ASE_MT);
7627 gen_helper_mtc0_yqmask(cpu_env, arg);
7628 register_name = "YQMask";
7629 break;
7630 case 5:
7631 CP0_CHECK(ctx->insn_flags & ASE_MT);
7632 tcg_gen_st_tl(arg, cpu_env,
7633 offsetof(CPUMIPSState, CP0_VPESchedule));
7634 register_name = "VPESchedule";
7635 break;
7636 case 6:
7637 CP0_CHECK(ctx->insn_flags & ASE_MT);
7638 tcg_gen_st_tl(arg, cpu_env,
7639 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7640 register_name = "VPEScheFBack";
7641 break;
7642 case 7:
7643 CP0_CHECK(ctx->insn_flags & ASE_MT);
7644 gen_helper_mtc0_vpeopt(cpu_env, arg);
7645 register_name = "VPEOpt";
7646 break;
7647 default:
7648 goto cp0_unimplemented;
7649 }
7650 break;
7651 case CP0_REGISTER_02:
7652 switch (sel) {
7653 case 0:
7654 gen_helper_mtc0_entrylo0(cpu_env, arg);
7655 register_name = "EntryLo0";
7656 break;
7657 case 1:
7658 CP0_CHECK(ctx->insn_flags & ASE_MT);
7659 gen_helper_mtc0_tcstatus(cpu_env, arg);
7660 register_name = "TCStatus";
7661 break;
7662 case 2:
7663 CP0_CHECK(ctx->insn_flags & ASE_MT);
7664 gen_helper_mtc0_tcbind(cpu_env, arg);
7665 register_name = "TCBind";
7666 break;
7667 case 3:
7668 CP0_CHECK(ctx->insn_flags & ASE_MT);
7669 gen_helper_mtc0_tcrestart(cpu_env, arg);
7670 register_name = "TCRestart";
7671 break;
7672 case 4:
7673 CP0_CHECK(ctx->insn_flags & ASE_MT);
7674 gen_helper_mtc0_tchalt(cpu_env, arg);
7675 register_name = "TCHalt";
7676 break;
7677 case 5:
7678 CP0_CHECK(ctx->insn_flags & ASE_MT);
7679 gen_helper_mtc0_tccontext(cpu_env, arg);
7680 register_name = "TCContext";
7681 break;
7682 case 6:
7683 CP0_CHECK(ctx->insn_flags & ASE_MT);
7684 gen_helper_mtc0_tcschedule(cpu_env, arg);
7685 register_name = "TCSchedule";
7686 break;
7687 case 7:
7688 CP0_CHECK(ctx->insn_flags & ASE_MT);
7689 gen_helper_mtc0_tcschefback(cpu_env, arg);
7690 register_name = "TCScheFBack";
7691 break;
7692 default:
7693 goto cp0_unimplemented;
7694 }
7695 break;
7696 case CP0_REGISTER_03:
7697 switch (sel) {
7698 case 0:
7699 gen_helper_mtc0_entrylo1(cpu_env, arg);
7700 register_name = "EntryLo1";
7701 break;
7702 case 1:
7703 CP0_CHECK(ctx->vp);
7704
7705 register_name = "GlobalNumber";
7706 break;
7707 default:
7708 goto cp0_unimplemented;
7709 }
7710 break;
7711 case CP0_REGISTER_04:
7712 switch (sel) {
7713 case 0:
7714 gen_helper_mtc0_context(cpu_env, arg);
7715 register_name = "Context";
7716 break;
7717 case 1:
7718
7719 register_name = "ContextConfig";
7720 goto cp0_unimplemented;
7721 case 2:
7722 CP0_CHECK(ctx->ulri);
7723 tcg_gen_st_tl(arg, cpu_env,
7724 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7725 register_name = "UserLocal";
7726 break;
7727 default:
7728 goto cp0_unimplemented;
7729 }
7730 break;
7731 case CP0_REGISTER_05:
7732 switch (sel) {
7733 case 0:
7734 gen_helper_mtc0_pagemask(cpu_env, arg);
7735 register_name = "PageMask";
7736 break;
7737 case 1:
7738 check_insn(ctx, ISA_MIPS32R2);
7739 gen_helper_mtc0_pagegrain(cpu_env, arg);
7740 register_name = "PageGrain";
7741 ctx->base.is_jmp = DISAS_STOP;
7742 break;
7743 case 2:
7744 CP0_CHECK(ctx->sc);
7745 gen_helper_mtc0_segctl0(cpu_env, arg);
7746 register_name = "SegCtl0";
7747 break;
7748 case 3:
7749 CP0_CHECK(ctx->sc);
7750 gen_helper_mtc0_segctl1(cpu_env, arg);
7751 register_name = "SegCtl1";
7752 break;
7753 case 4:
7754 CP0_CHECK(ctx->sc);
7755 gen_helper_mtc0_segctl2(cpu_env, arg);
7756 register_name = "SegCtl2";
7757 break;
7758 case 5:
7759 check_pw(ctx);
7760 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7761 register_name = "PWBase";
7762 break;
7763 case 6:
7764 check_pw(ctx);
7765 gen_helper_mtc0_pwfield(cpu_env, arg);
7766 register_name = "PWField";
7767 break;
7768 case 7:
7769 check_pw(ctx);
7770 gen_helper_mtc0_pwsize(cpu_env, arg);
7771 register_name = "PWSize";
7772 break;
7773 default:
7774 goto cp0_unimplemented;
7775 }
7776 break;
7777 case CP0_REGISTER_06:
7778 switch (sel) {
7779 case 0:
7780 gen_helper_mtc0_wired(cpu_env, arg);
7781 register_name = "Wired";
7782 break;
7783 case 1:
7784 check_insn(ctx, ISA_MIPS32R2);
7785 gen_helper_mtc0_srsconf0(cpu_env, arg);
7786 register_name = "SRSConf0";
7787 break;
7788 case 2:
7789 check_insn(ctx, ISA_MIPS32R2);
7790 gen_helper_mtc0_srsconf1(cpu_env, arg);
7791 register_name = "SRSConf1";
7792 break;
7793 case 3:
7794 check_insn(ctx, ISA_MIPS32R2);
7795 gen_helper_mtc0_srsconf2(cpu_env, arg);
7796 register_name = "SRSConf2";
7797 break;
7798 case 4:
7799 check_insn(ctx, ISA_MIPS32R2);
7800 gen_helper_mtc0_srsconf3(cpu_env, arg);
7801 register_name = "SRSConf3";
7802 break;
7803 case 5:
7804 check_insn(ctx, ISA_MIPS32R2);
7805 gen_helper_mtc0_srsconf4(cpu_env, arg);
7806 register_name = "SRSConf4";
7807 break;
7808 case 6:
7809 check_pw(ctx);
7810 gen_helper_mtc0_pwctl(cpu_env, arg);
7811 register_name = "PWCtl";
7812 break;
7813 default:
7814 goto cp0_unimplemented;
7815 }
7816 break;
7817 case CP0_REGISTER_07:
7818 switch (sel) {
7819 case 0:
7820 check_insn(ctx, ISA_MIPS32R2);
7821 gen_helper_mtc0_hwrena(cpu_env, arg);
7822 ctx->base.is_jmp = DISAS_STOP;
7823 register_name = "HWREna";
7824 break;
7825 default:
7826 goto cp0_unimplemented;
7827 }
7828 break;
7829 case CP0_REGISTER_08:
7830 switch (sel) {
7831 case 0:
7832
7833 register_name = "BadVAddr";
7834 break;
7835 case 1:
7836
7837 register_name = "BadInstr";
7838 break;
7839 case 2:
7840
7841 register_name = "BadInstrP";
7842 break;
7843 case 3:
7844
7845 register_name = "BadInstrX";
7846 break;
7847 default:
7848 goto cp0_unimplemented;
7849 }
7850 break;
7851 case CP0_REGISTER_09:
7852 switch (sel) {
7853 case 0:
7854 gen_helper_mtc0_count(cpu_env, arg);
7855 register_name = "Count";
7856 break;
7857 case 6:
7858 CP0_CHECK(ctx->saar);
7859 gen_helper_mtc0_saari(cpu_env, arg);
7860 register_name = "SAARI";
7861 break;
7862 case 7:
7863 CP0_CHECK(ctx->saar);
7864 gen_helper_mtc0_saar(cpu_env, arg);
7865 register_name = "SAAR";
7866 break;
7867 default:
7868 goto cp0_unimplemented;
7869 }
7870 break;
7871 case CP0_REGISTER_10:
7872 switch (sel) {
7873 case 0:
7874 gen_helper_mtc0_entryhi(cpu_env, arg);
7875 register_name = "EntryHi";
7876 break;
7877 default:
7878 goto cp0_unimplemented;
7879 }
7880 break;
7881 case CP0_REGISTER_11:
7882 switch (sel) {
7883 case 0:
7884 gen_helper_mtc0_compare(cpu_env, arg);
7885 register_name = "Compare";
7886 break;
7887
7888 default:
7889 goto cp0_unimplemented;
7890 }
7891 break;
7892 case CP0_REGISTER_12:
7893 switch (sel) {
7894 case 0:
7895 save_cpu_state(ctx, 1);
7896 gen_helper_mtc0_status(cpu_env, arg);
7897
7898 gen_save_pc(ctx->base.pc_next + 4);
7899 ctx->base.is_jmp = DISAS_EXIT;
7900 register_name = "Status";
7901 break;
7902 case 1:
7903 check_insn(ctx, ISA_MIPS32R2);
7904 gen_helper_mtc0_intctl(cpu_env, arg);
7905
7906 ctx->base.is_jmp = DISAS_STOP;
7907 register_name = "IntCtl";
7908 break;
7909 case 2:
7910 check_insn(ctx, ISA_MIPS32R2);
7911 gen_helper_mtc0_srsctl(cpu_env, arg);
7912
7913 ctx->base.is_jmp = DISAS_STOP;
7914 register_name = "SRSCtl";
7915 break;
7916 case 3:
7917 check_insn(ctx, ISA_MIPS32R2);
7918 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7919
7920 ctx->base.is_jmp = DISAS_STOP;
7921 register_name = "SRSMap";
7922 break;
7923 default:
7924 goto cp0_unimplemented;
7925 }
7926 break;
7927 case CP0_REGISTER_13:
7928 switch (sel) {
7929 case 0:
7930 save_cpu_state(ctx, 1);
7931 gen_helper_mtc0_cause(cpu_env, arg);
7932
7933
7934
7935
7936
7937 gen_save_pc(ctx->base.pc_next + 4);
7938 ctx->base.is_jmp = DISAS_EXIT;
7939 register_name = "Cause";
7940 break;
7941 default:
7942 goto cp0_unimplemented;
7943 }
7944 break;
7945 case CP0_REGISTER_14:
7946 switch (sel) {
7947 case 0:
7948 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7949 register_name = "EPC";
7950 break;
7951 default:
7952 goto cp0_unimplemented;
7953 }
7954 break;
7955 case CP0_REGISTER_15:
7956 switch (sel) {
7957 case 0:
7958
7959 register_name = "PRid";
7960 break;
7961 case 1:
7962 check_insn(ctx, ISA_MIPS32R2);
7963 gen_helper_mtc0_ebase(cpu_env, arg);
7964 register_name = "EBase";
7965 break;
7966 default:
7967 goto cp0_unimplemented;
7968 }
7969 break;
7970 case CP0_REGISTER_16:
7971 switch (sel) {
7972 case 0:
7973 gen_helper_mtc0_config0(cpu_env, arg);
7974 register_name = "Config";
7975
7976 ctx->base.is_jmp = DISAS_STOP;
7977 break;
7978 case 1:
7979
7980 register_name = "Config1";
7981 break;
7982 case 2:
7983 gen_helper_mtc0_config2(cpu_env, arg);
7984 register_name = "Config2";
7985
7986 ctx->base.is_jmp = DISAS_STOP;
7987 break;
7988 case 3:
7989 gen_helper_mtc0_config3(cpu_env, arg);
7990 register_name = "Config3";
7991
7992 ctx->base.is_jmp = DISAS_STOP;
7993 break;
7994 case 4:
7995 gen_helper_mtc0_config4(cpu_env, arg);
7996 register_name = "Config4";
7997 ctx->base.is_jmp = DISAS_STOP;
7998 break;
7999 case 5:
8000 gen_helper_mtc0_config5(cpu_env, arg);
8001 register_name = "Config5";
8002
8003 ctx->base.is_jmp = DISAS_STOP;
8004 break;
8005
8006 case 6:
8007
8008 register_name = "Config6";
8009 break;
8010 case 7:
8011
8012 register_name = "Config7";
8013 break;
8014 default:
8015 register_name = "Invalid config selector";
8016 goto cp0_unimplemented;
8017 }
8018 break;
8019 case CP0_REGISTER_17:
8020 switch (sel) {
8021 case 0:
8022 gen_helper_mtc0_lladdr(cpu_env, arg);
8023 register_name = "LLAddr";
8024 break;
8025 case 1:
8026 CP0_CHECK(ctx->mrp);
8027 gen_helper_mtc0_maar(cpu_env, arg);
8028 register_name = "MAAR";
8029 break;
8030 case 2:
8031 CP0_CHECK(ctx->mrp);
8032 gen_helper_mtc0_maari(cpu_env, arg);
8033 register_name = "MAARI";
8034 break;
8035 default:
8036 goto cp0_unimplemented;
8037 }
8038 break;
8039 case CP0_REGISTER_18:
8040 switch (sel) {
8041 case 0:
8042 case 1:
8043 case 2:
8044 case 3:
8045 case 4:
8046 case 5:
8047 case 6:
8048 case 7:
8049 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8050 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8051 register_name = "WatchLo";
8052 break;
8053 default:
8054 goto cp0_unimplemented;
8055 }
8056 break;
8057 case CP0_REGISTER_19:
8058 switch (sel) {
8059 case 0:
8060 case 1:
8061 case 2:
8062 case 3:
8063 case 4:
8064 case 5:
8065 case 6:
8066 case 7:
8067 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8068 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8069 register_name = "WatchHi";
8070 break;
8071 default:
8072 goto cp0_unimplemented;
8073 }
8074 break;
8075 case CP0_REGISTER_20:
8076 switch (sel) {
8077 case 0:
8078#if defined(TARGET_MIPS64)
8079 check_insn(ctx, ISA_MIPS3);
8080 gen_helper_mtc0_xcontext(cpu_env, arg);
8081 register_name = "XContext";
8082 break;
8083#endif
8084 default:
8085 goto cp0_unimplemented;
8086 }
8087 break;
8088 case CP0_REGISTER_21:
8089
8090 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8091 switch (sel) {
8092 case 0:
8093 gen_helper_mtc0_framemask(cpu_env, arg);
8094 register_name = "Framemask";
8095 break;
8096 default:
8097 goto cp0_unimplemented;
8098 }
8099 break;
8100 case CP0_REGISTER_22:
8101
8102 register_name = "Diagnostic";
8103 break;
8104 case CP0_REGISTER_23:
8105 switch (sel) {
8106 case 0:
8107 gen_helper_mtc0_debug(cpu_env, arg);
8108
8109 gen_save_pc(ctx->base.pc_next + 4);
8110 ctx->base.is_jmp = DISAS_EXIT;
8111 register_name = "Debug";
8112 break;
8113 case 1:
8114
8115 register_name = "TraceControl";
8116
8117 ctx->base.is_jmp = DISAS_STOP;
8118 goto cp0_unimplemented;
8119 case 2:
8120
8121 register_name = "TraceControl2";
8122
8123 ctx->base.is_jmp = DISAS_STOP;
8124 goto cp0_unimplemented;
8125 case 3:
8126
8127 ctx->base.is_jmp = DISAS_STOP;
8128
8129 register_name = "UserTraceData";
8130
8131 ctx->base.is_jmp = DISAS_STOP;
8132 goto cp0_unimplemented;
8133 case 4:
8134
8135
8136 ctx->base.is_jmp = DISAS_STOP;
8137 register_name = "TraceBPC";
8138 goto cp0_unimplemented;
8139 default:
8140 goto cp0_unimplemented;
8141 }
8142 break;
8143 case CP0_REGISTER_24:
8144 switch (sel) {
8145 case 0:
8146
8147 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8148 register_name = "DEPC";
8149 break;
8150 default:
8151 goto cp0_unimplemented;
8152 }
8153 break;
8154 case CP0_REGISTER_25:
8155 switch (sel) {
8156 case 0:
8157 gen_helper_mtc0_performance0(cpu_env, arg);
8158 register_name = "Performance0";
8159 break;
8160 case 1:
8161
8162 register_name = "Performance1";
8163 goto cp0_unimplemented;
8164 case 2:
8165
8166 register_name = "Performance2";
8167 goto cp0_unimplemented;
8168 case 3:
8169
8170 register_name = "Performance3";
8171 goto cp0_unimplemented;
8172 case 4:
8173
8174 register_name = "Performance4";
8175 goto cp0_unimplemented;
8176 case 5:
8177
8178 register_name = "Performance5";
8179 goto cp0_unimplemented;
8180 case 6:
8181
8182 register_name = "Performance6";
8183 goto cp0_unimplemented;
8184 case 7:
8185
8186 register_name = "Performance7";
8187 goto cp0_unimplemented;
8188 default:
8189 goto cp0_unimplemented;
8190 }
8191 break;
8192 case CP0_REGISTER_26:
8193 switch (sel) {
8194 case 0:
8195 gen_helper_mtc0_errctl(cpu_env, arg);
8196 ctx->base.is_jmp = DISAS_STOP;
8197 register_name = "ErrCtl";
8198 break;
8199 default:
8200 goto cp0_unimplemented;
8201 }
8202 break;
8203 case CP0_REGISTER_27:
8204 switch (sel) {
8205 case 0:
8206 case 1:
8207 case 2:
8208 case 3:
8209
8210 register_name = "CacheErr";
8211 break;
8212 default:
8213 goto cp0_unimplemented;
8214 }
8215 break;
8216 case CP0_REGISTER_28:
8217 switch (sel) {
8218 case 0:
8219 case 2:
8220 case 4:
8221 case 6:
8222 gen_helper_mtc0_taglo(cpu_env, arg);
8223 register_name = "TagLo";
8224 break;
8225 case 1:
8226 case 3:
8227 case 5:
8228 case 7:
8229 gen_helper_mtc0_datalo(cpu_env, arg);
8230 register_name = "DataLo";
8231 break;
8232 default:
8233 goto cp0_unimplemented;
8234 }
8235 break;
8236 case CP0_REGISTER_29:
8237 switch (sel) {
8238 case 0:
8239 case 2:
8240 case 4:
8241 case 6:
8242 gen_helper_mtc0_taghi(cpu_env, arg);
8243 register_name = "TagHi";
8244 break;
8245 case 1:
8246 case 3:
8247 case 5:
8248 case 7:
8249 gen_helper_mtc0_datahi(cpu_env, arg);
8250 register_name = "DataHi";
8251 break;
8252 default:
8253 register_name = "invalid sel";
8254 goto cp0_unimplemented;
8255 }
8256 break;
8257 case CP0_REGISTER_30:
8258 switch (sel) {
8259 case 0:
8260 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8261 register_name = "ErrorEPC";
8262 break;
8263 default:
8264 goto cp0_unimplemented;
8265 }
8266 break;
8267 case CP0_REGISTER_31:
8268 switch (sel) {
8269 case 0:
8270
8271 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8272 register_name = "DESAVE";
8273 break;
8274 case 2:
8275 case 3:
8276 case 4:
8277 case 5:
8278 case 6:
8279 case 7:
8280 CP0_CHECK(ctx->kscrexist & (1 << sel));
8281 tcg_gen_st_tl(arg, cpu_env,
8282 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8283 register_name = "KScratch";
8284 break;
8285 default:
8286 goto cp0_unimplemented;
8287 }
8288 break;
8289 default:
8290 goto cp0_unimplemented;
8291 }
8292 trace_mips_translate_c0("mtc0", register_name, reg, sel);
8293
8294
8295 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8296 gen_io_end();
8297
8298
8299
8300
8301 gen_save_pc(ctx->base.pc_next + 4);
8302 ctx->base.is_jmp = DISAS_EXIT;
8303 }
8304 return;
8305
8306cp0_unimplemented:
8307 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8308 register_name, reg, sel);
8309}
8310
8311#if defined(TARGET_MIPS64)
8312static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8313{
8314 const char *register_name = "invalid";
8315
8316 if (sel != 0) {
8317 check_insn(ctx, ISA_MIPS64);
8318 }
8319
8320 switch (reg) {
8321 case CP0_REGISTER_00:
8322 switch (sel) {
8323 case 0:
8324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8325 register_name = "Index";
8326 break;
8327 case 1:
8328 CP0_CHECK(ctx->insn_flags & ASE_MT);
8329 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8330 register_name = "MVPControl";
8331 break;
8332 case 2:
8333 CP0_CHECK(ctx->insn_flags & ASE_MT);
8334 gen_helper_mfc0_mvpconf0(arg, cpu_env);
8335 register_name = "MVPConf0";
8336 break;
8337 case 3:
8338 CP0_CHECK(ctx->insn_flags & ASE_MT);
8339 gen_helper_mfc0_mvpconf1(arg, cpu_env);
8340 register_name = "MVPConf1";
8341 break;
8342 case 4:
8343 CP0_CHECK(ctx->vp);
8344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8345 register_name = "VPControl";
8346 break;
8347 default:
8348 goto cp0_unimplemented;
8349 }
8350 break;
8351 case CP0_REGISTER_01:
8352 switch (sel) {
8353 case 0:
8354 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8355 gen_helper_mfc0_random(arg, cpu_env);
8356 register_name = "Random";
8357 break;
8358 case 1:
8359 CP0_CHECK(ctx->insn_flags & ASE_MT);
8360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8361 register_name = "VPEControl";
8362 break;
8363 case 2:
8364 CP0_CHECK(ctx->insn_flags & ASE_MT);
8365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8366 register_name = "VPEConf0";
8367 break;
8368 case 3:
8369 CP0_CHECK(ctx->insn_flags & ASE_MT);
8370 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8371 register_name = "VPEConf1";
8372 break;
8373 case 4:
8374 CP0_CHECK(ctx->insn_flags & ASE_MT);
8375 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8376 register_name = "YQMask";
8377 break;
8378 case 5:
8379 CP0_CHECK(ctx->insn_flags & ASE_MT);
8380 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8381 register_name = "VPESchedule";
8382 break;
8383 case 6:
8384 CP0_CHECK(ctx->insn_flags & ASE_MT);
8385 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8386 register_name = "VPEScheFBack";
8387 break;
8388 case 7:
8389 CP0_CHECK(ctx->insn_flags & ASE_MT);
8390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8391 register_name = "VPEOpt";
8392 break;
8393 default:
8394 goto cp0_unimplemented;
8395 }
8396 break;
8397 case CP0_REGISTER_02:
8398 switch (sel) {
8399 case 0:
8400 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8401 register_name = "EntryLo0";
8402 break;
8403 case 1:
8404 CP0_CHECK(ctx->insn_flags & ASE_MT);
8405 gen_helper_mfc0_tcstatus(arg, cpu_env);
8406 register_name = "TCStatus";
8407 break;
8408 case 2:
8409 CP0_CHECK(ctx->insn_flags & ASE_MT);
8410 gen_helper_mfc0_tcbind(arg, cpu_env);
8411 register_name = "TCBind";
8412 break;
8413 case 3:
8414 CP0_CHECK(ctx->insn_flags & ASE_MT);
8415 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8416 register_name = "TCRestart";
8417 break;
8418 case 4:
8419 CP0_CHECK(ctx->insn_flags & ASE_MT);
8420 gen_helper_dmfc0_tchalt(arg, cpu_env);
8421 register_name = "TCHalt";
8422 break;
8423 case 5:
8424 CP0_CHECK(ctx->insn_flags & ASE_MT);
8425 gen_helper_dmfc0_tccontext(arg, cpu_env);
8426 register_name = "TCContext";
8427 break;
8428 case 6:
8429 CP0_CHECK(ctx->insn_flags & ASE_MT);
8430 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8431 register_name = "TCSchedule";
8432 break;
8433 case 7:
8434 CP0_CHECK(ctx->insn_flags & ASE_MT);
8435 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8436 register_name = "TCScheFBack";
8437 break;
8438 default:
8439 goto cp0_unimplemented;
8440 }
8441 break;
8442 case CP0_REGISTER_03:
8443 switch (sel) {
8444 case 0:
8445 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8446 register_name = "EntryLo1";
8447 break;
8448 case 1:
8449 CP0_CHECK(ctx->vp);
8450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8451 register_name = "GlobalNumber";
8452 break;
8453 default:
8454 goto cp0_unimplemented;
8455 }
8456 break;
8457 case CP0_REGISTER_04:
8458 switch (sel) {
8459 case 0:
8460 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8461 register_name = "Context";
8462 break;
8463 case 1:
8464
8465 register_name = "ContextConfig";
8466 goto cp0_unimplemented;
8467 case 2:
8468 CP0_CHECK(ctx->ulri);
8469 tcg_gen_ld_tl(arg, cpu_env,
8470 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8471 register_name = "UserLocal";
8472 break;
8473 default:
8474 goto cp0_unimplemented;
8475 }
8476 break;
8477 case CP0_REGISTER_05:
8478 switch (sel) {
8479 case 0:
8480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8481 register_name = "PageMask";
8482 break;
8483 case 1:
8484 check_insn(ctx, ISA_MIPS32R2);
8485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8486 register_name = "PageGrain";
8487 break;
8488 case 2:
8489 CP0_CHECK(ctx->sc);
8490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8491 register_name = "SegCtl0";
8492 break;
8493 case 3:
8494 CP0_CHECK(ctx->sc);
8495 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8496 register_name = "SegCtl1";
8497 break;
8498 case 4:
8499 CP0_CHECK(ctx->sc);
8500 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8501 register_name = "SegCtl2";
8502 break;
8503 case 5:
8504 check_pw(ctx);
8505 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8506 register_name = "PWBase";
8507 break;
8508 case 6:
8509 check_pw(ctx);
8510 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8511 register_name = "PWField";
8512 break;
8513 case 7:
8514 check_pw(ctx);
8515 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8516 register_name = "PWSize";
8517 break;
8518 default:
8519 goto cp0_unimplemented;
8520 }
8521 break;
8522 case CP0_REGISTER_06:
8523 switch (sel) {
8524 case 0:
8525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8526 register_name = "Wired";
8527 break;
8528 case 1:
8529 check_insn(ctx, ISA_MIPS32R2);
8530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8531 register_name = "SRSConf0";
8532 break;
8533 case 2:
8534 check_insn(ctx, ISA_MIPS32R2);
8535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8536 register_name = "SRSConf1";
8537 break;
8538 case 3:
8539 check_insn(ctx, ISA_MIPS32R2);
8540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8541 register_name = "SRSConf2";
8542 break;
8543 case 4:
8544 check_insn(ctx, ISA_MIPS32R2);
8545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8546 register_name = "SRSConf3";
8547 break;
8548 case 5:
8549 check_insn(ctx, ISA_MIPS32R2);
8550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8551 register_name = "SRSConf4";
8552 break;
8553 case 6:
8554 check_pw(ctx);
8555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8556 register_name = "PWCtl";
8557 break;
8558 default:
8559 goto cp0_unimplemented;
8560 }
8561 break;
8562 case CP0_REGISTER_07:
8563 switch (sel) {
8564 case 0:
8565 check_insn(ctx, ISA_MIPS32R2);
8566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8567 register_name = "HWREna";
8568 break;
8569 default:
8570 goto cp0_unimplemented;
8571 }
8572 break;
8573 case CP0_REGISTER_08:
8574 switch (sel) {
8575 case 0:
8576 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8577 register_name = "BadVAddr";
8578 break;
8579 case 1:
8580 CP0_CHECK(ctx->bi);
8581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8582 register_name = "BadInstr";
8583 break;
8584 case 2:
8585 CP0_CHECK(ctx->bp);
8586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8587 register_name = "BadInstrP";
8588 break;
8589 case 3:
8590 CP0_CHECK(ctx->bi);
8591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8592 tcg_gen_andi_tl(arg, arg, ~0xffff);
8593 register_name = "BadInstrX";
8594 break;
8595 default:
8596 goto cp0_unimplemented;
8597 }
8598 break;
8599 case CP0_REGISTER_09:
8600 switch (sel) {
8601 case 0:
8602
8603 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8604 gen_io_start();
8605 }
8606 gen_helper_mfc0_count(arg, cpu_env);
8607 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8608 gen_io_end();
8609 }
8610
8611
8612
8613
8614
8615 gen_save_pc(ctx->base.pc_next + 4);
8616 ctx->base.is_jmp = DISAS_EXIT;
8617 register_name = "Count";
8618 break;
8619 case 6:
8620 CP0_CHECK(ctx->saar);
8621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8622 register_name = "SAARI";
8623 break;
8624 case 7:
8625 CP0_CHECK(ctx->saar);
8626 gen_helper_dmfc0_saar(arg, cpu_env);
8627 register_name = "SAAR";
8628 break;
8629 default:
8630 goto cp0_unimplemented;
8631 }
8632 break;
8633 case CP0_REGISTER_10:
8634 switch (sel) {
8635 case 0:
8636 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8637 register_name = "EntryHi";
8638 break;
8639 default:
8640 goto cp0_unimplemented;
8641 }
8642 break;
8643 case CP0_REGISTER_11:
8644 switch (sel) {
8645 case 0:
8646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8647 register_name = "Compare";
8648 break;
8649
8650 default:
8651 goto cp0_unimplemented;
8652 }
8653 break;
8654 case CP0_REGISTER_12:
8655 switch (sel) {
8656 case 0:
8657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8658 register_name = "Status";
8659 break;
8660 case 1:
8661 check_insn(ctx, ISA_MIPS32R2);
8662 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8663 register_name = "IntCtl";
8664 break;
8665 case 2:
8666 check_insn(ctx, ISA_MIPS32R2);
8667 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8668 register_name = "SRSCtl";
8669 break;
8670 case 3:
8671 check_insn(ctx, ISA_MIPS32R2);
8672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8673 register_name = "SRSMap";
8674 break;
8675 default:
8676 goto cp0_unimplemented;
8677 }
8678 break;
8679 case CP0_REGISTER_13:
8680 switch (sel) {
8681 case 0:
8682 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8683 register_name = "Cause";
8684 break;
8685 default:
8686 goto cp0_unimplemented;
8687 }
8688 break;
8689 case CP0_REGISTER_14:
8690 switch (sel) {
8691 case 0:
8692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8693 register_name = "EPC";
8694 break;
8695 default:
8696 goto cp0_unimplemented;
8697 }
8698 break;
8699 case CP0_REGISTER_15:
8700 switch (sel) {
8701 case 0:
8702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8703 register_name = "PRid";
8704 break;
8705 case 1:
8706 check_insn(ctx, ISA_MIPS32R2);
8707 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8708 register_name = "EBase";
8709 break;
8710 case 3:
8711 check_insn(ctx, ISA_MIPS32R2);
8712 CP0_CHECK(ctx->cmgcr);
8713 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8714 register_name = "CMGCRBase";
8715 break;
8716 default:
8717 goto cp0_unimplemented;
8718 }
8719 break;
8720 case CP0_REGISTER_16:
8721 switch (sel) {
8722 case 0:
8723 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8724 register_name = "Config";
8725 break;
8726 case 1:
8727 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8728 register_name = "Config1";
8729 break;
8730 case 2:
8731 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8732 register_name = "Config2";
8733 break;
8734 case 3:
8735 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8736 register_name = "Config3";
8737 break;
8738 case 4:
8739 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8740 register_name = "Config4";
8741 break;
8742 case 5:
8743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8744 register_name = "Config5";
8745 break;
8746
8747 case 6:
8748 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8749 register_name = "Config6";
8750 break;
8751 case 7:
8752 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8753 register_name = "Config7";
8754 break;
8755 default:
8756 goto cp0_unimplemented;
8757 }
8758 break;
8759 case CP0_REGISTER_17:
8760 switch (sel) {
8761 case 0:
8762 gen_helper_dmfc0_lladdr(arg, cpu_env);
8763 register_name = "LLAddr";
8764 break;
8765 case 1:
8766 CP0_CHECK(ctx->mrp);
8767 gen_helper_dmfc0_maar(arg, cpu_env);
8768 register_name = "MAAR";
8769 break;
8770 case 2:
8771 CP0_CHECK(ctx->mrp);
8772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8773 register_name = "MAARI";
8774 break;
8775 default:
8776 goto cp0_unimplemented;
8777 }
8778 break;
8779 case CP0_REGISTER_18:
8780 switch (sel) {
8781 case 0:
8782 case 1:
8783 case 2:
8784 case 3:
8785 case 4:
8786 case 5:
8787 case 6:
8788 case 7:
8789 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8790 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8791 register_name = "WatchLo";
8792 break;
8793 default:
8794 goto cp0_unimplemented;
8795 }
8796 break;
8797 case CP0_REGISTER_19:
8798 switch (sel) {
8799 case 0:
8800 case 1:
8801 case 2:
8802 case 3:
8803 case 4:
8804 case 5:
8805 case 6:
8806 case 7:
8807 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8808 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8809 register_name = "WatchHi";
8810 break;
8811 default:
8812 goto cp0_unimplemented;
8813 }
8814 break;
8815 case CP0_REGISTER_20:
8816 switch (sel) {
8817 case 0:
8818 check_insn(ctx, ISA_MIPS3);
8819 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8820 register_name = "XContext";
8821 break;
8822 default:
8823 goto cp0_unimplemented;
8824 }
8825 break;
8826 case CP0_REGISTER_21:
8827
8828 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8829 switch (sel) {
8830 case 0:
8831 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8832 register_name = "Framemask";
8833 break;
8834 default:
8835 goto cp0_unimplemented;
8836 }
8837 break;
8838 case CP0_REGISTER_22:
8839 tcg_gen_movi_tl(arg, 0);
8840 register_name = "'Diagnostic";
8841 break;
8842 case CP0_REGISTER_23:
8843 switch (sel) {
8844 case 0:
8845 gen_helper_mfc0_debug(arg, cpu_env);
8846 register_name = "Debug";
8847 break;
8848 case 1:
8849
8850 register_name = "TraceControl";
8851 goto cp0_unimplemented;
8852 case 2:
8853
8854 register_name = "TraceControl2";
8855 goto cp0_unimplemented;
8856 case 3:
8857
8858 register_name = "UserTraceData";
8859 goto cp0_unimplemented;
8860 case 4:
8861
8862 register_name = "TraceBPC";
8863 goto cp0_unimplemented;
8864 default:
8865 goto cp0_unimplemented;
8866 }
8867 break;
8868 case CP0_REGISTER_24:
8869 switch (sel) {
8870 case 0:
8871
8872 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8873 register_name = "DEPC";
8874 break;
8875 default:
8876 goto cp0_unimplemented;
8877 }
8878 break;
8879 case CP0_REGISTER_25:
8880 switch (sel) {
8881 case 0:
8882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8883 register_name = "Performance0";
8884 break;
8885 case 1:
8886
8887 register_name = "Performance1";
8888 goto cp0_unimplemented;
8889 case 2:
8890
8891 register_name = "Performance2";
8892 goto cp0_unimplemented;
8893 case 3:
8894
8895 register_name = "Performance3";
8896 goto cp0_unimplemented;
8897 case 4:
8898
8899 register_name = "Performance4";
8900 goto cp0_unimplemented;
8901 case 5:
8902
8903 register_name = "Performance5";
8904 goto cp0_unimplemented;
8905 case 6:
8906
8907 register_name = "Performance6";
8908 goto cp0_unimplemented;
8909 case 7:
8910
8911 register_name = "Performance7";
8912 goto cp0_unimplemented;
8913 default:
8914 goto cp0_unimplemented;
8915 }
8916 break;
8917 case CP0_REGISTER_26:
8918 switch (sel) {
8919 case 0:
8920 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8921 register_name = "ErrCtl";
8922 break;
8923 default:
8924 goto cp0_unimplemented;
8925 }
8926 break;
8927 case CP0_REGISTER_27:
8928 switch (sel) {
8929
8930 case 0:
8931 case 1:
8932 case 2:
8933 case 3:
8934 tcg_gen_movi_tl(arg, 0);
8935 register_name = "CacheErr";
8936 break;
8937 default:
8938 goto cp0_unimplemented;
8939 }
8940 break;
8941 case CP0_REGISTER_28:
8942 switch (sel) {
8943 case 0:
8944 case 2:
8945 case 4:
8946 case 6:
8947 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8948 register_name = "TagLo";
8949 break;
8950 case 1:
8951 case 3:
8952 case 5:
8953 case 7:
8954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8955 register_name = "DataLo";
8956 break;
8957 default:
8958 goto cp0_unimplemented;
8959 }
8960 break;
8961 case CP0_REGISTER_29:
8962 switch (sel) {
8963 case 0:
8964 case 2:
8965 case 4:
8966 case 6:
8967 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8968 register_name = "TagHi";
8969 break;
8970 case 1:
8971 case 3:
8972 case 5:
8973 case 7:
8974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8975 register_name = "DataHi";
8976 break;
8977 default:
8978 goto cp0_unimplemented;
8979 }
8980 break;
8981 case CP0_REGISTER_30:
8982 switch (sel) {
8983 case 0:
8984 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8985 register_name = "ErrorEPC";
8986 break;
8987 default:
8988 goto cp0_unimplemented;
8989 }
8990 break;
8991 case CP0_REGISTER_31:
8992 switch (sel) {
8993 case 0:
8994
8995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8996 register_name = "DESAVE";
8997 break;
8998 case 2:
8999 case 3:
9000 case 4:
9001 case 5:
9002 case 6:
9003 case 7:
9004 CP0_CHECK(ctx->kscrexist & (1 << sel));
9005 tcg_gen_ld_tl(arg, cpu_env,
9006 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9007 register_name = "KScratch";
9008 break;
9009 default:
9010 goto cp0_unimplemented;
9011 }
9012 break;
9013 default:
9014 goto cp0_unimplemented;
9015 }
9016 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9017 return;
9018
9019cp0_unimplemented:
9020 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
9021 register_name, reg, sel);
9022 gen_mfc0_unimplemented(ctx, arg);
9023}
9024
9025static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9026{
9027 const char *register_name = "invalid";
9028
9029 if (sel != 0) {
9030 check_insn(ctx, ISA_MIPS64);
9031 }
9032
9033 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9034 gen_io_start();
9035 }
9036
9037 switch (reg) {
9038 case CP0_REGISTER_00:
9039 switch (sel) {
9040 case 0:
9041 gen_helper_mtc0_index(cpu_env, arg);
9042 register_name = "Index";
9043 break;
9044 case 1:
9045 CP0_CHECK(ctx->insn_flags & ASE_MT);
9046 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9047 register_name = "MVPControl";
9048 break;
9049 case 2:
9050 CP0_CHECK(ctx->insn_flags & ASE_MT);
9051
9052 register_name = "MVPConf0";
9053 break;
9054 case 3:
9055 CP0_CHECK(ctx->insn_flags & ASE_MT);
9056
9057 register_name = "MVPConf1";
9058 break;
9059 case 4:
9060 CP0_CHECK(ctx->vp);
9061
9062 register_name = "VPControl";
9063 break;
9064 default:
9065 goto cp0_unimplemented;
9066 }
9067 break;
9068 case CP0_REGISTER_01:
9069 switch (sel) {
9070 case 0:
9071
9072 register_name = "Random";
9073 break;
9074 case 1:
9075 CP0_CHECK(ctx->insn_flags & ASE_MT);
9076 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9077 register_name = "VPEControl";
9078 break;
9079 case 2:
9080 CP0_CHECK(ctx->insn_flags & ASE_MT);
9081 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9082 register_name = "VPEConf0";
9083 break;
9084 case 3:
9085 CP0_CHECK(ctx->insn_flags & ASE_MT);
9086 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9087 register_name = "VPEConf1";
9088 break;
9089 case 4:
9090 CP0_CHECK(ctx->insn_flags & ASE_MT);
9091 gen_helper_mtc0_yqmask(cpu_env, arg);
9092 register_name = "YQMask";
9093 break;
9094 case 5:
9095 CP0_CHECK(ctx->insn_flags & ASE_MT);
9096 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9097 register_name = "VPESchedule";
9098 break;
9099 case 6:
9100 CP0_CHECK(ctx->insn_flags & ASE_MT);
9101 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9102 register_name = "VPEScheFBack";
9103 break;
9104 case 7:
9105 CP0_CHECK(ctx->insn_flags & ASE_MT);
9106 gen_helper_mtc0_vpeopt(cpu_env, arg);
9107 register_name = "VPEOpt";
9108 break;
9109 default:
9110 goto cp0_unimplemented;
9111 }
9112 break;
9113 case CP0_REGISTER_02:
9114 switch (sel) {
9115 case 0:
9116 gen_helper_dmtc0_entrylo0(cpu_env, arg);
9117 register_name = "EntryLo0";
9118 break;
9119 case 1:
9120 CP0_CHECK(ctx->insn_flags & ASE_MT);
9121 gen_helper_mtc0_tcstatus(cpu_env, arg);
9122 register_name = "TCStatus";
9123 break;
9124 case 2:
9125 CP0_CHECK(ctx->insn_flags & ASE_MT);
9126 gen_helper_mtc0_tcbind(cpu_env, arg);
9127 register_name = "TCBind";
9128 break;
9129 case 3:
9130 CP0_CHECK(ctx->insn_flags & ASE_MT);
9131 gen_helper_mtc0_tcrestart(cpu_env, arg);
9132 register_name = "TCRestart";
9133 break;
9134 case 4:
9135 CP0_CHECK(ctx->insn_flags & ASE_MT);
9136 gen_helper_mtc0_tchalt(cpu_env, arg);
9137 register_name = "TCHalt";
9138 break;
9139 case 5:
9140 CP0_CHECK(ctx->insn_flags & ASE_MT);
9141 gen_helper_mtc0_tccontext(cpu_env, arg);
9142 register_name = "TCContext";
9143 break;
9144 case 6:
9145 CP0_CHECK(ctx->insn_flags & ASE_MT);
9146 gen_helper_mtc0_tcschedule(cpu_env, arg);
9147 register_name = "TCSchedule";
9148 break;
9149 case 7:
9150 CP0_CHECK(ctx->insn_flags & ASE_MT);
9151 gen_helper_mtc0_tcschefback(cpu_env, arg);
9152 register_name = "TCScheFBack";
9153 break;
9154 default:
9155 goto cp0_unimplemented;
9156 }
9157 break;
9158 case CP0_REGISTER_03:
9159 switch (sel) {
9160 case 0:
9161 gen_helper_dmtc0_entrylo1(cpu_env, arg);
9162 register_name = "EntryLo1";
9163 break;
9164 case 1:
9165 CP0_CHECK(ctx->vp);
9166
9167 register_name = "GlobalNumber";
9168 break;
9169 default:
9170 goto cp0_unimplemented;
9171 }
9172 break;
9173 case CP0_REGISTER_04:
9174 switch (sel) {
9175 case 0:
9176 gen_helper_mtc0_context(cpu_env, arg);
9177 register_name = "Context";
9178 break;
9179 case 1:
9180
9181 register_name = "ContextConfig";
9182 goto cp0_unimplemented;
9183 case 2:
9184 CP0_CHECK(ctx->ulri);
9185 tcg_gen_st_tl(arg, cpu_env,
9186 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9187 register_name = "UserLocal";
9188 break;
9189 default:
9190 goto cp0_unimplemented;
9191 }
9192 break;
9193 case CP0_REGISTER_05:
9194 switch (sel) {
9195 case 0:
9196 gen_helper_mtc0_pagemask(cpu_env, arg);
9197 register_name = "PageMask";
9198 break;
9199 case 1:
9200 check_insn(ctx, ISA_MIPS32R2);
9201 gen_helper_mtc0_pagegrain(cpu_env, arg);
9202 register_name = "PageGrain";
9203 break;
9204 case 2:
9205 CP0_CHECK(ctx->sc);
9206 gen_helper_mtc0_segctl0(cpu_env, arg);
9207 register_name = "SegCtl0";
9208 break;
9209 case 3:
9210 CP0_CHECK(ctx->sc);
9211 gen_helper_mtc0_segctl1(cpu_env, arg);
9212 register_name = "SegCtl1";
9213 break;
9214 case 4:
9215 CP0_CHECK(ctx->sc);
9216 gen_helper_mtc0_segctl2(cpu_env, arg);
9217 register_name = "SegCtl2";
9218 break;
9219 case 5:
9220 check_pw(ctx);
9221 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9222 register_name = "PWBase";
9223 break;
9224 case 6:
9225 check_pw(ctx);
9226 gen_helper_mtc0_pwfield(cpu_env, arg);
9227 register_name = "PWField";
9228 break;
9229 case 7:
9230 check_pw(ctx);
9231 gen_helper_mtc0_pwsize(cpu_env, arg);
9232 register_name = "PWSize";
9233 break;
9234 default:
9235 goto cp0_unimplemented;
9236 }
9237 break;
9238 case CP0_REGISTER_06:
9239 switch (sel) {
9240 case 0:
9241 gen_helper_mtc0_wired(cpu_env, arg);
9242 register_name = "Wired";
9243 break;
9244 case 1:
9245 check_insn(ctx, ISA_MIPS32R2);
9246 gen_helper_mtc0_srsconf0(cpu_env, arg);
9247 register_name = "SRSConf0";
9248 break;
9249 case 2:
9250 check_insn(ctx, ISA_MIPS32R2);
9251 gen_helper_mtc0_srsconf1(cpu_env, arg);
9252 register_name = "SRSConf1";
9253 break;
9254 case 3:
9255 check_insn(ctx, ISA_MIPS32R2);
9256 gen_helper_mtc0_srsconf2(cpu_env, arg);
9257 register_name = "SRSConf2";
9258 break;
9259 case 4:
9260 check_insn(ctx, ISA_MIPS32R2);
9261 gen_helper_mtc0_srsconf3(cpu_env, arg);
9262 register_name = "SRSConf3";
9263 break;
9264 case 5:
9265 check_insn(ctx, ISA_MIPS32R2);
9266 gen_helper_mtc0_srsconf4(cpu_env, arg);
9267 register_name = "SRSConf4";
9268 break;
9269 case 6:
9270 check_pw(ctx);
9271 gen_helper_mtc0_pwctl(cpu_env, arg);
9272 register_name = "PWCtl";
9273 break;
9274 default:
9275 goto cp0_unimplemented;
9276 }
9277 break;
9278 case CP0_REGISTER_07:
9279 switch (sel) {
9280 case 0:
9281 check_insn(ctx, ISA_MIPS32R2);
9282 gen_helper_mtc0_hwrena(cpu_env, arg);
9283 ctx->base.is_jmp = DISAS_STOP;
9284 register_name = "HWREna";
9285 break;
9286 default:
9287 goto cp0_unimplemented;
9288 }
9289 break;
9290 case CP0_REGISTER_08:
9291 switch (sel) {
9292 case 0:
9293
9294 register_name = "BadVAddr";
9295 break;
9296 case 1:
9297
9298 register_name = "BadInstr";
9299 break;
9300 case 2:
9301
9302 register_name = "BadInstrP";
9303 break;
9304 case 3:
9305
9306 register_name = "BadInstrX";
9307 break;
9308 default:
9309 goto cp0_unimplemented;
9310 }
9311 break;
9312 case CP0_REGISTER_09:
9313 switch (sel) {
9314 case 0:
9315 gen_helper_mtc0_count(cpu_env, arg);
9316 register_name = "Count";
9317 break;
9318 case 6:
9319 CP0_CHECK(ctx->saar);
9320 gen_helper_mtc0_saari(cpu_env, arg);
9321 register_name = "SAARI";
9322 break;
9323 case 7:
9324 CP0_CHECK(ctx->saar);
9325 gen_helper_mtc0_saar(cpu_env, arg);
9326 register_name = "SAAR";
9327 break;
9328 default:
9329 goto cp0_unimplemented;
9330 }
9331
9332 ctx->base.is_jmp = DISAS_STOP;
9333 break;
9334 case CP0_REGISTER_10:
9335 switch (sel) {
9336 case 0:
9337 gen_helper_mtc0_entryhi(cpu_env, arg);
9338 register_name = "EntryHi";
9339 break;
9340 default:
9341 goto cp0_unimplemented;
9342 }
9343 break;
9344 case CP0_REGISTER_11:
9345 switch (sel) {
9346 case 0:
9347 gen_helper_mtc0_compare(cpu_env, arg);
9348 register_name = "Compare";
9349 break;
9350
9351 default:
9352 goto cp0_unimplemented;
9353 }
9354
9355 ctx->base.is_jmp = DISAS_STOP;
9356 break;
9357 case CP0_REGISTER_12:
9358 switch (sel) {
9359 case 0:
9360 save_cpu_state(ctx, 1);
9361 gen_helper_mtc0_status(cpu_env, arg);
9362
9363 gen_save_pc(ctx->base.pc_next + 4);
9364 ctx->base.is_jmp = DISAS_EXIT;
9365 register_name = "Status";
9366 break;
9367 case 1:
9368 check_insn(ctx, ISA_MIPS32R2);
9369 gen_helper_mtc0_intctl(cpu_env, arg);
9370
9371 ctx->base.is_jmp = DISAS_STOP;
9372 register_name = "IntCtl";
9373 break;
9374 case 2:
9375 check_insn(ctx, ISA_MIPS32R2);
9376 gen_helper_mtc0_srsctl(cpu_env, arg);
9377
9378 ctx->base.is_jmp = DISAS_STOP;
9379 register_name = "SRSCtl";
9380 break;
9381 case 3:
9382 check_insn(ctx, ISA_MIPS32R2);
9383 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9384
9385 ctx->base.is_jmp = DISAS_STOP;
9386 register_name = "SRSMap";
9387 break;
9388 default:
9389 goto cp0_unimplemented;
9390 }
9391 break;
9392 case CP0_REGISTER_13:
9393 switch (sel) {
9394 case 0:
9395 save_cpu_state(ctx, 1);
9396 gen_helper_mtc0_cause(cpu_env, arg);
9397
9398
9399
9400
9401
9402 gen_save_pc(ctx->base.pc_next + 4);
9403 ctx->base.is_jmp = DISAS_EXIT;
9404 register_name = "Cause";
9405 break;
9406 default:
9407 goto cp0_unimplemented;
9408 }
9409 break;
9410 case CP0_REGISTER_14:
9411 switch (sel) {
9412 case 0:
9413 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9414 register_name = "EPC";
9415 break;
9416 default:
9417 goto cp0_unimplemented;
9418 }
9419 break;
9420 case CP0_REGISTER_15:
9421 switch (sel) {
9422 case 0:
9423
9424 register_name = "PRid";
9425 break;
9426 case 1:
9427 check_insn(ctx, ISA_MIPS32R2);
9428 gen_helper_mtc0_ebase(cpu_env, arg);
9429 register_name = "EBase";
9430 break;
9431 default:
9432 goto cp0_unimplemented;
9433 }
9434 break;
9435 case CP0_REGISTER_16:
9436 switch (sel) {
9437 case 0:
9438 gen_helper_mtc0_config0(cpu_env, arg);
9439 register_name = "Config";
9440
9441 ctx->base.is_jmp = DISAS_STOP;
9442 break;
9443 case 1:
9444
9445 register_name = "Config1";
9446 break;
9447 case 2:
9448 gen_helper_mtc0_config2(cpu_env, arg);
9449 register_name = "Config2";
9450
9451 ctx->base.is_jmp = DISAS_STOP;
9452 break;
9453 case 3:
9454 gen_helper_mtc0_config3(cpu_env, arg);
9455 register_name = "Config3";
9456
9457 ctx->base.is_jmp = DISAS_STOP;
9458 break;
9459 case 4:
9460
9461 register_name = "Config4";
9462 break;
9463 case 5:
9464 gen_helper_mtc0_config5(cpu_env, arg);
9465 register_name = "Config5";
9466
9467 ctx->base.is_jmp = DISAS_STOP;
9468 break;
9469
9470 default:
9471 register_name = "Invalid config selector";
9472 goto cp0_unimplemented;
9473 }
9474 break;
9475 case CP0_REGISTER_17:
9476 switch (sel) {
9477 case 0:
9478 gen_helper_mtc0_lladdr(cpu_env, arg);
9479 register_name = "LLAddr";
9480 break;
9481 case 1:
9482 CP0_CHECK(ctx->mrp);
9483 gen_helper_mtc0_maar(cpu_env, arg);
9484 register_name = "MAAR";
9485 break;
9486 case 2:
9487 CP0_CHECK(ctx->mrp);
9488 gen_helper_mtc0_maari(cpu_env, arg);
9489 register_name = "MAARI";
9490 break;
9491 default:
9492 goto cp0_unimplemented;
9493 }
9494 break;
9495 case CP0_REGISTER_18:
9496 switch (sel) {
9497 case 0:
9498 case 1:
9499 case 2:
9500 case 3:
9501 case 4:
9502 case 5:
9503 case 6:
9504 case 7:
9505 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9506 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9507 register_name = "WatchLo";
9508 break;
9509 default:
9510 goto cp0_unimplemented;
9511 }
9512 break;
9513 case CP0_REGISTER_19:
9514 switch (sel) {
9515 case 0:
9516 case 1:
9517 case 2:
9518 case 3:
9519 case 4:
9520 case 5:
9521 case 6:
9522 case 7:
9523 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9524 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9525 register_name = "WatchHi";
9526 break;
9527 default:
9528 goto cp0_unimplemented;
9529 }
9530 break;
9531 case CP0_REGISTER_20:
9532 switch (sel) {
9533 case 0:
9534 check_insn(ctx, ISA_MIPS3);
9535 gen_helper_mtc0_xcontext(cpu_env, arg);
9536 register_name = "XContext";
9537 break;
9538 default:
9539 goto cp0_unimplemented;
9540 }
9541 break;
9542 case CP0_REGISTER_21:
9543
9544 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9545 switch (sel) {
9546 case 0:
9547 gen_helper_mtc0_framemask(cpu_env, arg);
9548 register_name = "Framemask";
9549 break;
9550 default:
9551 goto cp0_unimplemented;
9552 }
9553 break;
9554 case CP0_REGISTER_22:
9555
9556 register_name = "Diagnostic";
9557 break;
9558 case CP0_REGISTER_23:
9559 switch (sel) {
9560 case 0:
9561 gen_helper_mtc0_debug(cpu_env, arg);
9562
9563 gen_save_pc(ctx->base.pc_next + 4);
9564 ctx->base.is_jmp = DISAS_EXIT;
9565 register_name = "Debug";
9566 break;
9567 case 1:
9568
9569
9570 ctx->base.is_jmp = DISAS_STOP;
9571 register_name = "TraceControl";
9572 goto cp0_unimplemented;
9573 case 2:
9574
9575
9576 ctx->base.is_jmp = DISAS_STOP;
9577 register_name = "TraceControl2";
9578 goto cp0_unimplemented;
9579 case 3:
9580
9581
9582 ctx->base.is_jmp = DISAS_STOP;
9583 register_name = "UserTraceData";
9584 goto cp0_unimplemented;
9585 case 4:
9586
9587
9588 ctx->base.is_jmp = DISAS_STOP;
9589 register_name = "TraceBPC";
9590 goto cp0_unimplemented;
9591 default:
9592 goto cp0_unimplemented;
9593 }
9594 break;
9595 case CP0_REGISTER_24:
9596 switch (sel) {
9597 case 0:
9598
9599 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9600 register_name = "DEPC";
9601 break;
9602 default:
9603 goto cp0_unimplemented;
9604 }
9605 break;
9606 case CP0_REGISTER_25:
9607 switch (sel) {
9608 case 0:
9609 gen_helper_mtc0_performance0(cpu_env, arg);
9610 register_name = "Performance0";
9611 break;
9612 case 1:
9613
9614 register_name = "Performance1";
9615 goto cp0_unimplemented;
9616 case 2:
9617
9618 register_name = "Performance2";
9619 goto cp0_unimplemented;
9620 case 3:
9621
9622 register_name = "Performance3";
9623 goto cp0_unimplemented;
9624 case 4:
9625
9626 register_name = "Performance4";
9627 goto cp0_unimplemented;
9628 case 5:
9629
9630 register_name = "Performance5";
9631 goto cp0_unimplemented;
9632 case 6:
9633
9634 register_name = "Performance6";
9635 goto cp0_unimplemented;
9636 case 7:
9637
9638 register_name = "Performance7";
9639 goto cp0_unimplemented;
9640 default:
9641 goto cp0_unimplemented;
9642 }
9643 break;
9644 case CP0_REGISTER_26:
9645 switch (sel) {
9646 case 0:
9647 gen_helper_mtc0_errctl(cpu_env, arg);
9648 ctx->base.is_jmp = DISAS_STOP;
9649 register_name = "ErrCtl";
9650 break;
9651 default:
9652 goto cp0_unimplemented;
9653 }
9654 break;
9655 case CP0_REGISTER_27:
9656 switch (sel) {
9657 case 0:
9658 case 1:
9659 case 2:
9660 case 3:
9661
9662 register_name = "CacheErr";
9663 break;
9664 default:
9665 goto cp0_unimplemented;
9666 }
9667 break;
9668 case CP0_REGISTER_28:
9669 switch (sel) {
9670 case 0:
9671 case 2:
9672 case 4:
9673 case 6:
9674 gen_helper_mtc0_taglo(cpu_env, arg);
9675 register_name = "TagLo";
9676 break;
9677 case 1:
9678 case 3:
9679 case 5:
9680 case 7:
9681 gen_helper_mtc0_datalo(cpu_env, arg);
9682 register_name = "DataLo";
9683 break;
9684 default:
9685 goto cp0_unimplemented;
9686 }
9687 break;
9688 case CP0_REGISTER_29:
9689 switch (sel) {
9690 case 0:
9691 case 2:
9692 case 4:
9693 case 6:
9694 gen_helper_mtc0_taghi(cpu_env, arg);
9695 register_name = "TagHi";
9696 break;
9697 case 1:
9698 case 3:
9699 case 5:
9700 case 7:
9701 gen_helper_mtc0_datahi(cpu_env, arg);
9702 register_name = "DataHi";
9703 break;
9704 default:
9705 register_name = "invalid sel";
9706 goto cp0_unimplemented;
9707 }
9708 break;
9709 case CP0_REGISTER_30:
9710 switch (sel) {
9711 case 0:
9712 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9713 register_name = "ErrorEPC";
9714 break;
9715 default:
9716 goto cp0_unimplemented;
9717 }
9718 break;
9719 case CP0_REGISTER_31:
9720 switch (sel) {
9721 case 0:
9722
9723 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9724 register_name = "DESAVE";
9725 break;
9726 case 2:
9727 case 3:
9728 case 4:
9729 case 5:
9730 case 6:
9731 case 7:
9732 CP0_CHECK(ctx->kscrexist & (1 << sel));
9733 tcg_gen_st_tl(arg, cpu_env,
9734 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9735 register_name = "KScratch";
9736 break;
9737 default:
9738 goto cp0_unimplemented;
9739 }
9740 break;
9741 default:
9742 goto cp0_unimplemented;
9743 }
9744 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9745
9746
9747 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9748 gen_io_end();
9749
9750
9751
9752
9753 gen_save_pc(ctx->base.pc_next + 4);
9754 ctx->base.is_jmp = DISAS_EXIT;
9755 }
9756 return;
9757
9758cp0_unimplemented:
9759 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9760 register_name, reg, sel);
9761}
9762#endif
9763
9764static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9765 int u, int sel, int h)
9766{
9767 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9768 TCGv t0 = tcg_temp_local_new();
9769
9770 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9771 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9772 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9773 tcg_gen_movi_tl(t0, -1);
9774 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9775 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
9776 tcg_gen_movi_tl(t0, -1);
9777 } else if (u == 0) {
9778 switch (rt) {
9779 case 1:
9780 switch (sel) {
9781 case 1:
9782 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9783 break;
9784 case 2:
9785 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9786 break;
9787 default:
9788 goto die;
9789 break;
9790 }
9791 break;
9792 case 2:
9793 switch (sel) {
9794 case 1:
9795 gen_helper_mftc0_tcstatus(t0, cpu_env);
9796 break;
9797 case 2:
9798 gen_helper_mftc0_tcbind(t0, cpu_env);
9799 break;
9800 case 3:
9801 gen_helper_mftc0_tcrestart(t0, cpu_env);
9802 break;
9803 case 4:
9804 gen_helper_mftc0_tchalt(t0, cpu_env);
9805 break;
9806 case 5:
9807 gen_helper_mftc0_tccontext(t0, cpu_env);
9808 break;
9809 case 6:
9810 gen_helper_mftc0_tcschedule(t0, cpu_env);
9811 break;
9812 case 7:
9813 gen_helper_mftc0_tcschefback(t0, cpu_env);
9814 break;
9815 default:
9816 gen_mfc0(ctx, t0, rt, sel);
9817 break;
9818 }
9819 break;
9820 case 10:
9821 switch (sel) {
9822 case 0:
9823 gen_helper_mftc0_entryhi(t0, cpu_env);
9824 break;
9825 default:
9826 gen_mfc0(ctx, t0, rt, sel);
9827 break;
9828 }
9829 break;
9830 case 12:
9831 switch (sel) {
9832 case 0:
9833 gen_helper_mftc0_status(t0, cpu_env);
9834 break;
9835 default:
9836 gen_mfc0(ctx, t0, rt, sel);
9837 break;
9838 }
9839 break;
9840 case 13:
9841 switch (sel) {
9842 case 0:
9843 gen_helper_mftc0_cause(t0, cpu_env);
9844 break;
9845 default:
9846 goto die;
9847 break;
9848 }
9849 break;
9850 case 14:
9851 switch (sel) {
9852 case 0:
9853 gen_helper_mftc0_epc(t0, cpu_env);
9854 break;
9855 default:
9856 goto die;
9857 break;
9858 }
9859 break;
9860 case 15:
9861 switch (sel) {
9862 case 1:
9863 gen_helper_mftc0_ebase(t0, cpu_env);
9864 break;
9865 default:
9866 goto die;
9867 break;
9868 }
9869 break;
9870 case 16:
9871 switch (sel) {
9872 case 0:
9873 case 1:
9874 case 2:
9875 case 3:
9876 case 4:
9877 case 5:
9878 case 6:
9879 case 7:
9880 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9881 break;
9882 default:
9883 goto die;
9884 break;
9885 }
9886 break;
9887 case 23:
9888 switch (sel) {
9889 case 0:
9890 gen_helper_mftc0_debug(t0, cpu_env);
9891 break;
9892 default:
9893 gen_mfc0(ctx, t0, rt, sel);
9894 break;
9895 }
9896 break;
9897 default:
9898 gen_mfc0(ctx, t0, rt, sel);
9899 }
9900 } else switch (sel) {
9901
9902 case 0:
9903 gen_helper_1e0i(mftgpr, t0, rt);
9904 break;
9905
9906 case 1:
9907 switch (rt) {
9908 case 0:
9909 gen_helper_1e0i(mftlo, t0, 0);
9910 break;
9911 case 1:
9912 gen_helper_1e0i(mfthi, t0, 0);
9913 break;
9914 case 2:
9915 gen_helper_1e0i(mftacx, t0, 0);
9916 break;
9917 case 4:
9918 gen_helper_1e0i(mftlo, t0, 1);
9919 break;
9920 case 5:
9921 gen_helper_1e0i(mfthi, t0, 1);
9922 break;
9923 case 6:
9924 gen_helper_1e0i(mftacx, t0, 1);
9925 break;
9926 case 8:
9927 gen_helper_1e0i(mftlo, t0, 2);
9928 break;
9929 case 9:
9930 gen_helper_1e0i(mfthi, t0, 2);
9931 break;
9932 case 10:
9933 gen_helper_1e0i(mftacx, t0, 2);
9934 break;
9935 case 12:
9936 gen_helper_1e0i(mftlo, t0, 3);
9937 break;
9938 case 13:
9939 gen_helper_1e0i(mfthi, t0, 3);
9940 break;
9941 case 14:
9942 gen_helper_1e0i(mftacx, t0, 3);
9943 break;
9944 case 16:
9945 gen_helper_mftdsp(t0, cpu_env);
9946 break;
9947 default:
9948 goto die;
9949 }
9950 break;
9951
9952 case 2:
9953
9954 if (h == 0) {
9955 TCGv_i32 fp0 = tcg_temp_new_i32();
9956
9957 gen_load_fpr32(ctx, fp0, rt);
9958 tcg_gen_ext_i32_tl(t0, fp0);
9959 tcg_temp_free_i32(fp0);
9960 } else {
9961 TCGv_i32 fp0 = tcg_temp_new_i32();
9962
9963 gen_load_fpr32h(ctx, fp0, rt);
9964 tcg_gen_ext_i32_tl(t0, fp0);
9965 tcg_temp_free_i32(fp0);
9966 }
9967 break;
9968 case 3:
9969
9970 gen_helper_1e0i(cfc1, t0, rt);
9971 break;
9972
9973 case 4:
9974 case 5:
9975
9976 default:
9977 goto die;
9978 }
9979 trace_mips_translate_tr("mftr", rt, u, sel, h);
9980 gen_store_gpr(t0, rd);
9981 tcg_temp_free(t0);
9982 return;
9983
9984die:
9985 tcg_temp_free(t0);
9986 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9987 generate_exception_end(ctx, EXCP_RI);
9988}
9989
9990static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9991 int u, int sel, int h)
9992{
9993 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9994 TCGv t0 = tcg_temp_local_new();
9995
9996 gen_load_gpr(t0, rt);
9997 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9998 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9999 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
10000
10001 ;
10002 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10003 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
10004
10005 ;
10006 } else if (u == 0) {
10007 switch (rd) {
10008 case 1:
10009 switch (sel) {
10010 case 1:
10011 gen_helper_mttc0_vpecontrol(cpu_env, t0);
10012 break;
10013 case 2:
10014 gen_helper_mttc0_vpeconf0(cpu_env, t0);
10015 break;
10016 default:
10017 goto die;
10018 break;
10019 }
10020 break;
10021 case 2:
10022 switch (sel) {
10023 case 1:
10024 gen_helper_mttc0_tcstatus(cpu_env, t0);
10025 break;
10026 case 2:
10027 gen_helper_mttc0_tcbind(cpu_env, t0);
10028 break;
10029 case 3:
10030 gen_helper_mttc0_tcrestart(cpu_env, t0);
10031 break;
10032 case 4:
10033 gen_helper_mttc0_tchalt(cpu_env, t0);
10034 break;
10035 case 5:
10036 gen_helper_mttc0_tccontext(cpu_env, t0);
10037 break;
10038 case 6:
10039 gen_helper_mttc0_tcschedule(cpu_env, t0);
10040 break;
10041 case 7:
10042 gen_helper_mttc0_tcschefback(cpu_env, t0);
10043 break;
10044 default:
10045 gen_mtc0(ctx, t0, rd, sel);
10046 break;
10047 }
10048 break;
10049 case 10:
10050 switch (sel) {
10051 case 0:
10052 gen_helper_mttc0_entryhi(cpu_env, t0);
10053 break;
10054 default:
10055 gen_mtc0(ctx, t0, rd, sel);
10056 break;
10057 }
10058 break;
10059 case 12:
10060 switch (sel) {
10061 case 0:
10062 gen_helper_mttc0_status(cpu_env, t0);
10063 break;
10064 default:
10065 gen_mtc0(ctx, t0, rd, sel);
10066 break;
10067 }
10068 break;
10069 case 13:
10070 switch (sel) {
10071 case 0:
10072 gen_helper_mttc0_cause(cpu_env, t0);
10073 break;
10074 default:
10075 goto die;
10076 break;
10077 }
10078 break;
10079 case 15:
10080 switch (sel) {
10081 case 1:
10082 gen_helper_mttc0_ebase(cpu_env, t0);
10083 break;
10084 default:
10085 goto die;
10086 break;
10087 }
10088 break;
10089 case 23:
10090 switch (sel) {
10091 case 0:
10092 gen_helper_mttc0_debug(cpu_env, t0);
10093 break;
10094 default:
10095 gen_mtc0(ctx, t0, rd, sel);
10096 break;
10097 }
10098 break;
10099 default:
10100 gen_mtc0(ctx, t0, rd, sel);
10101 }
10102 } else switch (sel) {
10103
10104 case 0:
10105 gen_helper_0e1i(mttgpr, t0, rd);
10106 break;
10107
10108 case 1:
10109 switch (rd) {
10110 case 0:
10111 gen_helper_0e1i(mttlo, t0, 0);
10112 break;
10113 case 1:
10114 gen_helper_0e1i(mtthi, t0, 0);
10115 break;
10116 case 2:
10117 gen_helper_0e1i(mttacx, t0, 0);
10118 break;
10119 case 4:
10120 gen_helper_0e1i(mttlo, t0, 1);
10121 break;
10122 case 5:
10123 gen_helper_0e1i(mtthi, t0, 1);
10124 break;
10125 case 6:
10126 gen_helper_0e1i(mttacx, t0, 1);
10127 break;
10128 case 8:
10129 gen_helper_0e1i(mttlo, t0, 2);
10130 break;
10131 case 9:
10132 gen_helper_0e1i(mtthi, t0, 2);
10133 break;
10134 case 10:
10135 gen_helper_0e1i(mttacx, t0, 2);
10136 break;
10137 case 12:
10138 gen_helper_0e1i(mttlo, t0, 3);
10139 break;
10140 case 13:
10141 gen_helper_0e1i(mtthi, t0, 3);
10142 break;
10143 case 14:
10144 gen_helper_0e1i(mttacx, t0, 3);
10145 break;
10146 case 16:
10147 gen_helper_mttdsp(cpu_env, t0);
10148 break;
10149 default:
10150 goto die;
10151 }
10152 break;
10153
10154 case 2:
10155
10156 if (h == 0) {
10157 TCGv_i32 fp0 = tcg_temp_new_i32();
10158
10159 tcg_gen_trunc_tl_i32(fp0, t0);
10160 gen_store_fpr32(ctx, fp0, rd);
10161 tcg_temp_free_i32(fp0);
10162 } else {
10163 TCGv_i32 fp0 = tcg_temp_new_i32();
10164
10165 tcg_gen_trunc_tl_i32(fp0, t0);
10166 gen_store_fpr32h(ctx, fp0, rd);
10167 tcg_temp_free_i32(fp0);
10168 }
10169 break;
10170 case 3:
10171
10172 {
10173 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10174
10175 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10176 tcg_temp_free_i32(fs_tmp);
10177 }
10178
10179 ctx->base.is_jmp = DISAS_STOP;
10180 break;
10181
10182 case 4:
10183 case 5:
10184
10185 default:
10186 goto die;
10187 }
10188 trace_mips_translate_tr("mttr", rd, u, sel, h);
10189 tcg_temp_free(t0);
10190 return;
10191
10192die:
10193 tcg_temp_free(t0);
10194 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10195 generate_exception_end(ctx, EXCP_RI);
10196}
10197
10198static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
10199 int rt, int rd)
10200{
10201 const char *opn = "ldst";
10202
10203 check_cp0_enabled(ctx);
10204 switch (opc) {
10205 case OPC_MFC0:
10206 if (rt == 0) {
10207
10208 return;
10209 }
10210 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10211 opn = "mfc0";
10212 break;
10213 case OPC_MTC0:
10214 {
10215 TCGv t0 = tcg_temp_new();
10216
10217 gen_load_gpr(t0, rt);
10218 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10219 tcg_temp_free(t0);
10220 }
10221 opn = "mtc0";
10222 break;
10223#if defined(TARGET_MIPS64)
10224 case OPC_DMFC0:
10225 check_insn(ctx, ISA_MIPS3);
10226 if (rt == 0) {
10227
10228 return;
10229 }
10230 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10231 opn = "dmfc0";
10232 break;
10233 case OPC_DMTC0:
10234 check_insn(ctx, ISA_MIPS3);
10235 {
10236 TCGv t0 = tcg_temp_new();
10237
10238 gen_load_gpr(t0, rt);
10239 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10240 tcg_temp_free(t0);
10241 }
10242 opn = "dmtc0";
10243 break;
10244#endif
10245 case OPC_MFHC0:
10246 check_mvh(ctx);
10247 if (rt == 0) {
10248
10249 return;
10250 }
10251 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10252 opn = "mfhc0";
10253 break;
10254 case OPC_MTHC0:
10255 check_mvh(ctx);
10256 {
10257 TCGv t0 = tcg_temp_new();
10258 gen_load_gpr(t0, rt);
10259 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10260 tcg_temp_free(t0);
10261 }
10262 opn = "mthc0";
10263 break;
10264 case OPC_MFTR:
10265 check_cp0_enabled(ctx);
10266 if (rd == 0) {
10267
10268 return;
10269 }
10270 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10271 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10272 opn = "mftr";
10273 break;
10274 case OPC_MTTR:
10275 check_cp0_enabled(ctx);
10276 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10277 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10278 opn = "mttr";
10279 break;
10280 case OPC_TLBWI:
10281 opn = "tlbwi";
10282 if (!env->tlb->helper_tlbwi) {
10283 goto die;
10284 }
10285 gen_helper_tlbwi(cpu_env);
10286 break;
10287 case OPC_TLBINV:
10288 opn = "tlbinv";
10289 if (ctx->ie >= 2) {
10290 if (!env->tlb->helper_tlbinv) {
10291 goto die;
10292 }
10293 gen_helper_tlbinv(cpu_env);
10294 }
10295 break;
10296 case OPC_TLBINVF:
10297 opn = "tlbinvf";
10298 if (ctx->ie >= 2) {
10299 if (!env->tlb->helper_tlbinvf) {
10300 goto die;
10301 }
10302 gen_helper_tlbinvf(cpu_env);
10303 }
10304 break;
10305 case OPC_TLBWR:
10306 opn = "tlbwr";
10307 if (!env->tlb->helper_tlbwr) {
10308 goto die;
10309 }
10310 gen_helper_tlbwr(cpu_env);
10311 break;
10312 case OPC_TLBP:
10313 opn = "tlbp";
10314 if (!env->tlb->helper_tlbp) {
10315 goto die;
10316 }
10317 gen_helper_tlbp(cpu_env);
10318 break;
10319 case OPC_TLBR:
10320 opn = "tlbr";
10321 if (!env->tlb->helper_tlbr) {
10322 goto die;
10323 }
10324 gen_helper_tlbr(cpu_env);
10325 break;
10326 case OPC_ERET:
10327 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10328 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10329 goto die;
10330 } else {
10331 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10332 if (ctx->opcode & (1 << bit_shift)) {
10333
10334 opn = "eretnc";
10335 check_insn(ctx, ISA_MIPS32R5);
10336 gen_helper_eretnc(cpu_env);
10337 } else {
10338
10339 opn = "eret";
10340 check_insn(ctx, ISA_MIPS2);
10341 gen_helper_eret(cpu_env);
10342 }
10343 ctx->base.is_jmp = DISAS_EXIT;
10344 }
10345 break;
10346 case OPC_DERET:
10347 opn = "deret";
10348 check_insn(ctx, ISA_MIPS32);
10349 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10350 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10351 goto die;
10352 }
10353 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10354 MIPS_INVAL(opn);
10355 generate_exception_end(ctx, EXCP_RI);
10356 } else {
10357 gen_helper_deret(cpu_env);
10358 ctx->base.is_jmp = DISAS_EXIT;
10359 }
10360 break;
10361 case OPC_WAIT:
10362 opn = "wait";
10363 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10364 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10365 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10366 goto die;
10367 }
10368
10369 ctx->base.pc_next += 4;
10370 save_cpu_state(ctx, 1);
10371 ctx->base.pc_next -= 4;
10372 gen_helper_wait(cpu_env);
10373 ctx->base.is_jmp = DISAS_NORETURN;
10374 break;
10375 default:
10376 die:
10377 MIPS_INVAL(opn);
10378 generate_exception_end(ctx, EXCP_RI);
10379 return;
10380 }
10381 (void)opn;
10382}
10383#endif
10384
10385
10386static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10387 int32_t cc, int32_t offset)
10388{
10389 target_ulong btarget;
10390 TCGv_i32 t0 = tcg_temp_new_i32();
10391
10392 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10393 generate_exception_end(ctx, EXCP_RI);
10394 goto out;
10395 }
10396
10397 if (cc != 0) {
10398 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10399 }
10400
10401 btarget = ctx->base.pc_next + 4 + offset;
10402
10403 switch (op) {
10404 case OPC_BC1F:
10405 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10406 tcg_gen_not_i32(t0, t0);
10407 tcg_gen_andi_i32(t0, t0, 1);
10408 tcg_gen_extu_i32_tl(bcond, t0);
10409 goto not_likely;
10410 case OPC_BC1FL:
10411 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10412 tcg_gen_not_i32(t0, t0);
10413 tcg_gen_andi_i32(t0, t0, 1);
10414 tcg_gen_extu_i32_tl(bcond, t0);
10415 goto likely;
10416 case OPC_BC1T:
10417 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10418 tcg_gen_andi_i32(t0, t0, 1);
10419 tcg_gen_extu_i32_tl(bcond, t0);
10420 goto not_likely;
10421 case OPC_BC1TL:
10422 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10423 tcg_gen_andi_i32(t0, t0, 1);
10424 tcg_gen_extu_i32_tl(bcond, t0);
10425 likely:
10426 ctx->hflags |= MIPS_HFLAG_BL;
10427 break;
10428 case OPC_BC1FANY2:
10429 {
10430 TCGv_i32 t1 = tcg_temp_new_i32();
10431 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10432 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10433 tcg_gen_nand_i32(t0, t0, t1);
10434 tcg_temp_free_i32(t1);
10435 tcg_gen_andi_i32(t0, t0, 1);
10436 tcg_gen_extu_i32_tl(bcond, t0);
10437 }
10438 goto not_likely;
10439 case OPC_BC1TANY2:
10440 {
10441 TCGv_i32 t1 = tcg_temp_new_i32();
10442 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10443 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10444 tcg_gen_or_i32(t0, t0, t1);
10445 tcg_temp_free_i32(t1);
10446 tcg_gen_andi_i32(t0, t0, 1);
10447 tcg_gen_extu_i32_tl(bcond, t0);
10448 }
10449 goto not_likely;
10450 case OPC_BC1FANY4:
10451 {
10452 TCGv_i32 t1 = tcg_temp_new_i32();
10453 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10454 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10455 tcg_gen_and_i32(t0, t0, t1);
10456 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10457 tcg_gen_and_i32(t0, t0, t1);
10458 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10459 tcg_gen_nand_i32(t0, t0, t1);
10460 tcg_temp_free_i32(t1);
10461 tcg_gen_andi_i32(t0, t0, 1);
10462 tcg_gen_extu_i32_tl(bcond, t0);
10463 }
10464 goto not_likely;
10465 case OPC_BC1TANY4:
10466 {
10467 TCGv_i32 t1 = tcg_temp_new_i32();
10468 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10469 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10470 tcg_gen_or_i32(t0, t0, t1);
10471 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10472 tcg_gen_or_i32(t0, t0, t1);
10473 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10474 tcg_gen_or_i32(t0, t0, t1);
10475 tcg_temp_free_i32(t1);
10476 tcg_gen_andi_i32(t0, t0, 1);
10477 tcg_gen_extu_i32_tl(bcond, t0);
10478 }
10479 not_likely:
10480 ctx->hflags |= MIPS_HFLAG_BC;
10481 break;
10482 default:
10483 MIPS_INVAL("cp1 cond branch");
10484 generate_exception_end(ctx, EXCP_RI);
10485 goto out;
10486 }
10487 ctx->btarget = btarget;
10488 ctx->hflags |= MIPS_HFLAG_BDS32;
10489 out:
10490 tcg_temp_free_i32(t0);
10491}
10492
10493
10494static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10495 int32_t ft, int32_t offset,
10496 int delayslot_size)
10497{
10498 target_ulong btarget;
10499 TCGv_i64 t0 = tcg_temp_new_i64();
10500
10501 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10502#ifdef MIPS_DEBUG_DISAS
10503 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10504 "\n", ctx->base.pc_next);
10505#endif
10506 generate_exception_end(ctx, EXCP_RI);
10507 goto out;
10508 }
10509
10510 gen_load_fpr64(ctx, t0, ft);
10511 tcg_gen_andi_i64(t0, t0, 1);
10512
10513 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10514
10515 switch (op) {
10516 case OPC_BC1EQZ:
10517 tcg_gen_xori_i64(t0, t0, 1);
10518 ctx->hflags |= MIPS_HFLAG_BC;
10519 break;
10520 case OPC_BC1NEZ:
10521
10522 ctx->hflags |= MIPS_HFLAG_BC;
10523 break;
10524 default:
10525 MIPS_INVAL("cp1 cond branch");
10526 generate_exception_end(ctx, EXCP_RI);
10527 goto out;
10528 }
10529
10530 tcg_gen_trunc_i64_tl(bcond, t0);
10531
10532 ctx->btarget = btarget;
10533
10534 switch (delayslot_size) {
10535 case 2:
10536 ctx->hflags |= MIPS_HFLAG_BDS16;
10537 break;
10538 case 4:
10539 ctx->hflags |= MIPS_HFLAG_BDS32;
10540 break;
10541 }
10542
10543out:
10544 tcg_temp_free_i64(t0);
10545}
10546
10547
10548
10549#define FOP(func, fmt) (((fmt) << 21) | (func))
10550
10551enum fopcode {
10552 OPC_ADD_S = FOP(0, FMT_S),
10553 OPC_SUB_S = FOP(1, FMT_S),
10554 OPC_MUL_S = FOP(2, FMT_S),
10555 OPC_DIV_S = FOP(3, FMT_S),
10556 OPC_SQRT_S = FOP(4, FMT_S),
10557 OPC_ABS_S = FOP(5, FMT_S),
10558 OPC_MOV_S = FOP(6, FMT_S),
10559 OPC_NEG_S = FOP(7, FMT_S),
10560 OPC_ROUND_L_S = FOP(8, FMT_S),
10561 OPC_TRUNC_L_S = FOP(9, FMT_S),
10562 OPC_CEIL_L_S = FOP(10, FMT_S),
10563 OPC_FLOOR_L_S = FOP(11, FMT_S),
10564 OPC_ROUND_W_S = FOP(12, FMT_S),
10565 OPC_TRUNC_W_S = FOP(13, FMT_S),
10566 OPC_CEIL_W_S = FOP(14, FMT_S),
10567 OPC_FLOOR_W_S = FOP(15, FMT_S),
10568 OPC_SEL_S = FOP(16, FMT_S),
10569 OPC_MOVCF_S = FOP(17, FMT_S),
10570 OPC_MOVZ_S = FOP(18, FMT_S),
10571 OPC_MOVN_S = FOP(19, FMT_S),
10572 OPC_SELEQZ_S = FOP(20, FMT_S),
10573 OPC_RECIP_S = FOP(21, FMT_S),
10574 OPC_RSQRT_S = FOP(22, FMT_S),
10575 OPC_SELNEZ_S = FOP(23, FMT_S),
10576 OPC_MADDF_S = FOP(24, FMT_S),
10577 OPC_MSUBF_S = FOP(25, FMT_S),
10578 OPC_RINT_S = FOP(26, FMT_S),
10579 OPC_CLASS_S = FOP(27, FMT_S),
10580 OPC_MIN_S = FOP(28, FMT_S),
10581 OPC_RECIP2_S = FOP(28, FMT_S),
10582 OPC_MINA_S = FOP(29, FMT_S),
10583 OPC_RECIP1_S = FOP(29, FMT_S),
10584 OPC_MAX_S = FOP(30, FMT_S),
10585 OPC_RSQRT1_S = FOP(30, FMT_S),
10586 OPC_MAXA_S = FOP(31, FMT_S),
10587 OPC_RSQRT2_S = FOP(31, FMT_S),
10588 OPC_CVT_D_S = FOP(33, FMT_S),
10589 OPC_CVT_W_S = FOP(36, FMT_S),
10590 OPC_CVT_L_S = FOP(37, FMT_S),
10591 OPC_CVT_PS_S = FOP(38, FMT_S),
10592 OPC_CMP_F_S = FOP(48, FMT_S),
10593 OPC_CMP_UN_S = FOP(49, FMT_S),
10594 OPC_CMP_EQ_S = FOP(50, FMT_S),
10595 OPC_CMP_UEQ_S = FOP(51, FMT_S),
10596 OPC_CMP_OLT_S = FOP(52, FMT_S),
10597 OPC_CMP_ULT_S = FOP(53, FMT_S),
10598 OPC_CMP_OLE_S = FOP(54, FMT_S),
10599 OPC_CMP_ULE_S = FOP(55, FMT_S),
10600 OPC_CMP_SF_S = FOP(56, FMT_S),
10601 OPC_CMP_NGLE_S = FOP(57, FMT_S),
10602 OPC_CMP_SEQ_S = FOP(58, FMT_S),
10603 OPC_CMP_NGL_S = FOP(59, FMT_S),
10604 OPC_CMP_LT_S = FOP(60, FMT_S),
10605 OPC_CMP_NGE_S = FOP(61, FMT_S),
10606 OPC_CMP_LE_S = FOP(62, FMT_S),
10607 OPC_CMP_NGT_S = FOP(63, FMT_S),
10608
10609 OPC_ADD_D = FOP(0, FMT_D),
10610 OPC_SUB_D = FOP(1, FMT_D),
10611 OPC_MUL_D = FOP(2, FMT_D),
10612 OPC_DIV_D = FOP(3, FMT_D),
10613 OPC_SQRT_D = FOP(4, FMT_D),
10614 OPC_ABS_D = FOP(5, FMT_D),
10615 OPC_MOV_D = FOP(6, FMT_D),
10616 OPC_NEG_D = FOP(7, FMT_D),
10617 OPC_ROUND_L_D = FOP(8, FMT_D),
10618 OPC_TRUNC_L_D = FOP(9, FMT_D),
10619 OPC_CEIL_L_D = FOP(10, FMT_D),
10620 OPC_FLOOR_L_D = FOP(11, FMT_D),
10621 OPC_ROUND_W_D = FOP(12, FMT_D),
10622 OPC_TRUNC_W_D = FOP(13, FMT_D),
10623 OPC_CEIL_W_D = FOP(14, FMT_D),
10624 OPC_FLOOR_W_D = FOP(15, FMT_D),
10625 OPC_SEL_D = FOP(16, FMT_D),
10626 OPC_MOVCF_D = FOP(17, FMT_D),
10627 OPC_MOVZ_D = FOP(18, FMT_D),
10628 OPC_MOVN_D = FOP(19, FMT_D),
10629 OPC_SELEQZ_D = FOP(20, FMT_D),
10630 OPC_RECIP_D = FOP(21, FMT_D),
10631 OPC_RSQRT_D = FOP(22, FMT_D),
10632 OPC_SELNEZ_D = FOP(23, FMT_D),
10633 OPC_MADDF_D = FOP(24, FMT_D),
10634 OPC_MSUBF_D = FOP(25, FMT_D),
10635 OPC_RINT_D = FOP(26, FMT_D),
10636 OPC_CLASS_D = FOP(27, FMT_D),
10637 OPC_MIN_D = FOP(28, FMT_D),
10638 OPC_RECIP2_D = FOP(28, FMT_D),
10639 OPC_MINA_D = FOP(29, FMT_D),
10640 OPC_RECIP1_D = FOP(29, FMT_D),
10641 OPC_MAX_D = FOP(30, FMT_D),
10642 OPC_RSQRT1_D = FOP(30, FMT_D),
10643 OPC_MAXA_D = FOP(31, FMT_D),
10644 OPC_RSQRT2_D = FOP(31, FMT_D),
10645 OPC_CVT_S_D = FOP(32, FMT_D),
10646 OPC_CVT_W_D = FOP(36, FMT_D),
10647 OPC_CVT_L_D = FOP(37, FMT_D),
10648 OPC_CMP_F_D = FOP(48, FMT_D),
10649 OPC_CMP_UN_D = FOP(49, FMT_D),
10650 OPC_CMP_EQ_D = FOP(50, FMT_D),
10651 OPC_CMP_UEQ_D = FOP(51, FMT_D),
10652 OPC_CMP_OLT_D = FOP(52, FMT_D),
10653 OPC_CMP_ULT_D = FOP(53, FMT_D),
10654 OPC_CMP_OLE_D = FOP(54, FMT_D),
10655 OPC_CMP_ULE_D = FOP(55, FMT_D),
10656 OPC_CMP_SF_D = FOP(56, FMT_D),
10657 OPC_CMP_NGLE_D = FOP(57, FMT_D),
10658 OPC_CMP_SEQ_D = FOP(58, FMT_D),
10659 OPC_CMP_NGL_D = FOP(59, FMT_D),
10660 OPC_CMP_LT_D = FOP(60, FMT_D),
10661 OPC_CMP_NGE_D = FOP(61, FMT_D),
10662 OPC_CMP_LE_D = FOP(62, FMT_D),
10663 OPC_CMP_NGT_D = FOP(63, FMT_D),
10664
10665 OPC_CVT_S_W = FOP(32, FMT_W),
10666 OPC_CVT_D_W = FOP(33, FMT_W),
10667 OPC_CVT_S_L = FOP(32, FMT_L),
10668 OPC_CVT_D_L = FOP(33, FMT_L),
10669 OPC_CVT_PS_PW = FOP(38, FMT_W),
10670
10671 OPC_ADD_PS = FOP(0, FMT_PS),
10672 OPC_SUB_PS = FOP(1, FMT_PS),
10673 OPC_MUL_PS = FOP(2, FMT_PS),
10674 OPC_DIV_PS = FOP(3, FMT_PS),
10675 OPC_ABS_PS = FOP(5, FMT_PS),
10676 OPC_MOV_PS = FOP(6, FMT_PS),
10677 OPC_NEG_PS = FOP(7, FMT_PS),
10678 OPC_MOVCF_PS = FOP(17, FMT_PS),
10679 OPC_MOVZ_PS = FOP(18, FMT_PS),
10680 OPC_MOVN_PS = FOP(19, FMT_PS),
10681 OPC_ADDR_PS = FOP(24, FMT_PS),
10682 OPC_MULR_PS = FOP(26, FMT_PS),
10683 OPC_RECIP2_PS = FOP(28, FMT_PS),
10684 OPC_RECIP1_PS = FOP(29, FMT_PS),
10685 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10686 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10687
10688 OPC_CVT_S_PU = FOP(32, FMT_PS),
10689 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10690 OPC_CVT_S_PL = FOP(40, FMT_PS),
10691 OPC_PLL_PS = FOP(44, FMT_PS),
10692 OPC_PLU_PS = FOP(45, FMT_PS),
10693 OPC_PUL_PS = FOP(46, FMT_PS),
10694 OPC_PUU_PS = FOP(47, FMT_PS),
10695 OPC_CMP_F_PS = FOP(48, FMT_PS),
10696 OPC_CMP_UN_PS = FOP(49, FMT_PS),
10697 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
10698 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
10699 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
10700 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
10701 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
10702 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
10703 OPC_CMP_SF_PS = FOP(56, FMT_PS),
10704 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
10705 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
10706 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
10707 OPC_CMP_LT_PS = FOP(60, FMT_PS),
10708 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
10709 OPC_CMP_LE_PS = FOP(62, FMT_PS),
10710 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
10711};
10712
10713enum r6_f_cmp_op {
10714 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10715 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10716 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10717 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10718 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10719 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10720 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10721 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10722 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10723 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10724 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10725 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10726 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10727 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10728 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10729 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10730 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10731 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10732 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10733 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10734 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10735 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10736
10737 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10738 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10739 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10740 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10741 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10742 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10743 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10744 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10745 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10746 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10747 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10748 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10749 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10750 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10751 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10752 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10753 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10754 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10755 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10756 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10757 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10758 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10759};
10760
10761static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
10762{
10763 TCGv t0 = tcg_temp_new();
10764
10765 switch (opc) {
10766 case OPC_MFC1:
10767 {
10768 TCGv_i32 fp0 = tcg_temp_new_i32();
10769
10770 gen_load_fpr32(ctx, fp0, fs);
10771 tcg_gen_ext_i32_tl(t0, fp0);
10772 tcg_temp_free_i32(fp0);
10773 }
10774 gen_store_gpr(t0, rt);
10775 break;
10776 case OPC_MTC1:
10777 gen_load_gpr(t0, rt);
10778 {
10779 TCGv_i32 fp0 = tcg_temp_new_i32();
10780
10781 tcg_gen_trunc_tl_i32(fp0, t0);
10782 gen_store_fpr32(ctx, fp0, fs);
10783 tcg_temp_free_i32(fp0);
10784 }
10785 break;
10786 case OPC_CFC1:
10787 gen_helper_1e0i(cfc1, t0, fs);
10788 gen_store_gpr(t0, rt);
10789 break;
10790 case OPC_CTC1:
10791 gen_load_gpr(t0, rt);
10792 save_cpu_state(ctx, 0);
10793 {
10794 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10795
10796 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10797 tcg_temp_free_i32(fs_tmp);
10798 }
10799
10800 ctx->base.is_jmp = DISAS_STOP;
10801 break;
10802#if defined(TARGET_MIPS64)
10803 case OPC_DMFC1:
10804 gen_load_fpr64(ctx, t0, fs);
10805 gen_store_gpr(t0, rt);
10806 break;
10807 case OPC_DMTC1:
10808 gen_load_gpr(t0, rt);
10809 gen_store_fpr64(ctx, t0, fs);
10810 break;
10811#endif
10812 case OPC_MFHC1:
10813 {
10814 TCGv_i32 fp0 = tcg_temp_new_i32();
10815
10816 gen_load_fpr32h(ctx, fp0, fs);
10817 tcg_gen_ext_i32_tl(t0, fp0);
10818 tcg_temp_free_i32(fp0);
10819 }
10820 gen_store_gpr(t0, rt);
10821 break;
10822 case OPC_MTHC1:
10823 gen_load_gpr(t0, rt);
10824 {
10825 TCGv_i32 fp0 = tcg_temp_new_i32();
10826
10827 tcg_gen_trunc_tl_i32(fp0, t0);
10828 gen_store_fpr32h(ctx, fp0, fs);
10829 tcg_temp_free_i32(fp0);
10830 }
10831 break;
10832 default:
10833 MIPS_INVAL("cp1 move");
10834 generate_exception_end(ctx, EXCP_RI);
10835 goto out;
10836 }
10837
10838 out:
10839 tcg_temp_free(t0);
10840}
10841
10842static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
10843{
10844 TCGLabel *l1;
10845 TCGCond cond;
10846 TCGv_i32 t0;
10847
10848 if (rd == 0) {
10849
10850 return;
10851 }
10852
10853 if (tf) {
10854 cond = TCG_COND_EQ;
10855 } else {
10856 cond = TCG_COND_NE;
10857 }
10858
10859 l1 = gen_new_label();
10860 t0 = tcg_temp_new_i32();
10861 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10862 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10863 tcg_temp_free_i32(t0);
10864 if (rs == 0) {
10865 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10866 } else {
10867 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10868 }
10869 gen_set_label(l1);
10870}
10871
10872static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10873 int tf)
10874{
10875 int cond;
10876 TCGv_i32 t0 = tcg_temp_new_i32();
10877 TCGLabel *l1 = gen_new_label();
10878
10879 if (tf) {
10880 cond = TCG_COND_EQ;
10881 } else {
10882 cond = TCG_COND_NE;
10883 }
10884
10885 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10886 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10887 gen_load_fpr32(ctx, t0, fs);
10888 gen_store_fpr32(ctx, t0, fd);
10889 gen_set_label(l1);
10890 tcg_temp_free_i32(t0);
10891}
10892
10893static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
10894 int tf)
10895{
10896 int cond;
10897 TCGv_i32 t0 = tcg_temp_new_i32();
10898 TCGv_i64 fp0;
10899 TCGLabel *l1 = gen_new_label();
10900
10901 if (tf) {
10902 cond = TCG_COND_EQ;
10903 } else {
10904 cond = TCG_COND_NE;
10905 }
10906
10907 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10908 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10909 tcg_temp_free_i32(t0);
10910 fp0 = tcg_temp_new_i64();
10911 gen_load_fpr64(ctx, fp0, fs);
10912 gen_store_fpr64(ctx, fp0, fd);
10913 tcg_temp_free_i64(fp0);
10914 gen_set_label(l1);
10915}
10916
10917static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10918 int cc, int tf)
10919{
10920 int cond;
10921 TCGv_i32 t0 = tcg_temp_new_i32();
10922 TCGLabel *l1 = gen_new_label();
10923 TCGLabel *l2 = gen_new_label();
10924
10925 if (tf) {
10926 cond = TCG_COND_EQ;
10927 } else {
10928 cond = TCG_COND_NE;
10929 }
10930
10931 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10932 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10933 gen_load_fpr32(ctx, t0, fs);
10934 gen_store_fpr32(ctx, t0, fd);
10935 gen_set_label(l1);
10936
10937 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10938 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10939 gen_load_fpr32h(ctx, t0, fs);
10940 gen_store_fpr32h(ctx, t0, fd);
10941 tcg_temp_free_i32(t0);
10942 gen_set_label(l2);
10943}
10944
10945static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10946 int fs)
10947{
10948 TCGv_i32 t1 = tcg_const_i32(0);
10949 TCGv_i32 fp0 = tcg_temp_new_i32();
10950 TCGv_i32 fp1 = tcg_temp_new_i32();
10951 TCGv_i32 fp2 = tcg_temp_new_i32();
10952 gen_load_fpr32(ctx, fp0, fd);
10953 gen_load_fpr32(ctx, fp1, ft);
10954 gen_load_fpr32(ctx, fp2, fs);
10955
10956 switch (op1) {
10957 case OPC_SEL_S:
10958 tcg_gen_andi_i32(fp0, fp0, 1);
10959 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10960 break;
10961 case OPC_SELEQZ_S:
10962 tcg_gen_andi_i32(fp1, fp1, 1);
10963 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10964 break;
10965 case OPC_SELNEZ_S:
10966 tcg_gen_andi_i32(fp1, fp1, 1);
10967 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10968 break;
10969 default:
10970 MIPS_INVAL("gen_sel_s");
10971 generate_exception_end(ctx, EXCP_RI);
10972 break;
10973 }
10974
10975 gen_store_fpr32(ctx, fp0, fd);
10976 tcg_temp_free_i32(fp2);
10977 tcg_temp_free_i32(fp1);
10978 tcg_temp_free_i32(fp0);
10979 tcg_temp_free_i32(t1);
10980}
10981
10982static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10983 int fs)
10984{
10985 TCGv_i64 t1 = tcg_const_i64(0);
10986 TCGv_i64 fp0 = tcg_temp_new_i64();
10987 TCGv_i64 fp1 = tcg_temp_new_i64();
10988 TCGv_i64 fp2 = tcg_temp_new_i64();
10989 gen_load_fpr64(ctx, fp0, fd);
10990 gen_load_fpr64(ctx, fp1, ft);
10991 gen_load_fpr64(ctx, fp2, fs);
10992
10993 switch (op1) {
10994 case OPC_SEL_D:
10995 tcg_gen_andi_i64(fp0, fp0, 1);
10996 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10997 break;
10998 case OPC_SELEQZ_D:
10999 tcg_gen_andi_i64(fp1, fp1, 1);
11000 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11001 break;
11002 case OPC_SELNEZ_D:
11003 tcg_gen_andi_i64(fp1, fp1, 1);
11004 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11005 break;
11006 default:
11007 MIPS_INVAL("gen_sel_d");
11008 generate_exception_end(ctx, EXCP_RI);
11009 break;
11010 }
11011
11012 gen_store_fpr64(ctx, fp0, fd);
11013 tcg_temp_free_i64(fp2);
11014 tcg_temp_free_i64(fp1);
11015 tcg_temp_free_i64(fp0);
11016 tcg_temp_free_i64(t1);
11017}
11018
11019static void gen_farith(DisasContext *ctx, enum fopcode op1,
11020 int ft, int fs, int fd, int cc)
11021{
11022 uint32_t func = ctx->opcode & 0x3f;
11023 switch (op1) {
11024 case OPC_ADD_S:
11025 {
11026 TCGv_i32 fp0 = tcg_temp_new_i32();
11027 TCGv_i32 fp1 = tcg_temp_new_i32();
11028
11029 gen_load_fpr32(ctx, fp0, fs);
11030 gen_load_fpr32(ctx, fp1, ft);
11031 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
11032 tcg_temp_free_i32(fp1);
11033 gen_store_fpr32(ctx, fp0, fd);
11034 tcg_temp_free_i32(fp0);
11035 }
11036 break;
11037 case OPC_SUB_S:
11038 {
11039 TCGv_i32 fp0 = tcg_temp_new_i32();
11040 TCGv_i32 fp1 = tcg_temp_new_i32();
11041
11042 gen_load_fpr32(ctx, fp0, fs);
11043 gen_load_fpr32(ctx, fp1, ft);
11044 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
11045 tcg_temp_free_i32(fp1);
11046 gen_store_fpr32(ctx, fp0, fd);
11047 tcg_temp_free_i32(fp0);
11048 }
11049 break;
11050 case OPC_MUL_S:
11051 {
11052 TCGv_i32 fp0 = tcg_temp_new_i32();
11053 TCGv_i32 fp1 = tcg_temp_new_i32();
11054
11055 gen_load_fpr32(ctx, fp0, fs);
11056 gen_load_fpr32(ctx, fp1, ft);
11057 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
11058 tcg_temp_free_i32(fp1);
11059 gen_store_fpr32(ctx, fp0, fd);
11060 tcg_temp_free_i32(fp0);
11061 }
11062 break;
11063 case OPC_DIV_S:
11064 {
11065 TCGv_i32 fp0 = tcg_temp_new_i32();
11066 TCGv_i32 fp1 = tcg_temp_new_i32();
11067
11068 gen_load_fpr32(ctx, fp0, fs);
11069 gen_load_fpr32(ctx, fp1, ft);
11070 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
11071 tcg_temp_free_i32(fp1);
11072 gen_store_fpr32(ctx, fp0, fd);
11073 tcg_temp_free_i32(fp0);
11074 }
11075 break;
11076 case OPC_SQRT_S:
11077 {
11078 TCGv_i32 fp0 = tcg_temp_new_i32();
11079
11080 gen_load_fpr32(ctx, fp0, fs);
11081 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
11082 gen_store_fpr32(ctx, fp0, fd);
11083 tcg_temp_free_i32(fp0);
11084 }
11085 break;
11086 case OPC_ABS_S:
11087 {
11088 TCGv_i32 fp0 = tcg_temp_new_i32();
11089
11090 gen_load_fpr32(ctx, fp0, fs);
11091 if (ctx->abs2008) {
11092 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11093 } else {
11094 gen_helper_float_abs_s(fp0, fp0);
11095 }
11096 gen_store_fpr32(ctx, fp0, fd);
11097 tcg_temp_free_i32(fp0);
11098 }
11099 break;
11100 case OPC_MOV_S:
11101 {
11102 TCGv_i32 fp0 = tcg_temp_new_i32();
11103
11104 gen_load_fpr32(ctx, fp0, fs);
11105 gen_store_fpr32(ctx, fp0, fd);
11106 tcg_temp_free_i32(fp0);
11107 }
11108 break;
11109 case OPC_NEG_S:
11110 {
11111 TCGv_i32 fp0 = tcg_temp_new_i32();
11112
11113 gen_load_fpr32(ctx, fp0, fs);
11114 if (ctx->abs2008) {
11115 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11116 } else {
11117 gen_helper_float_chs_s(fp0, fp0);
11118 }
11119 gen_store_fpr32(ctx, fp0, fd);
11120 tcg_temp_free_i32(fp0);
11121 }
11122 break;
11123 case OPC_ROUND_L_S:
11124 check_cp1_64bitmode(ctx);
11125 {
11126 TCGv_i32 fp32 = tcg_temp_new_i32();
11127 TCGv_i64 fp64 = tcg_temp_new_i64();
11128
11129 gen_load_fpr32(ctx, fp32, fs);
11130 if (ctx->nan2008) {
11131 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11132 } else {
11133 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11134 }
11135 tcg_temp_free_i32(fp32);
11136 gen_store_fpr64(ctx, fp64, fd);
11137 tcg_temp_free_i64(fp64);
11138 }
11139 break;
11140 case OPC_TRUNC_L_S:
11141 check_cp1_64bitmode(ctx);
11142 {
11143 TCGv_i32 fp32 = tcg_temp_new_i32();
11144 TCGv_i64 fp64 = tcg_temp_new_i64();
11145
11146 gen_load_fpr32(ctx, fp32, fs);
11147 if (ctx->nan2008) {
11148 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11149 } else {
11150 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11151 }
11152 tcg_temp_free_i32(fp32);
11153 gen_store_fpr64(ctx, fp64, fd);
11154 tcg_temp_free_i64(fp64);
11155 }
11156 break;
11157 case OPC_CEIL_L_S:
11158 check_cp1_64bitmode(ctx);
11159 {
11160 TCGv_i32 fp32 = tcg_temp_new_i32();
11161 TCGv_i64 fp64 = tcg_temp_new_i64();
11162
11163 gen_load_fpr32(ctx, fp32, fs);
11164 if (ctx->nan2008) {
11165 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11166 } else {
11167 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11168 }
11169 tcg_temp_free_i32(fp32);
11170 gen_store_fpr64(ctx, fp64, fd);
11171 tcg_temp_free_i64(fp64);
11172 }
11173 break;
11174 case OPC_FLOOR_L_S:
11175 check_cp1_64bitmode(ctx);
11176 {
11177 TCGv_i32 fp32 = tcg_temp_new_i32();
11178 TCGv_i64 fp64 = tcg_temp_new_i64();
11179
11180 gen_load_fpr32(ctx, fp32, fs);
11181 if (ctx->nan2008) {
11182 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11183 } else {
11184 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11185 }
11186 tcg_temp_free_i32(fp32);
11187 gen_store_fpr64(ctx, fp64, fd);
11188 tcg_temp_free_i64(fp64);
11189 }
11190 break;
11191 case OPC_ROUND_W_S:
11192 {
11193 TCGv_i32 fp0 = tcg_temp_new_i32();
11194
11195 gen_load_fpr32(ctx, fp0, fs);
11196 if (ctx->nan2008) {
11197 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11198 } else {
11199 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11200 }
11201 gen_store_fpr32(ctx, fp0, fd);
11202 tcg_temp_free_i32(fp0);
11203 }
11204 break;
11205 case OPC_TRUNC_W_S:
11206 {
11207 TCGv_i32 fp0 = tcg_temp_new_i32();
11208
11209 gen_load_fpr32(ctx, fp0, fs);
11210 if (ctx->nan2008) {
11211 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11212 } else {
11213 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11214 }
11215 gen_store_fpr32(ctx, fp0, fd);
11216 tcg_temp_free_i32(fp0);
11217 }
11218 break;
11219 case OPC_CEIL_W_S:
11220 {
11221 TCGv_i32 fp0 = tcg_temp_new_i32();
11222
11223 gen_load_fpr32(ctx, fp0, fs);
11224 if (ctx->nan2008) {
11225 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11226 } else {
11227 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11228 }
11229 gen_store_fpr32(ctx, fp0, fd);
11230 tcg_temp_free_i32(fp0);
11231 }
11232 break;
11233 case OPC_FLOOR_W_S:
11234 {
11235 TCGv_i32 fp0 = tcg_temp_new_i32();
11236
11237 gen_load_fpr32(ctx, fp0, fs);
11238 if (ctx->nan2008) {
11239 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11240 } else {
11241 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11242 }
11243 gen_store_fpr32(ctx, fp0, fd);
11244 tcg_temp_free_i32(fp0);
11245 }
11246 break;
11247 case OPC_SEL_S:
11248 check_insn(ctx, ISA_MIPS32R6);
11249 gen_sel_s(ctx, op1, fd, ft, fs);
11250 break;
11251 case OPC_SELEQZ_S:
11252 check_insn(ctx, ISA_MIPS32R6);
11253 gen_sel_s(ctx, op1, fd, ft, fs);
11254 break;
11255 case OPC_SELNEZ_S:
11256 check_insn(ctx, ISA_MIPS32R6);
11257 gen_sel_s(ctx, op1, fd, ft, fs);
11258 break;
11259 case OPC_MOVCF_S:
11260 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11261 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11262 break;
11263 case OPC_MOVZ_S:
11264 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11265 {
11266 TCGLabel *l1 = gen_new_label();
11267 TCGv_i32 fp0;
11268
11269 if (ft != 0) {
11270 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11271 }
11272 fp0 = tcg_temp_new_i32();
11273 gen_load_fpr32(ctx, fp0, fs);
11274 gen_store_fpr32(ctx, fp0, fd);
11275 tcg_temp_free_i32(fp0);
11276 gen_set_label(l1);
11277 }
11278 break;
11279 case OPC_MOVN_S:
11280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11281 {
11282 TCGLabel *l1 = gen_new_label();
11283 TCGv_i32 fp0;
11284
11285 if (ft != 0) {
11286 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11287 fp0 = tcg_temp_new_i32();
11288 gen_load_fpr32(ctx, fp0, fs);
11289 gen_store_fpr32(ctx, fp0, fd);
11290 tcg_temp_free_i32(fp0);
11291 gen_set_label(l1);
11292 }
11293 }
11294 break;
11295 case OPC_RECIP_S:
11296 {
11297 TCGv_i32 fp0 = tcg_temp_new_i32();
11298
11299 gen_load_fpr32(ctx, fp0, fs);
11300 gen_helper_float_recip_s(fp0, cpu_env, fp0);
11301 gen_store_fpr32(ctx, fp0, fd);
11302 tcg_temp_free_i32(fp0);
11303 }
11304 break;
11305 case OPC_RSQRT_S:
11306 {
11307 TCGv_i32 fp0 = tcg_temp_new_i32();
11308
11309 gen_load_fpr32(ctx, fp0, fs);
11310 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11311 gen_store_fpr32(ctx, fp0, fd);
11312 tcg_temp_free_i32(fp0);
11313 }
11314 break;
11315 case OPC_MADDF_S:
11316 check_insn(ctx, ISA_MIPS32R6);
11317 {
11318 TCGv_i32 fp0 = tcg_temp_new_i32();
11319 TCGv_i32 fp1 = tcg_temp_new_i32();
11320 TCGv_i32 fp2 = tcg_temp_new_i32();
11321 gen_load_fpr32(ctx, fp0, fs);
11322 gen_load_fpr32(ctx, fp1, ft);
11323 gen_load_fpr32(ctx, fp2, fd);
11324 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11325 gen_store_fpr32(ctx, fp2, fd);
11326 tcg_temp_free_i32(fp2);
11327 tcg_temp_free_i32(fp1);
11328 tcg_temp_free_i32(fp0);
11329 }
11330 break;
11331 case OPC_MSUBF_S:
11332 check_insn(ctx, ISA_MIPS32R6);
11333 {
11334 TCGv_i32 fp0 = tcg_temp_new_i32();
11335 TCGv_i32 fp1 = tcg_temp_new_i32();
11336 TCGv_i32 fp2 = tcg_temp_new_i32();
11337 gen_load_fpr32(ctx, fp0, fs);
11338 gen_load_fpr32(ctx, fp1, ft);
11339 gen_load_fpr32(ctx, fp2, fd);
11340 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11341 gen_store_fpr32(ctx, fp2, fd);
11342 tcg_temp_free_i32(fp2);
11343 tcg_temp_free_i32(fp1);
11344 tcg_temp_free_i32(fp0);
11345 }
11346 break;
11347 case OPC_RINT_S:
11348 check_insn(ctx, ISA_MIPS32R6);
11349 {
11350 TCGv_i32 fp0 = tcg_temp_new_i32();
11351 gen_load_fpr32(ctx, fp0, fs);
11352 gen_helper_float_rint_s(fp0, cpu_env, fp0);
11353 gen_store_fpr32(ctx, fp0, fd);
11354 tcg_temp_free_i32(fp0);
11355 }
11356 break;
11357 case OPC_CLASS_S:
11358 check_insn(ctx, ISA_MIPS32R6);
11359 {
11360 TCGv_i32 fp0 = tcg_temp_new_i32();
11361 gen_load_fpr32(ctx, fp0, fs);
11362 gen_helper_float_class_s(fp0, cpu_env, fp0);
11363 gen_store_fpr32(ctx, fp0, fd);
11364 tcg_temp_free_i32(fp0);
11365 }
11366 break;
11367 case OPC_MIN_S:
11368 if (ctx->insn_flags & ISA_MIPS32R6) {
11369
11370 TCGv_i32 fp0 = tcg_temp_new_i32();
11371 TCGv_i32 fp1 = tcg_temp_new_i32();
11372 TCGv_i32 fp2 = tcg_temp_new_i32();
11373 gen_load_fpr32(ctx, fp0, fs);
11374 gen_load_fpr32(ctx, fp1, ft);
11375 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11376 gen_store_fpr32(ctx, fp2, fd);
11377 tcg_temp_free_i32(fp2);
11378 tcg_temp_free_i32(fp1);
11379 tcg_temp_free_i32(fp0);
11380 } else {
11381
11382 check_cp1_64bitmode(ctx);
11383 {
11384 TCGv_i32 fp0 = tcg_temp_new_i32();
11385 TCGv_i32 fp1 = tcg_temp_new_i32();
11386
11387 gen_load_fpr32(ctx, fp0, fs);
11388 gen_load_fpr32(ctx, fp1, ft);
11389 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11390 tcg_temp_free_i32(fp1);
11391 gen_store_fpr32(ctx, fp0, fd);
11392 tcg_temp_free_i32(fp0);
11393 }
11394 }
11395 break;
11396 case OPC_MINA_S:
11397 if (ctx->insn_flags & ISA_MIPS32R6) {
11398
11399 TCGv_i32 fp0 = tcg_temp_new_i32();
11400 TCGv_i32 fp1 = tcg_temp_new_i32();
11401 TCGv_i32 fp2 = tcg_temp_new_i32();
11402 gen_load_fpr32(ctx, fp0, fs);
11403 gen_load_fpr32(ctx, fp1, ft);
11404 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11405 gen_store_fpr32(ctx, fp2, fd);
11406 tcg_temp_free_i32(fp2);
11407 tcg_temp_free_i32(fp1);
11408 tcg_temp_free_i32(fp0);
11409 } else {
11410
11411 check_cp1_64bitmode(ctx);
11412 {
11413 TCGv_i32 fp0 = tcg_temp_new_i32();
11414
11415 gen_load_fpr32(ctx, fp0, fs);
11416 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11417 gen_store_fpr32(ctx, fp0, fd);
11418 tcg_temp_free_i32(fp0);
11419 }
11420 }
11421 break;
11422 case OPC_MAX_S:
11423 if (ctx->insn_flags & ISA_MIPS32R6) {
11424
11425 TCGv_i32 fp0 = tcg_temp_new_i32();
11426 TCGv_i32 fp1 = tcg_temp_new_i32();
11427 gen_load_fpr32(ctx, fp0, fs);
11428 gen_load_fpr32(ctx, fp1, ft);
11429 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11430 gen_store_fpr32(ctx, fp1, fd);
11431 tcg_temp_free_i32(fp1);
11432 tcg_temp_free_i32(fp0);
11433 } else {
11434
11435 check_cp1_64bitmode(ctx);
11436 {
11437 TCGv_i32 fp0 = tcg_temp_new_i32();
11438
11439 gen_load_fpr32(ctx, fp0, fs);
11440 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11441 gen_store_fpr32(ctx, fp0, fd);
11442 tcg_temp_free_i32(fp0);
11443 }
11444 }
11445 break;
11446 case OPC_MAXA_S:
11447 if (ctx->insn_flags & ISA_MIPS32R6) {
11448
11449 TCGv_i32 fp0 = tcg_temp_new_i32();
11450 TCGv_i32 fp1 = tcg_temp_new_i32();
11451 gen_load_fpr32(ctx, fp0, fs);
11452 gen_load_fpr32(ctx, fp1, ft);
11453 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11454 gen_store_fpr32(ctx, fp1, fd);
11455 tcg_temp_free_i32(fp1);
11456 tcg_temp_free_i32(fp0);
11457 } else {
11458
11459 check_cp1_64bitmode(ctx);
11460 {
11461 TCGv_i32 fp0 = tcg_temp_new_i32();
11462 TCGv_i32 fp1 = tcg_temp_new_i32();
11463
11464 gen_load_fpr32(ctx, fp0, fs);
11465 gen_load_fpr32(ctx, fp1, ft);
11466 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11467 tcg_temp_free_i32(fp1);
11468 gen_store_fpr32(ctx, fp0, fd);
11469 tcg_temp_free_i32(fp0);
11470 }
11471 }
11472 break;
11473 case OPC_CVT_D_S:
11474 check_cp1_registers(ctx, fd);
11475 {
11476 TCGv_i32 fp32 = tcg_temp_new_i32();
11477 TCGv_i64 fp64 = tcg_temp_new_i64();
11478
11479 gen_load_fpr32(ctx, fp32, fs);
11480 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11481 tcg_temp_free_i32(fp32);
11482 gen_store_fpr64(ctx, fp64, fd);
11483 tcg_temp_free_i64(fp64);
11484 }
11485 break;
11486 case OPC_CVT_W_S:
11487 {
11488 TCGv_i32 fp0 = tcg_temp_new_i32();
11489
11490 gen_load_fpr32(ctx, fp0, fs);
11491 if (ctx->nan2008) {
11492 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11493 } else {
11494 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11495 }
11496 gen_store_fpr32(ctx, fp0, fd);
11497 tcg_temp_free_i32(fp0);
11498 }
11499 break;
11500 case OPC_CVT_L_S:
11501 check_cp1_64bitmode(ctx);
11502 {
11503 TCGv_i32 fp32 = tcg_temp_new_i32();
11504 TCGv_i64 fp64 = tcg_temp_new_i64();
11505
11506 gen_load_fpr32(ctx, fp32, fs);
11507 if (ctx->nan2008) {
11508 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11509 } else {
11510 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11511 }
11512 tcg_temp_free_i32(fp32);
11513 gen_store_fpr64(ctx, fp64, fd);
11514 tcg_temp_free_i64(fp64);
11515 }
11516 break;
11517 case OPC_CVT_PS_S:
11518 check_ps(ctx);
11519 {
11520 TCGv_i64 fp64 = tcg_temp_new_i64();
11521 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11522 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11523
11524 gen_load_fpr32(ctx, fp32_0, fs);
11525 gen_load_fpr32(ctx, fp32_1, ft);
11526 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11527 tcg_temp_free_i32(fp32_1);
11528 tcg_temp_free_i32(fp32_0);
11529 gen_store_fpr64(ctx, fp64, fd);
11530 tcg_temp_free_i64(fp64);
11531 }
11532 break;
11533 case OPC_CMP_F_S:
11534 case OPC_CMP_UN_S:
11535 case OPC_CMP_EQ_S:
11536 case OPC_CMP_UEQ_S:
11537 case OPC_CMP_OLT_S:
11538 case OPC_CMP_ULT_S:
11539 case OPC_CMP_OLE_S:
11540 case OPC_CMP_ULE_S:
11541 case OPC_CMP_SF_S:
11542 case OPC_CMP_NGLE_S:
11543 case OPC_CMP_SEQ_S:
11544 case OPC_CMP_NGL_S:
11545 case OPC_CMP_LT_S:
11546 case OPC_CMP_NGE_S:
11547 case OPC_CMP_LE_S:
11548 case OPC_CMP_NGT_S:
11549 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11550 if (ctx->opcode & (1 << 6)) {
11551 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11552 } else {
11553 gen_cmp_s(ctx, func-48, ft, fs, cc);
11554 }
11555 break;
11556 case OPC_ADD_D:
11557 check_cp1_registers(ctx, fs | ft | fd);
11558 {
11559 TCGv_i64 fp0 = tcg_temp_new_i64();
11560 TCGv_i64 fp1 = tcg_temp_new_i64();
11561
11562 gen_load_fpr64(ctx, fp0, fs);
11563 gen_load_fpr64(ctx, fp1, ft);
11564 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11565 tcg_temp_free_i64(fp1);
11566 gen_store_fpr64(ctx, fp0, fd);
11567 tcg_temp_free_i64(fp0);
11568 }
11569 break;
11570 case OPC_SUB_D:
11571 check_cp1_registers(ctx, fs | ft | fd);
11572 {
11573 TCGv_i64 fp0 = tcg_temp_new_i64();
11574 TCGv_i64 fp1 = tcg_temp_new_i64();
11575
11576 gen_load_fpr64(ctx, fp0, fs);
11577 gen_load_fpr64(ctx, fp1, ft);
11578 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11579 tcg_temp_free_i64(fp1);
11580 gen_store_fpr64(ctx, fp0, fd);
11581 tcg_temp_free_i64(fp0);
11582 }
11583 break;
11584 case OPC_MUL_D:
11585 check_cp1_registers(ctx, fs | ft | fd);
11586 {
11587 TCGv_i64 fp0 = tcg_temp_new_i64();
11588 TCGv_i64 fp1 = tcg_temp_new_i64();
11589
11590 gen_load_fpr64(ctx, fp0, fs);
11591 gen_load_fpr64(ctx, fp1, ft);
11592 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11593 tcg_temp_free_i64(fp1);
11594 gen_store_fpr64(ctx, fp0, fd);
11595 tcg_temp_free_i64(fp0);
11596 }
11597 break;
11598 case OPC_DIV_D:
11599 check_cp1_registers(ctx, fs | ft | fd);
11600 {
11601 TCGv_i64 fp0 = tcg_temp_new_i64();
11602 TCGv_i64 fp1 = tcg_temp_new_i64();
11603
11604 gen_load_fpr64(ctx, fp0, fs);
11605 gen_load_fpr64(ctx, fp1, ft);
11606 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11607 tcg_temp_free_i64(fp1);
11608 gen_store_fpr64(ctx, fp0, fd);
11609 tcg_temp_free_i64(fp0);
11610 }
11611 break;
11612 case OPC_SQRT_D:
11613 check_cp1_registers(ctx, fs | fd);
11614 {
11615 TCGv_i64 fp0 = tcg_temp_new_i64();
11616
11617 gen_load_fpr64(ctx, fp0, fs);
11618 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11619 gen_store_fpr64(ctx, fp0, fd);
11620 tcg_temp_free_i64(fp0);
11621 }
11622 break;
11623 case OPC_ABS_D:
11624 check_cp1_registers(ctx, fs | fd);
11625 {
11626 TCGv_i64 fp0 = tcg_temp_new_i64();
11627
11628 gen_load_fpr64(ctx, fp0, fs);
11629 if (ctx->abs2008) {
11630 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11631 } else {
11632 gen_helper_float_abs_d(fp0, fp0);
11633 }
11634 gen_store_fpr64(ctx, fp0, fd);
11635 tcg_temp_free_i64(fp0);
11636 }
11637 break;
11638 case OPC_MOV_D:
11639 check_cp1_registers(ctx, fs | fd);
11640 {
11641 TCGv_i64 fp0 = tcg_temp_new_i64();
11642
11643 gen_load_fpr64(ctx, fp0, fs);
11644 gen_store_fpr64(ctx, fp0, fd);
11645 tcg_temp_free_i64(fp0);
11646 }
11647 break;
11648 case OPC_NEG_D:
11649 check_cp1_registers(ctx, fs | fd);
11650 {
11651 TCGv_i64 fp0 = tcg_temp_new_i64();
11652
11653 gen_load_fpr64(ctx, fp0, fs);
11654 if (ctx->abs2008) {
11655 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11656 } else {
11657 gen_helper_float_chs_d(fp0, fp0);
11658 }
11659 gen_store_fpr64(ctx, fp0, fd);
11660 tcg_temp_free_i64(fp0);
11661 }
11662 break;
11663 case OPC_ROUND_L_D:
11664 check_cp1_64bitmode(ctx);
11665 {
11666 TCGv_i64 fp0 = tcg_temp_new_i64();
11667
11668 gen_load_fpr64(ctx, fp0, fs);
11669 if (ctx->nan2008) {
11670 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11671 } else {
11672 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11673 }
11674 gen_store_fpr64(ctx, fp0, fd);
11675 tcg_temp_free_i64(fp0);
11676 }
11677 break;
11678 case OPC_TRUNC_L_D:
11679 check_cp1_64bitmode(ctx);
11680 {
11681 TCGv_i64 fp0 = tcg_temp_new_i64();
11682
11683 gen_load_fpr64(ctx, fp0, fs);
11684 if (ctx->nan2008) {
11685 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11686 } else {
11687 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11688 }
11689 gen_store_fpr64(ctx, fp0, fd);
11690 tcg_temp_free_i64(fp0);
11691 }
11692 break;
11693 case OPC_CEIL_L_D:
11694 check_cp1_64bitmode(ctx);
11695 {
11696 TCGv_i64 fp0 = tcg_temp_new_i64();
11697
11698 gen_load_fpr64(ctx, fp0, fs);
11699 if (ctx->nan2008) {
11700 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11701 } else {
11702 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11703 }
11704 gen_store_fpr64(ctx, fp0, fd);
11705 tcg_temp_free_i64(fp0);
11706 }
11707 break;
11708 case OPC_FLOOR_L_D:
11709 check_cp1_64bitmode(ctx);
11710 {
11711 TCGv_i64 fp0 = tcg_temp_new_i64();
11712
11713 gen_load_fpr64(ctx, fp0, fs);
11714 if (ctx->nan2008) {
11715 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11716 } else {
11717 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11718 }
11719 gen_store_fpr64(ctx, fp0, fd);
11720 tcg_temp_free_i64(fp0);
11721 }
11722 break;
11723 case OPC_ROUND_W_D:
11724 check_cp1_registers(ctx, fs);
11725 {
11726 TCGv_i32 fp32 = tcg_temp_new_i32();
11727 TCGv_i64 fp64 = tcg_temp_new_i64();
11728
11729 gen_load_fpr64(ctx, fp64, fs);
11730 if (ctx->nan2008) {
11731 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11732 } else {
11733 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11734 }
11735 tcg_temp_free_i64(fp64);
11736 gen_store_fpr32(ctx, fp32, fd);
11737 tcg_temp_free_i32(fp32);
11738 }
11739 break;
11740 case OPC_TRUNC_W_D:
11741 check_cp1_registers(ctx, fs);
11742 {
11743 TCGv_i32 fp32 = tcg_temp_new_i32();
11744 TCGv_i64 fp64 = tcg_temp_new_i64();
11745
11746 gen_load_fpr64(ctx, fp64, fs);
11747 if (ctx->nan2008) {
11748 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11749 } else {
11750 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11751 }
11752 tcg_temp_free_i64(fp64);
11753 gen_store_fpr32(ctx, fp32, fd);
11754 tcg_temp_free_i32(fp32);
11755 }
11756 break;
11757 case OPC_CEIL_W_D:
11758 check_cp1_registers(ctx, fs);
11759 {
11760 TCGv_i32 fp32 = tcg_temp_new_i32();
11761 TCGv_i64 fp64 = tcg_temp_new_i64();
11762
11763 gen_load_fpr64(ctx, fp64, fs);
11764 if (ctx->nan2008) {
11765 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11766 } else {
11767 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11768 }
11769 tcg_temp_free_i64(fp64);
11770 gen_store_fpr32(ctx, fp32, fd);
11771 tcg_temp_free_i32(fp32);
11772 }
11773 break;
11774 case OPC_FLOOR_W_D:
11775 check_cp1_registers(ctx, fs);
11776 {
11777 TCGv_i32 fp32 = tcg_temp_new_i32();
11778 TCGv_i64 fp64 = tcg_temp_new_i64();
11779
11780 gen_load_fpr64(ctx, fp64, fs);
11781 if (ctx->nan2008) {
11782 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11783 } else {
11784 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11785 }
11786 tcg_temp_free_i64(fp64);
11787 gen_store_fpr32(ctx, fp32, fd);
11788 tcg_temp_free_i32(fp32);
11789 }
11790 break;
11791 case OPC_SEL_D:
11792 check_insn(ctx, ISA_MIPS32R6);
11793 gen_sel_d(ctx, op1, fd, ft, fs);
11794 break;
11795 case OPC_SELEQZ_D:
11796 check_insn(ctx, ISA_MIPS32R6);
11797 gen_sel_d(ctx, op1, fd, ft, fs);
11798 break;
11799 case OPC_SELNEZ_D:
11800 check_insn(ctx, ISA_MIPS32R6);
11801 gen_sel_d(ctx, op1, fd, ft, fs);
11802 break;
11803 case OPC_MOVCF_D:
11804 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11805 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11806 break;
11807 case OPC_MOVZ_D:
11808 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11809 {
11810 TCGLabel *l1 = gen_new_label();
11811 TCGv_i64 fp0;
11812
11813 if (ft != 0) {
11814 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11815 }
11816 fp0 = tcg_temp_new_i64();
11817 gen_load_fpr64(ctx, fp0, fs);
11818 gen_store_fpr64(ctx, fp0, fd);
11819 tcg_temp_free_i64(fp0);
11820 gen_set_label(l1);
11821 }
11822 break;
11823 case OPC_MOVN_D:
11824 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11825 {
11826 TCGLabel *l1 = gen_new_label();
11827 TCGv_i64 fp0;
11828
11829 if (ft != 0) {
11830 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11831 fp0 = tcg_temp_new_i64();
11832 gen_load_fpr64(ctx, fp0, fs);
11833 gen_store_fpr64(ctx, fp0, fd);
11834 tcg_temp_free_i64(fp0);
11835 gen_set_label(l1);
11836 }
11837 }
11838 break;
11839 case OPC_RECIP_D:
11840 check_cp1_registers(ctx, fs | fd);
11841 {
11842 TCGv_i64 fp0 = tcg_temp_new_i64();
11843
11844 gen_load_fpr64(ctx, fp0, fs);
11845 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11846 gen_store_fpr64(ctx, fp0, fd);
11847 tcg_temp_free_i64(fp0);
11848 }
11849 break;
11850 case OPC_RSQRT_D:
11851 check_cp1_registers(ctx, fs | fd);
11852 {
11853 TCGv_i64 fp0 = tcg_temp_new_i64();
11854
11855 gen_load_fpr64(ctx, fp0, fs);
11856 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11857 gen_store_fpr64(ctx, fp0, fd);
11858 tcg_temp_free_i64(fp0);
11859 }
11860 break;
11861 case OPC_MADDF_D:
11862 check_insn(ctx, ISA_MIPS32R6);
11863 {
11864 TCGv_i64 fp0 = tcg_temp_new_i64();
11865 TCGv_i64 fp1 = tcg_temp_new_i64();
11866 TCGv_i64 fp2 = tcg_temp_new_i64();
11867 gen_load_fpr64(ctx, fp0, fs);
11868 gen_load_fpr64(ctx, fp1, ft);
11869 gen_load_fpr64(ctx, fp2, fd);
11870 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11871 gen_store_fpr64(ctx, fp2, fd);
11872 tcg_temp_free_i64(fp2);
11873 tcg_temp_free_i64(fp1);
11874 tcg_temp_free_i64(fp0);
11875 }
11876 break;
11877 case OPC_MSUBF_D:
11878 check_insn(ctx, ISA_MIPS32R6);
11879 {
11880 TCGv_i64 fp0 = tcg_temp_new_i64();
11881 TCGv_i64 fp1 = tcg_temp_new_i64();
11882 TCGv_i64 fp2 = tcg_temp_new_i64();
11883 gen_load_fpr64(ctx, fp0, fs);
11884 gen_load_fpr64(ctx, fp1, ft);
11885 gen_load_fpr64(ctx, fp2, fd);
11886 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11887 gen_store_fpr64(ctx, fp2, fd);
11888 tcg_temp_free_i64(fp2);
11889 tcg_temp_free_i64(fp1);
11890 tcg_temp_free_i64(fp0);
11891 }
11892 break;
11893 case OPC_RINT_D:
11894 check_insn(ctx, ISA_MIPS32R6);
11895 {
11896 TCGv_i64 fp0 = tcg_temp_new_i64();
11897 gen_load_fpr64(ctx, fp0, fs);
11898 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11899 gen_store_fpr64(ctx, fp0, fd);
11900 tcg_temp_free_i64(fp0);
11901 }
11902 break;
11903 case OPC_CLASS_D:
11904 check_insn(ctx, ISA_MIPS32R6);
11905 {
11906 TCGv_i64 fp0 = tcg_temp_new_i64();
11907 gen_load_fpr64(ctx, fp0, fs);
11908 gen_helper_float_class_d(fp0, cpu_env, fp0);
11909 gen_store_fpr64(ctx, fp0, fd);
11910 tcg_temp_free_i64(fp0);
11911 }
11912 break;
11913 case OPC_MIN_D:
11914 if (ctx->insn_flags & ISA_MIPS32R6) {
11915
11916 TCGv_i64 fp0 = tcg_temp_new_i64();
11917 TCGv_i64 fp1 = tcg_temp_new_i64();
11918 gen_load_fpr64(ctx, fp0, fs);
11919 gen_load_fpr64(ctx, fp1, ft);
11920 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11921 gen_store_fpr64(ctx, fp1, fd);
11922 tcg_temp_free_i64(fp1);
11923 tcg_temp_free_i64(fp0);
11924 } else {
11925
11926 check_cp1_64bitmode(ctx);
11927 {
11928 TCGv_i64 fp0 = tcg_temp_new_i64();
11929 TCGv_i64 fp1 = tcg_temp_new_i64();
11930
11931 gen_load_fpr64(ctx, fp0, fs);
11932 gen_load_fpr64(ctx, fp1, ft);
11933 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11934 tcg_temp_free_i64(fp1);
11935 gen_store_fpr64(ctx, fp0, fd);
11936 tcg_temp_free_i64(fp0);
11937 }
11938 }
11939 break;
11940 case OPC_MINA_D:
11941 if (ctx->insn_flags & ISA_MIPS32R6) {
11942
11943 TCGv_i64 fp0 = tcg_temp_new_i64();
11944 TCGv_i64 fp1 = tcg_temp_new_i64();
11945 gen_load_fpr64(ctx, fp0, fs);
11946 gen_load_fpr64(ctx, fp1, ft);
11947 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11948 gen_store_fpr64(ctx, fp1, fd);
11949 tcg_temp_free_i64(fp1);
11950 tcg_temp_free_i64(fp0);
11951 } else {
11952
11953 check_cp1_64bitmode(ctx);
11954 {
11955 TCGv_i64 fp0 = tcg_temp_new_i64();
11956
11957 gen_load_fpr64(ctx, fp0, fs);
11958 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11959 gen_store_fpr64(ctx, fp0, fd);
11960 tcg_temp_free_i64(fp0);
11961 }
11962 }
11963 break;
11964 case OPC_MAX_D:
11965 if (ctx->insn_flags & ISA_MIPS32R6) {
11966
11967 TCGv_i64 fp0 = tcg_temp_new_i64();
11968 TCGv_i64 fp1 = tcg_temp_new_i64();
11969 gen_load_fpr64(ctx, fp0, fs);
11970 gen_load_fpr64(ctx, fp1, ft);
11971 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11972 gen_store_fpr64(ctx, fp1, fd);
11973 tcg_temp_free_i64(fp1);
11974 tcg_temp_free_i64(fp0);
11975 } else {
11976
11977 check_cp1_64bitmode(ctx);
11978 {
11979 TCGv_i64 fp0 = tcg_temp_new_i64();
11980
11981 gen_load_fpr64(ctx, fp0, fs);
11982 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11983 gen_store_fpr64(ctx, fp0, fd);
11984 tcg_temp_free_i64(fp0);
11985 }
11986 }
11987 break;
11988 case OPC_MAXA_D:
11989 if (ctx->insn_flags & ISA_MIPS32R6) {
11990
11991 TCGv_i64 fp0 = tcg_temp_new_i64();
11992 TCGv_i64 fp1 = tcg_temp_new_i64();
11993 gen_load_fpr64(ctx, fp0, fs);
11994 gen_load_fpr64(ctx, fp1, ft);
11995 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11996 gen_store_fpr64(ctx, fp1, fd);
11997 tcg_temp_free_i64(fp1);
11998 tcg_temp_free_i64(fp0);
11999 } else {
12000
12001 check_cp1_64bitmode(ctx);
12002 {
12003 TCGv_i64 fp0 = tcg_temp_new_i64();
12004 TCGv_i64 fp1 = tcg_temp_new_i64();
12005
12006 gen_load_fpr64(ctx, fp0, fs);
12007 gen_load_fpr64(ctx, fp1, ft);
12008 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
12009 tcg_temp_free_i64(fp1);
12010 gen_store_fpr64(ctx, fp0, fd);
12011 tcg_temp_free_i64(fp0);
12012 }
12013 }
12014 break;
12015 case OPC_CMP_F_D:
12016 case OPC_CMP_UN_D:
12017 case OPC_CMP_EQ_D:
12018 case OPC_CMP_UEQ_D:
12019 case OPC_CMP_OLT_D:
12020 case OPC_CMP_ULT_D:
12021 case OPC_CMP_OLE_D:
12022 case OPC_CMP_ULE_D:
12023 case OPC_CMP_SF_D:
12024 case OPC_CMP_NGLE_D:
12025 case OPC_CMP_SEQ_D:
12026 case OPC_CMP_NGL_D:
12027 case OPC_CMP_LT_D:
12028 case OPC_CMP_NGE_D:
12029 case OPC_CMP_LE_D:
12030 case OPC_CMP_NGT_D:
12031 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12032 if (ctx->opcode & (1 << 6)) {
12033 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
12034 } else {
12035 gen_cmp_d(ctx, func-48, ft, fs, cc);
12036 }
12037 break;
12038 case OPC_CVT_S_D:
12039 check_cp1_registers(ctx, fs);
12040 {
12041 TCGv_i32 fp32 = tcg_temp_new_i32();
12042 TCGv_i64 fp64 = tcg_temp_new_i64();
12043
12044 gen_load_fpr64(ctx, fp64, fs);
12045 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
12046 tcg_temp_free_i64(fp64);
12047 gen_store_fpr32(ctx, fp32, fd);
12048 tcg_temp_free_i32(fp32);
12049 }
12050 break;
12051 case OPC_CVT_W_D:
12052 check_cp1_registers(ctx, fs);
12053 {
12054 TCGv_i32 fp32 = tcg_temp_new_i32();
12055 TCGv_i64 fp64 = tcg_temp_new_i64();
12056
12057 gen_load_fpr64(ctx, fp64, fs);
12058 if (ctx->nan2008) {
12059 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
12060 } else {
12061 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
12062 }
12063 tcg_temp_free_i64(fp64);
12064 gen_store_fpr32(ctx, fp32, fd);
12065 tcg_temp_free_i32(fp32);
12066 }
12067 break;
12068 case OPC_CVT_L_D:
12069 check_cp1_64bitmode(ctx);
12070 {
12071 TCGv_i64 fp0 = tcg_temp_new_i64();
12072
12073 gen_load_fpr64(ctx, fp0, fs);
12074 if (ctx->nan2008) {
12075 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
12076 } else {
12077 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
12078 }
12079 gen_store_fpr64(ctx, fp0, fd);
12080 tcg_temp_free_i64(fp0);
12081 }
12082 break;
12083 case OPC_CVT_S_W:
12084 {
12085 TCGv_i32 fp0 = tcg_temp_new_i32();
12086
12087 gen_load_fpr32(ctx, fp0, fs);
12088 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
12089 gen_store_fpr32(ctx, fp0, fd);
12090 tcg_temp_free_i32(fp0);
12091 }
12092 break;
12093 case OPC_CVT_D_W:
12094 check_cp1_registers(ctx, fd);
12095 {
12096 TCGv_i32 fp32 = tcg_temp_new_i32();
12097 TCGv_i64 fp64 = tcg_temp_new_i64();
12098
12099 gen_load_fpr32(ctx, fp32, fs);
12100 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12101 tcg_temp_free_i32(fp32);
12102 gen_store_fpr64(ctx, fp64, fd);
12103 tcg_temp_free_i64(fp64);
12104 }
12105 break;
12106 case OPC_CVT_S_L:
12107 check_cp1_64bitmode(ctx);
12108 {
12109 TCGv_i32 fp32 = tcg_temp_new_i32();
12110 TCGv_i64 fp64 = tcg_temp_new_i64();
12111
12112 gen_load_fpr64(ctx, fp64, fs);
12113 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12114 tcg_temp_free_i64(fp64);
12115 gen_store_fpr32(ctx, fp32, fd);
12116 tcg_temp_free_i32(fp32);
12117 }
12118 break;
12119 case OPC_CVT_D_L:
12120 check_cp1_64bitmode(ctx);
12121 {
12122 TCGv_i64 fp0 = tcg_temp_new_i64();
12123
12124 gen_load_fpr64(ctx, fp0, fs);
12125 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12126 gen_store_fpr64(ctx, fp0, fd);
12127 tcg_temp_free_i64(fp0);
12128 }
12129 break;
12130 case OPC_CVT_PS_PW:
12131 check_ps(ctx);
12132 {
12133 TCGv_i64 fp0 = tcg_temp_new_i64();
12134
12135 gen_load_fpr64(ctx, fp0, fs);
12136 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12137 gen_store_fpr64(ctx, fp0, fd);
12138 tcg_temp_free_i64(fp0);
12139 }
12140 break;
12141 case OPC_ADD_PS:
12142 check_ps(ctx);
12143 {
12144 TCGv_i64 fp0 = tcg_temp_new_i64();
12145 TCGv_i64 fp1 = tcg_temp_new_i64();
12146
12147 gen_load_fpr64(ctx, fp0, fs);
12148 gen_load_fpr64(ctx, fp1, ft);
12149 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12150 tcg_temp_free_i64(fp1);
12151 gen_store_fpr64(ctx, fp0, fd);
12152 tcg_temp_free_i64(fp0);
12153 }
12154 break;
12155 case OPC_SUB_PS:
12156 check_ps(ctx);
12157 {
12158 TCGv_i64 fp0 = tcg_temp_new_i64();
12159 TCGv_i64 fp1 = tcg_temp_new_i64();
12160
12161 gen_load_fpr64(ctx, fp0, fs);
12162 gen_load_fpr64(ctx, fp1, ft);
12163 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12164 tcg_temp_free_i64(fp1);
12165 gen_store_fpr64(ctx, fp0, fd);
12166 tcg_temp_free_i64(fp0);
12167 }
12168 break;
12169 case OPC_MUL_PS:
12170 check_ps(ctx);
12171 {
12172 TCGv_i64 fp0 = tcg_temp_new_i64();
12173 TCGv_i64 fp1 = tcg_temp_new_i64();
12174
12175 gen_load_fpr64(ctx, fp0, fs);
12176 gen_load_fpr64(ctx, fp1, ft);
12177 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12178 tcg_temp_free_i64(fp1);
12179 gen_store_fpr64(ctx, fp0, fd);
12180 tcg_temp_free_i64(fp0);
12181 }
12182 break;
12183 case OPC_ABS_PS:
12184 check_ps(ctx);
12185 {
12186 TCGv_i64 fp0 = tcg_temp_new_i64();
12187
12188 gen_load_fpr64(ctx, fp0, fs);
12189 gen_helper_float_abs_ps(fp0, fp0);
12190 gen_store_fpr64(ctx, fp0, fd);
12191 tcg_temp_free_i64(fp0);
12192 }
12193 break;
12194 case OPC_MOV_PS:
12195 check_ps(ctx);
12196 {
12197 TCGv_i64 fp0 = tcg_temp_new_i64();
12198
12199 gen_load_fpr64(ctx, fp0, fs);
12200 gen_store_fpr64(ctx, fp0, fd);
12201 tcg_temp_free_i64(fp0);
12202 }
12203 break;
12204 case OPC_NEG_PS:
12205 check_ps(ctx);
12206 {
12207 TCGv_i64 fp0 = tcg_temp_new_i64();
12208
12209 gen_load_fpr64(ctx, fp0, fs);
12210 gen_helper_float_chs_ps(fp0, fp0);
12211 gen_store_fpr64(ctx, fp0, fd);
12212 tcg_temp_free_i64(fp0);
12213 }
12214 break;
12215 case OPC_MOVCF_PS:
12216 check_ps(ctx);
12217 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12218 break;
12219 case OPC_MOVZ_PS:
12220 check_ps(ctx);
12221 {
12222 TCGLabel *l1 = gen_new_label();
12223 TCGv_i64 fp0;
12224
12225 if (ft != 0) {
12226 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12227 }
12228 fp0 = tcg_temp_new_i64();
12229 gen_load_fpr64(ctx, fp0, fs);
12230 gen_store_fpr64(ctx, fp0, fd);
12231 tcg_temp_free_i64(fp0);
12232 gen_set_label(l1);
12233 }
12234 break;
12235 case OPC_MOVN_PS:
12236 check_ps(ctx);
12237 {
12238 TCGLabel *l1 = gen_new_label();
12239 TCGv_i64 fp0;
12240
12241 if (ft != 0) {
12242 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12243 fp0 = tcg_temp_new_i64();
12244 gen_load_fpr64(ctx, fp0, fs);
12245 gen_store_fpr64(ctx, fp0, fd);
12246 tcg_temp_free_i64(fp0);
12247 gen_set_label(l1);
12248 }
12249 }
12250 break;
12251 case OPC_ADDR_PS:
12252 check_ps(ctx);
12253 {
12254 TCGv_i64 fp0 = tcg_temp_new_i64();
12255 TCGv_i64 fp1 = tcg_temp_new_i64();
12256
12257 gen_load_fpr64(ctx, fp0, ft);
12258 gen_load_fpr64(ctx, fp1, fs);
12259 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12260 tcg_temp_free_i64(fp1);
12261 gen_store_fpr64(ctx, fp0, fd);
12262 tcg_temp_free_i64(fp0);
12263 }
12264 break;
12265 case OPC_MULR_PS:
12266 check_ps(ctx);
12267 {
12268 TCGv_i64 fp0 = tcg_temp_new_i64();
12269 TCGv_i64 fp1 = tcg_temp_new_i64();
12270
12271 gen_load_fpr64(ctx, fp0, ft);
12272 gen_load_fpr64(ctx, fp1, fs);
12273 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12274 tcg_temp_free_i64(fp1);
12275 gen_store_fpr64(ctx, fp0, fd);
12276 tcg_temp_free_i64(fp0);
12277 }
12278 break;
12279 case OPC_RECIP2_PS:
12280 check_ps(ctx);
12281 {
12282 TCGv_i64 fp0 = tcg_temp_new_i64();
12283 TCGv_i64 fp1 = tcg_temp_new_i64();
12284
12285 gen_load_fpr64(ctx, fp0, fs);
12286 gen_load_fpr64(ctx, fp1, ft);
12287 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12288 tcg_temp_free_i64(fp1);
12289 gen_store_fpr64(ctx, fp0, fd);
12290 tcg_temp_free_i64(fp0);
12291 }
12292 break;
12293 case OPC_RECIP1_PS:
12294 check_ps(ctx);
12295 {
12296 TCGv_i64 fp0 = tcg_temp_new_i64();
12297
12298 gen_load_fpr64(ctx, fp0, fs);
12299 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12300 gen_store_fpr64(ctx, fp0, fd);
12301 tcg_temp_free_i64(fp0);
12302 }
12303 break;
12304 case OPC_RSQRT1_PS:
12305 check_ps(ctx);
12306 {
12307 TCGv_i64 fp0 = tcg_temp_new_i64();
12308
12309 gen_load_fpr64(ctx, fp0, fs);
12310 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12311 gen_store_fpr64(ctx, fp0, fd);
12312 tcg_temp_free_i64(fp0);
12313 }
12314 break;
12315 case OPC_RSQRT2_PS:
12316 check_ps(ctx);
12317 {
12318 TCGv_i64 fp0 = tcg_temp_new_i64();
12319 TCGv_i64 fp1 = tcg_temp_new_i64();
12320
12321 gen_load_fpr64(ctx, fp0, fs);
12322 gen_load_fpr64(ctx, fp1, ft);
12323 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12324 tcg_temp_free_i64(fp1);
12325 gen_store_fpr64(ctx, fp0, fd);
12326 tcg_temp_free_i64(fp0);
12327 }
12328 break;
12329 case OPC_CVT_S_PU:
12330 check_cp1_64bitmode(ctx);
12331 {
12332 TCGv_i32 fp0 = tcg_temp_new_i32();
12333
12334 gen_load_fpr32h(ctx, fp0, fs);
12335 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12336 gen_store_fpr32(ctx, fp0, fd);
12337 tcg_temp_free_i32(fp0);
12338 }
12339 break;
12340 case OPC_CVT_PW_PS:
12341 check_ps(ctx);
12342 {
12343 TCGv_i64 fp0 = tcg_temp_new_i64();
12344
12345 gen_load_fpr64(ctx, fp0, fs);
12346 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12347 gen_store_fpr64(ctx, fp0, fd);
12348 tcg_temp_free_i64(fp0);
12349 }
12350 break;
12351 case OPC_CVT_S_PL:
12352 check_cp1_64bitmode(ctx);
12353 {
12354 TCGv_i32 fp0 = tcg_temp_new_i32();
12355
12356 gen_load_fpr32(ctx, fp0, fs);
12357 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12358 gen_store_fpr32(ctx, fp0, fd);
12359 tcg_temp_free_i32(fp0);
12360 }
12361 break;
12362 case OPC_PLL_PS:
12363 check_ps(ctx);
12364 {
12365 TCGv_i32 fp0 = tcg_temp_new_i32();
12366 TCGv_i32 fp1 = tcg_temp_new_i32();
12367
12368 gen_load_fpr32(ctx, fp0, fs);
12369 gen_load_fpr32(ctx, fp1, ft);
12370 gen_store_fpr32h(ctx, fp0, fd);
12371 gen_store_fpr32(ctx, fp1, fd);
12372 tcg_temp_free_i32(fp0);
12373 tcg_temp_free_i32(fp1);
12374 }
12375 break;
12376 case OPC_PLU_PS:
12377 check_ps(ctx);
12378 {
12379 TCGv_i32 fp0 = tcg_temp_new_i32();
12380 TCGv_i32 fp1 = tcg_temp_new_i32();
12381
12382 gen_load_fpr32(ctx, fp0, fs);
12383 gen_load_fpr32h(ctx, fp1, ft);
12384 gen_store_fpr32(ctx, fp1, fd);
12385 gen_store_fpr32h(ctx, fp0, fd);
12386 tcg_temp_free_i32(fp0);
12387 tcg_temp_free_i32(fp1);
12388 }
12389 break;
12390 case OPC_PUL_PS:
12391 check_ps(ctx);
12392 {
12393 TCGv_i32 fp0 = tcg_temp_new_i32();
12394 TCGv_i32 fp1 = tcg_temp_new_i32();
12395
12396 gen_load_fpr32h(ctx, fp0, fs);
12397 gen_load_fpr32(ctx, fp1, ft);
12398 gen_store_fpr32(ctx, fp1, fd);
12399 gen_store_fpr32h(ctx, fp0, fd);
12400 tcg_temp_free_i32(fp0);
12401 tcg_temp_free_i32(fp1);
12402 }
12403 break;
12404 case OPC_PUU_PS:
12405 check_ps(ctx);
12406 {
12407 TCGv_i32 fp0 = tcg_temp_new_i32();
12408 TCGv_i32 fp1 = tcg_temp_new_i32();
12409
12410 gen_load_fpr32h(ctx, fp0, fs);
12411 gen_load_fpr32h(ctx, fp1, ft);
12412 gen_store_fpr32(ctx, fp1, fd);
12413 gen_store_fpr32h(ctx, fp0, fd);
12414 tcg_temp_free_i32(fp0);
12415 tcg_temp_free_i32(fp1);
12416 }
12417 break;
12418 case OPC_CMP_F_PS:
12419 case OPC_CMP_UN_PS:
12420 case OPC_CMP_EQ_PS:
12421 case OPC_CMP_UEQ_PS:
12422 case OPC_CMP_OLT_PS:
12423 case OPC_CMP_ULT_PS:
12424 case OPC_CMP_OLE_PS:
12425 case OPC_CMP_ULE_PS:
12426 case OPC_CMP_SF_PS:
12427 case OPC_CMP_NGLE_PS:
12428 case OPC_CMP_SEQ_PS:
12429 case OPC_CMP_NGL_PS:
12430 case OPC_CMP_LT_PS:
12431 case OPC_CMP_NGE_PS:
12432 case OPC_CMP_LE_PS:
12433 case OPC_CMP_NGT_PS:
12434 if (ctx->opcode & (1 << 6)) {
12435 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12436 } else {
12437 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12438 }
12439 break;
12440 default:
12441 MIPS_INVAL("farith");
12442 generate_exception_end(ctx, EXCP_RI);
12443 return;
12444 }
12445}
12446
12447
12448static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
12449 int fd, int fs, int base, int index)
12450{
12451 TCGv t0 = tcg_temp_new();
12452
12453 if (base == 0) {
12454 gen_load_gpr(t0, index);
12455 } else if (index == 0) {
12456 gen_load_gpr(t0, base);
12457 } else {
12458 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12459 }
12460
12461
12462
12463
12464 switch (opc) {
12465 case OPC_LWXC1:
12466 check_cop1x(ctx);
12467 {
12468 TCGv_i32 fp0 = tcg_temp_new_i32();
12469
12470 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12471 tcg_gen_trunc_tl_i32(fp0, t0);
12472 gen_store_fpr32(ctx, fp0, fd);
12473 tcg_temp_free_i32(fp0);
12474 }
12475 break;
12476 case OPC_LDXC1:
12477 check_cop1x(ctx);
12478 check_cp1_registers(ctx, fd);
12479 {
12480 TCGv_i64 fp0 = tcg_temp_new_i64();
12481 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12482 gen_store_fpr64(ctx, fp0, fd);
12483 tcg_temp_free_i64(fp0);
12484 }
12485 break;
12486 case OPC_LUXC1:
12487 check_cp1_64bitmode(ctx);
12488 tcg_gen_andi_tl(t0, t0, ~0x7);
12489 {
12490 TCGv_i64 fp0 = tcg_temp_new_i64();
12491
12492 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12493 gen_store_fpr64(ctx, fp0, fd);
12494 tcg_temp_free_i64(fp0);
12495 }
12496 break;
12497 case OPC_SWXC1:
12498 check_cop1x(ctx);
12499 {
12500 TCGv_i32 fp0 = tcg_temp_new_i32();
12501 gen_load_fpr32(ctx, fp0, fs);
12502 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12503 tcg_temp_free_i32(fp0);
12504 }
12505 break;
12506 case OPC_SDXC1:
12507 check_cop1x(ctx);
12508 check_cp1_registers(ctx, fs);
12509 {
12510 TCGv_i64 fp0 = tcg_temp_new_i64();
12511 gen_load_fpr64(ctx, fp0, fs);
12512 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12513 tcg_temp_free_i64(fp0);
12514 }
12515 break;
12516 case OPC_SUXC1:
12517 check_cp1_64bitmode(ctx);
12518 tcg_gen_andi_tl(t0, t0, ~0x7);
12519 {
12520 TCGv_i64 fp0 = tcg_temp_new_i64();
12521 gen_load_fpr64(ctx, fp0, fs);
12522 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12523 tcg_temp_free_i64(fp0);
12524 }
12525 break;
12526 }
12527 tcg_temp_free(t0);
12528}
12529
12530static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
12531 int fd, int fr, int fs, int ft)
12532{
12533 switch (opc) {
12534 case OPC_ALNV_PS:
12535 check_ps(ctx);
12536 {
12537 TCGv t0 = tcg_temp_local_new();
12538 TCGv_i32 fp = tcg_temp_new_i32();
12539 TCGv_i32 fph = tcg_temp_new_i32();
12540 TCGLabel *l1 = gen_new_label();
12541 TCGLabel *l2 = gen_new_label();
12542
12543 gen_load_gpr(t0, fr);
12544 tcg_gen_andi_tl(t0, t0, 0x7);
12545
12546 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12547 gen_load_fpr32(ctx, fp, fs);
12548 gen_load_fpr32h(ctx, fph, fs);
12549 gen_store_fpr32(ctx, fp, fd);
12550 gen_store_fpr32h(ctx, fph, fd);
12551 tcg_gen_br(l2);
12552 gen_set_label(l1);
12553 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12554 tcg_temp_free(t0);
12555#ifdef TARGET_WORDS_BIGENDIAN
12556 gen_load_fpr32(ctx, fp, fs);
12557 gen_load_fpr32h(ctx, fph, ft);
12558 gen_store_fpr32h(ctx, fp, fd);
12559 gen_store_fpr32(ctx, fph, fd);
12560#else
12561 gen_load_fpr32h(ctx, fph, fs);
12562 gen_load_fpr32(ctx, fp, ft);
12563 gen_store_fpr32(ctx, fph, fd);
12564 gen_store_fpr32h(ctx, fp, fd);
12565#endif
12566 gen_set_label(l2);
12567 tcg_temp_free_i32(fp);
12568 tcg_temp_free_i32(fph);
12569 }
12570 break;
12571 case OPC_MADD_S:
12572 check_cop1x(ctx);
12573 {
12574 TCGv_i32 fp0 = tcg_temp_new_i32();
12575 TCGv_i32 fp1 = tcg_temp_new_i32();
12576 TCGv_i32 fp2 = tcg_temp_new_i32();
12577
12578 gen_load_fpr32(ctx, fp0, fs);
12579 gen_load_fpr32(ctx, fp1, ft);
12580 gen_load_fpr32(ctx, fp2, fr);
12581 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12582 tcg_temp_free_i32(fp0);
12583 tcg_temp_free_i32(fp1);
12584 gen_store_fpr32(ctx, fp2, fd);
12585 tcg_temp_free_i32(fp2);
12586 }
12587 break;
12588 case OPC_MADD_D:
12589 check_cop1x(ctx);
12590 check_cp1_registers(ctx, fd | fs | ft | fr);
12591 {
12592 TCGv_i64 fp0 = tcg_temp_new_i64();
12593 TCGv_i64 fp1 = tcg_temp_new_i64();
12594 TCGv_i64 fp2 = tcg_temp_new_i64();
12595
12596 gen_load_fpr64(ctx, fp0, fs);
12597 gen_load_fpr64(ctx, fp1, ft);
12598 gen_load_fpr64(ctx, fp2, fr);
12599 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12600 tcg_temp_free_i64(fp0);
12601 tcg_temp_free_i64(fp1);
12602 gen_store_fpr64(ctx, fp2, fd);
12603 tcg_temp_free_i64(fp2);
12604 }
12605 break;
12606 case OPC_MADD_PS:
12607 check_ps(ctx);
12608 {
12609 TCGv_i64 fp0 = tcg_temp_new_i64();
12610 TCGv_i64 fp1 = tcg_temp_new_i64();
12611 TCGv_i64 fp2 = tcg_temp_new_i64();
12612
12613 gen_load_fpr64(ctx, fp0, fs);
12614 gen_load_fpr64(ctx, fp1, ft);
12615 gen_load_fpr64(ctx, fp2, fr);
12616 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12617 tcg_temp_free_i64(fp0);
12618 tcg_temp_free_i64(fp1);
12619 gen_store_fpr64(ctx, fp2, fd);
12620 tcg_temp_free_i64(fp2);
12621 }
12622 break;
12623 case OPC_MSUB_S:
12624 check_cop1x(ctx);
12625 {
12626 TCGv_i32 fp0 = tcg_temp_new_i32();
12627 TCGv_i32 fp1 = tcg_temp_new_i32();
12628 TCGv_i32 fp2 = tcg_temp_new_i32();
12629
12630 gen_load_fpr32(ctx, fp0, fs);
12631 gen_load_fpr32(ctx, fp1, ft);
12632 gen_load_fpr32(ctx, fp2, fr);
12633 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12634 tcg_temp_free_i32(fp0);
12635 tcg_temp_free_i32(fp1);
12636 gen_store_fpr32(ctx, fp2, fd);
12637 tcg_temp_free_i32(fp2);
12638 }
12639 break;
12640 case OPC_MSUB_D:
12641 check_cop1x(ctx);
12642 check_cp1_registers(ctx, fd | fs | ft | fr);
12643 {
12644 TCGv_i64 fp0 = tcg_temp_new_i64();
12645 TCGv_i64 fp1 = tcg_temp_new_i64();
12646 TCGv_i64 fp2 = tcg_temp_new_i64();
12647
12648 gen_load_fpr64(ctx, fp0, fs);
12649 gen_load_fpr64(ctx, fp1, ft);
12650 gen_load_fpr64(ctx, fp2, fr);
12651 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12652 tcg_temp_free_i64(fp0);
12653 tcg_temp_free_i64(fp1);
12654 gen_store_fpr64(ctx, fp2, fd);
12655 tcg_temp_free_i64(fp2);
12656 }
12657 break;
12658 case OPC_MSUB_PS:
12659 check_ps(ctx);
12660 {
12661 TCGv_i64 fp0 = tcg_temp_new_i64();
12662 TCGv_i64 fp1 = tcg_temp_new_i64();
12663 TCGv_i64 fp2 = tcg_temp_new_i64();
12664
12665 gen_load_fpr64(ctx, fp0, fs);
12666 gen_load_fpr64(ctx, fp1, ft);
12667 gen_load_fpr64(ctx, fp2, fr);
12668 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12669 tcg_temp_free_i64(fp0);
12670 tcg_temp_free_i64(fp1);
12671 gen_store_fpr64(ctx, fp2, fd);
12672 tcg_temp_free_i64(fp2);
12673 }
12674 break;
12675 case OPC_NMADD_S:
12676 check_cop1x(ctx);
12677 {
12678 TCGv_i32 fp0 = tcg_temp_new_i32();
12679 TCGv_i32 fp1 = tcg_temp_new_i32();
12680 TCGv_i32 fp2 = tcg_temp_new_i32();
12681
12682 gen_load_fpr32(ctx, fp0, fs);
12683 gen_load_fpr32(ctx, fp1, ft);
12684 gen_load_fpr32(ctx, fp2, fr);
12685 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12686 tcg_temp_free_i32(fp0);
12687 tcg_temp_free_i32(fp1);
12688 gen_store_fpr32(ctx, fp2, fd);
12689 tcg_temp_free_i32(fp2);
12690 }
12691 break;
12692 case OPC_NMADD_D:
12693 check_cop1x(ctx);
12694 check_cp1_registers(ctx, fd | fs | ft | fr);
12695 {
12696 TCGv_i64 fp0 = tcg_temp_new_i64();
12697 TCGv_i64 fp1 = tcg_temp_new_i64();
12698 TCGv_i64 fp2 = tcg_temp_new_i64();
12699
12700 gen_load_fpr64(ctx, fp0, fs);
12701 gen_load_fpr64(ctx, fp1, ft);
12702 gen_load_fpr64(ctx, fp2, fr);
12703 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12704 tcg_temp_free_i64(fp0);
12705 tcg_temp_free_i64(fp1);
12706 gen_store_fpr64(ctx, fp2, fd);
12707 tcg_temp_free_i64(fp2);
12708 }
12709 break;
12710 case OPC_NMADD_PS:
12711 check_ps(ctx);
12712 {
12713 TCGv_i64 fp0 = tcg_temp_new_i64();
12714 TCGv_i64 fp1 = tcg_temp_new_i64();
12715 TCGv_i64 fp2 = tcg_temp_new_i64();
12716
12717 gen_load_fpr64(ctx, fp0, fs);
12718 gen_load_fpr64(ctx, fp1, ft);
12719 gen_load_fpr64(ctx, fp2, fr);
12720 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12721 tcg_temp_free_i64(fp0);
12722 tcg_temp_free_i64(fp1);
12723 gen_store_fpr64(ctx, fp2, fd);
12724 tcg_temp_free_i64(fp2);
12725 }
12726 break;
12727 case OPC_NMSUB_S:
12728 check_cop1x(ctx);
12729 {
12730 TCGv_i32 fp0 = tcg_temp_new_i32();
12731 TCGv_i32 fp1 = tcg_temp_new_i32();
12732 TCGv_i32 fp2 = tcg_temp_new_i32();
12733
12734 gen_load_fpr32(ctx, fp0, fs);
12735 gen_load_fpr32(ctx, fp1, ft);
12736 gen_load_fpr32(ctx, fp2, fr);
12737 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12738 tcg_temp_free_i32(fp0);
12739 tcg_temp_free_i32(fp1);
12740 gen_store_fpr32(ctx, fp2, fd);
12741 tcg_temp_free_i32(fp2);
12742 }
12743 break;
12744 case OPC_NMSUB_D:
12745 check_cop1x(ctx);
12746 check_cp1_registers(ctx, fd | fs | ft | fr);
12747 {
12748 TCGv_i64 fp0 = tcg_temp_new_i64();
12749 TCGv_i64 fp1 = tcg_temp_new_i64();
12750 TCGv_i64 fp2 = tcg_temp_new_i64();
12751
12752 gen_load_fpr64(ctx, fp0, fs);
12753 gen_load_fpr64(ctx, fp1, ft);
12754 gen_load_fpr64(ctx, fp2, fr);
12755 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12756 tcg_temp_free_i64(fp0);
12757 tcg_temp_free_i64(fp1);
12758 gen_store_fpr64(ctx, fp2, fd);
12759 tcg_temp_free_i64(fp2);
12760 }
12761 break;
12762 case OPC_NMSUB_PS:
12763 check_ps(ctx);
12764 {
12765 TCGv_i64 fp0 = tcg_temp_new_i64();
12766 TCGv_i64 fp1 = tcg_temp_new_i64();
12767 TCGv_i64 fp2 = tcg_temp_new_i64();
12768
12769 gen_load_fpr64(ctx, fp0, fs);
12770 gen_load_fpr64(ctx, fp1, ft);
12771 gen_load_fpr64(ctx, fp2, fr);
12772 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12773 tcg_temp_free_i64(fp0);
12774 tcg_temp_free_i64(fp1);
12775 gen_store_fpr64(ctx, fp2, fd);
12776 tcg_temp_free_i64(fp2);
12777 }
12778 break;
12779 default:
12780 MIPS_INVAL("flt3_arith");
12781 generate_exception_end(ctx, EXCP_RI);
12782 return;
12783 }
12784}
12785
12786static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12787{
12788 TCGv t0;
12789
12790#if !defined(CONFIG_USER_ONLY)
12791
12792
12793
12794
12795 check_insn(ctx, ISA_MIPS32R2);
12796#endif
12797 t0 = tcg_temp_new();
12798
12799 switch (rd) {
12800 case 0:
12801 gen_helper_rdhwr_cpunum(t0, cpu_env);
12802 gen_store_gpr(t0, rt);
12803 break;
12804 case 1:
12805 gen_helper_rdhwr_synci_step(t0, cpu_env);
12806 gen_store_gpr(t0, rt);
12807 break;
12808 case 2:
12809 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12810 gen_io_start();
12811 }
12812 gen_helper_rdhwr_cc(t0, cpu_env);
12813 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12814 gen_io_end();
12815 }
12816 gen_store_gpr(t0, rt);
12817
12818
12819
12820
12821
12822 gen_save_pc(ctx->base.pc_next + 4);
12823 ctx->base.is_jmp = DISAS_EXIT;
12824 break;
12825 case 3:
12826 gen_helper_rdhwr_ccres(t0, cpu_env);
12827 gen_store_gpr(t0, rt);
12828 break;
12829 case 4:
12830 check_insn(ctx, ISA_MIPS32R6);
12831 if (sel != 0) {
12832
12833
12834
12835
12836 generate_exception(ctx, EXCP_RI);
12837 }
12838 gen_helper_rdhwr_performance(t0, cpu_env);
12839 gen_store_gpr(t0, rt);
12840 break;
12841 case 5:
12842 check_insn(ctx, ISA_MIPS32R6);
12843 gen_helper_rdhwr_xnp(t0, cpu_env);
12844 gen_store_gpr(t0, rt);
12845 break;
12846 case 29:
12847#if defined(CONFIG_USER_ONLY)
12848 tcg_gen_ld_tl(t0, cpu_env,
12849 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12850 gen_store_gpr(t0, rt);
12851 break;
12852#else
12853 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12854 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12855 tcg_gen_ld_tl(t0, cpu_env,
12856 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12857 gen_store_gpr(t0, rt);
12858 } else {
12859 generate_exception_end(ctx, EXCP_RI);
12860 }
12861 break;
12862#endif
12863 default:
12864 MIPS_INVAL("rdhwr");
12865 generate_exception_end(ctx, EXCP_RI);
12866 break;
12867 }
12868 tcg_temp_free(t0);
12869}
12870
12871static inline void clear_branch_hflags(DisasContext *ctx)
12872{
12873 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12874 if (ctx->base.is_jmp == DISAS_NEXT) {
12875 save_cpu_state(ctx, 0);
12876 } else {
12877
12878
12879
12880
12881 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12882 }
12883}
12884
12885static void gen_branch(DisasContext *ctx, int insn_bytes)
12886{
12887 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12888 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12889
12890 clear_branch_hflags(ctx);
12891 ctx->base.is_jmp = DISAS_NORETURN;
12892
12893 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12894 case MIPS_HFLAG_FBNSLOT:
12895 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12896 break;
12897 case MIPS_HFLAG_B:
12898
12899 if (proc_hflags & MIPS_HFLAG_BX) {
12900 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12901 }
12902 gen_goto_tb(ctx, 0, ctx->btarget);
12903 break;
12904 case MIPS_HFLAG_BL:
12905
12906 gen_goto_tb(ctx, 0, ctx->btarget);
12907 break;
12908 case MIPS_HFLAG_BC:
12909
12910 {
12911 TCGLabel *l1 = gen_new_label();
12912
12913 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12914 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12915 gen_set_label(l1);
12916 gen_goto_tb(ctx, 0, ctx->btarget);
12917 }
12918 break;
12919 case MIPS_HFLAG_BR:
12920
12921 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12922 TCGv t0 = tcg_temp_new();
12923 TCGv_i32 t1 = tcg_temp_new_i32();
12924
12925 tcg_gen_andi_tl(t0, btarget, 0x1);
12926 tcg_gen_trunc_tl_i32(t1, t0);
12927 tcg_temp_free(t0);
12928 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12929 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12930 tcg_gen_or_i32(hflags, hflags, t1);
12931 tcg_temp_free_i32(t1);
12932
12933 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12934 } else {
12935 tcg_gen_mov_tl(cpu_PC, btarget);
12936 }
12937 if (ctx->base.singlestep_enabled) {
12938 save_cpu_state(ctx, 0);
12939 gen_helper_raise_exception_debug(cpu_env);
12940 }
12941 tcg_gen_lookup_and_goto_ptr();
12942 break;
12943 default:
12944 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12945 abort();
12946 }
12947 }
12948}
12949
12950
12951static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12952 int rs, int rt, int32_t offset)
12953{
12954 int bcond_compute = 0;
12955 TCGv t0 = tcg_temp_new();
12956 TCGv t1 = tcg_temp_new();
12957 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12958
12959 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12960#ifdef MIPS_DEBUG_DISAS
12961 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12962 "\n", ctx->base.pc_next);
12963#endif
12964 generate_exception_end(ctx, EXCP_RI);
12965 goto out;
12966 }
12967
12968
12969 switch (opc) {
12970
12971 case OPC_BOVC:
12972 case OPC_BNVC:
12973 gen_load_gpr(t0, rs);
12974 gen_load_gpr(t1, rt);
12975 bcond_compute = 1;
12976 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12977 if (rs <= rt && rs == 0) {
12978
12979 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12980 }
12981 break;
12982 case OPC_BLEZC:
12983 case OPC_BGTZC:
12984 gen_load_gpr(t0, rs);
12985 gen_load_gpr(t1, rt);
12986 bcond_compute = 1;
12987 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12988 break;
12989 case OPC_BLEZALC:
12990 case OPC_BGTZALC:
12991 if (rs == 0 || rs == rt) {
12992
12993
12994 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12995 }
12996 gen_load_gpr(t0, rs);
12997 gen_load_gpr(t1, rt);
12998 bcond_compute = 1;
12999 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13000 break;
13001 case OPC_BC:
13002 case OPC_BALC:
13003 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13004 break;
13005 case OPC_BEQZC:
13006 case OPC_BNEZC:
13007 if (rs != 0) {
13008
13009 gen_load_gpr(t0, rs);
13010 bcond_compute = 1;
13011 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13012 } else {
13013
13014 TCGv tbase = tcg_temp_new();
13015 TCGv toffset = tcg_temp_new();
13016
13017 gen_load_gpr(tbase, rt);
13018 tcg_gen_movi_tl(toffset, offset);
13019 gen_op_addr_add(ctx, btarget, tbase, toffset);
13020 tcg_temp_free(tbase);
13021 tcg_temp_free(toffset);
13022 }
13023 break;
13024 default:
13025 MIPS_INVAL("Compact branch/jump");
13026 generate_exception_end(ctx, EXCP_RI);
13027 goto out;
13028 }
13029
13030 if (bcond_compute == 0) {
13031
13032 switch (opc) {
13033 case OPC_JIALC:
13034 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13035
13036 case OPC_JIC:
13037 ctx->hflags |= MIPS_HFLAG_BR;
13038 break;
13039 case OPC_BALC:
13040 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13041
13042 case OPC_BC:
13043 ctx->hflags |= MIPS_HFLAG_B;
13044 break;
13045 default:
13046 MIPS_INVAL("Compact branch/jump");
13047 generate_exception_end(ctx, EXCP_RI);
13048 goto out;
13049 }
13050
13051
13052 gen_branch(ctx, 4);
13053 } else {
13054
13055 TCGLabel *fs = gen_new_label();
13056 save_cpu_state(ctx, 0);
13057
13058 switch (opc) {
13059 case OPC_BLEZALC:
13060 if (rs == 0 && rt != 0) {
13061
13062 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13063 } else if (rs != 0 && rt != 0 && rs == rt) {
13064
13065 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13066 } else {
13067
13068 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
13069 }
13070 break;
13071 case OPC_BGTZALC:
13072 if (rs == 0 && rt != 0) {
13073
13074 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13075 } else if (rs != 0 && rt != 0 && rs == rt) {
13076
13077 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13078 } else {
13079
13080 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
13081 }
13082 break;
13083 case OPC_BLEZC:
13084 if (rs == 0 && rt != 0) {
13085
13086 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13087 } else if (rs != 0 && rt != 0 && rs == rt) {
13088
13089 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13090 } else {
13091
13092 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
13093 }
13094 break;
13095 case OPC_BGTZC:
13096 if (rs == 0 && rt != 0) {
13097
13098 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13099 } else if (rs != 0 && rt != 0 && rs == rt) {
13100
13101 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13102 } else {
13103
13104 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13105 }
13106 break;
13107 case OPC_BOVC:
13108 case OPC_BNVC:
13109 if (rs >= rt) {
13110
13111 TCGv t2 = tcg_temp_new();
13112 TCGv t3 = tcg_temp_new();
13113 TCGv t4 = tcg_temp_new();
13114 TCGv input_overflow = tcg_temp_new();
13115
13116 gen_load_gpr(t0, rs);
13117 gen_load_gpr(t1, rt);
13118 tcg_gen_ext32s_tl(t2, t0);
13119 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13120 tcg_gen_ext32s_tl(t3, t1);
13121 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13122 tcg_gen_or_tl(input_overflow, input_overflow, t4);
13123
13124 tcg_gen_add_tl(t4, t2, t3);
13125 tcg_gen_ext32s_tl(t4, t4);
13126 tcg_gen_xor_tl(t2, t2, t3);
13127 tcg_gen_xor_tl(t3, t4, t3);
13128 tcg_gen_andc_tl(t2, t3, t2);
13129 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13130 tcg_gen_or_tl(t4, t4, input_overflow);
13131 if (opc == OPC_BOVC) {
13132
13133 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13134 } else {
13135
13136 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13137 }
13138 tcg_temp_free(input_overflow);
13139 tcg_temp_free(t4);
13140 tcg_temp_free(t3);
13141 tcg_temp_free(t2);
13142 } else if (rs < rt && rs == 0) {
13143
13144 if (opc == OPC_BEQZALC) {
13145
13146 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13147 } else {
13148
13149 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13150 }
13151 } else {
13152
13153 if (opc == OPC_BEQC) {
13154
13155 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13156 } else {
13157
13158 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13159 }
13160 }
13161 break;
13162 case OPC_BEQZC:
13163 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13164 break;
13165 case OPC_BNEZC:
13166 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13167 break;
13168 default:
13169 MIPS_INVAL("Compact conditional branch/jump");
13170 generate_exception_end(ctx, EXCP_RI);
13171 goto out;
13172 }
13173
13174
13175 gen_goto_tb(ctx, 1, ctx->btarget);
13176 gen_set_label(fs);
13177
13178 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13179 }
13180
13181out:
13182 tcg_temp_free(t0);
13183 tcg_temp_free(t1);
13184}
13185
13186
13187
13188
13189
13190enum {
13191 M16_OPC_ADDIUSP = 0x00,
13192 M16_OPC_ADDIUPC = 0x01,
13193 M16_OPC_B = 0x02,
13194 M16_OPC_JAL = 0x03,
13195 M16_OPC_BEQZ = 0x04,
13196 M16_OPC_BNEQZ = 0x05,
13197 M16_OPC_SHIFT = 0x06,
13198 M16_OPC_LD = 0x07,
13199 M16_OPC_RRIA = 0x08,
13200 M16_OPC_ADDIU8 = 0x09,
13201 M16_OPC_SLTI = 0x0a,
13202 M16_OPC_SLTIU = 0x0b,
13203 M16_OPC_I8 = 0x0c,
13204 M16_OPC_LI = 0x0d,
13205 M16_OPC_CMPI = 0x0e,
13206 M16_OPC_SD = 0x0f,
13207 M16_OPC_LB = 0x10,
13208 M16_OPC_LH = 0x11,
13209 M16_OPC_LWSP = 0x12,
13210 M16_OPC_LW = 0x13,
13211 M16_OPC_LBU = 0x14,
13212 M16_OPC_LHU = 0x15,
13213 M16_OPC_LWPC = 0x16,
13214 M16_OPC_LWU = 0x17,
13215 M16_OPC_SB = 0x18,
13216 M16_OPC_SH = 0x19,
13217 M16_OPC_SWSP = 0x1a,
13218 M16_OPC_SW = 0x1b,
13219 M16_OPC_RRR = 0x1c,
13220 M16_OPC_RR = 0x1d,
13221 M16_OPC_EXTEND = 0x1e,
13222 M16_OPC_I64 = 0x1f
13223};
13224
13225
13226enum {
13227 I8_BTEQZ = 0x0,
13228 I8_BTNEZ = 0x1,
13229 I8_SWRASP = 0x2,
13230 I8_ADJSP = 0x3,
13231 I8_SVRS = 0x4,
13232 I8_MOV32R = 0x5,
13233 I8_MOVR32 = 0x7
13234};
13235
13236
13237enum {
13238 RRR_DADDU = 0x0,
13239 RRR_ADDU = 0x1,
13240 RRR_DSUBU = 0x2,
13241 RRR_SUBU = 0x3
13242};
13243
13244
13245enum {
13246 RR_JR = 0x00,
13247 RR_SDBBP = 0x01,
13248 RR_SLT = 0x02,
13249 RR_SLTU = 0x03,
13250 RR_SLLV = 0x04,
13251 RR_BREAK = 0x05,
13252 RR_SRLV = 0x06,
13253 RR_SRAV = 0x07,
13254 RR_DSRL = 0x08,
13255 RR_CMP = 0x0a,
13256 RR_NEG = 0x0b,
13257 RR_AND = 0x0c,
13258 RR_OR = 0x0d,
13259 RR_XOR = 0x0e,
13260 RR_NOT = 0x0f,
13261 RR_MFHI = 0x10,
13262 RR_CNVT = 0x11,
13263 RR_MFLO = 0x12,
13264 RR_DSRA = 0x13,
13265 RR_DSLLV = 0x14,
13266 RR_DSRLV = 0x16,
13267 RR_DSRAV = 0x17,
13268 RR_MULT = 0x18,
13269 RR_MULTU = 0x19,
13270 RR_DIV = 0x1a,
13271 RR_DIVU = 0x1b,
13272 RR_DMULT = 0x1c,
13273 RR_DMULTU = 0x1d,
13274 RR_DDIV = 0x1e,
13275 RR_DDIVU = 0x1f
13276};
13277
13278
13279enum {
13280 I64_LDSP = 0x0,
13281 I64_SDSP = 0x1,
13282 I64_SDRASP = 0x2,
13283 I64_DADJSP = 0x3,
13284 I64_LDPC = 0x4,
13285 I64_DADDIU5 = 0x5,
13286 I64_DADDIUPC = 0x6,
13287 I64_DADDIUSP = 0x7
13288};
13289
13290
13291enum {
13292 RR_RY_CNVT_ZEB = 0x0,
13293 RR_RY_CNVT_ZEH = 0x1,
13294 RR_RY_CNVT_ZEW = 0x2,
13295 RR_RY_CNVT_SEB = 0x4,
13296 RR_RY_CNVT_SEH = 0x5,
13297 RR_RY_CNVT_SEW = 0x6,
13298};
13299
13300static int xlat(int r)
13301{
13302 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13303
13304 return map[r];
13305}
13306
13307static void gen_mips16_save(DisasContext *ctx,
13308 int xsregs, int aregs,
13309 int do_ra, int do_s0, int do_s1,
13310 int framesize)
13311{
13312 TCGv t0 = tcg_temp_new();
13313 TCGv t1 = tcg_temp_new();
13314 TCGv t2 = tcg_temp_new();
13315 int args, astatic;
13316
13317 switch (aregs) {
13318 case 0:
13319 case 1:
13320 case 2:
13321 case 3:
13322 case 11:
13323 args = 0;
13324 break;
13325 case 4:
13326 case 5:
13327 case 6:
13328 case 7:
13329 args = 1;
13330 break;
13331 case 8:
13332 case 9:
13333 case 10:
13334 args = 2;
13335 break;
13336 case 12:
13337 case 13:
13338 args = 3;
13339 break;
13340 case 14:
13341 args = 4;
13342 break;
13343 default:
13344 generate_exception_end(ctx, EXCP_RI);
13345 return;
13346 }
13347
13348 switch (args) {
13349 case 4:
13350 gen_base_offset_addr(ctx, t0, 29, 12);
13351 gen_load_gpr(t1, 7);
13352 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13353
13354 case 3:
13355 gen_base_offset_addr(ctx, t0, 29, 8);
13356 gen_load_gpr(t1, 6);
13357 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13358
13359 case 2:
13360 gen_base_offset_addr(ctx, t0, 29, 4);
13361 gen_load_gpr(t1, 5);
13362 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13363
13364 case 1:
13365 gen_base_offset_addr(ctx, t0, 29, 0);
13366 gen_load_gpr(t1, 4);
13367 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13368 }
13369
13370 gen_load_gpr(t0, 29);
13371
13372#define DECR_AND_STORE(reg) do { \
13373 tcg_gen_movi_tl(t2, -4); \
13374 gen_op_addr_add(ctx, t0, t0, t2); \
13375 gen_load_gpr(t1, reg); \
13376 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13377 } while (0)
13378
13379 if (do_ra) {
13380 DECR_AND_STORE(31);
13381 }
13382
13383 switch (xsregs) {
13384 case 7:
13385 DECR_AND_STORE(30);
13386
13387 case 6:
13388 DECR_AND_STORE(23);
13389
13390 case 5:
13391 DECR_AND_STORE(22);
13392
13393 case 4:
13394 DECR_AND_STORE(21);
13395
13396 case 3:
13397 DECR_AND_STORE(20);
13398
13399 case 2:
13400 DECR_AND_STORE(19);
13401
13402 case 1:
13403 DECR_AND_STORE(18);
13404 }
13405
13406 if (do_s1) {
13407 DECR_AND_STORE(17);
13408 }
13409 if (do_s0) {
13410 DECR_AND_STORE(16);
13411 }
13412
13413 switch (aregs) {
13414 case 0:
13415 case 4:
13416 case 8:
13417 case 12:
13418 case 14:
13419 astatic = 0;
13420 break;
13421 case 1:
13422 case 5:
13423 case 9:
13424 case 13:
13425 astatic = 1;
13426 break;
13427 case 2:
13428 case 6:
13429 case 10:
13430 astatic = 2;
13431 break;
13432 case 3:
13433 case 7:
13434 astatic = 3;
13435 break;
13436 case 11:
13437 astatic = 4;
13438 break;
13439 default:
13440 generate_exception_end(ctx, EXCP_RI);
13441 return;
13442 }
13443
13444 if (astatic > 0) {
13445 DECR_AND_STORE(7);
13446 if (astatic > 1) {
13447 DECR_AND_STORE(6);
13448 if (astatic > 2) {
13449 DECR_AND_STORE(5);
13450 if (astatic > 3) {
13451 DECR_AND_STORE(4);
13452 }
13453 }
13454 }
13455 }
13456#undef DECR_AND_STORE
13457
13458 tcg_gen_movi_tl(t2, -framesize);
13459 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13460 tcg_temp_free(t0);
13461 tcg_temp_free(t1);
13462 tcg_temp_free(t2);
13463}
13464
13465static void gen_mips16_restore(DisasContext *ctx,
13466 int xsregs, int aregs,
13467 int do_ra, int do_s0, int do_s1,
13468 int framesize)
13469{
13470 int astatic;
13471 TCGv t0 = tcg_temp_new();
13472 TCGv t1 = tcg_temp_new();
13473 TCGv t2 = tcg_temp_new();
13474
13475 tcg_gen_movi_tl(t2, framesize);
13476 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13477
13478#define DECR_AND_LOAD(reg) do { \
13479 tcg_gen_movi_tl(t2, -4); \
13480 gen_op_addr_add(ctx, t0, t0, t2); \
13481 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13482 gen_store_gpr(t1, reg); \
13483 } while (0)
13484
13485 if (do_ra) {
13486 DECR_AND_LOAD(31);
13487 }
13488
13489 switch (xsregs) {
13490 case 7:
13491 DECR_AND_LOAD(30);
13492
13493 case 6:
13494 DECR_AND_LOAD(23);
13495
13496 case 5:
13497 DECR_AND_LOAD(22);
13498
13499 case 4:
13500 DECR_AND_LOAD(21);
13501
13502 case 3:
13503 DECR_AND_LOAD(20);
13504
13505 case 2:
13506 DECR_AND_LOAD(19);
13507
13508 case 1:
13509 DECR_AND_LOAD(18);
13510 }
13511
13512 if (do_s1) {
13513 DECR_AND_LOAD(17);
13514 }
13515 if (do_s0) {
13516 DECR_AND_LOAD(16);
13517 }
13518
13519 switch (aregs) {
13520 case 0:
13521 case 4:
13522 case 8:
13523 case 12:
13524 case 14:
13525 astatic = 0;
13526 break;
13527 case 1:
13528 case 5:
13529 case 9:
13530 case 13:
13531 astatic = 1;
13532 break;
13533 case 2:
13534 case 6:
13535 case 10:
13536 astatic = 2;
13537 break;
13538 case 3:
13539 case 7:
13540 astatic = 3;
13541 break;
13542 case 11:
13543 astatic = 4;
13544 break;
13545 default:
13546 generate_exception_end(ctx, EXCP_RI);
13547 return;
13548 }
13549
13550 if (astatic > 0) {
13551 DECR_AND_LOAD(7);
13552 if (astatic > 1) {
13553 DECR_AND_LOAD(6);
13554 if (astatic > 2) {
13555 DECR_AND_LOAD(5);
13556 if (astatic > 3) {
13557 DECR_AND_LOAD(4);
13558 }
13559 }
13560 }
13561 }
13562#undef DECR_AND_LOAD
13563
13564 tcg_gen_movi_tl(t2, framesize);
13565 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13566 tcg_temp_free(t0);
13567 tcg_temp_free(t1);
13568 tcg_temp_free(t2);
13569}
13570
13571static void gen_addiupc(DisasContext *ctx, int rx, int imm,
13572 int is_64_bit, int extended)
13573{
13574 TCGv t0;
13575
13576 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13577 generate_exception_end(ctx, EXCP_RI);
13578 return;
13579 }
13580
13581 t0 = tcg_temp_new();
13582
13583 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13584 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13585 if (!is_64_bit) {
13586 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13587 }
13588
13589 tcg_temp_free(t0);
13590}
13591
13592static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13593 int16_t offset)
13594{
13595 TCGv_i32 t0 = tcg_const_i32(op);
13596 TCGv t1 = tcg_temp_new();
13597 gen_base_offset_addr(ctx, t1, base, offset);
13598 gen_helper_cache(cpu_env, t1, t0);
13599}
13600
13601#if defined(TARGET_MIPS64)
13602static void decode_i64_mips16(DisasContext *ctx,
13603 int ry, int funct, int16_t offset,
13604 int extended)
13605{
13606 switch (funct) {
13607 case I64_LDSP:
13608 check_insn(ctx, ISA_MIPS3);
13609 check_mips_64(ctx);
13610 offset = extended ? offset : offset << 3;
13611 gen_ld(ctx, OPC_LD, ry, 29, offset);
13612 break;
13613 case I64_SDSP:
13614 check_insn(ctx, ISA_MIPS3);
13615 check_mips_64(ctx);
13616 offset = extended ? offset : offset << 3;
13617 gen_st(ctx, OPC_SD, ry, 29, offset);
13618 break;
13619 case I64_SDRASP:
13620 check_insn(ctx, ISA_MIPS3);
13621 check_mips_64(ctx);
13622 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13623 gen_st(ctx, OPC_SD, 31, 29, offset);
13624 break;
13625 case I64_DADJSP:
13626 check_insn(ctx, ISA_MIPS3);
13627 check_mips_64(ctx);
13628 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13629 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13630 break;
13631 case I64_LDPC:
13632 check_insn(ctx, ISA_MIPS3);
13633 check_mips_64(ctx);
13634 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13635 generate_exception_end(ctx, EXCP_RI);
13636 } else {
13637 offset = extended ? offset : offset << 3;
13638 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13639 }
13640 break;
13641 case I64_DADDIU5:
13642 check_insn(ctx, ISA_MIPS3);
13643 check_mips_64(ctx);
13644 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13645 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13646 break;
13647 case I64_DADDIUPC:
13648 check_insn(ctx, ISA_MIPS3);
13649 check_mips_64(ctx);
13650 offset = extended ? offset : offset << 2;
13651 gen_addiupc(ctx, ry, offset, 1, extended);
13652 break;
13653 case I64_DADDIUSP:
13654 check_insn(ctx, ISA_MIPS3);
13655 check_mips_64(ctx);
13656 offset = extended ? offset : offset << 2;
13657 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13658 break;
13659 }
13660}
13661#endif
13662
13663static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13664{
13665 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13666 int op, rx, ry, funct, sa;
13667 int16_t imm, offset;
13668
13669 ctx->opcode = (ctx->opcode << 16) | extend;
13670 op = (ctx->opcode >> 11) & 0x1f;
13671 sa = (ctx->opcode >> 22) & 0x1f;
13672 funct = (ctx->opcode >> 8) & 0x7;
13673 rx = xlat((ctx->opcode >> 8) & 0x7);
13674 ry = xlat((ctx->opcode >> 5) & 0x7);
13675 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13676 | ((ctx->opcode >> 21) & 0x3f) << 5
13677 | (ctx->opcode & 0x1f));
13678
13679
13680
13681
13682
13683 switch (op) {
13684 case M16_OPC_ADDIUSP:
13685 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13686 break;
13687 case M16_OPC_ADDIUPC:
13688 gen_addiupc(ctx, rx, imm, 0, 1);
13689 break;
13690 case M16_OPC_B:
13691 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13692
13693 break;
13694 case M16_OPC_BEQZ:
13695 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13696
13697 break;
13698 case M16_OPC_BNEQZ:
13699 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13700
13701 break;
13702 case M16_OPC_SHIFT:
13703 switch (ctx->opcode & 0x3) {
13704 case 0x0:
13705 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13706 break;
13707 case 0x1:
13708#if defined(TARGET_MIPS64)
13709 check_mips_64(ctx);
13710 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13711#else
13712 generate_exception_end(ctx, EXCP_RI);
13713#endif
13714 break;
13715 case 0x2:
13716 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13717 break;
13718 case 0x3:
13719 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13720 break;
13721 }
13722 break;
13723#if defined(TARGET_MIPS64)
13724 case M16_OPC_LD:
13725 check_insn(ctx, ISA_MIPS3);
13726 check_mips_64(ctx);
13727 gen_ld(ctx, OPC_LD, ry, rx, offset);
13728 break;
13729#endif
13730 case M16_OPC_RRIA:
13731 imm = ctx->opcode & 0xf;
13732 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13733 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13734 imm = (int16_t) (imm << 1) >> 1;
13735 if ((ctx->opcode >> 4) & 0x1) {
13736#if defined(TARGET_MIPS64)
13737 check_mips_64(ctx);
13738 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13739#else
13740 generate_exception_end(ctx, EXCP_RI);
13741#endif
13742 } else {
13743 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13744 }
13745 break;
13746 case M16_OPC_ADDIU8:
13747 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13748 break;
13749 case M16_OPC_SLTI:
13750 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13751 break;
13752 case M16_OPC_SLTIU:
13753 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13754 break;
13755 case M16_OPC_I8:
13756 switch (funct) {
13757 case I8_BTEQZ:
13758 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13759 break;
13760 case I8_BTNEZ:
13761 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13762 break;
13763 case I8_SWRASP:
13764 gen_st(ctx, OPC_SW, 31, 29, imm);
13765 break;
13766 case I8_ADJSP:
13767 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13768 break;
13769 case I8_SVRS:
13770 check_insn(ctx, ISA_MIPS32);
13771 {
13772 int xsregs = (ctx->opcode >> 24) & 0x7;
13773 int aregs = (ctx->opcode >> 16) & 0xf;
13774 int do_ra = (ctx->opcode >> 6) & 0x1;
13775 int do_s0 = (ctx->opcode >> 5) & 0x1;
13776 int do_s1 = (ctx->opcode >> 4) & 0x1;
13777 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13778 | (ctx->opcode & 0xf)) << 3;
13779
13780 if (ctx->opcode & (1 << 7)) {
13781 gen_mips16_save(ctx, xsregs, aregs,
13782 do_ra, do_s0, do_s1,
13783 framesize);
13784 } else {
13785 gen_mips16_restore(ctx, xsregs, aregs,
13786 do_ra, do_s0, do_s1,
13787 framesize);
13788 }
13789 }
13790 break;
13791 default:
13792 generate_exception_end(ctx, EXCP_RI);
13793 break;
13794 }
13795 break;
13796 case M16_OPC_LI:
13797 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13798 break;
13799 case M16_OPC_CMPI:
13800 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13801 break;
13802#if defined(TARGET_MIPS64)
13803 case M16_OPC_SD:
13804 check_insn(ctx, ISA_MIPS3);
13805 check_mips_64(ctx);
13806 gen_st(ctx, OPC_SD, ry, rx, offset);
13807 break;
13808#endif
13809 case M16_OPC_LB:
13810 gen_ld(ctx, OPC_LB, ry, rx, offset);
13811 break;
13812 case M16_OPC_LH:
13813 gen_ld(ctx, OPC_LH, ry, rx, offset);
13814 break;
13815 case M16_OPC_LWSP:
13816 gen_ld(ctx, OPC_LW, rx, 29, offset);
13817 break;
13818 case M16_OPC_LW:
13819 gen_ld(ctx, OPC_LW, ry, rx, offset);
13820 break;
13821 case M16_OPC_LBU:
13822 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13823 break;
13824 case M16_OPC_LHU:
13825 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13826 break;
13827 case M16_OPC_LWPC:
13828 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13829 break;
13830#if defined(TARGET_MIPS64)
13831 case M16_OPC_LWU:
13832 check_insn(ctx, ISA_MIPS3);
13833 check_mips_64(ctx);
13834 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13835 break;
13836#endif
13837 case M16_OPC_SB:
13838 gen_st(ctx, OPC_SB, ry, rx, offset);
13839 break;
13840 case M16_OPC_SH:
13841 gen_st(ctx, OPC_SH, ry, rx, offset);
13842 break;
13843 case M16_OPC_SWSP:
13844 gen_st(ctx, OPC_SW, rx, 29, offset);
13845 break;
13846 case M16_OPC_SW:
13847 gen_st(ctx, OPC_SW, ry, rx, offset);
13848 break;
13849#if defined(TARGET_MIPS64)
13850 case M16_OPC_I64:
13851 decode_i64_mips16(ctx, ry, funct, offset, 1);
13852 break;
13853#endif
13854 default:
13855 generate_exception_end(ctx, EXCP_RI);
13856 break;
13857 }
13858
13859 return 4;
13860}
13861
13862static inline bool is_uhi(int sdbbp_code)
13863{
13864#ifdef CONFIG_USER_ONLY
13865 return false;
13866#else
13867 return semihosting_enabled() && sdbbp_code == 1;
13868#endif
13869}
13870
13871#ifdef CONFIG_USER_ONLY
13872
13873static inline void gen_helper_do_semihosting(void *env)
13874{
13875 g_assert_not_reached();
13876}
13877#endif
13878
13879static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13880{
13881 int rx, ry;
13882 int sa;
13883 int op, cnvt_op, op1, offset;
13884 int funct;
13885 int n_bytes;
13886
13887 op = (ctx->opcode >> 11) & 0x1f;
13888 sa = (ctx->opcode >> 2) & 0x7;
13889 sa = sa == 0 ? 8 : sa;
13890 rx = xlat((ctx->opcode >> 8) & 0x7);
13891 cnvt_op = (ctx->opcode >> 5) & 0x7;
13892 ry = xlat((ctx->opcode >> 5) & 0x7);
13893 op1 = offset = ctx->opcode & 0x1f;
13894
13895 n_bytes = 2;
13896
13897 switch (op) {
13898 case M16_OPC_ADDIUSP:
13899 {
13900 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13901
13902 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13903 }
13904 break;
13905 case M16_OPC_ADDIUPC:
13906 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13907 break;
13908 case M16_OPC_B:
13909 offset = (ctx->opcode & 0x7ff) << 1;
13910 offset = (int16_t)(offset << 4) >> 4;
13911 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13912
13913 break;
13914 case M16_OPC_JAL:
13915 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13916 offset = (((ctx->opcode & 0x1f) << 21)
13917 | ((ctx->opcode >> 5) & 0x1f) << 16
13918 | offset) << 2;
13919 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13920 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13921 n_bytes = 4;
13922 break;
13923 case M16_OPC_BEQZ:
13924 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13925 ((int8_t)ctx->opcode) << 1, 0);
13926
13927 break;
13928 case M16_OPC_BNEQZ:
13929 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13930 ((int8_t)ctx->opcode) << 1, 0);
13931
13932 break;
13933 case M16_OPC_SHIFT:
13934 switch (ctx->opcode & 0x3) {
13935 case 0x0:
13936 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13937 break;
13938 case 0x1:
13939#if defined(TARGET_MIPS64)
13940 check_insn(ctx, ISA_MIPS3);
13941 check_mips_64(ctx);
13942 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13943#else
13944 generate_exception_end(ctx, EXCP_RI);
13945#endif
13946 break;
13947 case 0x2:
13948 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13949 break;
13950 case 0x3:
13951 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13952 break;
13953 }
13954 break;
13955#if defined(TARGET_MIPS64)
13956 case M16_OPC_LD:
13957 check_insn(ctx, ISA_MIPS3);
13958 check_mips_64(ctx);
13959 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13960 break;
13961#endif
13962 case M16_OPC_RRIA:
13963 {
13964 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13965
13966 if ((ctx->opcode >> 4) & 1) {
13967#if defined(TARGET_MIPS64)
13968 check_insn(ctx, ISA_MIPS3);
13969 check_mips_64(ctx);
13970 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13971#else
13972 generate_exception_end(ctx, EXCP_RI);
13973#endif
13974 } else {
13975 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13976 }
13977 }
13978 break;
13979 case M16_OPC_ADDIU8:
13980 {
13981 int16_t imm = (int8_t) ctx->opcode;
13982
13983 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13984 }
13985 break;
13986 case M16_OPC_SLTI:
13987 {
13988 int16_t imm = (uint8_t) ctx->opcode;
13989 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13990 }
13991 break;
13992 case M16_OPC_SLTIU:
13993 {
13994 int16_t imm = (uint8_t) ctx->opcode;
13995 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13996 }
13997 break;
13998 case M16_OPC_I8:
13999 {
14000 int reg32;
14001
14002 funct = (ctx->opcode >> 8) & 0x7;
14003 switch (funct) {
14004 case I8_BTEQZ:
14005 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
14006 ((int8_t)ctx->opcode) << 1, 0);
14007 break;
14008 case I8_BTNEZ:
14009 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
14010 ((int8_t)ctx->opcode) << 1, 0);
14011 break;
14012 case I8_SWRASP:
14013 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
14014 break;
14015 case I8_ADJSP:
14016 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
14017 ((int8_t)ctx->opcode) << 3);
14018 break;
14019 case I8_SVRS:
14020 check_insn(ctx, ISA_MIPS32);
14021 {
14022 int do_ra = ctx->opcode & (1 << 6);
14023 int do_s0 = ctx->opcode & (1 << 5);
14024 int do_s1 = ctx->opcode & (1 << 4);
14025 int framesize = ctx->opcode & 0xf;
14026
14027 if (framesize == 0) {
14028 framesize = 128;
14029 } else {
14030 framesize = framesize << 3;
14031 }
14032
14033 if (ctx->opcode & (1 << 7)) {
14034 gen_mips16_save(ctx, 0, 0,
14035 do_ra, do_s0, do_s1, framesize);
14036 } else {
14037 gen_mips16_restore(ctx, 0, 0,
14038 do_ra, do_s0, do_s1, framesize);
14039 }
14040 }
14041 break;
14042 case I8_MOV32R:
14043 {
14044 int rz = xlat(ctx->opcode & 0x7);
14045
14046 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
14047 ((ctx->opcode >> 5) & 0x7);
14048 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
14049 }
14050 break;
14051 case I8_MOVR32:
14052 reg32 = ctx->opcode & 0x1f;
14053 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
14054 break;
14055 default:
14056 generate_exception_end(ctx, EXCP_RI);
14057 break;
14058 }
14059 }
14060 break;
14061 case M16_OPC_LI:
14062 {
14063 int16_t imm = (uint8_t) ctx->opcode;
14064
14065 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
14066 }
14067 break;
14068 case M16_OPC_CMPI:
14069 {
14070 int16_t imm = (uint8_t) ctx->opcode;
14071 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
14072 }
14073 break;
14074#if defined(TARGET_MIPS64)
14075 case M16_OPC_SD:
14076 check_insn(ctx, ISA_MIPS3);
14077 check_mips_64(ctx);
14078 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
14079 break;
14080#endif
14081 case M16_OPC_LB:
14082 gen_ld(ctx, OPC_LB, ry, rx, offset);
14083 break;
14084 case M16_OPC_LH:
14085 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
14086 break;
14087 case M16_OPC_LWSP:
14088 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14089 break;
14090 case M16_OPC_LW:
14091 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
14092 break;
14093 case M16_OPC_LBU:
14094 gen_ld(ctx, OPC_LBU, ry, rx, offset);
14095 break;
14096 case M16_OPC_LHU:
14097 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
14098 break;
14099 case M16_OPC_LWPC:
14100 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
14101 break;
14102#if defined(TARGET_MIPS64)
14103 case M16_OPC_LWU:
14104 check_insn(ctx, ISA_MIPS3);
14105 check_mips_64(ctx);
14106 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
14107 break;
14108#endif
14109 case M16_OPC_SB:
14110 gen_st(ctx, OPC_SB, ry, rx, offset);
14111 break;
14112 case M16_OPC_SH:
14113 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
14114 break;
14115 case M16_OPC_SWSP:
14116 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14117 break;
14118 case M16_OPC_SW:
14119 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14120 break;
14121 case M16_OPC_RRR:
14122 {
14123 int rz = xlat((ctx->opcode >> 2) & 0x7);
14124 int mips32_op;
14125
14126 switch (ctx->opcode & 0x3) {
14127 case RRR_ADDU:
14128 mips32_op = OPC_ADDU;
14129 break;
14130 case RRR_SUBU:
14131 mips32_op = OPC_SUBU;
14132 break;
14133#if defined(TARGET_MIPS64)
14134 case RRR_DADDU:
14135 mips32_op = OPC_DADDU;
14136 check_insn(ctx, ISA_MIPS3);
14137 check_mips_64(ctx);
14138 break;
14139 case RRR_DSUBU:
14140 mips32_op = OPC_DSUBU;
14141 check_insn(ctx, ISA_MIPS3);
14142 check_mips_64(ctx);
14143 break;
14144#endif
14145 default:
14146 generate_exception_end(ctx, EXCP_RI);
14147 goto done;
14148 }
14149
14150 gen_arith(ctx, mips32_op, rz, rx, ry);
14151 done:
14152 ;
14153 }
14154 break;
14155 case M16_OPC_RR:
14156 switch (op1) {
14157 case RR_JR:
14158 {
14159 int nd = (ctx->opcode >> 7) & 0x1;
14160 int link = (ctx->opcode >> 6) & 0x1;
14161 int ra = (ctx->opcode >> 5) & 0x1;
14162
14163 if (nd) {
14164 check_insn(ctx, ISA_MIPS32);
14165 }
14166
14167 if (link) {
14168 op = OPC_JALR;
14169 } else {
14170 op = OPC_JR;
14171 }
14172
14173 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14174 (nd ? 0 : 2));
14175 }
14176 break;
14177 case RR_SDBBP:
14178 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14179 gen_helper_do_semihosting(cpu_env);
14180 } else {
14181
14182
14183
14184
14185 check_insn(ctx, ISA_MIPS32);
14186 generate_exception_end(ctx, EXCP_DBp);
14187 }
14188 break;
14189 case RR_SLT:
14190 gen_slt(ctx, OPC_SLT, 24, rx, ry);
14191 break;
14192 case RR_SLTU:
14193 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14194 break;
14195 case RR_BREAK:
14196 generate_exception_end(ctx, EXCP_BREAK);
14197 break;
14198 case RR_SLLV:
14199 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14200 break;
14201 case RR_SRLV:
14202 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14203 break;
14204 case RR_SRAV:
14205 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14206 break;
14207#if defined(TARGET_MIPS64)
14208 case RR_DSRL:
14209 check_insn(ctx, ISA_MIPS3);
14210 check_mips_64(ctx);
14211 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14212 break;
14213#endif
14214 case RR_CMP:
14215 gen_logic(ctx, OPC_XOR, 24, rx, ry);
14216 break;
14217 case RR_NEG:
14218 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14219 break;
14220 case RR_AND:
14221 gen_logic(ctx, OPC_AND, rx, rx, ry);
14222 break;
14223 case RR_OR:
14224 gen_logic(ctx, OPC_OR, rx, rx, ry);
14225 break;
14226 case RR_XOR:
14227 gen_logic(ctx, OPC_XOR, rx, rx, ry);
14228 break;
14229 case RR_NOT:
14230 gen_logic(ctx, OPC_NOR, rx, ry, 0);
14231 break;
14232 case RR_MFHI:
14233 gen_HILO(ctx, OPC_MFHI, 0, rx);
14234 break;
14235 case RR_CNVT:
14236 check_insn(ctx, ISA_MIPS32);
14237 switch (cnvt_op) {
14238 case RR_RY_CNVT_ZEB:
14239 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14240 break;
14241 case RR_RY_CNVT_ZEH:
14242 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14243 break;
14244 case RR_RY_CNVT_SEB:
14245 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14246 break;
14247 case RR_RY_CNVT_SEH:
14248 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14249 break;
14250#if defined (TARGET_MIPS64)
14251 case RR_RY_CNVT_ZEW:
14252 check_insn(ctx, ISA_MIPS64);
14253 check_mips_64(ctx);
14254 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14255 break;
14256 case RR_RY_CNVT_SEW:
14257 check_insn(ctx, ISA_MIPS64);
14258 check_mips_64(ctx);
14259 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14260 break;
14261#endif
14262 default:
14263 generate_exception_end(ctx, EXCP_RI);
14264 break;
14265 }
14266 break;
14267 case RR_MFLO:
14268 gen_HILO(ctx, OPC_MFLO, 0, rx);
14269 break;
14270#if defined(TARGET_MIPS64)
14271 case RR_DSRA:
14272 check_insn(ctx, ISA_MIPS3);
14273 check_mips_64(ctx);
14274 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14275 break;
14276 case RR_DSLLV:
14277 check_insn(ctx, ISA_MIPS3);
14278 check_mips_64(ctx);
14279 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14280 break;
14281 case RR_DSRLV:
14282 check_insn(ctx, ISA_MIPS3);
14283 check_mips_64(ctx);
14284 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14285 break;
14286 case RR_DSRAV:
14287 check_insn(ctx, ISA_MIPS3);
14288 check_mips_64(ctx);
14289 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14290 break;
14291#endif
14292 case RR_MULT:
14293 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14294 break;
14295 case RR_MULTU:
14296 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14297 break;
14298 case RR_DIV:
14299 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14300 break;
14301 case RR_DIVU:
14302 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14303 break;
14304#if defined(TARGET_MIPS64)
14305 case RR_DMULT:
14306 check_insn(ctx, ISA_MIPS3);
14307 check_mips_64(ctx);
14308 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14309 break;
14310 case RR_DMULTU:
14311 check_insn(ctx, ISA_MIPS3);
14312 check_mips_64(ctx);
14313 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14314 break;
14315 case RR_DDIV:
14316 check_insn(ctx, ISA_MIPS3);
14317 check_mips_64(ctx);
14318 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14319 break;
14320 case RR_DDIVU:
14321 check_insn(ctx, ISA_MIPS3);
14322 check_mips_64(ctx);
14323 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14324 break;
14325#endif
14326 default:
14327 generate_exception_end(ctx, EXCP_RI);
14328 break;
14329 }
14330 break;
14331 case M16_OPC_EXTEND:
14332 decode_extended_mips16_opc(env, ctx);
14333 n_bytes = 4;
14334 break;
14335#if defined(TARGET_MIPS64)
14336 case M16_OPC_I64:
14337 funct = (ctx->opcode >> 8) & 0x7;
14338 decode_i64_mips16(ctx, ry, funct, offset, 0);
14339 break;
14340#endif
14341 default:
14342 generate_exception_end(ctx, EXCP_RI);
14343 break;
14344 }
14345
14346 return n_bytes;
14347}
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363enum {
14364 POOL32A = 0x00,
14365 POOL16A = 0x01,
14366 LBU16 = 0x02,
14367 MOVE16 = 0x03,
14368 ADDI32 = 0x04,
14369 R6_LUI = 0x04,
14370 AUI = 0x04,
14371 LBU32 = 0x05,
14372 SB32 = 0x06,
14373 LB32 = 0x07,
14374
14375 POOL32B = 0x08,
14376 POOL16B = 0x09,
14377 LHU16 = 0x0a,
14378 ANDI16 = 0x0b,
14379 ADDIU32 = 0x0c,
14380 LHU32 = 0x0d,
14381 SH32 = 0x0e,
14382 LH32 = 0x0f,
14383
14384 POOL32I = 0x10,
14385 POOL16C = 0x11,
14386 LWSP16 = 0x12,
14387 POOL16D = 0x13,
14388 ORI32 = 0x14,
14389 POOL32F = 0x15,
14390 POOL32S = 0x16,
14391 DADDIU32 = 0x17,
14392
14393 POOL32C = 0x18,
14394 LWGP16 = 0x19,
14395 LW16 = 0x1a,
14396 POOL16E = 0x1b,
14397 XORI32 = 0x1c,
14398 JALS32 = 0x1d,
14399 BOVC = 0x1d,
14400 BEQC = 0x1d,
14401 BEQZALC = 0x1d,
14402 ADDIUPC = 0x1e,
14403 PCREL = 0x1e,
14404 BNVC = 0x1f,
14405 BNEC = 0x1f,
14406 BNEZALC = 0x1f,
14407
14408 R6_BEQZC = 0x20,
14409 JIC = 0x20,
14410 POOL16F = 0x21,
14411 SB16 = 0x22,
14412 BEQZ16 = 0x23,
14413 BEQZC16 = 0x23,
14414 SLTI32 = 0x24,
14415 BEQ32 = 0x25,
14416 BC = 0x25,
14417 SWC132 = 0x26,
14418 LWC132 = 0x27,
14419
14420
14421 RES_29 = 0x29,
14422 R6_BNEZC = 0x28,
14423 JIALC = 0x28,
14424 SH16 = 0x2a,
14425 BNEZ16 = 0x2b,
14426 BNEZC16 = 0x2b,
14427 SLTIU32 = 0x2c,
14428 BNE32 = 0x2d,
14429 BALC = 0x2d,
14430 SDC132 = 0x2e,
14431 LDC132 = 0x2f,
14432
14433
14434 RES_31 = 0x31,
14435 BLEZALC = 0x30,
14436 BGEZALC = 0x30,
14437 BGEUC = 0x30,
14438 SWSP16 = 0x32,
14439 B16 = 0x33,
14440 BC16 = 0x33,
14441 ANDI32 = 0x34,
14442 J32 = 0x35,
14443 BGTZC = 0x35,
14444 BLTZC = 0x35,
14445 BLTC = 0x35,
14446 SD32 = 0x36,
14447 LD32 = 0x37,
14448
14449
14450 RES_39 = 0x39,
14451 BGTZALC = 0x38,
14452 BLTZALC = 0x38,
14453 BLTUC = 0x38,
14454 SW16 = 0x3a,
14455 LI16 = 0x3b,
14456 JALX32 = 0x3c,
14457 JAL32 = 0x3d,
14458 BLEZC = 0x3d,
14459 BGEZC = 0x3d,
14460 BGEC = 0x3d,
14461 SW32 = 0x3e,
14462 LW32 = 0x3f
14463};
14464
14465
14466enum {
14467 ADDIUPC_00 = 0x00,
14468 ADDIUPC_01 = 0x01,
14469 ADDIUPC_02 = 0x02,
14470 ADDIUPC_03 = 0x03,
14471 ADDIUPC_04 = 0x04,
14472 ADDIUPC_05 = 0x05,
14473 ADDIUPC_06 = 0x06,
14474 ADDIUPC_07 = 0x07,
14475 AUIPC = 0x1e,
14476 ALUIPC = 0x1f,
14477 LWPC_08 = 0x08,
14478 LWPC_09 = 0x09,
14479 LWPC_0A = 0x0A,
14480 LWPC_0B = 0x0B,
14481 LWPC_0C = 0x0C,
14482 LWPC_0D = 0x0D,
14483 LWPC_0E = 0x0E,
14484 LWPC_0F = 0x0F,
14485};
14486
14487
14488
14489enum {
14490
14491
14492
14493
14494 SLL32 = 0x0,
14495 SRL32 = 0x1,
14496 SRA = 0x2,
14497 ROTR = 0x3,
14498 SELEQZ = 0x5,
14499 SELNEZ = 0x6,
14500 R6_RDHWR = 0x7,
14501
14502 SLLV = 0x0,
14503 SRLV = 0x1,
14504 SRAV = 0x2,
14505 ROTRV = 0x3,
14506 ADD = 0x4,
14507 ADDU32 = 0x5,
14508 SUB = 0x6,
14509 SUBU32 = 0x7,
14510 MUL = 0x8,
14511 AND = 0x9,
14512 OR32 = 0xa,
14513 NOR = 0xb,
14514 XOR32 = 0xc,
14515 SLT = 0xd,
14516 SLTU = 0xe,
14517
14518 MOVN = 0x0,
14519 R6_MUL = 0x0,
14520 MOVZ = 0x1,
14521 MUH = 0x1,
14522 MULU = 0x2,
14523 MUHU = 0x3,
14524 LWXS = 0x4,
14525 R6_DIV = 0x4,
14526 MOD = 0x5,
14527 R6_DIVU = 0x6,
14528 MODU = 0x7,
14529
14530
14531 BREAK32 = 0x07,
14532 INS = 0x0c,
14533 LSA = 0x0f,
14534 ALIGN = 0x1f,
14535 EXT = 0x2c,
14536 POOL32AXF = 0x3c,
14537 SIGRIE = 0x3f
14538};
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555enum {
14556
14557 TEQ = 0x00,
14558 TGE = 0x08,
14559 TGEU = 0x10,
14560 TLT = 0x20,
14561 TLTU = 0x28,
14562 TNE = 0x30,
14563
14564 MFC0 = 0x03,
14565 MTC0 = 0x0b,
14566
14567
14568
14569
14570 MFHI_ACC = 0x0,
14571 MFLO_ACC = 0x1,
14572 MTHI_ACC = 0x2,
14573 MTLO_ACC = 0x3,
14574
14575
14576 MADD_ACC = 0x0,
14577 MADDU_ACC = 0x1,
14578 MSUB_ACC = 0x2,
14579 MSUBU_ACC = 0x3,
14580
14581
14582 MULT_ACC = 0x0,
14583 MULTU_ACC = 0x1,
14584
14585
14586
14587
14588 BITSWAP = 0x0,
14589 SEB = 0x2,
14590 SEH = 0x3,
14591 CLO = 0x4,
14592 CLZ = 0x5,
14593 RDHWR = 0x6,
14594 WSBH = 0x7,
14595 MULT = 0x8,
14596 MULTU = 0x9,
14597 DIV = 0xa,
14598 DIVU = 0xb,
14599 MADD = 0xc,
14600 MADDU = 0xd,
14601 MSUB = 0xe,
14602 MSUBU = 0xf,
14603
14604
14605 MFC2 = 0x4,
14606 MTC2 = 0x5,
14607 MFHC2 = 0x8,
14608 MTHC2 = 0x9,
14609 CFC2 = 0xc,
14610 CTC2 = 0xd,
14611
14612
14613 JALR = 0x0,
14614 JR = 0x0,
14615 JALRC = 0x0,
14616 JRC = 0x0,
14617 JALR_HB = 0x1,
14618 JALRC_HB = 0x1,
14619 JALRS = 0x4,
14620 JALRS_HB = 0x5,
14621
14622
14623 RDPGPR = 0xe,
14624 WRPGPR = 0xf,
14625
14626
14627 TLBP = 0x0,
14628 TLBR = 0x1,
14629 TLBWI = 0x2,
14630 TLBWR = 0x3,
14631 TLBINV = 0x4,
14632 TLBINVF = 0x5,
14633 WAIT = 0x9,
14634 IRET = 0xd,
14635 DERET = 0xe,
14636 ERET = 0xf,
14637
14638
14639 DMT = 0x0,
14640 DVPE = 0x1,
14641 EMT = 0x2,
14642 EVPE = 0x3,
14643
14644
14645 DI = 0x4,
14646 EI = 0x5,
14647
14648
14649 SYNC = 0x6,
14650 SYSCALL = 0x8,
14651 SDBBP = 0xd,
14652
14653
14654 MFHI32 = 0x0,
14655 MFLO32 = 0x1,
14656 MTHI32 = 0x2,
14657 MTLO32 = 0x3,
14658};
14659
14660
14661
14662enum {
14663 LWC2 = 0x0,
14664 LWP = 0x1,
14665 LDP = 0x4,
14666 LWM32 = 0x5,
14667 CACHE = 0x6,
14668 LDM = 0x7,
14669 SWC2 = 0x8,
14670 SWP = 0x9,
14671 SDP = 0xc,
14672 SWM32 = 0xd,
14673 SDM = 0xf
14674};
14675
14676
14677
14678enum {
14679 LWL = 0x0,
14680 SWL = 0x8,
14681 LWR = 0x1,
14682 SWR = 0x9,
14683 PREF = 0x2,
14684 ST_EVA = 0xa,
14685 LL = 0x3,
14686 SC = 0xb,
14687 LDL = 0x4,
14688 SDL = 0xc,
14689 LDR = 0x5,
14690 SDR = 0xd,
14691 LD_EVA = 0x6,
14692 LWU = 0xe,
14693 LLD = 0x7,
14694 SCD = 0xf
14695};
14696
14697
14698
14699enum {
14700 LBUE = 0x0,
14701 LHUE = 0x1,
14702 LWLE = 0x2,
14703 LWRE = 0x3,
14704 LBE = 0x4,
14705 LHE = 0x5,
14706 LLE = 0x6,
14707 LWE = 0x7,
14708};
14709
14710
14711
14712enum {
14713 SWLE = 0x0,
14714 SWRE = 0x1,
14715 PREFE = 0x2,
14716 CACHEE = 0x3,
14717 SBE = 0x4,
14718 SHE = 0x5,
14719 SCE = 0x6,
14720 SWE = 0x7,
14721};
14722
14723
14724
14725enum {
14726
14727 ADD_FMT = 0x0,
14728
14729 SUB_FMT = 0x1,
14730
14731 MUL_FMT = 0x2,
14732
14733 DIV_FMT = 0x3,
14734
14735
14736 MOVN_FMT = 0x0,
14737 RSQRT2_FMT = 0x0,
14738 MOVF_FMT = 0x0,
14739 RINT_FMT = 0x0,
14740 SELNEZ_FMT = 0x0,
14741
14742 MOVZ_FMT = 0x1,
14743 LWXC1 = 0x1,
14744 MOVT_FMT = 0x1,
14745 CLASS_FMT = 0x1,
14746 SELEQZ_FMT = 0x1,
14747
14748 PLL_PS = 0x2,
14749 SWXC1 = 0x2,
14750 SEL_FMT = 0x2,
14751
14752 PLU_PS = 0x3,
14753 LDXC1 = 0x3,
14754
14755 MOVN_FMT_04 = 0x4,
14756 PUL_PS = 0x4,
14757 SDXC1 = 0x4,
14758 RECIP2_FMT = 0x4,
14759
14760 MOVZ_FMT_05 = 0x05,
14761 PUU_PS = 0x5,
14762 LUXC1 = 0x5,
14763
14764 CVT_PS_S = 0x6,
14765 SUXC1 = 0x6,
14766 ADDR_PS = 0x6,
14767 PREFX = 0x6,
14768 MADDF_FMT = 0x6,
14769
14770 MULR_PS = 0x7,
14771 MSUBF_FMT = 0x7,
14772
14773 MADD_S = 0x01,
14774 MADD_D = 0x09,
14775 MADD_PS = 0x11,
14776 ALNV_PS = 0x19,
14777 MSUB_S = 0x21,
14778 MSUB_D = 0x29,
14779 MSUB_PS = 0x31,
14780
14781 NMADD_S = 0x02,
14782 NMADD_D = 0x0a,
14783 NMADD_PS = 0x12,
14784 NMSUB_S = 0x22,
14785 NMSUB_D = 0x2a,
14786 NMSUB_PS = 0x32,
14787
14788 MIN_FMT = 0x3,
14789 MAX_FMT = 0xb,
14790 MINA_FMT = 0x23,
14791 MAXA_FMT = 0x2b,
14792 POOL32FXF = 0x3b,
14793
14794 CABS_COND_FMT = 0x1c,
14795 C_COND_FMT = 0x3c,
14796
14797 CMP_CONDN_S = 0x5,
14798 CMP_CONDN_D = 0x15
14799};
14800
14801
14802
14803enum {
14804 CVT_L = 0x04,
14805 RSQRT_FMT = 0x08,
14806 FLOOR_L = 0x0c,
14807 CVT_PW_PS = 0x1c,
14808 CVT_W = 0x24,
14809 SQRT_FMT = 0x28,
14810 FLOOR_W = 0x2c,
14811 CVT_PS_PW = 0x3c,
14812 CFC1 = 0x40,
14813 RECIP_FMT = 0x48,
14814 CEIL_L = 0x4c,
14815 CTC1 = 0x60,
14816 CEIL_W = 0x6c,
14817 MFC1 = 0x80,
14818 CVT_S_PL = 0x84,
14819 TRUNC_L = 0x8c,
14820 MTC1 = 0xa0,
14821 CVT_S_PU = 0xa4,
14822 TRUNC_W = 0xac,
14823 MFHC1 = 0xc0,
14824 ROUND_L = 0xcc,
14825 MTHC1 = 0xe0,
14826 ROUND_W = 0xec,
14827
14828 MOV_FMT = 0x01,
14829 MOVF = 0x05,
14830 ABS_FMT = 0x0d,
14831 RSQRT1_FMT = 0x1d,
14832 MOVT = 0x25,
14833 NEG_FMT = 0x2d,
14834 CVT_D = 0x4d,
14835 RECIP1_FMT = 0x5d,
14836 CVT_S = 0x6d
14837};
14838
14839
14840
14841enum {
14842 BLTZ = 0x00,
14843 BLTZAL = 0x01,
14844 BGEZ = 0x02,
14845 BGEZAL = 0x03,
14846 BLEZ = 0x04,
14847 BNEZC = 0x05,
14848 BGTZ = 0x06,
14849 BEQZC = 0x07,
14850 TLTI = 0x08,
14851 BC1EQZC = 0x08,
14852 TGEI = 0x09,
14853 BC1NEZC = 0x09,
14854 TLTIU = 0x0a,
14855 BC2EQZC = 0x0a,
14856 TGEIU = 0x0b,
14857 BC2NEZC = 0x0a,
14858 TNEI = 0x0c,
14859 R6_SYNCI = 0x0c,
14860 LUI = 0x0d,
14861 TEQI = 0x0e,
14862 SYNCI = 0x10,
14863 BLTZALS = 0x11,
14864 BGEZALS = 0x13,
14865 BC2F = 0x14,
14866 BC2T = 0x15,
14867 BPOSGE64 = 0x1a,
14868 BPOSGE32 = 0x1b,
14869
14870 BC1F = 0x1c,
14871 BC1T = 0x1d,
14872 BC1ANY2F = 0x1c,
14873 BC1ANY2T = 0x1d,
14874 BC1ANY4F = 0x1e,
14875 BC1ANY4T = 0x1f
14876};
14877
14878
14879
14880enum {
14881 ADDU16 = 0x0,
14882 SUBU16 = 0x1
14883};
14884
14885
14886
14887enum {
14888 SLL16 = 0x0,
14889 SRL16 = 0x1
14890};
14891
14892
14893
14894enum {
14895 NOT16 = 0x00,
14896 XOR16 = 0x04,
14897 AND16 = 0x08,
14898 OR16 = 0x0c,
14899 LWM16 = 0x10,
14900 SWM16 = 0x14,
14901 JR16 = 0x18,
14902 JRC16 = 0x1a,
14903 JALR16 = 0x1c,
14904 JALR16S = 0x1e,
14905 MFHI16 = 0x20,
14906 MFLO16 = 0x24,
14907 BREAK16 = 0x28,
14908 SDBBP16 = 0x2c,
14909 JRADDIUSP = 0x30
14910};
14911
14912
14913
14914enum {
14915 R6_NOT16 = 0x00,
14916 R6_AND16 = 0x01,
14917 R6_LWM16 = 0x02,
14918 R6_JRC16 = 0x03,
14919 MOVEP = 0x04,
14920 MOVEP_05 = 0x05,
14921 MOVEP_06 = 0x06,
14922 MOVEP_07 = 0x07,
14923 R6_XOR16 = 0x08,
14924 R6_OR16 = 0x09,
14925 R6_SWM16 = 0x0a,
14926 JALRC16 = 0x0b,
14927 MOVEP_0C = 0x0c,
14928 MOVEP_0D = 0x0d,
14929 MOVEP_0E = 0x0e,
14930 MOVEP_0F = 0x0f,
14931 JRCADDIUSP = 0x13,
14932 R6_BREAK16 = 0x1b,
14933 R6_SDBBP16 = 0x3b
14934};
14935
14936
14937
14938enum {
14939 ADDIUS5 = 0x0,
14940 ADDIUSP = 0x1
14941};
14942
14943
14944
14945enum {
14946 ADDIUR2 = 0x0,
14947 ADDIUR1SP = 0x1
14948};
14949
14950static int mmreg(int r)
14951{
14952 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14953
14954 return map[r];
14955}
14956
14957
14958static int mmreg2(int r)
14959{
14960 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14961
14962 return map[r];
14963}
14964
14965#define uMIPS_RD(op) ((op >> 7) & 0x7)
14966#define uMIPS_RS(op) ((op >> 4) & 0x7)
14967#define uMIPS_RS2(op) uMIPS_RS(op)
14968#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14969#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14970#define uMIPS_RS5(op) (op & 0x1f)
14971
14972
14973#define SIMM(op, start, width) \
14974 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14975 << (32-width)) \
14976 >> (32-width))
14977
14978#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14979
14980static void gen_addiur1sp(DisasContext *ctx)
14981{
14982 int rd = mmreg(uMIPS_RD(ctx->opcode));
14983
14984 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14985}
14986
14987static void gen_addiur2(DisasContext *ctx)
14988{
14989 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14990 int rd = mmreg(uMIPS_RD(ctx->opcode));
14991 int rs = mmreg(uMIPS_RS(ctx->opcode));
14992
14993 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14994}
14995
14996static void gen_addiusp(DisasContext *ctx)
14997{
14998 int encoded = ZIMM(ctx->opcode, 1, 9);
14999 int decoded;
15000
15001 if (encoded <= 1) {
15002 decoded = 256 + encoded;
15003 } else if (encoded <= 255) {
15004 decoded = encoded;
15005 } else if (encoded <= 509) {
15006 decoded = encoded - 512;
15007 } else {
15008 decoded = encoded - 768;
15009 }
15010
15011 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
15012}
15013
15014static void gen_addius5(DisasContext *ctx)
15015{
15016 int imm = SIMM(ctx->opcode, 1, 4);
15017 int rd = (ctx->opcode >> 5) & 0x1f;
15018
15019 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
15020}
15021
15022static void gen_andi16(DisasContext *ctx)
15023{
15024 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15025 31, 32, 63, 64, 255, 32768, 65535 };
15026 int rd = mmreg(uMIPS_RD(ctx->opcode));
15027 int rs = mmreg(uMIPS_RS(ctx->opcode));
15028 int encoded = ZIMM(ctx->opcode, 0, 4);
15029
15030 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
15031}
15032
15033static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
15034 int base, int16_t offset)
15035{
15036 TCGv t0, t1;
15037 TCGv_i32 t2;
15038
15039 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15040 generate_exception_end(ctx, EXCP_RI);
15041 return;
15042 }
15043
15044 t0 = tcg_temp_new();
15045
15046 gen_base_offset_addr(ctx, t0, base, offset);
15047
15048 t1 = tcg_const_tl(reglist);
15049 t2 = tcg_const_i32(ctx->mem_idx);
15050
15051 save_cpu_state(ctx, 1);
15052 switch (opc) {
15053 case LWM32:
15054 gen_helper_lwm(cpu_env, t0, t1, t2);
15055 break;
15056 case SWM32:
15057 gen_helper_swm(cpu_env, t0, t1, t2);
15058 break;
15059#ifdef TARGET_MIPS64
15060 case LDM:
15061 gen_helper_ldm(cpu_env, t0, t1, t2);
15062 break;
15063 case SDM:
15064 gen_helper_sdm(cpu_env, t0, t1, t2);
15065 break;
15066#endif
15067 }
15068 tcg_temp_free(t0);
15069 tcg_temp_free(t1);
15070 tcg_temp_free_i32(t2);
15071}
15072
15073
15074static void gen_pool16c_insn(DisasContext *ctx)
15075{
15076 int rd = mmreg((ctx->opcode >> 3) & 0x7);
15077 int rs = mmreg(ctx->opcode & 0x7);
15078
15079 switch (((ctx->opcode) >> 4) & 0x3f) {
15080 case NOT16 + 0:
15081 case NOT16 + 1:
15082 case NOT16 + 2:
15083 case NOT16 + 3:
15084 gen_logic(ctx, OPC_NOR, rd, rs, 0);
15085 break;
15086 case XOR16 + 0:
15087 case XOR16 + 1:
15088 case XOR16 + 2:
15089 case XOR16 + 3:
15090 gen_logic(ctx, OPC_XOR, rd, rd, rs);
15091 break;
15092 case AND16 + 0:
15093 case AND16 + 1:
15094 case AND16 + 2:
15095 case AND16 + 3:
15096 gen_logic(ctx, OPC_AND, rd, rd, rs);
15097 break;
15098 case OR16 + 0:
15099 case OR16 + 1:
15100 case OR16 + 2:
15101 case OR16 + 3:
15102 gen_logic(ctx, OPC_OR, rd, rd, rs);
15103 break;
15104 case LWM16 + 0:
15105 case LWM16 + 1:
15106 case LWM16 + 2:
15107 case LWM16 + 3:
15108 {
15109 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15110 int offset = ZIMM(ctx->opcode, 0, 4);
15111
15112 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15113 29, offset << 2);
15114 }
15115 break;
15116 case SWM16 + 0:
15117 case SWM16 + 1:
15118 case SWM16 + 2:
15119 case SWM16 + 3:
15120 {
15121 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15122 int offset = ZIMM(ctx->opcode, 0, 4);
15123
15124 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15125 29, offset << 2);
15126 }
15127 break;
15128 case JR16 + 0:
15129 case JR16 + 1:
15130 {
15131 int reg = ctx->opcode & 0x1f;
15132
15133 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15134 }
15135 break;
15136 case JRC16 + 0:
15137 case JRC16 + 1:
15138 {
15139 int reg = ctx->opcode & 0x1f;
15140 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15141
15142
15143
15144
15145 }
15146 break;
15147 case JALR16 + 0:
15148 case JALR16 + 1:
15149 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15150 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15151 break;
15152 case JALR16S + 0:
15153 case JALR16S + 1:
15154 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15155 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15156 break;
15157 case MFHI16 + 0:
15158 case MFHI16 + 1:
15159 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15160 break;
15161 case MFLO16 + 0:
15162 case MFLO16 + 1:
15163 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15164 break;
15165 case BREAK16:
15166 generate_exception_end(ctx, EXCP_BREAK);
15167 break;
15168 case SDBBP16:
15169 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15170 gen_helper_do_semihosting(cpu_env);
15171 } else {
15172
15173
15174
15175
15176 check_insn(ctx, ISA_MIPS32);
15177 generate_exception_end(ctx, EXCP_DBp);
15178 }
15179 break;
15180 case JRADDIUSP + 0:
15181 case JRADDIUSP + 1:
15182 {
15183 int imm = ZIMM(ctx->opcode, 0, 5);
15184 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15185 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15186
15187
15188
15189
15190 }
15191 break;
15192 default:
15193 generate_exception_end(ctx, EXCP_RI);
15194 break;
15195 }
15196}
15197
15198static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15199 int enc_rs)
15200{
15201 int rd, rs, re, rt;
15202 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15203 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15204 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15205 rd = rd_enc[enc_dest];
15206 re = re_enc[enc_dest];
15207 rs = rs_rt_enc[enc_rs];
15208 rt = rs_rt_enc[enc_rt];
15209 if (rs) {
15210 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15211 } else {
15212 tcg_gen_movi_tl(cpu_gpr[rd], 0);
15213 }
15214 if (rt) {
15215 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15216 } else {
15217 tcg_gen_movi_tl(cpu_gpr[re], 0);
15218 }
15219}
15220
15221static void gen_pool16c_r6_insn(DisasContext *ctx)
15222{
15223 int rt = mmreg((ctx->opcode >> 7) & 0x7);
15224 int rs = mmreg((ctx->opcode >> 4) & 0x7);
15225
15226 switch (ctx->opcode & 0xf) {
15227 case R6_NOT16:
15228 gen_logic(ctx, OPC_NOR, rt, rs, 0);
15229 break;
15230 case R6_AND16:
15231 gen_logic(ctx, OPC_AND, rt, rt, rs);
15232 break;
15233 case R6_LWM16:
15234 {
15235 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15236 int offset = extract32(ctx->opcode, 4, 4);
15237 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15238 }
15239 break;
15240 case R6_JRC16:
15241 if ((ctx->opcode >> 4) & 1) {
15242
15243 int imm = extract32(ctx->opcode, 5, 5);
15244 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15245 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15246 } else {
15247
15248 rs = extract32(ctx->opcode, 5, 5);
15249 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15250 }
15251 break;
15252 case MOVEP:
15253 case MOVEP_05:
15254 case MOVEP_06:
15255 case MOVEP_07:
15256 case MOVEP_0C:
15257 case MOVEP_0D:
15258 case MOVEP_0E:
15259 case MOVEP_0F:
15260 {
15261 int enc_dest = uMIPS_RD(ctx->opcode);
15262 int enc_rt = uMIPS_RS2(ctx->opcode);
15263 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15264 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15265 }
15266 break;
15267 case R6_XOR16:
15268 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15269 break;
15270 case R6_OR16:
15271 gen_logic(ctx, OPC_OR, rt, rt, rs);
15272 break;
15273 case R6_SWM16:
15274 {
15275 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15276 int offset = extract32(ctx->opcode, 4, 4);
15277 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15278 }
15279 break;
15280 case JALRC16:
15281 switch (ctx->opcode & 0x3f) {
15282 case JALRC16:
15283 case JALRC16 + 0x20:
15284
15285 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15286 31, 0, 0);
15287 break;
15288 case R6_BREAK16:
15289
15290 generate_exception(ctx, EXCP_BREAK);
15291 break;
15292 case R6_SDBBP16:
15293
15294 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15295 gen_helper_do_semihosting(cpu_env);
15296 } else {
15297 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15298 generate_exception(ctx, EXCP_RI);
15299 } else {
15300 generate_exception(ctx, EXCP_DBp);
15301 }
15302 }
15303 break;
15304 }
15305 break;
15306 default:
15307 generate_exception(ctx, EXCP_RI);
15308 break;
15309 }
15310}
15311
15312static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
15313{
15314 TCGv t0 = tcg_temp_new();
15315 TCGv t1 = tcg_temp_new();
15316
15317 gen_load_gpr(t0, base);
15318
15319 if (index != 0) {
15320 gen_load_gpr(t1, index);
15321 tcg_gen_shli_tl(t1, t1, 2);
15322 gen_op_addr_add(ctx, t0, t1, t0);
15323 }
15324
15325 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15326 gen_store_gpr(t1, rd);
15327
15328 tcg_temp_free(t0);
15329 tcg_temp_free(t1);
15330}
15331
15332static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
15333 int base, int16_t offset)
15334{
15335 TCGv t0, t1;
15336
15337 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15338 generate_exception_end(ctx, EXCP_RI);
15339 return;
15340 }
15341
15342 t0 = tcg_temp_new();
15343 t1 = tcg_temp_new();
15344
15345 gen_base_offset_addr(ctx, t0, base, offset);
15346
15347 switch (opc) {
15348 case LWP:
15349 if (rd == base) {
15350 generate_exception_end(ctx, EXCP_RI);
15351 return;
15352 }
15353 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15354 gen_store_gpr(t1, rd);
15355 tcg_gen_movi_tl(t1, 4);
15356 gen_op_addr_add(ctx, t0, t0, t1);
15357 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15358 gen_store_gpr(t1, rd + 1);
15359 break;
15360 case SWP:
15361 gen_load_gpr(t1, rd);
15362 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15363 tcg_gen_movi_tl(t1, 4);
15364 gen_op_addr_add(ctx, t0, t0, t1);
15365 gen_load_gpr(t1, rd + 1);
15366 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15367 break;
15368#ifdef TARGET_MIPS64
15369 case LDP:
15370 if (rd == base) {
15371 generate_exception_end(ctx, EXCP_RI);
15372 return;
15373 }
15374 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15375 gen_store_gpr(t1, rd);
15376 tcg_gen_movi_tl(t1, 8);
15377 gen_op_addr_add(ctx, t0, t0, t1);
15378 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15379 gen_store_gpr(t1, rd + 1);
15380 break;
15381 case SDP:
15382 gen_load_gpr(t1, rd);
15383 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15384 tcg_gen_movi_tl(t1, 8);
15385 gen_op_addr_add(ctx, t0, t0, t1);
15386 gen_load_gpr(t1, rd + 1);
15387 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15388 break;
15389#endif
15390 }
15391 tcg_temp_free(t0);
15392 tcg_temp_free(t1);
15393}
15394
15395static void gen_sync(int stype)
15396{
15397 TCGBar tcg_mo = TCG_BAR_SC;
15398
15399 switch (stype) {
15400 case 0x4:
15401 tcg_mo |= TCG_MO_ST_ST;
15402 break;
15403 case 0x10:
15404 tcg_mo |= TCG_MO_ALL;
15405 break;
15406 case 0x11:
15407 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15408 break;
15409 case 0x12:
15410 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15411 break;
15412 case 0x13:
15413 tcg_mo |= TCG_MO_LD_LD;
15414 break;
15415 default:
15416 tcg_mo |= TCG_MO_ALL;
15417 break;
15418 }
15419
15420 tcg_gen_mb(tcg_mo);
15421}
15422
15423static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15424{
15425 int extension = (ctx->opcode >> 6) & 0x3f;
15426 int minor = (ctx->opcode >> 12) & 0xf;
15427 uint32_t mips32_op;
15428
15429 switch (extension) {
15430 case TEQ:
15431 mips32_op = OPC_TEQ;
15432 goto do_trap;
15433 case TGE:
15434 mips32_op = OPC_TGE;
15435 goto do_trap;
15436 case TGEU:
15437 mips32_op = OPC_TGEU;
15438 goto do_trap;
15439 case TLT:
15440 mips32_op = OPC_TLT;
15441 goto do_trap;
15442 case TLTU:
15443 mips32_op = OPC_TLTU;
15444 goto do_trap;
15445 case TNE:
15446 mips32_op = OPC_TNE;
15447 do_trap:
15448 gen_trap(ctx, mips32_op, rs, rt, -1);
15449 break;
15450#ifndef CONFIG_USER_ONLY
15451 case MFC0:
15452 case MFC0 + 32:
15453 check_cp0_enabled(ctx);
15454 if (rt == 0) {
15455
15456 break;
15457 }
15458 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15459 break;
15460 case MTC0:
15461 case MTC0 + 32:
15462 check_cp0_enabled(ctx);
15463 {
15464 TCGv t0 = tcg_temp_new();
15465
15466 gen_load_gpr(t0, rt);
15467 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15468 tcg_temp_free(t0);
15469 }
15470 break;
15471#endif
15472 case 0x2a:
15473 switch (minor & 3) {
15474 case MADD_ACC:
15475 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15476 break;
15477 case MADDU_ACC:
15478 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15479 break;
15480 case MSUB_ACC:
15481 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15482 break;
15483 case MSUBU_ACC:
15484 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15485 break;
15486 default:
15487 goto pool32axf_invalid;
15488 }
15489 break;
15490 case 0x32:
15491 switch (minor & 3) {
15492 case MULT_ACC:
15493 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15494 break;
15495 case MULTU_ACC:
15496 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15497 break;
15498 default:
15499 goto pool32axf_invalid;
15500 }
15501 break;
15502 case 0x2c:
15503 switch (minor) {
15504 case BITSWAP:
15505 check_insn(ctx, ISA_MIPS32R6);
15506 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15507 break;
15508 case SEB:
15509 gen_bshfl(ctx, OPC_SEB, rs, rt);
15510 break;
15511 case SEH:
15512 gen_bshfl(ctx, OPC_SEH, rs, rt);
15513 break;
15514 case CLO:
15515 mips32_op = OPC_CLO;
15516 goto do_cl;
15517 case CLZ:
15518 mips32_op = OPC_CLZ;
15519 do_cl:
15520 check_insn(ctx, ISA_MIPS32);
15521 gen_cl(ctx, mips32_op, rt, rs);
15522 break;
15523 case RDHWR:
15524 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15525 gen_rdhwr(ctx, rt, rs, 0);
15526 break;
15527 case WSBH:
15528 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15529 break;
15530 case MULT:
15531 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15532 mips32_op = OPC_MULT;
15533 goto do_mul;
15534 case MULTU:
15535 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15536 mips32_op = OPC_MULTU;
15537 goto do_mul;
15538 case DIV:
15539 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15540 mips32_op = OPC_DIV;
15541 goto do_div;
15542 case DIVU:
15543 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15544 mips32_op = OPC_DIVU;
15545 goto do_div;
15546 do_div:
15547 check_insn(ctx, ISA_MIPS32);
15548 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15549 break;
15550 case MADD:
15551 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15552 mips32_op = OPC_MADD;
15553 goto do_mul;
15554 case MADDU:
15555 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15556 mips32_op = OPC_MADDU;
15557 goto do_mul;
15558 case MSUB:
15559 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15560 mips32_op = OPC_MSUB;
15561 goto do_mul;
15562 case MSUBU:
15563 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15564 mips32_op = OPC_MSUBU;
15565 do_mul:
15566 check_insn(ctx, ISA_MIPS32);
15567 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15568 break;
15569 default:
15570 goto pool32axf_invalid;
15571 }
15572 break;
15573 case 0x34:
15574 switch (minor) {
15575 case MFC2:
15576 case MTC2:
15577 case MFHC2:
15578 case MTHC2:
15579 case CFC2:
15580 case CTC2:
15581 generate_exception_err(ctx, EXCP_CpU, 2);
15582 break;
15583 default:
15584 goto pool32axf_invalid;
15585 }
15586 break;
15587 case 0x3c:
15588 switch (minor) {
15589 case JALR:
15590 case JALR_HB:
15591 if (ctx->insn_flags & ISA_MIPS32R6) {
15592
15593 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15594 } else {
15595
15596 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15597 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15598 }
15599 break;
15600 case JALRS:
15601 case JALRS_HB:
15602 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15603 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15604 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15605 break;
15606 default:
15607 goto pool32axf_invalid;
15608 }
15609 break;
15610 case 0x05:
15611 switch (minor) {
15612 case RDPGPR:
15613 check_cp0_enabled(ctx);
15614 check_insn(ctx, ISA_MIPS32R2);
15615 gen_load_srsgpr(rs, rt);
15616 break;
15617 case WRPGPR:
15618 check_cp0_enabled(ctx);
15619 check_insn(ctx, ISA_MIPS32R2);
15620 gen_store_srsgpr(rs, rt);
15621 break;
15622 default:
15623 goto pool32axf_invalid;
15624 }
15625 break;
15626#ifndef CONFIG_USER_ONLY
15627 case 0x0d:
15628 switch (minor) {
15629 case TLBP:
15630 mips32_op = OPC_TLBP;
15631 goto do_cp0;
15632 case TLBR:
15633 mips32_op = OPC_TLBR;
15634 goto do_cp0;
15635 case TLBWI:
15636 mips32_op = OPC_TLBWI;
15637 goto do_cp0;
15638 case TLBWR:
15639 mips32_op = OPC_TLBWR;
15640 goto do_cp0;
15641 case TLBINV:
15642 mips32_op = OPC_TLBINV;
15643 goto do_cp0;
15644 case TLBINVF:
15645 mips32_op = OPC_TLBINVF;
15646 goto do_cp0;
15647 case WAIT:
15648 mips32_op = OPC_WAIT;
15649 goto do_cp0;
15650 case DERET:
15651 mips32_op = OPC_DERET;
15652 goto do_cp0;
15653 case ERET:
15654 mips32_op = OPC_ERET;
15655 do_cp0:
15656 gen_cp0(env, ctx, mips32_op, rt, rs);
15657 break;
15658 default:
15659 goto pool32axf_invalid;
15660 }
15661 break;
15662 case 0x1d:
15663 switch (minor) {
15664 case DI:
15665 check_cp0_enabled(ctx);
15666 {
15667 TCGv t0 = tcg_temp_new();
15668
15669 save_cpu_state(ctx, 1);
15670 gen_helper_di(t0, cpu_env);
15671 gen_store_gpr(t0, rs);
15672
15673 ctx->base.is_jmp = DISAS_STOP;
15674 tcg_temp_free(t0);
15675 }
15676 break;
15677 case EI:
15678 check_cp0_enabled(ctx);
15679 {
15680 TCGv t0 = tcg_temp_new();
15681
15682 save_cpu_state(ctx, 1);
15683 gen_helper_ei(t0, cpu_env);
15684 gen_store_gpr(t0, rs);
15685
15686
15687
15688
15689 gen_save_pc(ctx->base.pc_next + 4);
15690 ctx->base.is_jmp = DISAS_EXIT;
15691 tcg_temp_free(t0);
15692 }
15693 break;
15694 default:
15695 goto pool32axf_invalid;
15696 }
15697 break;
15698#endif
15699 case 0x2d:
15700 switch (minor) {
15701 case SYNC:
15702 gen_sync(extract32(ctx->opcode, 16, 5));
15703 break;
15704 case SYSCALL:
15705 generate_exception_end(ctx, EXCP_SYSCALL);
15706 break;
15707 case SDBBP:
15708 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15709 gen_helper_do_semihosting(cpu_env);
15710 } else {
15711 check_insn(ctx, ISA_MIPS32);
15712 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15713 generate_exception_end(ctx, EXCP_RI);
15714 } else {
15715 generate_exception_end(ctx, EXCP_DBp);
15716 }
15717 }
15718 break;
15719 default:
15720 goto pool32axf_invalid;
15721 }
15722 break;
15723 case 0x01:
15724 switch (minor & 3) {
15725 case MFHI_ACC:
15726 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15727 break;
15728 case MFLO_ACC:
15729 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15730 break;
15731 case MTHI_ACC:
15732 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15733 break;
15734 case MTLO_ACC:
15735 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15736 break;
15737 default:
15738 goto pool32axf_invalid;
15739 }
15740 break;
15741 case 0x35:
15742 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15743 switch (minor) {
15744 case MFHI32:
15745 gen_HILO(ctx, OPC_MFHI, 0, rs);
15746 break;
15747 case MFLO32:
15748 gen_HILO(ctx, OPC_MFLO, 0, rs);
15749 break;
15750 case MTHI32:
15751 gen_HILO(ctx, OPC_MTHI, 0, rs);
15752 break;
15753 case MTLO32:
15754 gen_HILO(ctx, OPC_MTLO, 0, rs);
15755 break;
15756 default:
15757 goto pool32axf_invalid;
15758 }
15759 break;
15760 default:
15761 pool32axf_invalid:
15762 MIPS_INVAL("pool32axf");
15763 generate_exception_end(ctx, EXCP_RI);
15764 break;
15765 }
15766}
15767
15768
15769
15770
15771
15772enum {
15773 FMT_SD_S = 0,
15774 FMT_SD_D = 1,
15775
15776 FMT_SDPS_S = 0,
15777 FMT_SDPS_D = 1,
15778 FMT_SDPS_PS = 2,
15779
15780 FMT_SWL_S = 0,
15781 FMT_SWL_W = 1,
15782 FMT_SWL_L = 2,
15783
15784 FMT_DWL_D = 0,
15785 FMT_DWL_W = 1,
15786 FMT_DWL_L = 2
15787};
15788
15789static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15790{
15791 int extension = (ctx->opcode >> 6) & 0x3ff;
15792 uint32_t mips32_op;
15793
15794#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15795#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15796#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15797
15798 switch (extension) {
15799 case FLOAT_1BIT_FMT(CFC1, 0):
15800 mips32_op = OPC_CFC1;
15801 goto do_cp1;
15802 case FLOAT_1BIT_FMT(CTC1, 0):
15803 mips32_op = OPC_CTC1;
15804 goto do_cp1;
15805 case FLOAT_1BIT_FMT(MFC1, 0):
15806 mips32_op = OPC_MFC1;
15807 goto do_cp1;
15808 case FLOAT_1BIT_FMT(MTC1, 0):
15809 mips32_op = OPC_MTC1;
15810 goto do_cp1;
15811 case FLOAT_1BIT_FMT(MFHC1, 0):
15812 mips32_op = OPC_MFHC1;
15813 goto do_cp1;
15814 case FLOAT_1BIT_FMT(MTHC1, 0):
15815 mips32_op = OPC_MTHC1;
15816 do_cp1:
15817 gen_cp1(ctx, mips32_op, rt, rs);
15818 break;
15819
15820
15821 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15822 mips32_op = OPC_RSQRT_S;
15823 goto do_unaryfp;
15824 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15825 mips32_op = OPC_RSQRT_D;
15826 goto do_unaryfp;
15827
15828
15829 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15830 mips32_op = OPC_SQRT_S;
15831 goto do_unaryfp;
15832 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15833 mips32_op = OPC_SQRT_D;
15834 goto do_unaryfp;
15835
15836
15837 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15838 mips32_op = OPC_RECIP_S;
15839 goto do_unaryfp;
15840 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15841 mips32_op = OPC_RECIP_D;
15842 goto do_unaryfp;
15843
15844
15845 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15846 mips32_op = OPC_FLOOR_L_S;
15847 goto do_unaryfp;
15848 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15849 mips32_op = OPC_FLOOR_L_D;
15850 goto do_unaryfp;
15851 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15852 mips32_op = OPC_FLOOR_W_S;
15853 goto do_unaryfp;
15854 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15855 mips32_op = OPC_FLOOR_W_D;
15856 goto do_unaryfp;
15857
15858
15859 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15860 mips32_op = OPC_CEIL_L_S;
15861 goto do_unaryfp;
15862 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15863 mips32_op = OPC_CEIL_L_D;
15864 goto do_unaryfp;
15865 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15866 mips32_op = OPC_CEIL_W_S;
15867 goto do_unaryfp;
15868 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15869 mips32_op = OPC_CEIL_W_D;
15870 goto do_unaryfp;
15871
15872
15873 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15874 mips32_op = OPC_TRUNC_L_S;
15875 goto do_unaryfp;
15876 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15877 mips32_op = OPC_TRUNC_L_D;
15878 goto do_unaryfp;
15879 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15880 mips32_op = OPC_TRUNC_W_S;
15881 goto do_unaryfp;
15882 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15883 mips32_op = OPC_TRUNC_W_D;
15884 goto do_unaryfp;
15885
15886
15887 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15888 mips32_op = OPC_ROUND_L_S;
15889 goto do_unaryfp;
15890 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15891 mips32_op = OPC_ROUND_L_D;
15892 goto do_unaryfp;
15893 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15894 mips32_op = OPC_ROUND_W_S;
15895 goto do_unaryfp;
15896 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15897 mips32_op = OPC_ROUND_W_D;
15898 goto do_unaryfp;
15899
15900
15901 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15902 mips32_op = OPC_CVT_L_S;
15903 goto do_unaryfp;
15904 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15905 mips32_op = OPC_CVT_L_D;
15906 goto do_unaryfp;
15907 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15908 mips32_op = OPC_CVT_W_S;
15909 goto do_unaryfp;
15910 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15911 mips32_op = OPC_CVT_W_D;
15912 goto do_unaryfp;
15913
15914
15915 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15916 mips32_op = OPC_CVT_S_PL;
15917 goto do_unaryfp;
15918 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15919 mips32_op = OPC_CVT_S_PU;
15920 goto do_unaryfp;
15921 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15922 mips32_op = OPC_CVT_PW_PS;
15923 goto do_unaryfp;
15924 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15925 mips32_op = OPC_CVT_PS_PW;
15926 goto do_unaryfp;
15927
15928
15929 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15930 mips32_op = OPC_MOV_S;
15931 goto do_unaryfp;
15932 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15933 mips32_op = OPC_MOV_D;
15934 goto do_unaryfp;
15935 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15936 mips32_op = OPC_MOV_PS;
15937 goto do_unaryfp;
15938
15939
15940 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15941 mips32_op = OPC_ABS_S;
15942 goto do_unaryfp;
15943 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15944 mips32_op = OPC_ABS_D;
15945 goto do_unaryfp;
15946 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15947 mips32_op = OPC_ABS_PS;
15948 goto do_unaryfp;
15949
15950
15951 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15952 mips32_op = OPC_NEG_S;
15953 goto do_unaryfp;
15954 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15955 mips32_op = OPC_NEG_D;
15956 goto do_unaryfp;
15957 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15958 mips32_op = OPC_NEG_PS;
15959 goto do_unaryfp;
15960
15961
15962 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15963 mips32_op = OPC_RSQRT1_S;
15964 goto do_unaryfp;
15965 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15966 mips32_op = OPC_RSQRT1_D;
15967 goto do_unaryfp;
15968 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15969 mips32_op = OPC_RSQRT1_PS;
15970 goto do_unaryfp;
15971
15972
15973 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15974 mips32_op = OPC_RECIP1_S;
15975 goto do_unaryfp;
15976 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15977 mips32_op = OPC_RECIP1_S;
15978 goto do_unaryfp;
15979 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15980 mips32_op = OPC_RECIP1_PS;
15981 goto do_unaryfp;
15982
15983
15984 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15985 mips32_op = OPC_CVT_D_S;
15986 goto do_unaryfp;
15987 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15988 mips32_op = OPC_CVT_D_W;
15989 goto do_unaryfp;
15990 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15991 mips32_op = OPC_CVT_D_L;
15992 goto do_unaryfp;
15993
15994
15995 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15996 mips32_op = OPC_CVT_S_D;
15997 goto do_unaryfp;
15998 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15999 mips32_op = OPC_CVT_S_W;
16000 goto do_unaryfp;
16001 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
16002 mips32_op = OPC_CVT_S_L;
16003 do_unaryfp:
16004 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
16005 break;
16006
16007
16008 case COND_FLOAT_MOV(MOVT, 0):
16009 case COND_FLOAT_MOV(MOVT, 1):
16010 case COND_FLOAT_MOV(MOVT, 2):
16011 case COND_FLOAT_MOV(MOVT, 3):
16012 case COND_FLOAT_MOV(MOVT, 4):
16013 case COND_FLOAT_MOV(MOVT, 5):
16014 case COND_FLOAT_MOV(MOVT, 6):
16015 case COND_FLOAT_MOV(MOVT, 7):
16016 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16017 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
16018 break;
16019 case COND_FLOAT_MOV(MOVF, 0):
16020 case COND_FLOAT_MOV(MOVF, 1):
16021 case COND_FLOAT_MOV(MOVF, 2):
16022 case COND_FLOAT_MOV(MOVF, 3):
16023 case COND_FLOAT_MOV(MOVF, 4):
16024 case COND_FLOAT_MOV(MOVF, 5):
16025 case COND_FLOAT_MOV(MOVF, 6):
16026 case COND_FLOAT_MOV(MOVF, 7):
16027 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16028 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
16029 break;
16030 default:
16031 MIPS_INVAL("pool32fxf");
16032 generate_exception_end(ctx, EXCP_RI);
16033 break;
16034 }
16035}
16036
16037static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
16038{
16039 int32_t offset;
16040 uint16_t insn;
16041 int rt, rs, rd, rr;
16042 int16_t imm;
16043 uint32_t op, minor, minor2, mips32_op;
16044 uint32_t cond, fmt, cc;
16045
16046 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
16047 ctx->opcode = (ctx->opcode << 16) | insn;
16048
16049 rt = (ctx->opcode >> 21) & 0x1f;
16050 rs = (ctx->opcode >> 16) & 0x1f;
16051 rd = (ctx->opcode >> 11) & 0x1f;
16052 rr = (ctx->opcode >> 6) & 0x1f;
16053 imm = (int16_t) ctx->opcode;
16054
16055 op = (ctx->opcode >> 26) & 0x3f;
16056 switch (op) {
16057 case POOL32A:
16058 minor = ctx->opcode & 0x3f;
16059 switch (minor) {
16060 case 0x00:
16061 minor = (ctx->opcode >> 6) & 0xf;
16062 switch (minor) {
16063 case SLL32:
16064 mips32_op = OPC_SLL;
16065 goto do_shifti;
16066 case SRA:
16067 mips32_op = OPC_SRA;
16068 goto do_shifti;
16069 case SRL32:
16070 mips32_op = OPC_SRL;
16071 goto do_shifti;
16072 case ROTR:
16073 mips32_op = OPC_ROTR;
16074 do_shifti:
16075 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
16076 break;
16077 case SELEQZ:
16078 check_insn(ctx, ISA_MIPS32R6);
16079 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
16080 break;
16081 case SELNEZ:
16082 check_insn(ctx, ISA_MIPS32R6);
16083 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
16084 break;
16085 case R6_RDHWR:
16086 check_insn(ctx, ISA_MIPS32R6);
16087 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
16088 break;
16089 default:
16090 goto pool32a_invalid;
16091 }
16092 break;
16093 case 0x10:
16094 minor = (ctx->opcode >> 6) & 0xf;
16095 switch (minor) {
16096
16097 case ADD:
16098 mips32_op = OPC_ADD;
16099 goto do_arith;
16100 case ADDU32:
16101 mips32_op = OPC_ADDU;
16102 goto do_arith;
16103 case SUB:
16104 mips32_op = OPC_SUB;
16105 goto do_arith;
16106 case SUBU32:
16107 mips32_op = OPC_SUBU;
16108 goto do_arith;
16109 case MUL:
16110 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16111 mips32_op = OPC_MUL;
16112 do_arith:
16113 gen_arith(ctx, mips32_op, rd, rs, rt);
16114 break;
16115
16116 case SLLV:
16117 mips32_op = OPC_SLLV;
16118 goto do_shift;
16119 case SRLV:
16120 mips32_op = OPC_SRLV;
16121 goto do_shift;
16122 case SRAV:
16123 mips32_op = OPC_SRAV;
16124 goto do_shift;
16125 case ROTRV:
16126 mips32_op = OPC_ROTRV;
16127 do_shift:
16128 gen_shift(ctx, mips32_op, rd, rs, rt);
16129 break;
16130
16131 case AND:
16132 mips32_op = OPC_AND;
16133 goto do_logic;
16134 case OR32:
16135 mips32_op = OPC_OR;
16136 goto do_logic;
16137 case NOR:
16138 mips32_op = OPC_NOR;
16139 goto do_logic;
16140 case XOR32:
16141 mips32_op = OPC_XOR;
16142 do_logic:
16143 gen_logic(ctx, mips32_op, rd, rs, rt);
16144 break;
16145
16146 case SLT:
16147 mips32_op = OPC_SLT;
16148 goto do_slt;
16149 case SLTU:
16150 mips32_op = OPC_SLTU;
16151 do_slt:
16152 gen_slt(ctx, mips32_op, rd, rs, rt);
16153 break;
16154 default:
16155 goto pool32a_invalid;
16156 }
16157 break;
16158 case 0x18:
16159 minor = (ctx->opcode >> 6) & 0xf;
16160 switch (minor) {
16161
16162 case MOVN:
16163 if (ctx->insn_flags & ISA_MIPS32R6) {
16164
16165 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16166 } else {
16167
16168 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16169 }
16170 break;
16171 case MOVZ:
16172 if (ctx->insn_flags & ISA_MIPS32R6) {
16173
16174 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16175 } else {
16176
16177 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16178 }
16179 break;
16180 case MULU:
16181 check_insn(ctx, ISA_MIPS32R6);
16182 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16183 break;
16184 case MUHU:
16185 check_insn(ctx, ISA_MIPS32R6);
16186 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16187 break;
16188 case LWXS:
16189 if (ctx->insn_flags & ISA_MIPS32R6) {
16190
16191 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16192 } else {
16193
16194 gen_ldxs(ctx, rs, rt, rd);
16195 }
16196 break;
16197 case MOD:
16198 check_insn(ctx, ISA_MIPS32R6);
16199 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16200 break;
16201 case R6_DIVU:
16202 check_insn(ctx, ISA_MIPS32R6);
16203 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16204 break;
16205 case MODU:
16206 check_insn(ctx, ISA_MIPS32R6);
16207 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16208 break;
16209 default:
16210 goto pool32a_invalid;
16211 }
16212 break;
16213 case INS:
16214 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16215 return;
16216 case LSA:
16217 check_insn(ctx, ISA_MIPS32R6);
16218 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16219 extract32(ctx->opcode, 9, 2));
16220 break;
16221 case ALIGN:
16222 check_insn(ctx, ISA_MIPS32R6);
16223 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16224 break;
16225 case EXT:
16226 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16227 return;
16228 case POOL32AXF:
16229 gen_pool32axf(env, ctx, rt, rs);
16230 break;
16231 case BREAK32:
16232 generate_exception_end(ctx, EXCP_BREAK);
16233 break;
16234 case SIGRIE:
16235 check_insn(ctx, ISA_MIPS32R6);
16236 generate_exception_end(ctx, EXCP_RI);
16237 break;
16238 default:
16239 pool32a_invalid:
16240 MIPS_INVAL("pool32a");
16241 generate_exception_end(ctx, EXCP_RI);
16242 break;
16243 }
16244 break;
16245 case POOL32B:
16246 minor = (ctx->opcode >> 12) & 0xf;
16247 switch (minor) {
16248 case CACHE:
16249 check_cp0_enabled(ctx);
16250 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16251 gen_cache_operation(ctx, rt, rs, imm);
16252 }
16253 break;
16254 case LWC2:
16255 case SWC2:
16256
16257 generate_exception_err(ctx, EXCP_CpU, 2);
16258 break;
16259#ifdef TARGET_MIPS64
16260 case LDP:
16261 case SDP:
16262 check_insn(ctx, ISA_MIPS3);
16263 check_mips_64(ctx);
16264#endif
16265
16266 case LWP:
16267 case SWP:
16268 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16269 break;
16270#ifdef TARGET_MIPS64
16271 case LDM:
16272 case SDM:
16273 check_insn(ctx, ISA_MIPS3);
16274 check_mips_64(ctx);
16275#endif
16276
16277 case LWM32:
16278 case SWM32:
16279 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16280 break;
16281 default:
16282 MIPS_INVAL("pool32b");
16283 generate_exception_end(ctx, EXCP_RI);
16284 break;
16285 }
16286 break;
16287 case POOL32F:
16288 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16289 minor = ctx->opcode & 0x3f;
16290 check_cp1_enabled(ctx);
16291 switch (minor) {
16292 case ALNV_PS:
16293 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16294 mips32_op = OPC_ALNV_PS;
16295 goto do_madd;
16296 case MADD_S:
16297 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16298 mips32_op = OPC_MADD_S;
16299 goto do_madd;
16300 case MADD_D:
16301 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16302 mips32_op = OPC_MADD_D;
16303 goto do_madd;
16304 case MADD_PS:
16305 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16306 mips32_op = OPC_MADD_PS;
16307 goto do_madd;
16308 case MSUB_S:
16309 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16310 mips32_op = OPC_MSUB_S;
16311 goto do_madd;
16312 case MSUB_D:
16313 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16314 mips32_op = OPC_MSUB_D;
16315 goto do_madd;
16316 case MSUB_PS:
16317 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16318 mips32_op = OPC_MSUB_PS;
16319 goto do_madd;
16320 case NMADD_S:
16321 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16322 mips32_op = OPC_NMADD_S;
16323 goto do_madd;
16324 case NMADD_D:
16325 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16326 mips32_op = OPC_NMADD_D;
16327 goto do_madd;
16328 case NMADD_PS:
16329 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16330 mips32_op = OPC_NMADD_PS;
16331 goto do_madd;
16332 case NMSUB_S:
16333 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16334 mips32_op = OPC_NMSUB_S;
16335 goto do_madd;
16336 case NMSUB_D:
16337 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16338 mips32_op = OPC_NMSUB_D;
16339 goto do_madd;
16340 case NMSUB_PS:
16341 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16342 mips32_op = OPC_NMSUB_PS;
16343 do_madd:
16344 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16345 break;
16346 case CABS_COND_FMT:
16347 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16348 cond = (ctx->opcode >> 6) & 0xf;
16349 cc = (ctx->opcode >> 13) & 0x7;
16350 fmt = (ctx->opcode >> 10) & 0x3;
16351 switch (fmt) {
16352 case 0x0:
16353 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16354 break;
16355 case 0x1:
16356 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16357 break;
16358 case 0x2:
16359 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16360 break;
16361 default:
16362 goto pool32f_invalid;
16363 }
16364 break;
16365 case C_COND_FMT:
16366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16367 cond = (ctx->opcode >> 6) & 0xf;
16368 cc = (ctx->opcode >> 13) & 0x7;
16369 fmt = (ctx->opcode >> 10) & 0x3;
16370 switch (fmt) {
16371 case 0x0:
16372 gen_cmp_s(ctx, cond, rt, rs, cc);
16373 break;
16374 case 0x1:
16375 gen_cmp_d(ctx, cond, rt, rs, cc);
16376 break;
16377 case 0x2:
16378 gen_cmp_ps(ctx, cond, rt, rs, cc);
16379 break;
16380 default:
16381 goto pool32f_invalid;
16382 }
16383 break;
16384 case CMP_CONDN_S:
16385 check_insn(ctx, ISA_MIPS32R6);
16386 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16387 break;
16388 case CMP_CONDN_D:
16389 check_insn(ctx, ISA_MIPS32R6);
16390 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16391 break;
16392 case POOL32FXF:
16393 gen_pool32fxf(ctx, rt, rs);
16394 break;
16395 case 0x00:
16396
16397 switch ((ctx->opcode >> 6) & 0x7) {
16398 case PLL_PS:
16399 mips32_op = OPC_PLL_PS;
16400 goto do_ps;
16401 case PLU_PS:
16402 mips32_op = OPC_PLU_PS;
16403 goto do_ps;
16404 case PUL_PS:
16405 mips32_op = OPC_PUL_PS;
16406 goto do_ps;
16407 case PUU_PS:
16408 mips32_op = OPC_PUU_PS;
16409 goto do_ps;
16410 case CVT_PS_S:
16411 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16412 mips32_op = OPC_CVT_PS_S;
16413 do_ps:
16414 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16415 break;
16416 default:
16417 goto pool32f_invalid;
16418 }
16419 break;
16420 case MIN_FMT:
16421 check_insn(ctx, ISA_MIPS32R6);
16422 switch ((ctx->opcode >> 9) & 0x3) {
16423 case FMT_SDPS_S:
16424 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16425 break;
16426 case FMT_SDPS_D:
16427 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16428 break;
16429 default:
16430 goto pool32f_invalid;
16431 }
16432 break;
16433 case 0x08:
16434
16435 switch ((ctx->opcode >> 6) & 0x7) {
16436 case LWXC1:
16437 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16438 mips32_op = OPC_LWXC1;
16439 goto do_ldst_cp1;
16440 case SWXC1:
16441 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16442 mips32_op = OPC_SWXC1;
16443 goto do_ldst_cp1;
16444 case LDXC1:
16445 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16446 mips32_op = OPC_LDXC1;
16447 goto do_ldst_cp1;
16448 case SDXC1:
16449 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16450 mips32_op = OPC_SDXC1;
16451 goto do_ldst_cp1;
16452 case LUXC1:
16453 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16454 mips32_op = OPC_LUXC1;
16455 goto do_ldst_cp1;
16456 case SUXC1:
16457 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16458 mips32_op = OPC_SUXC1;
16459 do_ldst_cp1:
16460 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16461 break;
16462 default:
16463 goto pool32f_invalid;
16464 }
16465 break;
16466 case MAX_FMT:
16467 check_insn(ctx, ISA_MIPS32R6);
16468 switch ((ctx->opcode >> 9) & 0x3) {
16469 case FMT_SDPS_S:
16470 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16471 break;
16472 case FMT_SDPS_D:
16473 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16474 break;
16475 default:
16476 goto pool32f_invalid;
16477 }
16478 break;
16479 case 0x18:
16480
16481 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16482 fmt = (ctx->opcode >> 9) & 0x3;
16483 switch ((ctx->opcode >> 6) & 0x7) {
16484 case RSQRT2_FMT:
16485 switch (fmt) {
16486 case FMT_SDPS_S:
16487 mips32_op = OPC_RSQRT2_S;
16488 goto do_3d;
16489 case FMT_SDPS_D:
16490 mips32_op = OPC_RSQRT2_D;
16491 goto do_3d;
16492 case FMT_SDPS_PS:
16493 mips32_op = OPC_RSQRT2_PS;
16494 goto do_3d;
16495 default:
16496 goto pool32f_invalid;
16497 }
16498 break;
16499 case RECIP2_FMT:
16500 switch (fmt) {
16501 case FMT_SDPS_S:
16502 mips32_op = OPC_RECIP2_S;
16503 goto do_3d;
16504 case FMT_SDPS_D:
16505 mips32_op = OPC_RECIP2_D;
16506 goto do_3d;
16507 case FMT_SDPS_PS:
16508 mips32_op = OPC_RECIP2_PS;
16509 goto do_3d;
16510 default:
16511 goto pool32f_invalid;
16512 }
16513 break;
16514 case ADDR_PS:
16515 mips32_op = OPC_ADDR_PS;
16516 goto do_3d;
16517 case MULR_PS:
16518 mips32_op = OPC_MULR_PS;
16519 do_3d:
16520 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16521 break;
16522 default:
16523 goto pool32f_invalid;
16524 }
16525 break;
16526 case 0x20:
16527
16528 cc = (ctx->opcode >> 13) & 0x7;
16529 fmt = (ctx->opcode >> 9) & 0x3;
16530 switch ((ctx->opcode >> 6) & 0x7) {
16531 case MOVF_FMT:
16532 if (ctx->insn_flags & ISA_MIPS32R6) {
16533
16534 switch (fmt) {
16535 case FMT_SDPS_S:
16536 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16537 break;
16538 case FMT_SDPS_D:
16539 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16540 break;
16541 default:
16542 goto pool32f_invalid;
16543 }
16544 } else {
16545
16546 switch (fmt) {
16547 case FMT_SDPS_S:
16548 gen_movcf_s(ctx, rs, rt, cc, 0);
16549 break;
16550 case FMT_SDPS_D:
16551 gen_movcf_d(ctx, rs, rt, cc, 0);
16552 break;
16553 case FMT_SDPS_PS:
16554 check_ps(ctx);
16555 gen_movcf_ps(ctx, rs, rt, cc, 0);
16556 break;
16557 default:
16558 goto pool32f_invalid;
16559 }
16560 }
16561 break;
16562 case MOVT_FMT:
16563 if (ctx->insn_flags & ISA_MIPS32R6) {
16564
16565 switch (fmt) {
16566 case FMT_SDPS_S:
16567 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16568 break;
16569 case FMT_SDPS_D:
16570 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16571 break;
16572 default:
16573 goto pool32f_invalid;
16574 }
16575 } else {
16576
16577 switch (fmt) {
16578 case FMT_SDPS_S:
16579 gen_movcf_s(ctx, rs, rt, cc, 1);
16580 break;
16581 case FMT_SDPS_D:
16582 gen_movcf_d(ctx, rs, rt, cc, 1);
16583 break;
16584 case FMT_SDPS_PS:
16585 check_ps(ctx);
16586 gen_movcf_ps(ctx, rs, rt, cc, 1);
16587 break;
16588 default:
16589 goto pool32f_invalid;
16590 }
16591 }
16592 break;
16593 case PREFX:
16594 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16595 break;
16596 default:
16597 goto pool32f_invalid;
16598 }
16599 break;
16600#define FINSN_3ARG_SDPS(prfx) \
16601 switch ((ctx->opcode >> 8) & 0x3) { \
16602 case FMT_SDPS_S: \
16603 mips32_op = OPC_##prfx##_S; \
16604 goto do_fpop; \
16605 case FMT_SDPS_D: \
16606 mips32_op = OPC_##prfx##_D; \
16607 goto do_fpop; \
16608 case FMT_SDPS_PS: \
16609 check_ps(ctx); \
16610 mips32_op = OPC_##prfx##_PS; \
16611 goto do_fpop; \
16612 default: \
16613 goto pool32f_invalid; \
16614 }
16615 case MINA_FMT:
16616 check_insn(ctx, ISA_MIPS32R6);
16617 switch ((ctx->opcode >> 9) & 0x3) {
16618 case FMT_SDPS_S:
16619 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16620 break;
16621 case FMT_SDPS_D:
16622 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16623 break;
16624 default:
16625 goto pool32f_invalid;
16626 }
16627 break;
16628 case MAXA_FMT:
16629 check_insn(ctx, ISA_MIPS32R6);
16630 switch ((ctx->opcode >> 9) & 0x3) {
16631 case FMT_SDPS_S:
16632 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16633 break;
16634 case FMT_SDPS_D:
16635 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16636 break;
16637 default:
16638 goto pool32f_invalid;
16639 }
16640 break;
16641 case 0x30:
16642
16643 switch ((ctx->opcode >> 6) & 0x3) {
16644 case ADD_FMT:
16645 FINSN_3ARG_SDPS(ADD);
16646 break;
16647 case SUB_FMT:
16648 FINSN_3ARG_SDPS(SUB);
16649 break;
16650 case MUL_FMT:
16651 FINSN_3ARG_SDPS(MUL);
16652 break;
16653 case DIV_FMT:
16654 fmt = (ctx->opcode >> 8) & 0x3;
16655 if (fmt == 1) {
16656 mips32_op = OPC_DIV_D;
16657 } else if (fmt == 0) {
16658 mips32_op = OPC_DIV_S;
16659 } else {
16660 goto pool32f_invalid;
16661 }
16662 goto do_fpop;
16663 default:
16664 goto pool32f_invalid;
16665 }
16666 break;
16667 case 0x38:
16668
16669 switch ((ctx->opcode >> 6) & 0x7) {
16670 case MOVN_FMT:
16671 if (ctx->insn_flags & ISA_MIPS32R6) {
16672
16673 switch ((ctx->opcode >> 9) & 0x3) {
16674 case FMT_SDPS_S:
16675 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16676 break;
16677 case FMT_SDPS_D:
16678 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16679 break;
16680 default:
16681 goto pool32f_invalid;
16682 }
16683 } else {
16684
16685 FINSN_3ARG_SDPS(MOVN);
16686 }
16687 break;
16688 case MOVN_FMT_04:
16689 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16690 FINSN_3ARG_SDPS(MOVN);
16691 break;
16692 case MOVZ_FMT:
16693 if (ctx->insn_flags & ISA_MIPS32R6) {
16694
16695 switch ((ctx->opcode >> 9) & 0x3) {
16696 case FMT_SDPS_S:
16697 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16698 break;
16699 case FMT_SDPS_D:
16700 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16701 break;
16702 default:
16703 goto pool32f_invalid;
16704 }
16705 } else {
16706
16707 FINSN_3ARG_SDPS(MOVZ);
16708 }
16709 break;
16710 case MOVZ_FMT_05:
16711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16712 FINSN_3ARG_SDPS(MOVZ);
16713 break;
16714 case SEL_FMT:
16715 check_insn(ctx, ISA_MIPS32R6);
16716 switch ((ctx->opcode >> 9) & 0x3) {
16717 case FMT_SDPS_S:
16718 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16719 break;
16720 case FMT_SDPS_D:
16721 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16722 break;
16723 default:
16724 goto pool32f_invalid;
16725 }
16726 break;
16727 case MADDF_FMT:
16728 check_insn(ctx, ISA_MIPS32R6);
16729 switch ((ctx->opcode >> 9) & 0x3) {
16730 case FMT_SDPS_S:
16731 mips32_op = OPC_MADDF_S;
16732 goto do_fpop;
16733 case FMT_SDPS_D:
16734 mips32_op = OPC_MADDF_D;
16735 goto do_fpop;
16736 default:
16737 goto pool32f_invalid;
16738 }
16739 break;
16740 case MSUBF_FMT:
16741 check_insn(ctx, ISA_MIPS32R6);
16742 switch ((ctx->opcode >> 9) & 0x3) {
16743 case FMT_SDPS_S:
16744 mips32_op = OPC_MSUBF_S;
16745 goto do_fpop;
16746 case FMT_SDPS_D:
16747 mips32_op = OPC_MSUBF_D;
16748 goto do_fpop;
16749 default:
16750 goto pool32f_invalid;
16751 }
16752 break;
16753 default:
16754 goto pool32f_invalid;
16755 }
16756 break;
16757 do_fpop:
16758 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16759 break;
16760 default:
16761 pool32f_invalid:
16762 MIPS_INVAL("pool32f");
16763 generate_exception_end(ctx, EXCP_RI);
16764 break;
16765 }
16766 } else {
16767 generate_exception_err(ctx, EXCP_CpU, 1);
16768 }
16769 break;
16770 case POOL32I:
16771 minor = (ctx->opcode >> 21) & 0x1f;
16772 switch (minor) {
16773 case BLTZ:
16774 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16775 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16776 break;
16777 case BLTZAL:
16778 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16779 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16780 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16781 break;
16782 case BLTZALS:
16783 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16784 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16785 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16786 break;
16787 case BGEZ:
16788 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16789 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16790 break;
16791 case BGEZAL:
16792 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16793 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16794 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16795 break;
16796 case BGEZALS:
16797 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16798 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16799 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16800 break;
16801 case BLEZ:
16802 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16803 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16804 break;
16805 case BGTZ:
16806 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16807 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16808 break;
16809
16810
16811 case TLTI:
16812 if (ctx->insn_flags & ISA_MIPS32R6) {
16813
16814 check_cp1_enabled(ctx);
16815 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16816 } else {
16817
16818 mips32_op = OPC_TLTI;
16819 goto do_trapi;
16820 }
16821 break;
16822 case TGEI:
16823 if (ctx->insn_flags & ISA_MIPS32R6) {
16824
16825 check_cp1_enabled(ctx);
16826 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16827 } else {
16828
16829 mips32_op = OPC_TGEI;
16830 goto do_trapi;
16831 }
16832 break;
16833 case TLTIU:
16834 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16835 mips32_op = OPC_TLTIU;
16836 goto do_trapi;
16837 case TGEIU:
16838 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16839 mips32_op = OPC_TGEIU;
16840 goto do_trapi;
16841 case TNEI:
16842 if (ctx->insn_flags & ISA_MIPS32R6) {
16843
16844
16845
16846
16847
16848 ctx->base.is_jmp = DISAS_STOP;
16849 } else {
16850
16851 mips32_op = OPC_TNEI;
16852 goto do_trapi;
16853 }
16854 break;
16855 case TEQI:
16856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16857 mips32_op = OPC_TEQI;
16858 do_trapi:
16859 gen_trap(ctx, mips32_op, rs, -1, imm);
16860 break;
16861
16862 case BNEZC:
16863 case BEQZC:
16864 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16865 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16866 4, rs, 0, imm << 1, 0);
16867
16868
16869
16870
16871
16872 break;
16873 case LUI:
16874 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16875 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16876 break;
16877 case SYNCI:
16878 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16879
16880
16881
16882
16883 ctx->base.is_jmp = DISAS_STOP;
16884 break;
16885 case BC2F:
16886 case BC2T:
16887 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16888
16889 generate_exception_err(ctx, EXCP_CpU, 2);
16890 break;
16891 case BC1F:
16892 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16893 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16894 goto do_cp1branch;
16895 case BC1T:
16896 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16897 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16898 goto do_cp1branch;
16899 case BC1ANY4F:
16900 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16901 mips32_op = OPC_BC1FANY4;
16902 goto do_cp1mips3d;
16903 case BC1ANY4T:
16904 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16905 mips32_op = OPC_BC1TANY4;
16906 do_cp1mips3d:
16907 check_cop1x(ctx);
16908 check_insn(ctx, ASE_MIPS3D);
16909
16910 do_cp1branch:
16911 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16912 check_cp1_enabled(ctx);
16913 gen_compute_branch1(ctx, mips32_op,
16914 (ctx->opcode >> 18) & 0x7, imm << 1);
16915 } else {
16916 generate_exception_err(ctx, EXCP_CpU, 1);
16917 }
16918 break;
16919 case BPOSGE64:
16920 case BPOSGE32:
16921
16922
16923 default:
16924 MIPS_INVAL("pool32i");
16925 generate_exception_end(ctx, EXCP_RI);
16926 break;
16927 }
16928 break;
16929 case POOL32C:
16930 minor = (ctx->opcode >> 12) & 0xf;
16931 offset = sextract32(ctx->opcode, 0,
16932 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16933 switch (minor) {
16934 case LWL:
16935 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16936 mips32_op = OPC_LWL;
16937 goto do_ld_lr;
16938 case SWL:
16939 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16940 mips32_op = OPC_SWL;
16941 goto do_st_lr;
16942 case LWR:
16943 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16944 mips32_op = OPC_LWR;
16945 goto do_ld_lr;
16946 case SWR:
16947 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16948 mips32_op = OPC_SWR;
16949 goto do_st_lr;
16950#if defined(TARGET_MIPS64)
16951 case LDL:
16952 check_insn(ctx, ISA_MIPS3);
16953 check_mips_64(ctx);
16954 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16955 mips32_op = OPC_LDL;
16956 goto do_ld_lr;
16957 case SDL:
16958 check_insn(ctx, ISA_MIPS3);
16959 check_mips_64(ctx);
16960 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16961 mips32_op = OPC_SDL;
16962 goto do_st_lr;
16963 case LDR:
16964 check_insn(ctx, ISA_MIPS3);
16965 check_mips_64(ctx);
16966 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16967 mips32_op = OPC_LDR;
16968 goto do_ld_lr;
16969 case SDR:
16970 check_insn(ctx, ISA_MIPS3);
16971 check_mips_64(ctx);
16972 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16973 mips32_op = OPC_SDR;
16974 goto do_st_lr;
16975 case LWU:
16976 check_insn(ctx, ISA_MIPS3);
16977 check_mips_64(ctx);
16978 mips32_op = OPC_LWU;
16979 goto do_ld_lr;
16980 case LLD:
16981 check_insn(ctx, ISA_MIPS3);
16982 check_mips_64(ctx);
16983 mips32_op = OPC_LLD;
16984 goto do_ld_lr;
16985#endif
16986 case LL:
16987 mips32_op = OPC_LL;
16988 goto do_ld_lr;
16989 do_ld_lr:
16990 gen_ld(ctx, mips32_op, rt, rs, offset);
16991 break;
16992 do_st_lr:
16993 gen_st(ctx, mips32_op, rt, rs, offset);
16994 break;
16995 case SC:
16996 gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16997 break;
16998#if defined(TARGET_MIPS64)
16999 case SCD:
17000 check_insn(ctx, ISA_MIPS3);
17001 check_mips_64(ctx);
17002 gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
17003 break;
17004#endif
17005 case LD_EVA:
17006 if (!ctx->eva) {
17007 MIPS_INVAL("pool32c ld-eva");
17008 generate_exception_end(ctx, EXCP_RI);
17009 break;
17010 }
17011 check_cp0_enabled(ctx);
17012
17013 minor2 = (ctx->opcode >> 9) & 0x7;
17014 offset = sextract32(ctx->opcode, 0, 9);
17015 switch (minor2) {
17016 case LBUE:
17017 mips32_op = OPC_LBUE;
17018 goto do_ld_lr;
17019 case LHUE:
17020 mips32_op = OPC_LHUE;
17021 goto do_ld_lr;
17022 case LWLE:
17023 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17024 mips32_op = OPC_LWLE;
17025 goto do_ld_lr;
17026 case LWRE:
17027 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17028 mips32_op = OPC_LWRE;
17029 goto do_ld_lr;
17030 case LBE:
17031 mips32_op = OPC_LBE;
17032 goto do_ld_lr;
17033 case LHE:
17034 mips32_op = OPC_LHE;
17035 goto do_ld_lr;
17036 case LLE:
17037 mips32_op = OPC_LLE;
17038 goto do_ld_lr;
17039 case LWE:
17040 mips32_op = OPC_LWE;
17041 goto do_ld_lr;
17042 };
17043 break;
17044 case ST_EVA:
17045 if (!ctx->eva) {
17046 MIPS_INVAL("pool32c st-eva");
17047 generate_exception_end(ctx, EXCP_RI);
17048 break;
17049 }
17050 check_cp0_enabled(ctx);
17051
17052 minor2 = (ctx->opcode >> 9) & 0x7;
17053 offset = sextract32(ctx->opcode, 0, 9);
17054 switch (minor2) {
17055 case SWLE:
17056 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17057 mips32_op = OPC_SWLE;
17058 goto do_st_lr;
17059 case SWRE:
17060 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17061 mips32_op = OPC_SWRE;
17062 goto do_st_lr;
17063 case PREFE:
17064
17065 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17066
17067 generate_exception(ctx, EXCP_RI);
17068 }
17069 break;
17070 case CACHEE:
17071
17072 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17073 gen_cache_operation(ctx, rt, rs, offset);
17074 }
17075 break;
17076 case SBE:
17077 mips32_op = OPC_SBE;
17078 goto do_st_lr;
17079 case SHE:
17080 mips32_op = OPC_SHE;
17081 goto do_st_lr;
17082 case SCE:
17083 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
17084 break;
17085 case SWE:
17086 mips32_op = OPC_SWE;
17087 goto do_st_lr;
17088 };
17089 break;
17090 case PREF:
17091
17092 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17093
17094 generate_exception(ctx, EXCP_RI);
17095 }
17096 break;
17097 default:
17098 MIPS_INVAL("pool32c");
17099 generate_exception_end(ctx, EXCP_RI);
17100 break;
17101 }
17102 break;
17103 case ADDI32:
17104 if (ctx->insn_flags & ISA_MIPS32R6) {
17105
17106 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
17107 } else {
17108
17109 mips32_op = OPC_ADDI;
17110 goto do_addi;
17111 }
17112 break;
17113 case ADDIU32:
17114 mips32_op = OPC_ADDIU;
17115 do_addi:
17116 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
17117 break;
17118
17119
17120 case ORI32:
17121 mips32_op = OPC_ORI;
17122 goto do_logici;
17123 case XORI32:
17124 mips32_op = OPC_XORI;
17125 goto do_logici;
17126 case ANDI32:
17127 mips32_op = OPC_ANDI;
17128 do_logici:
17129 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
17130 break;
17131
17132
17133 case SLTI32:
17134 mips32_op = OPC_SLTI;
17135 goto do_slti;
17136 case SLTIU32:
17137 mips32_op = OPC_SLTIU;
17138 do_slti:
17139 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17140 break;
17141 case JALX32:
17142 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17143 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17144 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17145 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17146 break;
17147 case JALS32:
17148 if (ctx->insn_flags & ISA_MIPS32R6) {
17149 if (rs >= rt) {
17150
17151 mips32_op = OPC_BOVC;
17152 } else if (rs < rt && rs == 0) {
17153
17154 mips32_op = OPC_BEQZALC;
17155 } else {
17156
17157 mips32_op = OPC_BEQC;
17158 }
17159 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17160 } else {
17161
17162 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17163 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17164 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17165 }
17166 break;
17167 case BEQ32:
17168 if (ctx->insn_flags & ISA_MIPS32R6) {
17169
17170 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17171 sextract32(ctx->opcode << 1, 0, 27));
17172 } else {
17173
17174 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17175 }
17176 break;
17177 case BNE32:
17178 if (ctx->insn_flags & ISA_MIPS32R6) {
17179
17180 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17181 sextract32(ctx->opcode << 1, 0, 27));
17182 } else {
17183
17184 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17185 }
17186 break;
17187 case J32:
17188 if (ctx->insn_flags & ISA_MIPS32R6) {
17189 if (rs == 0 && rt != 0) {
17190
17191 mips32_op = OPC_BGTZC;
17192 } else if (rs != 0 && rt != 0 && rs == rt) {
17193
17194 mips32_op = OPC_BLTZC;
17195 } else {
17196
17197 mips32_op = OPC_BLTC;
17198 }
17199 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17200 } else {
17201
17202 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17203 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17204 }
17205 break;
17206 case JAL32:
17207 if (ctx->insn_flags & ISA_MIPS32R6) {
17208 if (rs == 0 && rt != 0) {
17209
17210 mips32_op = OPC_BLEZC;
17211 } else if (rs != 0 && rt != 0 && rs == rt) {
17212
17213 mips32_op = OPC_BGEZC;
17214 } else {
17215
17216 mips32_op = OPC_BGEC;
17217 }
17218 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17219 } else {
17220
17221 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17222 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17223 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17224 }
17225 break;
17226
17227 case LWC132:
17228 mips32_op = OPC_LWC1;
17229 goto do_cop1;
17230 case LDC132:
17231 mips32_op = OPC_LDC1;
17232 goto do_cop1;
17233 case SWC132:
17234 mips32_op = OPC_SWC1;
17235 goto do_cop1;
17236 case SDC132:
17237 mips32_op = OPC_SDC1;
17238 do_cop1:
17239 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17240 break;
17241 case ADDIUPC:
17242 if (ctx->insn_flags & ISA_MIPS32R6) {
17243
17244 switch ((ctx->opcode >> 16) & 0x1f) {
17245 case ADDIUPC_00:
17246 case ADDIUPC_01:
17247 case ADDIUPC_02:
17248 case ADDIUPC_03:
17249 case ADDIUPC_04:
17250 case ADDIUPC_05:
17251 case ADDIUPC_06:
17252 case ADDIUPC_07:
17253 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17254 break;
17255 case AUIPC:
17256 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17257 break;
17258 case ALUIPC:
17259 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17260 break;
17261 case LWPC_08:
17262 case LWPC_09:
17263 case LWPC_0A:
17264 case LWPC_0B:
17265 case LWPC_0C:
17266 case LWPC_0D:
17267 case LWPC_0E:
17268 case LWPC_0F:
17269 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17270 break;
17271 default:
17272 generate_exception(ctx, EXCP_RI);
17273 break;
17274 }
17275 } else {
17276
17277 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17278 offset = SIMM(ctx->opcode, 0, 23) << 2;
17279
17280 gen_addiupc(ctx, reg, offset, 0, 0);
17281 }
17282 break;
17283 case BNVC:
17284 check_insn(ctx, ISA_MIPS32R6);
17285 if (rs >= rt) {
17286
17287 mips32_op = OPC_BNVC;
17288 } else if (rs < rt && rs == 0) {
17289
17290 mips32_op = OPC_BNEZALC;
17291 } else {
17292
17293 mips32_op = OPC_BNEC;
17294 }
17295 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17296 break;
17297 case R6_BNEZC:
17298 check_insn(ctx, ISA_MIPS32R6);
17299 if (rt != 0) {
17300
17301 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17302 sextract32(ctx->opcode << 1, 0, 22));
17303 } else {
17304
17305 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17306 }
17307 break;
17308 case R6_BEQZC:
17309 check_insn(ctx, ISA_MIPS32R6);
17310 if (rt != 0) {
17311
17312 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17313 sextract32(ctx->opcode << 1, 0, 22));
17314 } else {
17315
17316 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17317 }
17318 break;
17319 case BLEZALC:
17320 check_insn(ctx, ISA_MIPS32R6);
17321 if (rs == 0 && rt != 0) {
17322
17323 mips32_op = OPC_BLEZALC;
17324 } else if (rs != 0 && rt != 0 && rs == rt) {
17325
17326 mips32_op = OPC_BGEZALC;
17327 } else {
17328
17329 mips32_op = OPC_BGEUC;
17330 }
17331 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17332 break;
17333 case BGTZALC:
17334 check_insn(ctx, ISA_MIPS32R6);
17335 if (rs == 0 && rt != 0) {
17336
17337 mips32_op = OPC_BGTZALC;
17338 } else if (rs != 0 && rt != 0 && rs == rt) {
17339
17340 mips32_op = OPC_BLTZALC;
17341 } else {
17342
17343 mips32_op = OPC_BLTUC;
17344 }
17345 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17346 break;
17347
17348 case LB32:
17349 mips32_op = OPC_LB;
17350 goto do_ld;
17351 case LBU32:
17352 mips32_op = OPC_LBU;
17353 goto do_ld;
17354 case LH32:
17355 mips32_op = OPC_LH;
17356 goto do_ld;
17357 case LHU32:
17358 mips32_op = OPC_LHU;
17359 goto do_ld;
17360 case LW32:
17361 mips32_op = OPC_LW;
17362 goto do_ld;
17363#ifdef TARGET_MIPS64
17364 case LD32:
17365 check_insn(ctx, ISA_MIPS3);
17366 check_mips_64(ctx);
17367 mips32_op = OPC_LD;
17368 goto do_ld;
17369 case SD32:
17370 check_insn(ctx, ISA_MIPS3);
17371 check_mips_64(ctx);
17372 mips32_op = OPC_SD;
17373 goto do_st;
17374#endif
17375 case SB32:
17376 mips32_op = OPC_SB;
17377 goto do_st;
17378 case SH32:
17379 mips32_op = OPC_SH;
17380 goto do_st;
17381 case SW32:
17382 mips32_op = OPC_SW;
17383 goto do_st;
17384 do_ld:
17385 gen_ld(ctx, mips32_op, rt, rs, imm);
17386 break;
17387 do_st:
17388 gen_st(ctx, mips32_op, rt, rs, imm);
17389 break;
17390 default:
17391 generate_exception_end(ctx, EXCP_RI);
17392 break;
17393 }
17394}
17395
17396static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
17397{
17398 uint32_t op;
17399
17400
17401 if (ctx->base.pc_next & 0x1) {
17402 env->CP0_BadVAddr = ctx->base.pc_next;
17403 generate_exception_end(ctx, EXCP_AdEL);
17404 return 2;
17405 }
17406
17407 op = (ctx->opcode >> 10) & 0x3f;
17408
17409 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17410 switch (op & 0x7) {
17411 case 0:
17412
17413 case 4:
17414
17415 case 5:
17416
17417 case 6:
17418
17419 case 7:
17420
17421 if (ctx->hflags & MIPS_HFLAG_BDS16) {
17422 generate_exception_end(ctx, EXCP_RI);
17423 return 2;
17424 }
17425 break;
17426 case 1:
17427
17428 case 2:
17429
17430 case 3:
17431
17432 if (ctx->hflags & MIPS_HFLAG_BDS32) {
17433 generate_exception_end(ctx, EXCP_RI);
17434 return 2;
17435 }
17436 break;
17437 }
17438 }
17439
17440 switch (op) {
17441 case POOL16A:
17442 {
17443 int rd = mmreg(uMIPS_RD(ctx->opcode));
17444 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17445 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17446 uint32_t opc = 0;
17447
17448 switch (ctx->opcode & 0x1) {
17449 case ADDU16:
17450 opc = OPC_ADDU;
17451 break;
17452 case SUBU16:
17453 opc = OPC_SUBU;
17454 break;
17455 }
17456 if (ctx->insn_flags & ISA_MIPS32R6) {
17457
17458
17459
17460
17461 gen_arith(ctx, opc, rs1, rd, rs2);
17462 } else {
17463 gen_arith(ctx, opc, rd, rs1, rs2);
17464 }
17465 }
17466 break;
17467 case POOL16B:
17468 {
17469 int rd = mmreg(uMIPS_RD(ctx->opcode));
17470 int rs = mmreg(uMIPS_RS(ctx->opcode));
17471 int amount = (ctx->opcode >> 1) & 0x7;
17472 uint32_t opc = 0;
17473 amount = amount == 0 ? 8 : amount;
17474
17475 switch (ctx->opcode & 0x1) {
17476 case SLL16:
17477 opc = OPC_SLL;
17478 break;
17479 case SRL16:
17480 opc = OPC_SRL;
17481 break;
17482 }
17483
17484 gen_shift_imm(ctx, opc, rd, rs, amount);
17485 }
17486 break;
17487 case POOL16C:
17488 if (ctx->insn_flags & ISA_MIPS32R6) {
17489 gen_pool16c_r6_insn(ctx);
17490 } else {
17491 gen_pool16c_insn(ctx);
17492 }
17493 break;
17494 case LWGP16:
17495 {
17496 int rd = mmreg(uMIPS_RD(ctx->opcode));
17497 int rb = 28;
17498 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17499
17500 gen_ld(ctx, OPC_LW, rd, rb, offset);
17501 }
17502 break;
17503 case POOL16F:
17504 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17505 if (ctx->opcode & 1) {
17506 generate_exception_end(ctx, EXCP_RI);
17507 } else {
17508
17509 int enc_dest = uMIPS_RD(ctx->opcode);
17510 int enc_rt = uMIPS_RS2(ctx->opcode);
17511 int enc_rs = uMIPS_RS1(ctx->opcode);
17512 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17513 }
17514 break;
17515 case LBU16:
17516 {
17517 int rd = mmreg(uMIPS_RD(ctx->opcode));
17518 int rb = mmreg(uMIPS_RS(ctx->opcode));
17519 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17520 offset = (offset == 0xf ? -1 : offset);
17521
17522 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17523 }
17524 break;
17525 case LHU16:
17526 {
17527 int rd = mmreg(uMIPS_RD(ctx->opcode));
17528 int rb = mmreg(uMIPS_RS(ctx->opcode));
17529 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17530
17531 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17532 }
17533 break;
17534 case LWSP16:
17535 {
17536 int rd = (ctx->opcode >> 5) & 0x1f;
17537 int rb = 29;
17538 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17539
17540 gen_ld(ctx, OPC_LW, rd, rb, offset);
17541 }
17542 break;
17543 case LW16:
17544 {
17545 int rd = mmreg(uMIPS_RD(ctx->opcode));
17546 int rb = mmreg(uMIPS_RS(ctx->opcode));
17547 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17548
17549 gen_ld(ctx, OPC_LW, rd, rb, offset);
17550 }
17551 break;
17552 case SB16:
17553 {
17554 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17555 int rb = mmreg(uMIPS_RS(ctx->opcode));
17556 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17557
17558 gen_st(ctx, OPC_SB, rd, rb, offset);
17559 }
17560 break;
17561 case SH16:
17562 {
17563 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17564 int rb = mmreg(uMIPS_RS(ctx->opcode));
17565 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17566
17567 gen_st(ctx, OPC_SH, rd, rb, offset);
17568 }
17569 break;
17570 case SWSP16:
17571 {
17572 int rd = (ctx->opcode >> 5) & 0x1f;
17573 int rb = 29;
17574 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17575
17576 gen_st(ctx, OPC_SW, rd, rb, offset);
17577 }
17578 break;
17579 case SW16:
17580 {
17581 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17582 int rb = mmreg(uMIPS_RS(ctx->opcode));
17583 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17584
17585 gen_st(ctx, OPC_SW, rd, rb, offset);
17586 }
17587 break;
17588 case MOVE16:
17589 {
17590 int rd = uMIPS_RD5(ctx->opcode);
17591 int rs = uMIPS_RS5(ctx->opcode);
17592
17593 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17594 }
17595 break;
17596 case ANDI16:
17597 gen_andi16(ctx);
17598 break;
17599 case POOL16D:
17600 switch (ctx->opcode & 0x1) {
17601 case ADDIUS5:
17602 gen_addius5(ctx);
17603 break;
17604 case ADDIUSP:
17605 gen_addiusp(ctx);
17606 break;
17607 }
17608 break;
17609 case POOL16E:
17610 switch (ctx->opcode & 0x1) {
17611 case ADDIUR2:
17612 gen_addiur2(ctx);
17613 break;
17614 case ADDIUR1SP:
17615 gen_addiur1sp(ctx);
17616 break;
17617 }
17618 break;
17619 case B16:
17620 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17621 sextract32(ctx->opcode, 0, 10) << 1,
17622 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17623 break;
17624 case BNEZ16:
17625 case BEQZ16:
17626 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17627 mmreg(uMIPS_RD(ctx->opcode)),
17628 0, sextract32(ctx->opcode, 0, 7) << 1,
17629 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17630
17631 break;
17632 case LI16:
17633 {
17634 int reg = mmreg(uMIPS_RD(ctx->opcode));
17635 int imm = ZIMM(ctx->opcode, 0, 7);
17636
17637 imm = (imm == 0x7f ? -1 : imm);
17638 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17639 }
17640 break;
17641 case RES_29:
17642 case RES_31:
17643 case RES_39:
17644 generate_exception_end(ctx, EXCP_RI);
17645 break;
17646 default:
17647 decode_micromips32_opc(env, ctx);
17648 return 4;
17649 }
17650
17651 return 2;
17652}
17653
17654
17655
17656
17657
17658
17659
17660
17661enum {
17662 NM_P_ADDIU = 0x00,
17663 NM_ADDIUPC = 0x01,
17664 NM_MOVE_BALC = 0x02,
17665 NM_P16_MV = 0x04,
17666 NM_LW16 = 0x05,
17667 NM_BC16 = 0x06,
17668 NM_P16_SR = 0x07,
17669
17670 NM_POOL32A = 0x08,
17671 NM_P_BAL = 0x0a,
17672 NM_P16_SHIFT = 0x0c,
17673 NM_LWSP16 = 0x0d,
17674 NM_BALC16 = 0x0e,
17675 NM_P16_4X4 = 0x0f,
17676
17677 NM_P_GP_W = 0x10,
17678 NM_P_GP_BH = 0x11,
17679 NM_P_J = 0x12,
17680 NM_P16C = 0x14,
17681 NM_LWGP16 = 0x15,
17682 NM_P16_LB = 0x17,
17683
17684 NM_P48I = 0x18,
17685 NM_P16_A1 = 0x1c,
17686 NM_LW4X4 = 0x1d,
17687 NM_P16_LH = 0x1f,
17688
17689 NM_P_U12 = 0x20,
17690 NM_P_LS_U12 = 0x21,
17691 NM_P_BR1 = 0x22,
17692 NM_P16_A2 = 0x24,
17693 NM_SW16 = 0x25,
17694 NM_BEQZC16 = 0x26,
17695
17696 NM_POOL32F = 0x28,
17697 NM_P_LS_S9 = 0x29,
17698 NM_P_BR2 = 0x2a,
17699
17700 NM_P16_ADDU = 0x2c,
17701 NM_SWSP16 = 0x2d,
17702 NM_BNEZC16 = 0x2e,
17703 NM_MOVEP = 0x2f,
17704
17705 NM_POOL32S = 0x30,
17706 NM_P_BRI = 0x32,
17707 NM_LI16 = 0x34,
17708 NM_SWGP16 = 0x35,
17709 NM_P16_BR = 0x36,
17710
17711 NM_P_LUI = 0x38,
17712 NM_ANDI16 = 0x3c,
17713 NM_SW4X4 = 0x3d,
17714 NM_MOVEPREV = 0x3f,
17715};
17716
17717
17718enum {
17719 NM_POOL32A0 = 0x00,
17720 NM_SPECIAL2 = 0x01,
17721 NM_COP2_1 = 0x02,
17722 NM_UDI = 0x03,
17723 NM_POOL32A5 = 0x05,
17724 NM_POOL32A7 = 0x07,
17725};
17726
17727
17728enum {
17729 NM_ADDIUGP_W = 0x00,
17730 NM_LWGP = 0x02,
17731 NM_SWGP = 0x03,
17732};
17733
17734
17735enum {
17736 NM_LI48 = 0x00,
17737 NM_ADDIU48 = 0x01,
17738 NM_ADDIUGP48 = 0x02,
17739 NM_ADDIUPC48 = 0x03,
17740 NM_LWPC48 = 0x0b,
17741 NM_SWPC48 = 0x0f,
17742};
17743
17744
17745enum {
17746 NM_ORI = 0x00,
17747 NM_XORI = 0x01,
17748 NM_ANDI = 0x02,
17749 NM_P_SR = 0x03,
17750 NM_SLTI = 0x04,
17751 NM_SLTIU = 0x05,
17752 NM_SEQI = 0x06,
17753 NM_ADDIUNEG = 0x08,
17754 NM_P_SHIFT = 0x0c,
17755 NM_P_ROTX = 0x0d,
17756 NM_P_INS = 0x0e,
17757 NM_P_EXT = 0x0f,
17758};
17759
17760
17761enum {
17762 NM_POOL32F_0 = 0x00,
17763 NM_POOL32F_3 = 0x03,
17764 NM_POOL32F_5 = 0x05,
17765};
17766
17767
17768enum {
17769 NM_POOL32S_0 = 0x00,
17770 NM_POOL32S_4 = 0x04,
17771};
17772
17773
17774enum {
17775 NM_LUI = 0x00,
17776 NM_ALUIPC = 0x01,
17777};
17778
17779
17780enum {
17781 NM_LBGP = 0x00,
17782 NM_SBGP = 0x01,
17783 NM_LBUGP = 0x02,
17784 NM_ADDIUGP_B = 0x03,
17785 NM_P_GP_LH = 0x04,
17786 NM_P_GP_SH = 0x05,
17787 NM_P_GP_CP1 = 0x06,
17788};
17789
17790
17791enum {
17792 NM_LB = 0x00,
17793 NM_SB = 0x01,
17794 NM_LBU = 0x02,
17795 NM_P_PREFU12 = 0x03,
17796 NM_LH = 0x04,
17797 NM_SH = 0x05,
17798 NM_LHU = 0x06,
17799 NM_LWU = 0x07,
17800 NM_LW = 0x08,
17801 NM_SW = 0x09,
17802 NM_LWC1 = 0x0a,
17803 NM_SWC1 = 0x0b,
17804 NM_LDC1 = 0x0e,
17805 NM_SDC1 = 0x0f,
17806};
17807
17808
17809enum {
17810 NM_P_LS_S0 = 0x00,
17811 NM_P_LS_S1 = 0x01,
17812 NM_P_LS_E0 = 0x02,
17813 NM_P_LS_WM = 0x04,
17814 NM_P_LS_UAWM = 0x05,
17815};
17816
17817
17818enum {
17819 NM_BC = 0x00,
17820 NM_BALC = 0x01,
17821};
17822
17823
17824enum {
17825 NM_JALRC = 0x00,
17826 NM_JALRC_HB = 0x01,
17827 NM_P_BALRSC = 0x08,
17828};
17829
17830
17831enum {
17832 NM_BEQC = 0x00,
17833 NM_P_BR3A = 0x01,
17834 NM_BGEC = 0x02,
17835 NM_BGEUC = 0x03,
17836};
17837
17838
17839enum {
17840 NM_BNEC = 0x00,
17841 NM_BLTC = 0x02,
17842 NM_BLTUC = 0x03,
17843};
17844
17845
17846enum {
17847 NM_BEQIC = 0x00,
17848 NM_BBEQZC = 0x01,
17849 NM_BGEIC = 0x02,
17850 NM_BGEIUC = 0x03,
17851 NM_BNEIC = 0x04,
17852 NM_BBNEZC = 0x05,
17853 NM_BLTIC = 0x06,
17854 NM_BLTIUC = 0x07,
17855};
17856
17857
17858enum {
17859 NM_SLL16 = 0x00,
17860 NM_SRL16 = 0x01,
17861};
17862
17863
17864enum {
17865 NM_POOL16C_0 = 0x00,
17866 NM_LWXS16 = 0x01,
17867};
17868
17869
17870enum {
17871 NM_ADDIUR1SP = 0x01,
17872};
17873
17874
17875enum {
17876 NM_ADDIUR2 = 0x00,
17877 NM_P_ADDIURS5 = 0x01,
17878};
17879
17880
17881enum {
17882 NM_ADDU16 = 0x00,
17883 NM_SUBU16 = 0x01,
17884};
17885
17886
17887enum {
17888 NM_SAVE16 = 0x00,
17889 NM_RESTORE_JRC16 = 0x01,
17890};
17891
17892
17893enum {
17894 NM_ADDU4X4 = 0x00,
17895 NM_MUL4X4 = 0x01,
17896};
17897
17898
17899enum {
17900 NM_LB16 = 0x00,
17901 NM_SB16 = 0x01,
17902 NM_LBU16 = 0x02,
17903};
17904
17905
17906enum {
17907 NM_LH16 = 0x00,
17908 NM_SH16 = 0x01,
17909 NM_LHU16 = 0x02,
17910};
17911
17912
17913enum {
17914 NM_SIGRIE = 0x00,
17915 NM_P_SYSCALL = 0x01,
17916 NM_BREAK = 0x02,
17917 NM_SDBBP = 0x03,
17918};
17919
17920
17921enum {
17922 NM_P_TRAP = 0x00,
17923 NM_SEB = 0x01,
17924 NM_SLLV = 0x02,
17925 NM_MUL = 0x03,
17926 NM_MFC0 = 0x06,
17927 NM_MFHC0 = 0x07,
17928 NM_SEH = 0x09,
17929 NM_SRLV = 0x0a,
17930 NM_MUH = 0x0b,
17931 NM_MTC0 = 0x0e,
17932 NM_MTHC0 = 0x0f,
17933 NM_SRAV = 0x12,
17934 NM_MULU = 0x13,
17935 NM_ROTRV = 0x1a,
17936 NM_MUHU = 0x1b,
17937 NM_ADD = 0x22,
17938 NM_DIV = 0x23,
17939 NM_ADDU = 0x2a,
17940 NM_MOD = 0x2b,
17941 NM_SUB = 0x32,
17942 NM_DIVU = 0x33,
17943 NM_RDHWR = 0x38,
17944 NM_SUBU = 0x3a,
17945 NM_MODU = 0x3b,
17946 NM_P_CMOVE = 0x42,
17947 NM_FORK = 0x45,
17948 NM_MFTR = 0x46,
17949 NM_MFHTR = 0x47,
17950 NM_AND = 0x4a,
17951 NM_YIELD = 0x4d,
17952 NM_MTTR = 0x4e,
17953 NM_MTHTR = 0x4f,
17954 NM_OR = 0x52,
17955 NM_D_E_MT_VPE = 0x56,
17956 NM_NOR = 0x5a,
17957 NM_XOR = 0x62,
17958 NM_SLT = 0x6a,
17959 NM_P_SLTU = 0x72,
17960 NM_SOV = 0x7a,
17961};
17962
17963
17964enum {
17965 NM_CRC32B = 0x00,
17966 NM_CRC32H = 0x01,
17967 NM_CRC32W = 0x02,
17968 NM_CRC32CB = 0x04,
17969 NM_CRC32CH = 0x05,
17970 NM_CRC32CW = 0x06,
17971};
17972
17973
17974enum {
17975 NM_CMP_EQ_PH = 0x00,
17976 NM_CMP_LT_PH = 0x08,
17977 NM_CMP_LE_PH = 0x10,
17978 NM_CMPGU_EQ_QB = 0x18,
17979 NM_CMPGU_LT_QB = 0x20,
17980 NM_CMPGU_LE_QB = 0x28,
17981 NM_CMPGDU_EQ_QB = 0x30,
17982 NM_CMPGDU_LT_QB = 0x38,
17983 NM_CMPGDU_LE_QB = 0x40,
17984 NM_CMPU_EQ_QB = 0x48,
17985 NM_CMPU_LT_QB = 0x50,
17986 NM_CMPU_LE_QB = 0x58,
17987 NM_ADDQ_S_W = 0x60,
17988 NM_SUBQ_S_W = 0x68,
17989 NM_ADDSC = 0x70,
17990 NM_ADDWC = 0x78,
17991
17992 NM_ADDQ_S_PH = 0x01,
17993 NM_ADDQH_R_PH = 0x09,
17994 NM_ADDQH_R_W = 0x11,
17995 NM_ADDU_S_QB = 0x19,
17996 NM_ADDU_S_PH = 0x21,
17997 NM_ADDUH_R_QB = 0x29,
17998 NM_SHRAV_R_PH = 0x31,
17999 NM_SHRAV_R_QB = 0x39,
18000 NM_SUBQ_S_PH = 0x41,
18001 NM_SUBQH_R_PH = 0x49,
18002 NM_SUBQH_R_W = 0x51,
18003 NM_SUBU_S_QB = 0x59,
18004 NM_SUBU_S_PH = 0x61,
18005 NM_SUBUH_R_QB = 0x69,
18006 NM_SHLLV_S_PH = 0x71,
18007 NM_PRECR_SRA_R_PH_W = 0x79,
18008
18009 NM_MULEU_S_PH_QBL = 0x12,
18010 NM_MULEU_S_PH_QBR = 0x1a,
18011 NM_MULQ_RS_PH = 0x22,
18012 NM_MULQ_S_PH = 0x2a,
18013 NM_MULQ_RS_W = 0x32,
18014 NM_MULQ_S_W = 0x3a,
18015 NM_APPEND = 0x42,
18016 NM_MODSUB = 0x52,
18017 NM_SHRAV_R_W = 0x5a,
18018 NM_SHRLV_PH = 0x62,
18019 NM_SHRLV_QB = 0x6a,
18020 NM_SHLLV_QB = 0x72,
18021 NM_SHLLV_S_W = 0x7a,
18022
18023 NM_SHILO = 0x03,
18024
18025 NM_MULEQ_S_W_PHL = 0x04,
18026 NM_MULEQ_S_W_PHR = 0x0c,
18027
18028 NM_MUL_S_PH = 0x05,
18029 NM_PRECR_QB_PH = 0x0d,
18030 NM_PRECRQ_QB_PH = 0x15,
18031 NM_PRECRQ_PH_W = 0x1d,
18032 NM_PRECRQ_RS_PH_W = 0x25,
18033 NM_PRECRQU_S_QB_PH = 0x2d,
18034 NM_PACKRL_PH = 0x35,
18035 NM_PICK_QB = 0x3d,
18036 NM_PICK_PH = 0x45,
18037
18038 NM_SHRA_R_W = 0x5e,
18039 NM_SHRA_R_PH = 0x66,
18040 NM_SHLL_S_PH = 0x76,
18041 NM_SHLL_S_W = 0x7e,
18042
18043 NM_REPL_PH = 0x07
18044};
18045
18046
18047enum {
18048 NM_P_LSX = 0x00,
18049 NM_LSA = 0x01,
18050 NM_EXTW = 0x03,
18051 NM_POOL32AXF = 0x07,
18052};
18053
18054
18055enum {
18056 NM_PP_SR = 0x00,
18057 NM_P_SR_F = 0x01,
18058};
18059
18060
18061enum {
18062 NM_P_SLL = 0x00,
18063 NM_SRL = 0x02,
18064 NM_SRA = 0x04,
18065 NM_ROTR = 0x06,
18066};
18067
18068
18069enum {
18070 NM_ROTX = 0x00,
18071};
18072
18073
18074enum {
18075 NM_INS = 0x00,
18076};
18077
18078
18079enum {
18080 NM_EXT = 0x00,
18081};
18082
18083
18084enum {
18085 NM_RINT_S = 0x04,
18086 NM_RINT_D = 0x44,
18087 NM_ADD_S = 0x06,
18088 NM_SELEQZ_S = 0x07,
18089 NM_SELEQZ_D = 0x47,
18090 NM_CLASS_S = 0x0c,
18091 NM_CLASS_D = 0x4c,
18092 NM_SUB_S = 0x0e,
18093 NM_SELNEZ_S = 0x0f,
18094 NM_SELNEZ_D = 0x4f,
18095 NM_MUL_S = 0x16,
18096 NM_SEL_S = 0x17,
18097 NM_SEL_D = 0x57,
18098 NM_DIV_S = 0x1e,
18099 NM_ADD_D = 0x26,
18100 NM_SUB_D = 0x2e,
18101 NM_MUL_D = 0x36,
18102 NM_MADDF_S = 0x37,
18103 NM_MADDF_D = 0x77,
18104 NM_DIV_D = 0x3e,
18105 NM_MSUBF_S = 0x3f,
18106 NM_MSUBF_D = 0x7f,
18107};
18108
18109
18110enum {
18111 NM_MIN_FMT = 0x00,
18112 NM_MAX_FMT = 0x01,
18113 NM_MINA_FMT = 0x04,
18114 NM_MAXA_FMT = 0x05,
18115 NM_POOL32FXF = 0x07,
18116};
18117
18118
18119enum {
18120 NM_CMP_CONDN_S = 0x00,
18121 NM_CMP_CONDN_D = 0x02,
18122};
18123
18124
18125enum {
18126 NM_LHGP = 0x00,
18127 NM_LHUGP = 0x01,
18128};
18129
18130
18131enum {
18132 NM_SHGP = 0x00,
18133};
18134
18135
18136enum {
18137 NM_LWC1GP = 0x00,
18138 NM_SWC1GP = 0x01,
18139 NM_LDC1GP = 0x02,
18140 NM_SDC1GP = 0x03,
18141};
18142
18143
18144enum {
18145 NM_LBS9 = 0x00,
18146 NM_LHS9 = 0x04,
18147 NM_LWS9 = 0x08,
18148 NM_LDS9 = 0x0c,
18149
18150 NM_SBS9 = 0x01,
18151 NM_SHS9 = 0x05,
18152 NM_SWS9 = 0x09,
18153 NM_SDS9 = 0x0d,
18154
18155 NM_LBUS9 = 0x02,
18156 NM_LHUS9 = 0x06,
18157 NM_LWC1S9 = 0x0a,
18158 NM_LDC1S9 = 0x0e,
18159
18160 NM_P_PREFS9 = 0x03,
18161 NM_LWUS9 = 0x07,
18162 NM_SWC1S9 = 0x0b,
18163 NM_SDC1S9 = 0x0f,
18164};
18165
18166
18167enum {
18168 NM_ASET_ACLR = 0x02,
18169 NM_UALH = 0x04,
18170 NM_UASH = 0x05,
18171 NM_CACHE = 0x07,
18172 NM_P_LL = 0x0a,
18173 NM_P_SC = 0x0b,
18174};
18175
18176
18177enum {
18178 NM_LBE = 0x00,
18179 NM_SBE = 0x01,
18180 NM_LBUE = 0x02,
18181 NM_P_PREFE = 0x03,
18182 NM_LHE = 0x04,
18183 NM_SHE = 0x05,
18184 NM_LHUE = 0x06,
18185 NM_CACHEE = 0x07,
18186 NM_LWE = 0x08,
18187 NM_SWE = 0x09,
18188 NM_P_LLE = 0x0a,
18189 NM_P_SCE = 0x0b,
18190};
18191
18192
18193enum {
18194 NM_SYNCIE = 0x00,
18195 NM_PREFE = 0x01,
18196};
18197
18198
18199enum {
18200 NM_LLE = 0x00,
18201 NM_LLWPE = 0x01,
18202};
18203
18204
18205enum {
18206 NM_SCE = 0x00,
18207 NM_SCWPE = 0x01,
18208};
18209
18210
18211enum {
18212 NM_LWM = 0x00,
18213 NM_SWM = 0x01,
18214};
18215
18216
18217enum {
18218 NM_UALWM = 0x00,
18219 NM_UASWM = 0x01,
18220};
18221
18222
18223enum {
18224 NM_BC1EQZC = 0x00,
18225 NM_BC1NEZC = 0x01,
18226 NM_BC2EQZC = 0x02,
18227 NM_BC2NEZC = 0x03,
18228 NM_BPOSGE32C = 0x04,
18229};
18230
18231
18232enum {
18233 NM_P16_SYSCALL = 0x01,
18234 NM_BREAK16 = 0x02,
18235 NM_SDBBP16 = 0x03,
18236};
18237
18238
18239enum {
18240 NM_POOL16C_00 = 0x00,
18241};
18242
18243
18244enum {
18245 NM_JRC = 0x00,
18246 NM_JALRC16 = 0x01,
18247};
18248
18249
18250enum {
18251 NM_SYSCALL = 0x00,
18252 NM_HYPCALL = 0x01,
18253};
18254
18255
18256enum {
18257 NM_TEQ = 0x00,
18258 NM_TNE = 0x01,
18259};
18260
18261
18262enum {
18263 NM_MOVZ = 0x00,
18264 NM_MOVN = 0x01,
18265};
18266
18267
18268enum {
18269 NM_POOL32AXF_1 = 0x01,
18270 NM_POOL32AXF_2 = 0x02,
18271 NM_POOL32AXF_4 = 0x04,
18272 NM_POOL32AXF_5 = 0x05,
18273 NM_POOL32AXF_7 = 0x07,
18274};
18275
18276
18277enum {
18278 NM_POOL32AXF_1_0 = 0x00,
18279 NM_POOL32AXF_1_1 = 0x01,
18280 NM_POOL32AXF_1_3 = 0x03,
18281 NM_POOL32AXF_1_4 = 0x04,
18282 NM_POOL32AXF_1_5 = 0x05,
18283 NM_POOL32AXF_1_7 = 0x07,
18284};
18285
18286
18287enum {
18288 NM_POOL32AXF_2_0_7 = 0x00,
18289 NM_POOL32AXF_2_8_15 = 0x01,
18290 NM_POOL32AXF_2_16_23 = 0x02,
18291 NM_POOL32AXF_2_24_31 = 0x03,
18292};
18293
18294
18295enum {
18296 NM_SHRA_R_QB = 0x0,
18297 NM_SHRL_PH = 0x1,
18298 NM_REPL_QB = 0x2,
18299};
18300
18301
18302enum {
18303 NM_MFHI = 0x0,
18304 NM_MFLO = 0x1,
18305 NM_MTHI = 0x2,
18306 NM_MTLO = 0x3,
18307};
18308
18309
18310enum {
18311 NM_MTHLIP = 0x0,
18312 NM_SHILOV = 0x1,
18313};
18314
18315
18316enum {
18317 NM_RDDSP = 0x0,
18318 NM_WRDSP = 0x1,
18319 NM_EXTP = 0x2,
18320 NM_EXTPDP = 0x3,
18321};
18322
18323
18324enum {
18325 NM_SHLL_QB = 0x0,
18326 NM_SHRL_QB = 0x1,
18327};
18328
18329
18330enum {
18331 NM_MAQ_S_W_PHR = 0x0,
18332 NM_MAQ_S_W_PHL = 0x1,
18333 NM_MAQ_SA_W_PHR = 0x2,
18334 NM_MAQ_SA_W_PHL = 0x3,
18335};
18336
18337
18338enum {
18339 NM_EXTR_W = 0x0,
18340 NM_EXTR_R_W = 0x1,
18341 NM_EXTR_RS_W = 0x2,
18342 NM_EXTR_S_H = 0x3,
18343};
18344
18345
18346enum {
18347 NM_DPA_W_PH = 0x0,
18348 NM_DPAQ_S_W_PH = 0x1,
18349 NM_DPS_W_PH = 0x2,
18350 NM_DPSQ_S_W_PH = 0x3,
18351 NM_BALIGN = 0x4,
18352 NM_MADD = 0x5,
18353 NM_MULT = 0x6,
18354 NM_EXTRV_W = 0x7,
18355};
18356
18357
18358enum {
18359 NM_DPAX_W_PH = 0x0,
18360 NM_DPAQ_SA_L_W = 0x1,
18361 NM_DPSX_W_PH = 0x2,
18362 NM_DPSQ_SA_L_W = 0x3,
18363 NM_MADDU = 0x5,
18364 NM_MULTU = 0x6,
18365 NM_EXTRV_R_W = 0x7,
18366};
18367
18368
18369enum {
18370 NM_DPAU_H_QBL = 0x0,
18371 NM_DPAQX_S_W_PH = 0x1,
18372 NM_DPSU_H_QBL = 0x2,
18373 NM_DPSQX_S_W_PH = 0x3,
18374 NM_EXTPV = 0x4,
18375 NM_MSUB = 0x5,
18376 NM_MULSA_W_PH = 0x6,
18377 NM_EXTRV_RS_W = 0x7,
18378};
18379
18380
18381enum {
18382 NM_DPAU_H_QBR = 0x0,
18383 NM_DPAQX_SA_W_PH = 0x1,
18384 NM_DPSU_H_QBR = 0x2,
18385 NM_DPSQX_SA_W_PH = 0x3,
18386 NM_EXTPDPV = 0x4,
18387 NM_MSUBU = 0x5,
18388 NM_MULSAQ_S_W_PH = 0x6,
18389 NM_EXTRV_S_H = 0x7,
18390};
18391
18392
18393enum {
18394 NM_CLO = 0x25,
18395 NM_CLZ = 0x2d,
18396
18397 NM_TLBP = 0x01,
18398 NM_TLBR = 0x09,
18399 NM_TLBWI = 0x11,
18400 NM_TLBWR = 0x19,
18401 NM_TLBINV = 0x03,
18402 NM_TLBINVF = 0x0b,
18403 NM_DI = 0x23,
18404 NM_EI = 0x2b,
18405 NM_RDPGPR = 0x70,
18406 NM_WRPGPR = 0x78,
18407 NM_WAIT = 0x61,
18408 NM_DERET = 0x71,
18409 NM_ERETX = 0x79,
18410
18411
18412 NM_ABSQ_S_QB = 0x00,
18413 NM_ABSQ_S_PH = 0x08,
18414 NM_ABSQ_S_W = 0x10,
18415 NM_PRECEQ_W_PHL = 0x28,
18416 NM_PRECEQ_W_PHR = 0x30,
18417 NM_PRECEQU_PH_QBL = 0x38,
18418 NM_PRECEQU_PH_QBR = 0x48,
18419 NM_PRECEU_PH_QBL = 0x58,
18420 NM_PRECEU_PH_QBR = 0x68,
18421 NM_PRECEQU_PH_QBLA = 0x39,
18422 NM_PRECEQU_PH_QBRA = 0x49,
18423 NM_PRECEU_PH_QBLA = 0x59,
18424 NM_PRECEU_PH_QBRA = 0x69,
18425 NM_REPLV_PH = 0x01,
18426 NM_REPLV_QB = 0x09,
18427 NM_BITREV = 0x18,
18428 NM_INSV = 0x20,
18429 NM_RADDU_W_QB = 0x78,
18430
18431 NM_BITSWAP = 0x05,
18432 NM_WSBH = 0x3d,
18433};
18434
18435
18436enum {
18437 NM_SAVE = 0x00,
18438 NM_RESTORE = 0x02,
18439 NM_RESTORE_JRC = 0x03,
18440};
18441
18442
18443enum {
18444 NM_SAVEF = 0x00,
18445 NM_RESTOREF = 0x01,
18446};
18447
18448
18449enum {
18450 NM_SYSCALL16 = 0x00,
18451 NM_HYPCALL16 = 0x01,
18452};
18453
18454
18455enum {
18456 NM_NOT16 = 0x00,
18457 NM_XOR16 = 0x01,
18458 NM_AND16 = 0x02,
18459 NM_OR16 = 0x03,
18460};
18461
18462
18463enum {
18464 NM_LBX = 0x00,
18465 NM_LHX = 0x04,
18466 NM_LWX = 0x08,
18467 NM_LDX = 0x0c,
18468
18469 NM_SBX = 0x01,
18470 NM_SHX = 0x05,
18471 NM_SWX = 0x09,
18472 NM_SDX = 0x0d,
18473
18474 NM_LBUX = 0x02,
18475 NM_LHUX = 0x06,
18476 NM_LWC1X = 0x0a,
18477 NM_LDC1X = 0x0e,
18478
18479 NM_LWUX = 0x07,
18480 NM_SWC1X = 0x0b,
18481 NM_SDC1X = 0x0f,
18482
18483 NM_LHXS = 0x04,
18484 NM_LWXS = 0x08,
18485 NM_LDXS = 0x0c,
18486
18487 NM_SHXS = 0x05,
18488 NM_SWXS = 0x09,
18489 NM_SDXS = 0x0d,
18490
18491 NM_LHUXS = 0x06,
18492 NM_LWC1XS = 0x0a,
18493 NM_LDC1XS = 0x0e,
18494
18495 NM_LWUXS = 0x07,
18496 NM_SWC1XS = 0x0b,
18497 NM_SDC1XS = 0x0f,
18498};
18499
18500
18501enum {
18502 NM_ERET = 0x00,
18503 NM_ERETNC = 0x01,
18504};
18505
18506
18507enum {
18508 NM_CFC1 = 0x40,
18509 NM_CTC1 = 0x60,
18510 NM_MFC1 = 0x80,
18511 NM_MTC1 = 0xa0,
18512 NM_MFHC1 = 0xc0,
18513 NM_MTHC1 = 0xe0,
18514
18515 NM_CVT_S_PL = 0x84,
18516 NM_CVT_S_PU = 0xa4,
18517
18518 NM_CVT_L_S = 0x004,
18519 NM_CVT_L_D = 0x104,
18520 NM_CVT_W_S = 0x024,
18521 NM_CVT_W_D = 0x124,
18522
18523 NM_RSQRT_S = 0x008,
18524 NM_RSQRT_D = 0x108,
18525
18526 NM_SQRT_S = 0x028,
18527 NM_SQRT_D = 0x128,
18528
18529 NM_RECIP_S = 0x048,
18530 NM_RECIP_D = 0x148,
18531
18532 NM_FLOOR_L_S = 0x00c,
18533 NM_FLOOR_L_D = 0x10c,
18534
18535 NM_FLOOR_W_S = 0x02c,
18536 NM_FLOOR_W_D = 0x12c,
18537
18538 NM_CEIL_L_S = 0x04c,
18539 NM_CEIL_L_D = 0x14c,
18540 NM_CEIL_W_S = 0x06c,
18541 NM_CEIL_W_D = 0x16c,
18542 NM_TRUNC_L_S = 0x08c,
18543 NM_TRUNC_L_D = 0x18c,
18544 NM_TRUNC_W_S = 0x0ac,
18545 NM_TRUNC_W_D = 0x1ac,
18546 NM_ROUND_L_S = 0x0cc,
18547 NM_ROUND_L_D = 0x1cc,
18548 NM_ROUND_W_S = 0x0ec,
18549 NM_ROUND_W_D = 0x1ec,
18550
18551 NM_MOV_S = 0x01,
18552 NM_MOV_D = 0x81,
18553 NM_ABS_S = 0x0d,
18554 NM_ABS_D = 0x8d,
18555 NM_NEG_S = 0x2d,
18556 NM_NEG_D = 0xad,
18557 NM_CVT_D_S = 0x04d,
18558 NM_CVT_D_W = 0x0cd,
18559 NM_CVT_D_L = 0x14d,
18560 NM_CVT_S_D = 0x06d,
18561 NM_CVT_S_W = 0x0ed,
18562 NM_CVT_S_L = 0x16d,
18563};
18564
18565
18566enum {
18567 NM_LL = 0x00,
18568 NM_LLWP = 0x01,
18569};
18570
18571
18572enum {
18573 NM_SC = 0x00,
18574 NM_SCWP = 0x01,
18575};
18576
18577
18578enum {
18579 NM_DVP = 0x00,
18580 NM_EVP = 0x01,
18581};
18582
18583
18584
18585
18586
18587
18588
18589
18590
18591
18592
18593#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18594#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18595#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18596#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18597#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18598
18599
18600static inline int decode_gpr_gpr3(int r)
18601{
18602 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18603
18604 return map[r & 0x7];
18605}
18606
18607
18608static inline int decode_gpr_gpr3_src_store(int r)
18609{
18610 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18611
18612 return map[r & 0x7];
18613}
18614
18615
18616static inline int decode_gpr_gpr4(int r)
18617{
18618 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18619 16, 17, 18, 19, 20, 21, 22, 23 };
18620
18621 return map[r & 0xf];
18622}
18623
18624
18625static inline int decode_gpr_gpr4_zero(int r)
18626{
18627 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18628 16, 17, 18, 19, 20, 21, 22, 23 };
18629
18630 return map[r & 0xf];
18631}
18632
18633
18634static void gen_adjust_sp(DisasContext *ctx, int u)
18635{
18636 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18637}
18638
18639static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18640 uint8_t gp, uint16_t u)
18641{
18642 int counter = 0;
18643 TCGv va = tcg_temp_new();
18644 TCGv t0 = tcg_temp_new();
18645
18646 while (counter != count) {
18647 bool use_gp = gp && (counter == count - 1);
18648 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18649 int this_offset = -((counter + 1) << 2);
18650 gen_base_offset_addr(ctx, va, 29, this_offset);
18651 gen_load_gpr(t0, this_rt);
18652 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18653 (MO_TEUL | ctx->default_tcg_memop_mask));
18654 counter++;
18655 }
18656
18657
18658 gen_adjust_sp(ctx, -u);
18659
18660 tcg_temp_free(t0);
18661 tcg_temp_free(va);
18662}
18663
18664static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18665 uint8_t gp, uint16_t u)
18666{
18667 int counter = 0;
18668 TCGv va = tcg_temp_new();
18669 TCGv t0 = tcg_temp_new();
18670
18671 while (counter != count) {
18672 bool use_gp = gp && (counter == count - 1);
18673 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18674 int this_offset = u - ((counter + 1) << 2);
18675 gen_base_offset_addr(ctx, va, 29, this_offset);
18676 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18677 ctx->default_tcg_memop_mask);
18678 tcg_gen_ext32s_tl(t0, t0);
18679 gen_store_gpr(t0, this_rt);
18680 counter++;
18681 }
18682
18683
18684 gen_adjust_sp(ctx, u);
18685
18686 tcg_temp_free(t0);
18687 tcg_temp_free(va);
18688}
18689
18690static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18691{
18692 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18693 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18694
18695 switch (extract32(ctx->opcode, 2, 2)) {
18696 case NM_NOT16:
18697 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18698 break;
18699 case NM_AND16:
18700 gen_logic(ctx, OPC_AND, rt, rt, rs);
18701 break;
18702 case NM_XOR16:
18703 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18704 break;
18705 case NM_OR16:
18706 gen_logic(ctx, OPC_OR, rt, rt, rs);
18707 break;
18708 }
18709}
18710
18711static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18712{
18713 int rt = extract32(ctx->opcode, 21, 5);
18714 int rs = extract32(ctx->opcode, 16, 5);
18715 int rd = extract32(ctx->opcode, 11, 5);
18716
18717 switch (extract32(ctx->opcode, 3, 7)) {
18718 case NM_P_TRAP:
18719 switch (extract32(ctx->opcode, 10, 1)) {
18720 case NM_TEQ:
18721 check_nms(ctx);
18722 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18723 break;
18724 case NM_TNE:
18725 check_nms(ctx);
18726 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18727 break;
18728 }
18729 break;
18730 case NM_RDHWR:
18731 check_nms(ctx);
18732 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18733 break;
18734 case NM_SEB:
18735 check_nms(ctx);
18736 gen_bshfl(ctx, OPC_SEB, rs, rt);
18737 break;
18738 case NM_SEH:
18739 gen_bshfl(ctx, OPC_SEH, rs, rt);
18740 break;
18741 case NM_SLLV:
18742 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18743 break;
18744 case NM_SRLV:
18745 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18746 break;
18747 case NM_SRAV:
18748 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18749 break;
18750 case NM_ROTRV:
18751 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18752 break;
18753 case NM_ADD:
18754 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18755 break;
18756 case NM_ADDU:
18757 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18758 break;
18759 case NM_SUB:
18760 check_nms(ctx);
18761 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18762 break;
18763 case NM_SUBU:
18764 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18765 break;
18766 case NM_P_CMOVE:
18767 switch (extract32(ctx->opcode, 10, 1)) {
18768 case NM_MOVZ:
18769 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18770 break;
18771 case NM_MOVN:
18772 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18773 break;
18774 }
18775 break;
18776 case NM_AND:
18777 gen_logic(ctx, OPC_AND, rd, rs, rt);
18778 break;
18779 case NM_OR:
18780 gen_logic(ctx, OPC_OR, rd, rs, rt);
18781 break;
18782 case NM_NOR:
18783 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18784 break;
18785 case NM_XOR:
18786 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18787 break;
18788 case NM_SLT:
18789 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18790 break;
18791 case NM_P_SLTU:
18792 if (rd == 0) {
18793
18794#ifndef CONFIG_USER_ONLY
18795 TCGv t0 = tcg_temp_new();
18796 switch (extract32(ctx->opcode, 10, 1)) {
18797 case NM_DVP:
18798 if (ctx->vp) {
18799 check_cp0_enabled(ctx);
18800 gen_helper_dvp(t0, cpu_env);
18801 gen_store_gpr(t0, rt);
18802 }
18803 break;
18804 case NM_EVP:
18805 if (ctx->vp) {
18806 check_cp0_enabled(ctx);
18807 gen_helper_evp(t0, cpu_env);
18808 gen_store_gpr(t0, rt);
18809 }
18810 break;
18811 }
18812 tcg_temp_free(t0);
18813#endif
18814 } else {
18815 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18816 }
18817 break;
18818 case NM_SOV:
18819 {
18820 TCGv t0 = tcg_temp_new();
18821 TCGv t1 = tcg_temp_new();
18822 TCGv t2 = tcg_temp_new();
18823
18824 gen_load_gpr(t1, rs);
18825 gen_load_gpr(t2, rt);
18826 tcg_gen_add_tl(t0, t1, t2);
18827 tcg_gen_ext32s_tl(t0, t0);
18828 tcg_gen_xor_tl(t1, t1, t2);
18829 tcg_gen_xor_tl(t2, t0, t2);
18830 tcg_gen_andc_tl(t1, t2, t1);
18831
18832
18833 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18834 gen_store_gpr(t0, rd);
18835
18836 tcg_temp_free(t0);
18837 tcg_temp_free(t1);
18838 tcg_temp_free(t2);
18839 }
18840 break;
18841 case NM_MUL:
18842 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18843 break;
18844 case NM_MUH:
18845 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18846 break;
18847 case NM_MULU:
18848 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18849 break;
18850 case NM_MUHU:
18851 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18852 break;
18853 case NM_DIV:
18854 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18855 break;
18856 case NM_MOD:
18857 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18858 break;
18859 case NM_DIVU:
18860 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18861 break;
18862 case NM_MODU:
18863 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18864 break;
18865#ifndef CONFIG_USER_ONLY
18866 case NM_MFC0:
18867 check_cp0_enabled(ctx);
18868 if (rt == 0) {
18869
18870 break;
18871 }
18872 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18873 break;
18874 case NM_MTC0:
18875 check_cp0_enabled(ctx);
18876 {
18877 TCGv t0 = tcg_temp_new();
18878
18879 gen_load_gpr(t0, rt);
18880 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18881 tcg_temp_free(t0);
18882 }
18883 break;
18884 case NM_D_E_MT_VPE:
18885 {
18886 uint8_t sc = extract32(ctx->opcode, 10, 1);
18887 TCGv t0 = tcg_temp_new();
18888
18889 switch (sc) {
18890 case 0:
18891 if (rs == 1) {
18892
18893 check_cp0_mt(ctx);
18894 gen_helper_dmt(t0);
18895 gen_store_gpr(t0, rt);
18896 } else if (rs == 0) {
18897
18898 check_cp0_mt(ctx);
18899 gen_helper_dvpe(t0, cpu_env);
18900 gen_store_gpr(t0, rt);
18901 } else {
18902 generate_exception_end(ctx, EXCP_RI);
18903 }
18904 break;
18905 case 1:
18906 if (rs == 1) {
18907
18908 check_cp0_mt(ctx);
18909 gen_helper_emt(t0);
18910 gen_store_gpr(t0, rt);
18911 } else if (rs == 0) {
18912
18913 check_cp0_mt(ctx);
18914 gen_helper_evpe(t0, cpu_env);
18915 gen_store_gpr(t0, rt);
18916 } else {
18917 generate_exception_end(ctx, EXCP_RI);
18918 }
18919 break;
18920 }
18921
18922 tcg_temp_free(t0);
18923 }
18924 break;
18925 case NM_FORK:
18926 check_mt(ctx);
18927 {
18928 TCGv t0 = tcg_temp_new();
18929 TCGv t1 = tcg_temp_new();
18930
18931 gen_load_gpr(t0, rt);
18932 gen_load_gpr(t1, rs);
18933 gen_helper_fork(t0, t1);
18934 tcg_temp_free(t0);
18935 tcg_temp_free(t1);
18936 }
18937 break;
18938 case NM_MFTR:
18939 case NM_MFHTR:
18940 check_cp0_enabled(ctx);
18941 if (rd == 0) {
18942
18943 return;
18944 }
18945 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18946 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18947 break;
18948 case NM_MTTR:
18949 case NM_MTHTR:
18950 check_cp0_enabled(ctx);
18951 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18952 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18953 break;
18954 case NM_YIELD:
18955 check_mt(ctx);
18956 {
18957 TCGv t0 = tcg_temp_new();
18958
18959 gen_load_gpr(t0, rs);
18960 gen_helper_yield(t0, cpu_env, t0);
18961 gen_store_gpr(t0, rt);
18962 tcg_temp_free(t0);
18963 }
18964 break;
18965#endif
18966 default:
18967 generate_exception_end(ctx, EXCP_RI);
18968 break;
18969 }
18970}
18971
18972
18973static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18974 int ret, int v1, int v2)
18975{
18976 TCGv_i32 t0;
18977 TCGv v0_t;
18978 TCGv v1_t;
18979
18980 t0 = tcg_temp_new_i32();
18981
18982 v0_t = tcg_temp_new();
18983 v1_t = tcg_temp_new();
18984
18985 tcg_gen_movi_i32(t0, v2 >> 3);
18986
18987 gen_load_gpr(v0_t, ret);
18988 gen_load_gpr(v1_t, v1);
18989
18990 switch (opc) {
18991 case NM_MAQ_S_W_PHR:
18992 check_dsp(ctx);
18993 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18994 break;
18995 case NM_MAQ_S_W_PHL:
18996 check_dsp(ctx);
18997 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18998 break;
18999 case NM_MAQ_SA_W_PHR:
19000 check_dsp(ctx);
19001 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
19002 break;
19003 case NM_MAQ_SA_W_PHL:
19004 check_dsp(ctx);
19005 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
19006 break;
19007 default:
19008 generate_exception_end(ctx, EXCP_RI);
19009 break;
19010 }
19011
19012 tcg_temp_free_i32(t0);
19013
19014 tcg_temp_free(v0_t);
19015 tcg_temp_free(v1_t);
19016}
19017
19018
19019static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
19020 int ret, int v1, int v2)
19021{
19022 int16_t imm;
19023 TCGv t0 = tcg_temp_new();
19024 TCGv t1 = tcg_temp_new();
19025 TCGv v0_t = tcg_temp_new();
19026
19027 gen_load_gpr(v0_t, v1);
19028
19029 switch (opc) {
19030 case NM_POOL32AXF_1_0:
19031 check_dsp(ctx);
19032 switch (extract32(ctx->opcode, 12, 2)) {
19033 case NM_MFHI:
19034 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
19035 break;
19036 case NM_MFLO:
19037 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
19038 break;
19039 case NM_MTHI:
19040 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
19041 break;
19042 case NM_MTLO:
19043 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
19044 break;
19045 }
19046 break;
19047 case NM_POOL32AXF_1_1:
19048 check_dsp(ctx);
19049 switch (extract32(ctx->opcode, 12, 2)) {
19050 case NM_MTHLIP:
19051 tcg_gen_movi_tl(t0, v2);
19052 gen_helper_mthlip(t0, v0_t, cpu_env);
19053 break;
19054 case NM_SHILOV:
19055 tcg_gen_movi_tl(t0, v2 >> 3);
19056 gen_helper_shilo(t0, v0_t, cpu_env);
19057 break;
19058 default:
19059 generate_exception_end(ctx, EXCP_RI);
19060 break;
19061 }
19062 break;
19063 case NM_POOL32AXF_1_3:
19064 check_dsp(ctx);
19065 imm = extract32(ctx->opcode, 14, 7);
19066 switch (extract32(ctx->opcode, 12, 2)) {
19067 case NM_RDDSP:
19068 tcg_gen_movi_tl(t0, imm);
19069 gen_helper_rddsp(t0, t0, cpu_env);
19070 gen_store_gpr(t0, ret);
19071 break;
19072 case NM_WRDSP:
19073 gen_load_gpr(t0, ret);
19074 tcg_gen_movi_tl(t1, imm);
19075 gen_helper_wrdsp(t0, t1, cpu_env);
19076 break;
19077 case NM_EXTP:
19078 tcg_gen_movi_tl(t0, v2 >> 3);
19079 tcg_gen_movi_tl(t1, v1);
19080 gen_helper_extp(t0, t0, t1, cpu_env);
19081 gen_store_gpr(t0, ret);
19082 break;
19083 case NM_EXTPDP:
19084 tcg_gen_movi_tl(t0, v2 >> 3);
19085 tcg_gen_movi_tl(t1, v1);
19086 gen_helper_extpdp(t0, t0, t1, cpu_env);
19087 gen_store_gpr(t0, ret);
19088 break;
19089 }
19090 break;
19091 case NM_POOL32AXF_1_4:
19092 check_dsp(ctx);
19093 tcg_gen_movi_tl(t0, v2 >> 2);
19094 switch (extract32(ctx->opcode, 12, 1)) {
19095 case NM_SHLL_QB:
19096 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
19097 gen_store_gpr(t0, ret);
19098 break;
19099 case NM_SHRL_QB:
19100 gen_helper_shrl_qb(t0, t0, v0_t);
19101 gen_store_gpr(t0, ret);
19102 break;
19103 }
19104 break;
19105 case NM_POOL32AXF_1_5:
19106 opc = extract32(ctx->opcode, 12, 2);
19107 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
19108 break;
19109 case NM_POOL32AXF_1_7:
19110 check_dsp(ctx);
19111 tcg_gen_movi_tl(t0, v2 >> 3);
19112 tcg_gen_movi_tl(t1, v1);
19113 switch (extract32(ctx->opcode, 12, 2)) {
19114 case NM_EXTR_W:
19115 gen_helper_extr_w(t0, t0, t1, cpu_env);
19116 gen_store_gpr(t0, ret);
19117 break;
19118 case NM_EXTR_R_W:
19119 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19120 gen_store_gpr(t0, ret);
19121 break;
19122 case NM_EXTR_RS_W:
19123 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19124 gen_store_gpr(t0, ret);
19125 break;
19126 case NM_EXTR_S_H:
19127 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19128 gen_store_gpr(t0, ret);
19129 break;
19130 }
19131 break;
19132 default:
19133 generate_exception_end(ctx, EXCP_RI);
19134 break;
19135 }
19136
19137 tcg_temp_free(t0);
19138 tcg_temp_free(t1);
19139 tcg_temp_free(v0_t);
19140}
19141
19142static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19143 TCGv v0, TCGv v1, int rd)
19144{
19145 TCGv_i32 t0;
19146
19147 t0 = tcg_temp_new_i32();
19148
19149 tcg_gen_movi_i32(t0, rd >> 3);
19150
19151 switch (opc) {
19152 case NM_POOL32AXF_2_0_7:
19153 switch (extract32(ctx->opcode, 9, 3)) {
19154 case NM_DPA_W_PH:
19155 check_dsp_r2(ctx);
19156 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19157 break;
19158 case NM_DPAQ_S_W_PH:
19159 check_dsp(ctx);
19160 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19161 break;
19162 case NM_DPS_W_PH:
19163 check_dsp_r2(ctx);
19164 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19165 break;
19166 case NM_DPSQ_S_W_PH:
19167 check_dsp(ctx);
19168 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19169 break;
19170 default:
19171 generate_exception_end(ctx, EXCP_RI);
19172 break;
19173 }
19174 break;
19175 case NM_POOL32AXF_2_8_15:
19176 switch (extract32(ctx->opcode, 9, 3)) {
19177 case NM_DPAX_W_PH:
19178 check_dsp_r2(ctx);
19179 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19180 break;
19181 case NM_DPAQ_SA_L_W:
19182 check_dsp(ctx);
19183 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19184 break;
19185 case NM_DPSX_W_PH:
19186 check_dsp_r2(ctx);
19187 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19188 break;
19189 case NM_DPSQ_SA_L_W:
19190 check_dsp(ctx);
19191 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19192 break;
19193 default:
19194 generate_exception_end(ctx, EXCP_RI);
19195 break;
19196 }
19197 break;
19198 case NM_POOL32AXF_2_16_23:
19199 switch (extract32(ctx->opcode, 9, 3)) {
19200 case NM_DPAU_H_QBL:
19201 check_dsp(ctx);
19202 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19203 break;
19204 case NM_DPAQX_S_W_PH:
19205 check_dsp_r2(ctx);
19206 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19207 break;
19208 case NM_DPSU_H_QBL:
19209 check_dsp(ctx);
19210 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19211 break;
19212 case NM_DPSQX_S_W_PH:
19213 check_dsp_r2(ctx);
19214 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19215 break;
19216 case NM_MULSA_W_PH:
19217 check_dsp_r2(ctx);
19218 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19219 break;
19220 default:
19221 generate_exception_end(ctx, EXCP_RI);
19222 break;
19223 }
19224 break;
19225 case NM_POOL32AXF_2_24_31:
19226 switch (extract32(ctx->opcode, 9, 3)) {
19227 case NM_DPAU_H_QBR:
19228 check_dsp(ctx);
19229 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19230 break;
19231 case NM_DPAQX_SA_W_PH:
19232 check_dsp_r2(ctx);
19233 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19234 break;
19235 case NM_DPSU_H_QBR:
19236 check_dsp(ctx);
19237 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19238 break;
19239 case NM_DPSQX_SA_W_PH:
19240 check_dsp_r2(ctx);
19241 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19242 break;
19243 case NM_MULSAQ_S_W_PH:
19244 check_dsp(ctx);
19245 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19246 break;
19247 default:
19248 generate_exception_end(ctx, EXCP_RI);
19249 break;
19250 }
19251 break;
19252 default:
19253 generate_exception_end(ctx, EXCP_RI);
19254 break;
19255 }
19256
19257 tcg_temp_free_i32(t0);
19258}
19259
19260static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19261 int rt, int rs, int rd)
19262{
19263 int ret = rt;
19264 TCGv t0 = tcg_temp_new();
19265 TCGv t1 = tcg_temp_new();
19266 TCGv v0_t = tcg_temp_new();
19267 TCGv v1_t = tcg_temp_new();
19268
19269 gen_load_gpr(v0_t, rt);
19270 gen_load_gpr(v1_t, rs);
19271
19272 switch (opc) {
19273 case NM_POOL32AXF_2_0_7:
19274 switch (extract32(ctx->opcode, 9, 3)) {
19275 case NM_DPA_W_PH:
19276 case NM_DPAQ_S_W_PH:
19277 case NM_DPS_W_PH:
19278 case NM_DPSQ_S_W_PH:
19279 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19280 break;
19281 case NM_BALIGN:
19282 check_dsp_r2(ctx);
19283 if (rt != 0) {
19284 gen_load_gpr(t0, rs);
19285 rd &= 3;
19286 if (rd != 0 && rd != 2) {
19287 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19288 tcg_gen_ext32u_tl(t0, t0);
19289 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19290 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19291 }
19292 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19293 }
19294 break;
19295 case NM_MADD:
19296 check_dsp(ctx);
19297 {
19298 int acc = extract32(ctx->opcode, 14, 2);
19299 TCGv_i64 t2 = tcg_temp_new_i64();
19300 TCGv_i64 t3 = tcg_temp_new_i64();
19301
19302 gen_load_gpr(t0, rt);
19303 gen_load_gpr(t1, rs);
19304 tcg_gen_ext_tl_i64(t2, t0);
19305 tcg_gen_ext_tl_i64(t3, t1);
19306 tcg_gen_mul_i64(t2, t2, t3);
19307 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19308 tcg_gen_add_i64(t2, t2, t3);
19309 tcg_temp_free_i64(t3);
19310 gen_move_low32(cpu_LO[acc], t2);
19311 gen_move_high32(cpu_HI[acc], t2);
19312 tcg_temp_free_i64(t2);
19313 }
19314 break;
19315 case NM_MULT:
19316 check_dsp(ctx);
19317 {
19318 int acc = extract32(ctx->opcode, 14, 2);
19319 TCGv_i32 t2 = tcg_temp_new_i32();
19320 TCGv_i32 t3 = tcg_temp_new_i32();
19321
19322 gen_load_gpr(t0, rs);
19323 gen_load_gpr(t1, rt);
19324 tcg_gen_trunc_tl_i32(t2, t0);
19325 tcg_gen_trunc_tl_i32(t3, t1);
19326 tcg_gen_muls2_i32(t2, t3, t2, t3);
19327 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19328 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19329 tcg_temp_free_i32(t2);
19330 tcg_temp_free_i32(t3);
19331 }
19332 break;
19333 case NM_EXTRV_W:
19334 check_dsp(ctx);
19335 gen_load_gpr(v1_t, rs);
19336 tcg_gen_movi_tl(t0, rd >> 3);
19337 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19338 gen_store_gpr(t0, ret);
19339 break;
19340 }
19341 break;
19342 case NM_POOL32AXF_2_8_15:
19343 switch (extract32(ctx->opcode, 9, 3)) {
19344 case NM_DPAX_W_PH:
19345 case NM_DPAQ_SA_L_W:
19346 case NM_DPSX_W_PH:
19347 case NM_DPSQ_SA_L_W:
19348 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19349 break;
19350 case NM_MADDU:
19351 check_dsp(ctx);
19352 {
19353 int acc = extract32(ctx->opcode, 14, 2);
19354 TCGv_i64 t2 = tcg_temp_new_i64();
19355 TCGv_i64 t3 = tcg_temp_new_i64();
19356
19357 gen_load_gpr(t0, rs);
19358 gen_load_gpr(t1, rt);
19359 tcg_gen_ext32u_tl(t0, t0);
19360 tcg_gen_ext32u_tl(t1, t1);
19361 tcg_gen_extu_tl_i64(t2, t0);
19362 tcg_gen_extu_tl_i64(t3, t1);
19363 tcg_gen_mul_i64(t2, t2, t3);
19364 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19365 tcg_gen_add_i64(t2, t2, t3);
19366 tcg_temp_free_i64(t3);
19367 gen_move_low32(cpu_LO[acc], t2);
19368 gen_move_high32(cpu_HI[acc], t2);
19369 tcg_temp_free_i64(t2);
19370 }
19371 break;
19372 case NM_MULTU:
19373 check_dsp(ctx);
19374 {
19375 int acc = extract32(ctx->opcode, 14, 2);
19376 TCGv_i32 t2 = tcg_temp_new_i32();
19377 TCGv_i32 t3 = tcg_temp_new_i32();
19378
19379 gen_load_gpr(t0, rs);
19380 gen_load_gpr(t1, rt);
19381 tcg_gen_trunc_tl_i32(t2, t0);
19382 tcg_gen_trunc_tl_i32(t3, t1);
19383 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19384 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19385 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19386 tcg_temp_free_i32(t2);
19387 tcg_temp_free_i32(t3);
19388 }
19389 break;
19390 case NM_EXTRV_R_W:
19391 check_dsp(ctx);
19392 tcg_gen_movi_tl(t0, rd >> 3);
19393 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19394 gen_store_gpr(t0, ret);
19395 break;
19396 default:
19397 generate_exception_end(ctx, EXCP_RI);
19398 break;
19399 }
19400 break;
19401 case NM_POOL32AXF_2_16_23:
19402 switch (extract32(ctx->opcode, 9, 3)) {
19403 case NM_DPAU_H_QBL:
19404 case NM_DPAQX_S_W_PH:
19405 case NM_DPSU_H_QBL:
19406 case NM_DPSQX_S_W_PH:
19407 case NM_MULSA_W_PH:
19408 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19409 break;
19410 case NM_EXTPV:
19411 check_dsp(ctx);
19412 tcg_gen_movi_tl(t0, rd >> 3);
19413 gen_helper_extp(t0, t0, v1_t, cpu_env);
19414 gen_store_gpr(t0, ret);
19415 break;
19416 case NM_MSUB:
19417 check_dsp(ctx);
19418 {
19419 int acc = extract32(ctx->opcode, 14, 2);
19420 TCGv_i64 t2 = tcg_temp_new_i64();
19421 TCGv_i64 t3 = tcg_temp_new_i64();
19422
19423 gen_load_gpr(t0, rs);
19424 gen_load_gpr(t1, rt);
19425 tcg_gen_ext_tl_i64(t2, t0);
19426 tcg_gen_ext_tl_i64(t3, t1);
19427 tcg_gen_mul_i64(t2, t2, t3);
19428 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19429 tcg_gen_sub_i64(t2, t3, t2);
19430 tcg_temp_free_i64(t3);
19431 gen_move_low32(cpu_LO[acc], t2);
19432 gen_move_high32(cpu_HI[acc], t2);
19433 tcg_temp_free_i64(t2);
19434 }
19435 break;
19436 case NM_EXTRV_RS_W:
19437 check_dsp(ctx);
19438 tcg_gen_movi_tl(t0, rd >> 3);
19439 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19440 gen_store_gpr(t0, ret);
19441 break;
19442 }
19443 break;
19444 case NM_POOL32AXF_2_24_31:
19445 switch (extract32(ctx->opcode, 9, 3)) {
19446 case NM_DPAU_H_QBR:
19447 case NM_DPAQX_SA_W_PH:
19448 case NM_DPSU_H_QBR:
19449 case NM_DPSQX_SA_W_PH:
19450 case NM_MULSAQ_S_W_PH:
19451 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19452 break;
19453 case NM_EXTPDPV:
19454 check_dsp(ctx);
19455 tcg_gen_movi_tl(t0, rd >> 3);
19456 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19457 gen_store_gpr(t0, ret);
19458 break;
19459 case NM_MSUBU:
19460 check_dsp(ctx);
19461 {
19462 int acc = extract32(ctx->opcode, 14, 2);
19463 TCGv_i64 t2 = tcg_temp_new_i64();
19464 TCGv_i64 t3 = tcg_temp_new_i64();
19465
19466 gen_load_gpr(t0, rs);
19467 gen_load_gpr(t1, rt);
19468 tcg_gen_ext32u_tl(t0, t0);
19469 tcg_gen_ext32u_tl(t1, t1);
19470 tcg_gen_extu_tl_i64(t2, t0);
19471 tcg_gen_extu_tl_i64(t3, t1);
19472 tcg_gen_mul_i64(t2, t2, t3);
19473 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19474 tcg_gen_sub_i64(t2, t3, t2);
19475 tcg_temp_free_i64(t3);
19476 gen_move_low32(cpu_LO[acc], t2);
19477 gen_move_high32(cpu_HI[acc], t2);
19478 tcg_temp_free_i64(t2);
19479 }
19480 break;
19481 case NM_EXTRV_S_H:
19482 check_dsp(ctx);
19483 tcg_gen_movi_tl(t0, rd >> 3);
19484 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19485 gen_store_gpr(t0, ret);
19486 break;
19487 }
19488 break;
19489 default:
19490 generate_exception_end(ctx, EXCP_RI);
19491 break;
19492 }
19493
19494 tcg_temp_free(t0);
19495 tcg_temp_free(t1);
19496
19497 tcg_temp_free(v0_t);
19498 tcg_temp_free(v1_t);
19499}
19500
19501static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19502 int rt, int rs)
19503{
19504 int ret = rt;
19505 TCGv t0 = tcg_temp_new();
19506 TCGv v0_t = tcg_temp_new();
19507
19508 gen_load_gpr(v0_t, rs);
19509
19510 switch (opc) {
19511 case NM_ABSQ_S_QB:
19512 check_dsp_r2(ctx);
19513 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19514 gen_store_gpr(v0_t, ret);
19515 break;
19516 case NM_ABSQ_S_PH:
19517 check_dsp(ctx);
19518 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19519 gen_store_gpr(v0_t, ret);
19520 break;
19521 case NM_ABSQ_S_W:
19522 check_dsp(ctx);
19523 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19524 gen_store_gpr(v0_t, ret);
19525 break;
19526 case NM_PRECEQ_W_PHL:
19527 check_dsp(ctx);
19528 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19529 tcg_gen_ext32s_tl(v0_t, v0_t);
19530 gen_store_gpr(v0_t, ret);
19531 break;
19532 case NM_PRECEQ_W_PHR:
19533 check_dsp(ctx);
19534 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19535 tcg_gen_shli_tl(v0_t, v0_t, 16);
19536 tcg_gen_ext32s_tl(v0_t, v0_t);
19537 gen_store_gpr(v0_t, ret);
19538 break;
19539 case NM_PRECEQU_PH_QBL:
19540 check_dsp(ctx);
19541 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19542 gen_store_gpr(v0_t, ret);
19543 break;
19544 case NM_PRECEQU_PH_QBR:
19545 check_dsp(ctx);
19546 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19547 gen_store_gpr(v0_t, ret);
19548 break;
19549 case NM_PRECEQU_PH_QBLA:
19550 check_dsp(ctx);
19551 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19552 gen_store_gpr(v0_t, ret);
19553 break;
19554 case NM_PRECEQU_PH_QBRA:
19555 check_dsp(ctx);
19556 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19557 gen_store_gpr(v0_t, ret);
19558 break;
19559 case NM_PRECEU_PH_QBL:
19560 check_dsp(ctx);
19561 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19562 gen_store_gpr(v0_t, ret);
19563 break;
19564 case NM_PRECEU_PH_QBR:
19565 check_dsp(ctx);
19566 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19567 gen_store_gpr(v0_t, ret);
19568 break;
19569 case NM_PRECEU_PH_QBLA:
19570 check_dsp(ctx);
19571 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19572 gen_store_gpr(v0_t, ret);
19573 break;
19574 case NM_PRECEU_PH_QBRA:
19575 check_dsp(ctx);
19576 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19577 gen_store_gpr(v0_t, ret);
19578 break;
19579 case NM_REPLV_PH:
19580 check_dsp(ctx);
19581 tcg_gen_ext16u_tl(v0_t, v0_t);
19582 tcg_gen_shli_tl(t0, v0_t, 16);
19583 tcg_gen_or_tl(v0_t, v0_t, t0);
19584 tcg_gen_ext32s_tl(v0_t, v0_t);
19585 gen_store_gpr(v0_t, ret);
19586 break;
19587 case NM_REPLV_QB:
19588 check_dsp(ctx);
19589 tcg_gen_ext8u_tl(v0_t, v0_t);
19590 tcg_gen_shli_tl(t0, v0_t, 8);
19591 tcg_gen_or_tl(v0_t, v0_t, t0);
19592 tcg_gen_shli_tl(t0, v0_t, 16);
19593 tcg_gen_or_tl(v0_t, v0_t, t0);
19594 tcg_gen_ext32s_tl(v0_t, v0_t);
19595 gen_store_gpr(v0_t, ret);
19596 break;
19597 case NM_BITREV:
19598 check_dsp(ctx);
19599 gen_helper_bitrev(v0_t, v0_t);
19600 gen_store_gpr(v0_t, ret);
19601 break;
19602 case NM_INSV:
19603 check_dsp(ctx);
19604 {
19605 TCGv tv0 = tcg_temp_new();
19606
19607 gen_load_gpr(tv0, rt);
19608 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19609 gen_store_gpr(v0_t, ret);
19610 tcg_temp_free(tv0);
19611 }
19612 break;
19613 case NM_RADDU_W_QB:
19614 check_dsp(ctx);
19615 gen_helper_raddu_w_qb(v0_t, v0_t);
19616 gen_store_gpr(v0_t, ret);
19617 break;
19618 case NM_BITSWAP:
19619 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19620 break;
19621 case NM_CLO:
19622 check_nms(ctx);
19623 gen_cl(ctx, OPC_CLO, ret, rs);
19624 break;
19625 case NM_CLZ:
19626 check_nms(ctx);
19627 gen_cl(ctx, OPC_CLZ, ret, rs);
19628 break;
19629 case NM_WSBH:
19630 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19631 break;
19632 default:
19633 generate_exception_end(ctx, EXCP_RI);
19634 break;
19635 }
19636
19637 tcg_temp_free(v0_t);
19638 tcg_temp_free(t0);
19639}
19640
19641static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19642 int rt, int rs, int rd)
19643{
19644 TCGv t0 = tcg_temp_new();
19645 TCGv rs_t = tcg_temp_new();
19646
19647 gen_load_gpr(rs_t, rs);
19648
19649 switch (opc) {
19650 case NM_SHRA_R_QB:
19651 check_dsp_r2(ctx);
19652 tcg_gen_movi_tl(t0, rd >> 2);
19653 switch (extract32(ctx->opcode, 12, 1)) {
19654 case 0:
19655
19656 gen_helper_shra_qb(t0, t0, rs_t);
19657 gen_store_gpr(t0, rt);
19658 break;
19659 case 1:
19660
19661 gen_helper_shra_r_qb(t0, t0, rs_t);
19662 gen_store_gpr(t0, rt);
19663 break;
19664 }
19665 break;
19666 case NM_SHRL_PH:
19667 check_dsp_r2(ctx);
19668 tcg_gen_movi_tl(t0, rd >> 1);
19669 gen_helper_shrl_ph(t0, t0, rs_t);
19670 gen_store_gpr(t0, rt);
19671 break;
19672 case NM_REPL_QB:
19673 check_dsp(ctx);
19674 {
19675 int16_t imm;
19676 target_long result;
19677 imm = extract32(ctx->opcode, 13, 8);
19678 result = (uint32_t)imm << 24 |
19679 (uint32_t)imm << 16 |
19680 (uint32_t)imm << 8 |
19681 (uint32_t)imm;
19682 result = (int32_t)result;
19683 tcg_gen_movi_tl(t0, result);
19684 gen_store_gpr(t0, rt);
19685 }
19686 break;
19687 default:
19688 generate_exception_end(ctx, EXCP_RI);
19689 break;
19690 }
19691 tcg_temp_free(t0);
19692 tcg_temp_free(rs_t);
19693}
19694
19695
19696static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19697{
19698 int rt = extract32(ctx->opcode, 21, 5);
19699 int rs = extract32(ctx->opcode, 16, 5);
19700 int rd = extract32(ctx->opcode, 11, 5);
19701
19702 switch (extract32(ctx->opcode, 6, 3)) {
19703 case NM_POOL32AXF_1:
19704 {
19705 int32_t op1 = extract32(ctx->opcode, 9, 3);
19706 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19707 }
19708 break;
19709 case NM_POOL32AXF_2:
19710 {
19711 int32_t op1 = extract32(ctx->opcode, 12, 2);
19712 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19713 }
19714 break;
19715 case NM_POOL32AXF_4:
19716 {
19717 int32_t op1 = extract32(ctx->opcode, 9, 7);
19718 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19719 }
19720 break;
19721 case NM_POOL32AXF_5:
19722 switch (extract32(ctx->opcode, 9, 7)) {
19723#ifndef CONFIG_USER_ONLY
19724 case NM_TLBP:
19725 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19726 break;
19727 case NM_TLBR:
19728 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19729 break;
19730 case NM_TLBWI:
19731 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19732 break;
19733 case NM_TLBWR:
19734 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19735 break;
19736 case NM_TLBINV:
19737 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19738 break;
19739 case NM_TLBINVF:
19740 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19741 break;
19742 case NM_DI:
19743 check_cp0_enabled(ctx);
19744 {
19745 TCGv t0 = tcg_temp_new();
19746
19747 save_cpu_state(ctx, 1);
19748 gen_helper_di(t0, cpu_env);
19749 gen_store_gpr(t0, rt);
19750
19751 ctx->base.is_jmp = DISAS_STOP;
19752 tcg_temp_free(t0);
19753 }
19754 break;
19755 case NM_EI:
19756 check_cp0_enabled(ctx);
19757 {
19758 TCGv t0 = tcg_temp_new();
19759
19760 save_cpu_state(ctx, 1);
19761 gen_helper_ei(t0, cpu_env);
19762 gen_store_gpr(t0, rt);
19763
19764 ctx->base.is_jmp = DISAS_STOP;
19765 tcg_temp_free(t0);
19766 }
19767 break;
19768 case NM_RDPGPR:
19769 gen_load_srsgpr(rs, rt);
19770 break;
19771 case NM_WRPGPR:
19772 gen_store_srsgpr(rs, rt);
19773 break;
19774 case NM_WAIT:
19775 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19776 break;
19777 case NM_DERET:
19778 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19779 break;
19780 case NM_ERETX:
19781 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19782 break;
19783#endif
19784 default:
19785 generate_exception_end(ctx, EXCP_RI);
19786 break;
19787 }
19788 break;
19789 case NM_POOL32AXF_7:
19790 {
19791 int32_t op1 = extract32(ctx->opcode, 9, 3);
19792 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19793 }
19794 break;
19795 default:
19796 generate_exception_end(ctx, EXCP_RI);
19797 break;
19798 }
19799}
19800
19801
19802static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19803 int rt, int32_t imm, int32_t offset)
19804{
19805 TCGCond cond;
19806 int bcond_compute = 0;
19807 TCGv t0 = tcg_temp_new();
19808 TCGv t1 = tcg_temp_new();
19809
19810 gen_load_gpr(t0, rt);
19811 tcg_gen_movi_tl(t1, imm);
19812 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19813
19814
19815 switch (opc) {
19816 case NM_BEQIC:
19817 if (rt == 0 && imm == 0) {
19818
19819 } else if (rt == 0 && imm != 0) {
19820
19821 goto out;
19822 } else {
19823 bcond_compute = 1;
19824 cond = TCG_COND_EQ;
19825 }
19826 break;
19827 case NM_BBEQZC:
19828 case NM_BBNEZC:
19829 check_nms(ctx);
19830 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19831 generate_exception_end(ctx, EXCP_RI);
19832 goto out;
19833 } else if (rt == 0 && opc == NM_BBEQZC) {
19834
19835 } else if (rt == 0 && opc == NM_BBNEZC) {
19836
19837 goto out;
19838 } else {
19839 tcg_gen_shri_tl(t0, t0, imm);
19840 tcg_gen_andi_tl(t0, t0, 1);
19841 tcg_gen_movi_tl(t1, 0);
19842 bcond_compute = 1;
19843 if (opc == NM_BBEQZC) {
19844 cond = TCG_COND_EQ;
19845 } else {
19846 cond = TCG_COND_NE;
19847 }
19848 }
19849 break;
19850 case NM_BNEIC:
19851 if (rt == 0 && imm == 0) {
19852
19853 goto out;
19854 } else if (rt == 0 && imm != 0) {
19855
19856 } else {
19857 bcond_compute = 1;
19858 cond = TCG_COND_NE;
19859 }
19860 break;
19861 case NM_BGEIC:
19862 if (rt == 0 && imm == 0) {
19863
19864 } else {
19865 bcond_compute = 1;
19866 cond = TCG_COND_GE;
19867 }
19868 break;
19869 case NM_BLTIC:
19870 bcond_compute = 1;
19871 cond = TCG_COND_LT;
19872 break;
19873 case NM_BGEIUC:
19874 if (rt == 0 && imm == 0) {
19875
19876 } else {
19877 bcond_compute = 1;
19878 cond = TCG_COND_GEU;
19879 }
19880 break;
19881 case NM_BLTIUC:
19882 bcond_compute = 1;
19883 cond = TCG_COND_LTU;
19884 break;
19885 default:
19886 MIPS_INVAL("Immediate Value Compact branch");
19887 generate_exception_end(ctx, EXCP_RI);
19888 goto out;
19889 }
19890
19891
19892 clear_branch_hflags(ctx);
19893 ctx->base.is_jmp = DISAS_NORETURN;
19894
19895 if (bcond_compute == 0) {
19896
19897 gen_goto_tb(ctx, 0, ctx->btarget);
19898 } else {
19899
19900 TCGLabel *fs = gen_new_label();
19901
19902 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19903
19904 gen_goto_tb(ctx, 1, ctx->btarget);
19905 gen_set_label(fs);
19906
19907 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19908 }
19909
19910out:
19911 tcg_temp_free(t0);
19912 tcg_temp_free(t1);
19913}
19914
19915
19916static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19917 int rt)
19918{
19919 TCGv t0 = tcg_temp_new();
19920 TCGv t1 = tcg_temp_new();
19921
19922
19923 gen_load_gpr(t0, rs);
19924
19925
19926 if (rt != 0) {
19927 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19928 }
19929
19930
19931 tcg_gen_shli_tl(t0, t0, 1);
19932 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19933 gen_op_addr_add(ctx, btarget, t1, t0);
19934
19935
19936 clear_branch_hflags(ctx);
19937 ctx->base.is_jmp = DISAS_NORETURN;
19938
19939
19940 tcg_gen_mov_tl(cpu_PC, btarget);
19941 tcg_gen_lookup_and_goto_ptr();
19942
19943 tcg_temp_free(t0);
19944 tcg_temp_free(t1);
19945}
19946
19947
19948static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19949 int rs, int rt, int32_t offset)
19950{
19951 int bcond_compute = 0;
19952 TCGv t0 = tcg_temp_new();
19953 TCGv t1 = tcg_temp_new();
19954
19955
19956 switch (opc) {
19957
19958 case OPC_BGEC:
19959 case OPC_BLTC:
19960 gen_load_gpr(t0, rs);
19961 gen_load_gpr(t1, rt);
19962 bcond_compute = 1;
19963 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19964 break;
19965 case OPC_BGEUC:
19966 case OPC_BLTUC:
19967 if (rs == 0 || rs == rt) {
19968
19969
19970 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19971 }
19972 gen_load_gpr(t0, rs);
19973 gen_load_gpr(t1, rt);
19974 bcond_compute = 1;
19975 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19976 break;
19977 case OPC_BC:
19978 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19979 break;
19980 case OPC_BEQZC:
19981 if (rs != 0) {
19982
19983 gen_load_gpr(t0, rs);
19984 bcond_compute = 1;
19985 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19986 } else {
19987
19988 TCGv tbase = tcg_temp_new();
19989 TCGv toffset = tcg_temp_new();
19990
19991 gen_load_gpr(tbase, rt);
19992 tcg_gen_movi_tl(toffset, offset);
19993 gen_op_addr_add(ctx, btarget, tbase, toffset);
19994 tcg_temp_free(tbase);
19995 tcg_temp_free(toffset);
19996 }
19997 break;
19998 default:
19999 MIPS_INVAL("Compact branch/jump");
20000 generate_exception_end(ctx, EXCP_RI);
20001 goto out;
20002 }
20003
20004 if (bcond_compute == 0) {
20005
20006 switch (opc) {
20007 case OPC_BC:
20008 gen_goto_tb(ctx, 0, ctx->btarget);
20009 break;
20010 default:
20011 MIPS_INVAL("Compact branch/jump");
20012 generate_exception_end(ctx, EXCP_RI);
20013 goto out;
20014 }
20015 } else {
20016
20017 TCGLabel *fs = gen_new_label();
20018
20019 switch (opc) {
20020 case OPC_BGEUC:
20021 if (rs == 0 && rt != 0) {
20022
20023 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20024 } else if (rs != 0 && rt != 0 && rs == rt) {
20025
20026 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20027 } else {
20028
20029 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
20030 }
20031 break;
20032 case OPC_BLTUC:
20033 if (rs == 0 && rt != 0) {
20034
20035 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20036 } else if (rs != 0 && rt != 0 && rs == rt) {
20037
20038 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20039 } else {
20040
20041 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
20042 }
20043 break;
20044 case OPC_BGEC:
20045 if (rs == 0 && rt != 0) {
20046
20047 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20048 } else if (rs != 0 && rt != 0 && rs == rt) {
20049
20050 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20051 } else {
20052
20053 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
20054 }
20055 break;
20056 case OPC_BLTC:
20057 if (rs == 0 && rt != 0) {
20058
20059 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20060 } else if (rs != 0 && rt != 0 && rs == rt) {
20061
20062 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20063 } else {
20064
20065 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
20066 }
20067 break;
20068 case OPC_BEQZC:
20069 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
20070 break;
20071 default:
20072 MIPS_INVAL("Compact conditional branch/jump");
20073 generate_exception_end(ctx, EXCP_RI);
20074 goto out;
20075 }
20076
20077
20078 clear_branch_hflags(ctx);
20079 ctx->base.is_jmp = DISAS_NORETURN;
20080
20081
20082 gen_goto_tb(ctx, 1, ctx->btarget);
20083 gen_set_label(fs);
20084
20085 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20086 }
20087
20088out:
20089 tcg_temp_free(t0);
20090 tcg_temp_free(t1);
20091}
20092
20093
20094
20095static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
20096 int32_t ft, int32_t offset)
20097{
20098 target_ulong btarget;
20099 TCGv_i64 t0 = tcg_temp_new_i64();
20100
20101 gen_load_fpr64(ctx, t0, ft);
20102 tcg_gen_andi_i64(t0, t0, 1);
20103
20104 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20105
20106 switch (op) {
20107 case NM_BC1EQZC:
20108 tcg_gen_xori_i64(t0, t0, 1);
20109 ctx->hflags |= MIPS_HFLAG_BC;
20110 break;
20111 case NM_BC1NEZC:
20112
20113 ctx->hflags |= MIPS_HFLAG_BC;
20114 break;
20115 default:
20116 MIPS_INVAL("cp1 cond branch");
20117 generate_exception_end(ctx, EXCP_RI);
20118 goto out;
20119 }
20120
20121 tcg_gen_trunc_i64_tl(bcond, t0);
20122
20123 ctx->btarget = btarget;
20124
20125out:
20126 tcg_temp_free_i64(t0);
20127}
20128
20129
20130static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20131{
20132 TCGv t0, t1;
20133 t0 = tcg_temp_new();
20134 t1 = tcg_temp_new();
20135
20136 gen_load_gpr(t0, rs);
20137 gen_load_gpr(t1, rt);
20138
20139 if ((extract32(ctx->opcode, 6, 1)) == 1) {
20140
20141 switch (extract32(ctx->opcode, 7, 4)) {
20142 case NM_SHXS:
20143 check_nms(ctx);
20144
20145 case NM_LHXS:
20146 case NM_LHUXS:
20147 tcg_gen_shli_tl(t0, t0, 1);
20148 break;
20149 case NM_SWXS:
20150 check_nms(ctx);
20151
20152 case NM_LWXS:
20153 case NM_LWC1XS:
20154 case NM_SWC1XS:
20155 tcg_gen_shli_tl(t0, t0, 2);
20156 break;
20157 case NM_LDC1XS:
20158 case NM_SDC1XS:
20159 tcg_gen_shli_tl(t0, t0, 3);
20160 break;
20161 }
20162 }
20163 gen_op_addr_add(ctx, t0, t0, t1);
20164
20165 switch (extract32(ctx->opcode, 7, 4)) {
20166 case NM_LBX:
20167 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20168 MO_SB);
20169 gen_store_gpr(t0, rd);
20170 break;
20171 case NM_LHX:
20172
20173 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20174 MO_TESW);
20175 gen_store_gpr(t0, rd);
20176 break;
20177 case NM_LWX:
20178
20179 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20180 MO_TESL);
20181 gen_store_gpr(t0, rd);
20182 break;
20183 case NM_LBUX:
20184 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20185 MO_UB);
20186 gen_store_gpr(t0, rd);
20187 break;
20188 case NM_LHUX:
20189
20190 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20191 MO_TEUW);
20192 gen_store_gpr(t0, rd);
20193 break;
20194 case NM_SBX:
20195 check_nms(ctx);
20196 gen_load_gpr(t1, rd);
20197 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20198 MO_8);
20199 break;
20200 case NM_SHX:
20201
20202 check_nms(ctx);
20203 gen_load_gpr(t1, rd);
20204 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20205 MO_TEUW);
20206 break;
20207 case NM_SWX:
20208
20209 check_nms(ctx);
20210 gen_load_gpr(t1, rd);
20211 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20212 MO_TEUL);
20213 break;
20214 case NM_LWC1X:
20215
20216 case NM_LDC1X:
20217
20218 case NM_SWC1X:
20219
20220 case NM_SDC1X:
20221
20222 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20223 check_cp1_enabled(ctx);
20224 switch (extract32(ctx->opcode, 7, 4)) {
20225 case NM_LWC1X:
20226
20227 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20228 break;
20229 case NM_LDC1X:
20230
20231 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20232 break;
20233 case NM_SWC1X:
20234
20235 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20236 break;
20237 case NM_SDC1X:
20238
20239 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20240 break;
20241 }
20242 } else {
20243 generate_exception_err(ctx, EXCP_CpU, 1);
20244 }
20245 break;
20246 default:
20247 generate_exception_end(ctx, EXCP_RI);
20248 break;
20249 }
20250
20251 tcg_temp_free(t0);
20252 tcg_temp_free(t1);
20253}
20254
20255static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20256{
20257 int rt, rs, rd;
20258
20259 rt = extract32(ctx->opcode, 21, 5);
20260 rs = extract32(ctx->opcode, 16, 5);
20261 rd = extract32(ctx->opcode, 11, 5);
20262
20263 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20264 generate_exception_end(ctx, EXCP_RI);
20265 return;
20266 }
20267 check_cp1_enabled(ctx);
20268 switch (extract32(ctx->opcode, 0, 3)) {
20269 case NM_POOL32F_0:
20270 switch (extract32(ctx->opcode, 3, 7)) {
20271 case NM_RINT_S:
20272 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20273 break;
20274 case NM_RINT_D:
20275 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20276 break;
20277 case NM_CLASS_S:
20278 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20279 break;
20280 case NM_CLASS_D:
20281 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20282 break;
20283 case NM_ADD_S:
20284 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20285 break;
20286 case NM_ADD_D:
20287 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20288 break;
20289 case NM_SUB_S:
20290 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20291 break;
20292 case NM_SUB_D:
20293 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20294 break;
20295 case NM_MUL_S:
20296 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20297 break;
20298 case NM_MUL_D:
20299 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20300 break;
20301 case NM_DIV_S:
20302 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20303 break;
20304 case NM_DIV_D:
20305 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20306 break;
20307 case NM_SELEQZ_S:
20308 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20309 break;
20310 case NM_SELEQZ_D:
20311 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20312 break;
20313 case NM_SELNEZ_S:
20314 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20315 break;
20316 case NM_SELNEZ_D:
20317 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20318 break;
20319 case NM_SEL_S:
20320 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20321 break;
20322 case NM_SEL_D:
20323 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20324 break;
20325 case NM_MADDF_S:
20326 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20327 break;
20328 case NM_MADDF_D:
20329 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20330 break;
20331 case NM_MSUBF_S:
20332 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20333 break;
20334 case NM_MSUBF_D:
20335 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20336 break;
20337 default:
20338 generate_exception_end(ctx, EXCP_RI);
20339 break;
20340 }
20341 break;
20342 case NM_POOL32F_3:
20343 switch (extract32(ctx->opcode, 3, 3)) {
20344 case NM_MIN_FMT:
20345 switch (extract32(ctx->opcode, 9, 1)) {
20346 case FMT_SDPS_S:
20347 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20348 break;
20349 case FMT_SDPS_D:
20350 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20351 break;
20352 }
20353 break;
20354 case NM_MAX_FMT:
20355 switch (extract32(ctx->opcode, 9, 1)) {
20356 case FMT_SDPS_S:
20357 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20358 break;
20359 case FMT_SDPS_D:
20360 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20361 break;
20362 }
20363 break;
20364 case NM_MINA_FMT:
20365 switch (extract32(ctx->opcode, 9, 1)) {
20366 case FMT_SDPS_S:
20367 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20368 break;
20369 case FMT_SDPS_D:
20370 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20371 break;
20372 }
20373 break;
20374 case NM_MAXA_FMT:
20375 switch (extract32(ctx->opcode, 9, 1)) {
20376 case FMT_SDPS_S:
20377 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20378 break;
20379 case FMT_SDPS_D:
20380 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20381 break;
20382 }
20383 break;
20384 case NM_POOL32FXF:
20385 switch (extract32(ctx->opcode, 6, 8)) {
20386 case NM_CFC1:
20387 gen_cp1(ctx, OPC_CFC1, rt, rs);
20388 break;
20389 case NM_CTC1:
20390 gen_cp1(ctx, OPC_CTC1, rt, rs);
20391 break;
20392 case NM_MFC1:
20393 gen_cp1(ctx, OPC_MFC1, rt, rs);
20394 break;
20395 case NM_MTC1:
20396 gen_cp1(ctx, OPC_MTC1, rt, rs);
20397 break;
20398 case NM_MFHC1:
20399 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20400 break;
20401 case NM_MTHC1:
20402 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20403 break;
20404 case NM_CVT_S_PL:
20405 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20406 break;
20407 case NM_CVT_S_PU:
20408 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20409 break;
20410 default:
20411 switch (extract32(ctx->opcode, 6, 9)) {
20412 case NM_CVT_L_S:
20413 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20414 break;
20415 case NM_CVT_L_D:
20416 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20417 break;
20418 case NM_CVT_W_S:
20419 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20420 break;
20421 case NM_CVT_W_D:
20422 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20423 break;
20424 case NM_RSQRT_S:
20425 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20426 break;
20427 case NM_RSQRT_D:
20428 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20429 break;
20430 case NM_SQRT_S:
20431 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20432 break;
20433 case NM_SQRT_D:
20434 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20435 break;
20436 case NM_RECIP_S:
20437 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20438 break;
20439 case NM_RECIP_D:
20440 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20441 break;
20442 case NM_FLOOR_L_S:
20443 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20444 break;
20445 case NM_FLOOR_L_D:
20446 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20447 break;
20448 case NM_FLOOR_W_S:
20449 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20450 break;
20451 case NM_FLOOR_W_D:
20452 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20453 break;
20454 case NM_CEIL_L_S:
20455 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20456 break;
20457 case NM_CEIL_L_D:
20458 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20459 break;
20460 case NM_CEIL_W_S:
20461 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20462 break;
20463 case NM_CEIL_W_D:
20464 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20465 break;
20466 case NM_TRUNC_L_S:
20467 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20468 break;
20469 case NM_TRUNC_L_D:
20470 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20471 break;
20472 case NM_TRUNC_W_S:
20473 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20474 break;
20475 case NM_TRUNC_W_D:
20476 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20477 break;
20478 case NM_ROUND_L_S:
20479 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20480 break;
20481 case NM_ROUND_L_D:
20482 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20483 break;
20484 case NM_ROUND_W_S:
20485 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20486 break;
20487 case NM_ROUND_W_D:
20488 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20489 break;
20490 case NM_MOV_S:
20491 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20492 break;
20493 case NM_MOV_D:
20494 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20495 break;
20496 case NM_ABS_S:
20497 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20498 break;
20499 case NM_ABS_D:
20500 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20501 break;
20502 case NM_NEG_S:
20503 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20504 break;
20505 case NM_NEG_D:
20506 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20507 break;
20508 case NM_CVT_D_S:
20509 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20510 break;
20511 case NM_CVT_D_W:
20512 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20513 break;
20514 case NM_CVT_D_L:
20515 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20516 break;
20517 case NM_CVT_S_D:
20518 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20519 break;
20520 case NM_CVT_S_W:
20521 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20522 break;
20523 case NM_CVT_S_L:
20524 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20525 break;
20526 default:
20527 generate_exception_end(ctx, EXCP_RI);
20528 break;
20529 }
20530 break;
20531 }
20532 break;
20533 }
20534 break;
20535 case NM_POOL32F_5:
20536 switch (extract32(ctx->opcode, 3, 3)) {
20537 case NM_CMP_CONDN_S:
20538 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20539 break;
20540 case NM_CMP_CONDN_D:
20541 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20542 break;
20543 default:
20544 generate_exception_end(ctx, EXCP_RI);
20545 break;
20546 }
20547 break;
20548 default:
20549 generate_exception_end(ctx, EXCP_RI);
20550 break;
20551 }
20552}
20553
20554static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20555 int rd, int rs, int rt)
20556{
20557 int ret = rd;
20558 TCGv t0 = tcg_temp_new();
20559 TCGv v1_t = tcg_temp_new();
20560 TCGv v2_t = tcg_temp_new();
20561
20562 gen_load_gpr(v1_t, rs);
20563 gen_load_gpr(v2_t, rt);
20564
20565 switch (opc) {
20566 case NM_CMP_EQ_PH:
20567 check_dsp(ctx);
20568 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20569 break;
20570 case NM_CMP_LT_PH:
20571 check_dsp(ctx);
20572 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20573 break;
20574 case NM_CMP_LE_PH:
20575 check_dsp(ctx);
20576 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20577 break;
20578 case NM_CMPU_EQ_QB:
20579 check_dsp(ctx);
20580 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20581 break;
20582 case NM_CMPU_LT_QB:
20583 check_dsp(ctx);
20584 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20585 break;
20586 case NM_CMPU_LE_QB:
20587 check_dsp(ctx);
20588 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20589 break;
20590 case NM_CMPGU_EQ_QB:
20591 check_dsp(ctx);
20592 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20593 gen_store_gpr(v1_t, ret);
20594 break;
20595 case NM_CMPGU_LT_QB:
20596 check_dsp(ctx);
20597 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20598 gen_store_gpr(v1_t, ret);
20599 break;
20600 case NM_CMPGU_LE_QB:
20601 check_dsp(ctx);
20602 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20603 gen_store_gpr(v1_t, ret);
20604 break;
20605 case NM_CMPGDU_EQ_QB:
20606 check_dsp_r2(ctx);
20607 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20608 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20609 gen_store_gpr(v1_t, ret);
20610 break;
20611 case NM_CMPGDU_LT_QB:
20612 check_dsp_r2(ctx);
20613 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20614 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20615 gen_store_gpr(v1_t, ret);
20616 break;
20617 case NM_CMPGDU_LE_QB:
20618 check_dsp_r2(ctx);
20619 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20620 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20621 gen_store_gpr(v1_t, ret);
20622 break;
20623 case NM_PACKRL_PH:
20624 check_dsp(ctx);
20625 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20626 gen_store_gpr(v1_t, ret);
20627 break;
20628 case NM_PICK_QB:
20629 check_dsp(ctx);
20630 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20631 gen_store_gpr(v1_t, ret);
20632 break;
20633 case NM_PICK_PH:
20634 check_dsp(ctx);
20635 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20636 gen_store_gpr(v1_t, ret);
20637 break;
20638 case NM_ADDQ_S_W:
20639 check_dsp(ctx);
20640 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20641 gen_store_gpr(v1_t, ret);
20642 break;
20643 case NM_SUBQ_S_W:
20644 check_dsp(ctx);
20645 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20646 gen_store_gpr(v1_t, ret);
20647 break;
20648 case NM_ADDSC:
20649 check_dsp(ctx);
20650 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20651 gen_store_gpr(v1_t, ret);
20652 break;
20653 case NM_ADDWC:
20654 check_dsp(ctx);
20655 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20656 gen_store_gpr(v1_t, ret);
20657 break;
20658 case NM_ADDQ_S_PH:
20659 check_dsp(ctx);
20660 switch (extract32(ctx->opcode, 10, 1)) {
20661 case 0:
20662
20663 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20664 gen_store_gpr(v1_t, ret);
20665 break;
20666 case 1:
20667
20668 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20669 gen_store_gpr(v1_t, ret);
20670 break;
20671 }
20672 break;
20673 case NM_ADDQH_R_PH:
20674 check_dsp_r2(ctx);
20675 switch (extract32(ctx->opcode, 10, 1)) {
20676 case 0:
20677
20678 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20679 gen_store_gpr(v1_t, ret);
20680 break;
20681 case 1:
20682
20683 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20684 gen_store_gpr(v1_t, ret);
20685 break;
20686 }
20687 break;
20688 case NM_ADDQH_R_W:
20689 check_dsp_r2(ctx);
20690 switch (extract32(ctx->opcode, 10, 1)) {
20691 case 0:
20692
20693 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20694 gen_store_gpr(v1_t, ret);
20695 break;
20696 case 1:
20697
20698 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20699 gen_store_gpr(v1_t, ret);
20700 break;
20701 }
20702 break;
20703 case NM_ADDU_S_QB:
20704 check_dsp(ctx);
20705 switch (extract32(ctx->opcode, 10, 1)) {
20706 case 0:
20707
20708 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20709 gen_store_gpr(v1_t, ret);
20710 break;
20711 case 1:
20712
20713 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20714 gen_store_gpr(v1_t, ret);
20715 break;
20716 }
20717 break;
20718 case NM_ADDU_S_PH:
20719 check_dsp_r2(ctx);
20720 switch (extract32(ctx->opcode, 10, 1)) {
20721 case 0:
20722
20723 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20724 gen_store_gpr(v1_t, ret);
20725 break;
20726 case 1:
20727
20728 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20729 gen_store_gpr(v1_t, ret);
20730 break;
20731 }
20732 break;
20733 case NM_ADDUH_R_QB:
20734 check_dsp_r2(ctx);
20735 switch (extract32(ctx->opcode, 10, 1)) {
20736 case 0:
20737
20738 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20739 gen_store_gpr(v1_t, ret);
20740 break;
20741 case 1:
20742
20743 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20744 gen_store_gpr(v1_t, ret);
20745 break;
20746 }
20747 break;
20748 case NM_SHRAV_R_PH:
20749 check_dsp(ctx);
20750 switch (extract32(ctx->opcode, 10, 1)) {
20751 case 0:
20752
20753 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20754 gen_store_gpr(v1_t, ret);
20755 break;
20756 case 1:
20757
20758 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20759 gen_store_gpr(v1_t, ret);
20760 break;
20761 }
20762 break;
20763 case NM_SHRAV_R_QB:
20764 check_dsp_r2(ctx);
20765 switch (extract32(ctx->opcode, 10, 1)) {
20766 case 0:
20767
20768 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20769 gen_store_gpr(v1_t, ret);
20770 break;
20771 case 1:
20772
20773 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20774 gen_store_gpr(v1_t, ret);
20775 break;
20776 }
20777 break;
20778 case NM_SUBQ_S_PH:
20779 check_dsp(ctx);
20780 switch (extract32(ctx->opcode, 10, 1)) {
20781 case 0:
20782
20783 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20784 gen_store_gpr(v1_t, ret);
20785 break;
20786 case 1:
20787
20788 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20789 gen_store_gpr(v1_t, ret);
20790 break;
20791 }
20792 break;
20793 case NM_SUBQH_R_PH:
20794 check_dsp_r2(ctx);
20795 switch (extract32(ctx->opcode, 10, 1)) {
20796 case 0:
20797
20798 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20799 gen_store_gpr(v1_t, ret);
20800 break;
20801 case 1:
20802
20803 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20804 gen_store_gpr(v1_t, ret);
20805 break;
20806 }
20807 break;
20808 case NM_SUBQH_R_W:
20809 check_dsp_r2(ctx);
20810 switch (extract32(ctx->opcode, 10, 1)) {
20811 case 0:
20812
20813 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20814 gen_store_gpr(v1_t, ret);
20815 break;
20816 case 1:
20817
20818 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20819 gen_store_gpr(v1_t, ret);
20820 break;
20821 }
20822 break;
20823 case NM_SUBU_S_QB:
20824 check_dsp(ctx);
20825 switch (extract32(ctx->opcode, 10, 1)) {
20826 case 0:
20827
20828 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20829 gen_store_gpr(v1_t, ret);
20830 break;
20831 case 1:
20832
20833 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20834 gen_store_gpr(v1_t, ret);
20835 break;
20836 }
20837 break;
20838 case NM_SUBU_S_PH:
20839 check_dsp_r2(ctx);
20840 switch (extract32(ctx->opcode, 10, 1)) {
20841 case 0:
20842
20843 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20844 gen_store_gpr(v1_t, ret);
20845 break;
20846 case 1:
20847
20848 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20849 gen_store_gpr(v1_t, ret);
20850 break;
20851 }
20852 break;
20853 case NM_SUBUH_R_QB:
20854 check_dsp_r2(ctx);
20855 switch (extract32(ctx->opcode, 10, 1)) {
20856 case 0:
20857
20858 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20859 gen_store_gpr(v1_t, ret);
20860 break;
20861 case 1:
20862
20863 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20864 gen_store_gpr(v1_t, ret);
20865 break;
20866 }
20867 break;
20868 case NM_SHLLV_S_PH:
20869 check_dsp(ctx);
20870 switch (extract32(ctx->opcode, 10, 1)) {
20871 case 0:
20872
20873 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20874 gen_store_gpr(v1_t, ret);
20875 break;
20876 case 1:
20877
20878 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20879 gen_store_gpr(v1_t, ret);
20880 break;
20881 }
20882 break;
20883 case NM_PRECR_SRA_R_PH_W:
20884 check_dsp_r2(ctx);
20885 switch (extract32(ctx->opcode, 10, 1)) {
20886 case 0:
20887
20888 {
20889 TCGv_i32 sa_t = tcg_const_i32(rd);
20890 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20891 cpu_gpr[rt]);
20892 gen_store_gpr(v1_t, rt);
20893 tcg_temp_free_i32(sa_t);
20894 }
20895 break;
20896 case 1:
20897
20898 {
20899 TCGv_i32 sa_t = tcg_const_i32(rd);
20900 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20901 cpu_gpr[rt]);
20902 gen_store_gpr(v1_t, rt);
20903 tcg_temp_free_i32(sa_t);
20904 }
20905 break;
20906 }
20907 break;
20908 case NM_MULEU_S_PH_QBL:
20909 check_dsp(ctx);
20910 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20911 gen_store_gpr(v1_t, ret);
20912 break;
20913 case NM_MULEU_S_PH_QBR:
20914 check_dsp(ctx);
20915 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20916 gen_store_gpr(v1_t, ret);
20917 break;
20918 case NM_MULQ_RS_PH:
20919 check_dsp(ctx);
20920 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20921 gen_store_gpr(v1_t, ret);
20922 break;
20923 case NM_MULQ_S_PH:
20924 check_dsp_r2(ctx);
20925 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20926 gen_store_gpr(v1_t, ret);
20927 break;
20928 case NM_MULQ_RS_W:
20929 check_dsp_r2(ctx);
20930 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20931 gen_store_gpr(v1_t, ret);
20932 break;
20933 case NM_MULQ_S_W:
20934 check_dsp_r2(ctx);
20935 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20936 gen_store_gpr(v1_t, ret);
20937 break;
20938 case NM_APPEND:
20939 check_dsp_r2(ctx);
20940 gen_load_gpr(t0, rs);
20941 if (rd != 0) {
20942 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20943 }
20944 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20945 break;
20946 case NM_MODSUB:
20947 check_dsp(ctx);
20948 gen_helper_modsub(v1_t, v1_t, v2_t);
20949 gen_store_gpr(v1_t, ret);
20950 break;
20951 case NM_SHRAV_R_W:
20952 check_dsp(ctx);
20953 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20954 gen_store_gpr(v1_t, ret);
20955 break;
20956 case NM_SHRLV_PH:
20957 check_dsp_r2(ctx);
20958 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20959 gen_store_gpr(v1_t, ret);
20960 break;
20961 case NM_SHRLV_QB:
20962 check_dsp(ctx);
20963 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20964 gen_store_gpr(v1_t, ret);
20965 break;
20966 case NM_SHLLV_QB:
20967 check_dsp(ctx);
20968 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20969 gen_store_gpr(v1_t, ret);
20970 break;
20971 case NM_SHLLV_S_W:
20972 check_dsp(ctx);
20973 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20974 gen_store_gpr(v1_t, ret);
20975 break;
20976 case NM_SHILO:
20977 check_dsp(ctx);
20978 {
20979 TCGv tv0 = tcg_temp_new();
20980 TCGv tv1 = tcg_temp_new();
20981 int16_t imm = extract32(ctx->opcode, 16, 7);
20982
20983 tcg_gen_movi_tl(tv0, rd >> 3);
20984 tcg_gen_movi_tl(tv1, imm);
20985 gen_helper_shilo(tv0, tv1, cpu_env);
20986 }
20987 break;
20988 case NM_MULEQ_S_W_PHL:
20989 check_dsp(ctx);
20990 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20991 gen_store_gpr(v1_t, ret);
20992 break;
20993 case NM_MULEQ_S_W_PHR:
20994 check_dsp(ctx);
20995 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20996 gen_store_gpr(v1_t, ret);
20997 break;
20998 case NM_MUL_S_PH:
20999 check_dsp_r2(ctx);
21000 switch (extract32(ctx->opcode, 10, 1)) {
21001 case 0:
21002
21003 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
21004 gen_store_gpr(v1_t, ret);
21005 break;
21006 case 1:
21007
21008 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
21009 gen_store_gpr(v1_t, ret);
21010 break;
21011 }
21012 break;
21013 case NM_PRECR_QB_PH:
21014 check_dsp_r2(ctx);
21015 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
21016 gen_store_gpr(v1_t, ret);
21017 break;
21018 case NM_PRECRQ_QB_PH:
21019 check_dsp(ctx);
21020 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
21021 gen_store_gpr(v1_t, ret);
21022 break;
21023 case NM_PRECRQ_PH_W:
21024 check_dsp(ctx);
21025 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
21026 gen_store_gpr(v1_t, ret);
21027 break;
21028 case NM_PRECRQ_RS_PH_W:
21029 check_dsp(ctx);
21030 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
21031 gen_store_gpr(v1_t, ret);
21032 break;
21033 case NM_PRECRQU_S_QB_PH:
21034 check_dsp(ctx);
21035 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
21036 gen_store_gpr(v1_t, ret);
21037 break;
21038 case NM_SHRA_R_W:
21039 check_dsp(ctx);
21040 tcg_gen_movi_tl(t0, rd);
21041 gen_helper_shra_r_w(v1_t, t0, v1_t);
21042 gen_store_gpr(v1_t, rt);
21043 break;
21044 case NM_SHRA_R_PH:
21045 check_dsp(ctx);
21046 tcg_gen_movi_tl(t0, rd >> 1);
21047 switch (extract32(ctx->opcode, 10, 1)) {
21048 case 0:
21049
21050 gen_helper_shra_ph(v1_t, t0, v1_t);
21051 gen_store_gpr(v1_t, rt);
21052 break;
21053 case 1:
21054
21055 gen_helper_shra_r_ph(v1_t, t0, v1_t);
21056 gen_store_gpr(v1_t, rt);
21057 break;
21058 }
21059 break;
21060 case NM_SHLL_S_PH:
21061 check_dsp(ctx);
21062 tcg_gen_movi_tl(t0, rd >> 1);
21063 switch (extract32(ctx->opcode, 10, 2)) {
21064 case 0:
21065
21066 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
21067 gen_store_gpr(v1_t, rt);
21068 break;
21069 case 2:
21070
21071 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
21072 gen_store_gpr(v1_t, rt);
21073 break;
21074 default:
21075 generate_exception_end(ctx, EXCP_RI);
21076 break;
21077 }
21078 break;
21079 case NM_SHLL_S_W:
21080 check_dsp(ctx);
21081 tcg_gen_movi_tl(t0, rd);
21082 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
21083 gen_store_gpr(v1_t, rt);
21084 break;
21085 case NM_REPL_PH:
21086 check_dsp(ctx);
21087 {
21088 int16_t imm;
21089 imm = sextract32(ctx->opcode, 11, 11);
21090 imm = (int16_t)(imm << 6) >> 6;
21091 if (rt != 0) {
21092 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
21093 }
21094 }
21095 break;
21096 default:
21097 generate_exception_end(ctx, EXCP_RI);
21098 break;
21099 }
21100}
21101
21102static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
21103{
21104 uint16_t insn;
21105 uint32_t op;
21106 int rt, rs, rd;
21107 int offset;
21108 int imm;
21109
21110 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
21111 ctx->opcode = (ctx->opcode << 16) | insn;
21112
21113 rt = extract32(ctx->opcode, 21, 5);
21114 rs = extract32(ctx->opcode, 16, 5);
21115 rd = extract32(ctx->opcode, 11, 5);
21116
21117 op = extract32(ctx->opcode, 26, 6);
21118 switch (op) {
21119 case NM_P_ADDIU:
21120 if (rt == 0) {
21121
21122 switch (extract32(ctx->opcode, 19, 2)) {
21123 case NM_SIGRIE:
21124 default:
21125 generate_exception_end(ctx, EXCP_RI);
21126 break;
21127 case NM_P_SYSCALL:
21128 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
21129 generate_exception_end(ctx, EXCP_SYSCALL);
21130 } else {
21131 generate_exception_end(ctx, EXCP_RI);
21132 }
21133 break;
21134 case NM_BREAK:
21135 generate_exception_end(ctx, EXCP_BREAK);
21136 break;
21137 case NM_SDBBP:
21138 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21139 gen_helper_do_semihosting(cpu_env);
21140 } else {
21141 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21142 generate_exception_end(ctx, EXCP_RI);
21143 } else {
21144 generate_exception_end(ctx, EXCP_DBp);
21145 }
21146 }
21147 break;
21148 }
21149 } else {
21150
21151 imm = extract32(ctx->opcode, 0, 16);
21152 if (rs != 0) {
21153 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21154 } else {
21155 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21156 }
21157 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21158 }
21159 break;
21160 case NM_ADDIUPC:
21161 if (rt != 0) {
21162 offset = sextract32(ctx->opcode, 0, 1) << 21 |
21163 extract32(ctx->opcode, 1, 20) << 1;
21164 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21165 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21166 }
21167 break;
21168 case NM_POOL32A:
21169 switch (ctx->opcode & 0x07) {
21170 case NM_POOL32A0:
21171 gen_pool32a0_nanomips_insn(env, ctx);
21172 break;
21173 case NM_POOL32A5:
21174 {
21175 int32_t op1 = extract32(ctx->opcode, 3, 7);
21176 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21177 }
21178 break;
21179 case NM_POOL32A7:
21180 switch (extract32(ctx->opcode, 3, 3)) {
21181 case NM_P_LSX:
21182 gen_p_lsx(ctx, rd, rs, rt);
21183 break;
21184 case NM_LSA:
21185
21186
21187
21188
21189
21190 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21191 extract32(ctx->opcode, 9, 2) - 1);
21192 break;
21193 case NM_EXTW:
21194 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21195 break;
21196 case NM_POOL32AXF:
21197 gen_pool32axf_nanomips_insn(env, ctx);
21198 break;
21199 default:
21200 generate_exception_end(ctx, EXCP_RI);
21201 break;
21202 }
21203 break;
21204 default:
21205 generate_exception_end(ctx, EXCP_RI);
21206 break;
21207 }
21208 break;
21209 case NM_P_GP_W:
21210 switch (ctx->opcode & 0x03) {
21211 case NM_ADDIUGP_W:
21212 if (rt != 0) {
21213 offset = extract32(ctx->opcode, 0, 21);
21214 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21215 }
21216 break;
21217 case NM_LWGP:
21218 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21219 break;
21220 case NM_SWGP:
21221 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21222 break;
21223 default:
21224 generate_exception_end(ctx, EXCP_RI);
21225 break;
21226 }
21227 break;
21228 case NM_P48I:
21229 {
21230 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21231 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21232 switch (extract32(ctx->opcode, 16, 5)) {
21233 case NM_LI48:
21234 check_nms(ctx);
21235 if (rt != 0) {
21236 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21237 }
21238 break;
21239 case NM_ADDIU48:
21240 check_nms(ctx);
21241 if (rt != 0) {
21242 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21243 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21244 }
21245 break;
21246 case NM_ADDIUGP48:
21247 check_nms(ctx);
21248 if (rt != 0) {
21249 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21250 }
21251 break;
21252 case NM_ADDIUPC48:
21253 check_nms(ctx);
21254 if (rt != 0) {
21255 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21256 addr_off);
21257
21258 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21259 }
21260 break;
21261 case NM_LWPC48:
21262 check_nms(ctx);
21263 if (rt != 0) {
21264 TCGv t0;
21265 t0 = tcg_temp_new();
21266
21267 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21268 addr_off);
21269
21270 tcg_gen_movi_tl(t0, addr);
21271 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21272 tcg_temp_free(t0);
21273 }
21274 break;
21275 case NM_SWPC48:
21276 check_nms(ctx);
21277 {
21278 TCGv t0, t1;
21279 t0 = tcg_temp_new();
21280 t1 = tcg_temp_new();
21281
21282 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21283 addr_off);
21284
21285 tcg_gen_movi_tl(t0, addr);
21286 gen_load_gpr(t1, rt);
21287
21288 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21289
21290 tcg_temp_free(t0);
21291 tcg_temp_free(t1);
21292 }
21293 break;
21294 default:
21295 generate_exception_end(ctx, EXCP_RI);
21296 break;
21297 }
21298 return 6;
21299 }
21300 case NM_P_U12:
21301 switch (extract32(ctx->opcode, 12, 4)) {
21302 case NM_ORI:
21303 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21304 break;
21305 case NM_XORI:
21306 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21307 break;
21308 case NM_ANDI:
21309 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21310 break;
21311 case NM_P_SR:
21312 switch (extract32(ctx->opcode, 20, 1)) {
21313 case NM_PP_SR:
21314 switch (ctx->opcode & 3) {
21315 case NM_SAVE:
21316 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21317 extract32(ctx->opcode, 2, 1),
21318 extract32(ctx->opcode, 3, 9) << 3);
21319 break;
21320 case NM_RESTORE:
21321 case NM_RESTORE_JRC:
21322 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21323 extract32(ctx->opcode, 2, 1),
21324 extract32(ctx->opcode, 3, 9) << 3);
21325 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21326 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21327 }
21328 break;
21329 default:
21330 generate_exception_end(ctx, EXCP_RI);
21331 break;
21332 }
21333 break;
21334 case NM_P_SR_F:
21335 generate_exception_end(ctx, EXCP_RI);
21336 break;
21337 }
21338 break;
21339 case NM_SLTI:
21340 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21341 break;
21342 case NM_SLTIU:
21343 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21344 break;
21345 case NM_SEQI:
21346 {
21347 TCGv t0 = tcg_temp_new();
21348
21349 imm = extract32(ctx->opcode, 0, 12);
21350 gen_load_gpr(t0, rs);
21351 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21352 gen_store_gpr(t0, rt);
21353
21354 tcg_temp_free(t0);
21355 }
21356 break;
21357 case NM_ADDIUNEG:
21358 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21359 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21360 break;
21361 case NM_P_SHIFT:
21362 {
21363 int shift = extract32(ctx->opcode, 0, 5);
21364 switch (extract32(ctx->opcode, 5, 4)) {
21365 case NM_P_SLL:
21366 if (rt == 0 && shift == 0) {
21367
21368 } else if (rt == 0 && shift == 3) {
21369
21370 } else if (rt == 0 && shift == 5) {
21371
21372 } else if (rt == 0 && shift == 6) {
21373
21374 gen_sync(extract32(ctx->opcode, 16, 5));
21375 } else {
21376
21377 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21378 extract32(ctx->opcode, 0, 5));
21379 }
21380 break;
21381 case NM_SRL:
21382 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21383 extract32(ctx->opcode, 0, 5));
21384 break;
21385 case NM_SRA:
21386 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21387 extract32(ctx->opcode, 0, 5));
21388 break;
21389 case NM_ROTR:
21390 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21391 extract32(ctx->opcode, 0, 5));
21392 break;
21393 }
21394 }
21395 break;
21396 case NM_P_ROTX:
21397 check_nms(ctx);
21398 if (rt != 0) {
21399 TCGv t0 = tcg_temp_new();
21400 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21401 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21402 << 1);
21403 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21404
21405 gen_load_gpr(t0, rs);
21406 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21407 tcg_temp_free(t0);
21408
21409 tcg_temp_free_i32(shift);
21410 tcg_temp_free_i32(shiftx);
21411 tcg_temp_free_i32(stripe);
21412 }
21413 break;
21414 case NM_P_INS:
21415 switch (((ctx->opcode >> 10) & 2) |
21416 (extract32(ctx->opcode, 5, 1))) {
21417 case NM_INS:
21418 check_nms(ctx);
21419 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21420 extract32(ctx->opcode, 6, 5));
21421 break;
21422 default:
21423 generate_exception_end(ctx, EXCP_RI);
21424 break;
21425 }
21426 break;
21427 case NM_P_EXT:
21428 switch (((ctx->opcode >> 10) & 2) |
21429 (extract32(ctx->opcode, 5, 1))) {
21430 case NM_EXT:
21431 check_nms(ctx);
21432 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21433 extract32(ctx->opcode, 6, 5));
21434 break;
21435 default:
21436 generate_exception_end(ctx, EXCP_RI);
21437 break;
21438 }
21439 break;
21440 default:
21441 generate_exception_end(ctx, EXCP_RI);
21442 break;
21443 }
21444 break;
21445 case NM_POOL32F:
21446 gen_pool32f_nanomips_insn(ctx);
21447 break;
21448 case NM_POOL32S:
21449 break;
21450 case NM_P_LUI:
21451 switch (extract32(ctx->opcode, 1, 1)) {
21452 case NM_LUI:
21453 if (rt != 0) {
21454 tcg_gen_movi_tl(cpu_gpr[rt],
21455 sextract32(ctx->opcode, 0, 1) << 31 |
21456 extract32(ctx->opcode, 2, 10) << 21 |
21457 extract32(ctx->opcode, 12, 9) << 12);
21458 }
21459 break;
21460 case NM_ALUIPC:
21461 if (rt != 0) {
21462 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21463 extract32(ctx->opcode, 2, 10) << 21 |
21464 extract32(ctx->opcode, 12, 9) << 12;
21465 target_long addr;
21466 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21467 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21468 }
21469 break;
21470 }
21471 break;
21472 case NM_P_GP_BH:
21473 {
21474 uint32_t u = extract32(ctx->opcode, 0, 18);
21475
21476 switch (extract32(ctx->opcode, 18, 3)) {
21477 case NM_LBGP:
21478 gen_ld(ctx, OPC_LB, rt, 28, u);
21479 break;
21480 case NM_SBGP:
21481 gen_st(ctx, OPC_SB, rt, 28, u);
21482 break;
21483 case NM_LBUGP:
21484 gen_ld(ctx, OPC_LBU, rt, 28, u);
21485 break;
21486 case NM_ADDIUGP_B:
21487 if (rt != 0) {
21488 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21489 }
21490 break;
21491 case NM_P_GP_LH:
21492 u &= ~1;
21493 switch (ctx->opcode & 1) {
21494 case NM_LHGP:
21495 gen_ld(ctx, OPC_LH, rt, 28, u);
21496 break;
21497 case NM_LHUGP:
21498 gen_ld(ctx, OPC_LHU, rt, 28, u);
21499 break;
21500 }
21501 break;
21502 case NM_P_GP_SH:
21503 u &= ~1;
21504 switch (ctx->opcode & 1) {
21505 case NM_SHGP:
21506 gen_st(ctx, OPC_SH, rt, 28, u);
21507 break;
21508 default:
21509 generate_exception_end(ctx, EXCP_RI);
21510 break;
21511 }
21512 break;
21513 case NM_P_GP_CP1:
21514 u &= ~0x3;
21515 switch (ctx->opcode & 0x3) {
21516 case NM_LWC1GP:
21517 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21518 break;
21519 case NM_LDC1GP:
21520 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21521 break;
21522 case NM_SWC1GP:
21523 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21524 break;
21525 case NM_SDC1GP:
21526 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21527 break;
21528 }
21529 break;
21530 default:
21531 generate_exception_end(ctx, EXCP_RI);
21532 break;
21533 }
21534 }
21535 break;
21536 case NM_P_LS_U12:
21537 {
21538 uint32_t u = extract32(ctx->opcode, 0, 12);
21539
21540 switch (extract32(ctx->opcode, 12, 4)) {
21541 case NM_P_PREFU12:
21542 if (rt == 31) {
21543
21544
21545
21546
21547
21548 ctx->base.is_jmp = DISAS_STOP;
21549 } else {
21550
21551
21552 }
21553 break;
21554 case NM_LB:
21555 gen_ld(ctx, OPC_LB, rt, rs, u);
21556 break;
21557 case NM_LH:
21558 gen_ld(ctx, OPC_LH, rt, rs, u);
21559 break;
21560 case NM_LW:
21561 gen_ld(ctx, OPC_LW, rt, rs, u);
21562 break;
21563 case NM_LBU:
21564 gen_ld(ctx, OPC_LBU, rt, rs, u);
21565 break;
21566 case NM_LHU:
21567 gen_ld(ctx, OPC_LHU, rt, rs, u);
21568 break;
21569 case NM_SB:
21570 gen_st(ctx, OPC_SB, rt, rs, u);
21571 break;
21572 case NM_SH:
21573 gen_st(ctx, OPC_SH, rt, rs, u);
21574 break;
21575 case NM_SW:
21576 gen_st(ctx, OPC_SW, rt, rs, u);
21577 break;
21578 case NM_LWC1:
21579 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21580 break;
21581 case NM_LDC1:
21582 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21583 break;
21584 case NM_SWC1:
21585 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21586 break;
21587 case NM_SDC1:
21588 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21589 break;
21590 default:
21591 generate_exception_end(ctx, EXCP_RI);
21592 break;
21593 }
21594 }
21595 break;
21596 case NM_P_LS_S9:
21597 {
21598 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21599 extract32(ctx->opcode, 0, 8);
21600
21601 switch (extract32(ctx->opcode, 8, 3)) {
21602 case NM_P_LS_S0:
21603 switch (extract32(ctx->opcode, 11, 4)) {
21604 case NM_LBS9:
21605 gen_ld(ctx, OPC_LB, rt, rs, s);
21606 break;
21607 case NM_LHS9:
21608 gen_ld(ctx, OPC_LH, rt, rs, s);
21609 break;
21610 case NM_LWS9:
21611 gen_ld(ctx, OPC_LW, rt, rs, s);
21612 break;
21613 case NM_LBUS9:
21614 gen_ld(ctx, OPC_LBU, rt, rs, s);
21615 break;
21616 case NM_LHUS9:
21617 gen_ld(ctx, OPC_LHU, rt, rs, s);
21618 break;
21619 case NM_SBS9:
21620 gen_st(ctx, OPC_SB, rt, rs, s);
21621 break;
21622 case NM_SHS9:
21623 gen_st(ctx, OPC_SH, rt, rs, s);
21624 break;
21625 case NM_SWS9:
21626 gen_st(ctx, OPC_SW, rt, rs, s);
21627 break;
21628 case NM_LWC1S9:
21629 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21630 break;
21631 case NM_LDC1S9:
21632 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21633 break;
21634 case NM_SWC1S9:
21635 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21636 break;
21637 case NM_SDC1S9:
21638 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21639 break;
21640 case NM_P_PREFS9:
21641 if (rt == 31) {
21642
21643
21644
21645
21646
21647 ctx->base.is_jmp = DISAS_STOP;
21648 } else {
21649
21650
21651 }
21652 break;
21653 default:
21654 generate_exception_end(ctx, EXCP_RI);
21655 break;
21656 }
21657 break;
21658 case NM_P_LS_S1:
21659 switch (extract32(ctx->opcode, 11, 4)) {
21660 case NM_UALH:
21661 case NM_UASH:
21662 check_nms(ctx);
21663 {
21664 TCGv t0 = tcg_temp_new();
21665 TCGv t1 = tcg_temp_new();
21666
21667 gen_base_offset_addr(ctx, t0, rs, s);
21668
21669 switch (extract32(ctx->opcode, 11, 4)) {
21670 case NM_UALH:
21671 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21672 MO_UNALN);
21673 gen_store_gpr(t0, rt);
21674 break;
21675 case NM_UASH:
21676 gen_load_gpr(t1, rt);
21677 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21678 MO_UNALN);
21679 break;
21680 }
21681 tcg_temp_free(t0);
21682 tcg_temp_free(t1);
21683 }
21684 break;
21685 case NM_P_LL:
21686 switch (ctx->opcode & 0x03) {
21687 case NM_LL:
21688 gen_ld(ctx, OPC_LL, rt, rs, s);
21689 break;
21690 case NM_LLWP:
21691 check_xnp(ctx);
21692 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21693 break;
21694 }
21695 break;
21696 case NM_P_SC:
21697 switch (ctx->opcode & 0x03) {
21698 case NM_SC:
21699 gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21700 break;
21701 case NM_SCWP:
21702 check_xnp(ctx);
21703 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21704 false);
21705 break;
21706 }
21707 break;
21708 case NM_CACHE:
21709 check_cp0_enabled(ctx);
21710 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21711 gen_cache_operation(ctx, rt, rs, s);
21712 }
21713 break;
21714 }
21715 break;
21716 case NM_P_LS_E0:
21717 switch (extract32(ctx->opcode, 11, 4)) {
21718 case NM_LBE:
21719 check_eva(ctx);
21720 check_cp0_enabled(ctx);
21721 gen_ld(ctx, OPC_LBE, rt, rs, s);
21722 break;
21723 case NM_SBE:
21724 check_eva(ctx);
21725 check_cp0_enabled(ctx);
21726 gen_st(ctx, OPC_SBE, rt, rs, s);
21727 break;
21728 case NM_LBUE:
21729 check_eva(ctx);
21730 check_cp0_enabled(ctx);
21731 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21732 break;
21733 case NM_P_PREFE:
21734 if (rt == 31) {
21735
21736 check_eva(ctx);
21737 check_cp0_enabled(ctx);
21738
21739
21740
21741
21742 ctx->base.is_jmp = DISAS_STOP;
21743 } else {
21744
21745 check_eva(ctx);
21746 check_cp0_enabled(ctx);
21747
21748 }
21749 break;
21750 case NM_LHE:
21751 check_eva(ctx);
21752 check_cp0_enabled(ctx);
21753 gen_ld(ctx, OPC_LHE, rt, rs, s);
21754 break;
21755 case NM_SHE:
21756 check_eva(ctx);
21757 check_cp0_enabled(ctx);
21758 gen_st(ctx, OPC_SHE, rt, rs, s);
21759 break;
21760 case NM_LHUE:
21761 check_eva(ctx);
21762 check_cp0_enabled(ctx);
21763 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21764 break;
21765 case NM_CACHEE:
21766 check_nms_dl_il_sl_tl_l2c(ctx);
21767 gen_cache_operation(ctx, rt, rs, s);
21768 break;
21769 case NM_LWE:
21770 check_eva(ctx);
21771 check_cp0_enabled(ctx);
21772 gen_ld(ctx, OPC_LWE, rt, rs, s);
21773 break;
21774 case NM_SWE:
21775 check_eva(ctx);
21776 check_cp0_enabled(ctx);
21777 gen_st(ctx, OPC_SWE, rt, rs, s);
21778 break;
21779 case NM_P_LLE:
21780 switch (extract32(ctx->opcode, 2, 2)) {
21781 case NM_LLE:
21782 check_xnp(ctx);
21783 check_eva(ctx);
21784 check_cp0_enabled(ctx);
21785 gen_ld(ctx, OPC_LLE, rt, rs, s);
21786 break;
21787 case NM_LLWPE:
21788 check_xnp(ctx);
21789 check_eva(ctx);
21790 check_cp0_enabled(ctx);
21791 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21792 break;
21793 default:
21794 generate_exception_end(ctx, EXCP_RI);
21795 break;
21796 }
21797 break;
21798 case NM_P_SCE:
21799 switch (extract32(ctx->opcode, 2, 2)) {
21800 case NM_SCE:
21801 check_xnp(ctx);
21802 check_eva(ctx);
21803 check_cp0_enabled(ctx);
21804 gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21805 break;
21806 case NM_SCWPE:
21807 check_xnp(ctx);
21808 check_eva(ctx);
21809 check_cp0_enabled(ctx);
21810 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21811 true);
21812 break;
21813 default:
21814 generate_exception_end(ctx, EXCP_RI);
21815 break;
21816 }
21817 break;
21818 }
21819 break;
21820 case NM_P_LS_WM:
21821 case NM_P_LS_UAWM:
21822 check_nms(ctx);
21823 {
21824 int count = extract32(ctx->opcode, 12, 3);
21825 int counter = 0;
21826
21827 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21828 extract32(ctx->opcode, 0, 8);
21829 TCGv va = tcg_temp_new();
21830 TCGv t1 = tcg_temp_new();
21831 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21832 NM_P_LS_UAWM ? MO_UNALN : 0;
21833
21834 count = (count == 0) ? 8 : count;
21835 while (counter != count) {
21836 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21837 int this_offset = offset + (counter << 2);
21838
21839 gen_base_offset_addr(ctx, va, rs, this_offset);
21840
21841 switch (extract32(ctx->opcode, 11, 1)) {
21842 case NM_LWM:
21843 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21844 memop | MO_TESL);
21845 gen_store_gpr(t1, this_rt);
21846 if ((this_rt == rs) &&
21847 (counter != (count - 1))) {
21848
21849 }
21850 break;
21851 case NM_SWM:
21852 this_rt = (rt == 0) ? 0 : this_rt;
21853 gen_load_gpr(t1, this_rt);
21854 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21855 memop | MO_TEUL);
21856 break;
21857 }
21858 counter++;
21859 }
21860 tcg_temp_free(va);
21861 tcg_temp_free(t1);
21862 }
21863 break;
21864 default:
21865 generate_exception_end(ctx, EXCP_RI);
21866 break;
21867 }
21868 }
21869 break;
21870 case NM_MOVE_BALC:
21871 check_nms(ctx);
21872 {
21873 TCGv t0 = tcg_temp_new();
21874 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21875 extract32(ctx->opcode, 1, 20) << 1;
21876 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21877 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21878 extract32(ctx->opcode, 21, 3));
21879 gen_load_gpr(t0, rt);
21880 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21881 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21882 tcg_temp_free(t0);
21883 }
21884 break;
21885 case NM_P_BAL:
21886 {
21887 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21888 extract32(ctx->opcode, 1, 24) << 1;
21889
21890 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21891
21892 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21893 } else {
21894
21895 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21896 }
21897 }
21898 break;
21899 case NM_P_J:
21900 switch (extract32(ctx->opcode, 12, 4)) {
21901 case NM_JALRC:
21902 case NM_JALRC_HB:
21903 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21904 break;
21905 case NM_P_BALRSC:
21906 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21907 break;
21908 default:
21909 generate_exception_end(ctx, EXCP_RI);
21910 break;
21911 }
21912 break;
21913 case NM_P_BR1:
21914 {
21915 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21916 extract32(ctx->opcode, 1, 13) << 1;
21917 switch (extract32(ctx->opcode, 14, 2)) {
21918 case NM_BEQC:
21919 check_nms(ctx);
21920 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21921 break;
21922 case NM_P_BR3A:
21923 s = sextract32(ctx->opcode, 0, 1) << 14 |
21924 extract32(ctx->opcode, 1, 13) << 1;
21925 check_cp1_enabled(ctx);
21926 switch (extract32(ctx->opcode, 16, 5)) {
21927 case NM_BC1EQZC:
21928 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21929 break;
21930 case NM_BC1NEZC:
21931 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21932 break;
21933 case NM_BPOSGE32C:
21934 check_dsp_r3(ctx);
21935 {
21936 int32_t imm = extract32(ctx->opcode, 1, 13) |
21937 extract32(ctx->opcode, 0, 1) << 13;
21938
21939 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21940 imm);
21941 }
21942 break;
21943 default:
21944 generate_exception_end(ctx, EXCP_RI);
21945 break;
21946 }
21947 break;
21948 case NM_BGEC:
21949 if (rs == rt) {
21950 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21951 } else {
21952 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21953 }
21954 break;
21955 case NM_BGEUC:
21956 if (rs == rt || rt == 0) {
21957 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21958 } else if (rs == 0) {
21959 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21960 } else {
21961 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21962 }
21963 break;
21964 }
21965 }
21966 break;
21967 case NM_P_BR2:
21968 {
21969 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21970 extract32(ctx->opcode, 1, 13) << 1;
21971 switch (extract32(ctx->opcode, 14, 2)) {
21972 case NM_BNEC:
21973 check_nms(ctx);
21974 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21975 break;
21976 case NM_BLTC:
21977 if (rs != 0 && rt != 0 && rs == rt) {
21978
21979 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21980 } else {
21981 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21982 }
21983 break;
21984 case NM_BLTUC:
21985 if (rs == 0 || rs == rt) {
21986
21987 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21988 } else {
21989 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21990 }
21991 break;
21992 default:
21993 generate_exception_end(ctx, EXCP_RI);
21994 break;
21995 }
21996 }
21997 break;
21998 case NM_P_BRI:
21999 {
22000 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
22001 extract32(ctx->opcode, 1, 10) << 1;
22002 uint32_t u = extract32(ctx->opcode, 11, 7);
22003
22004 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
22005 rt, u, s);
22006 }
22007 break;
22008 default:
22009 generate_exception_end(ctx, EXCP_RI);
22010 break;
22011 }
22012 return 4;
22013}
22014
22015static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
22016{
22017 uint32_t op;
22018 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
22019 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22020 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
22021 int offset;
22022 int imm;
22023
22024
22025 if (ctx->base.pc_next & 0x1) {
22026 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
22027 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
22028 tcg_temp_free(tmp);
22029 generate_exception_end(ctx, EXCP_AdEL);
22030 return 2;
22031 }
22032
22033 op = extract32(ctx->opcode, 10, 6);
22034 switch (op) {
22035 case NM_P16_MV:
22036 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22037 if (rt != 0) {
22038
22039 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
22040 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
22041 } else {
22042
22043 switch (extract32(ctx->opcode, 3, 2)) {
22044 case NM_P16_SYSCALL:
22045 if (extract32(ctx->opcode, 2, 1) == 0) {
22046 generate_exception_end(ctx, EXCP_SYSCALL);
22047 } else {
22048 generate_exception_end(ctx, EXCP_RI);
22049 }
22050 break;
22051 case NM_BREAK16:
22052 generate_exception_end(ctx, EXCP_BREAK);
22053 break;
22054 case NM_SDBBP16:
22055 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
22056 gen_helper_do_semihosting(cpu_env);
22057 } else {
22058 if (ctx->hflags & MIPS_HFLAG_SBRI) {
22059 generate_exception_end(ctx, EXCP_RI);
22060 } else {
22061 generate_exception_end(ctx, EXCP_DBp);
22062 }
22063 }
22064 break;
22065 default:
22066 generate_exception_end(ctx, EXCP_RI);
22067 break;
22068 }
22069 }
22070 break;
22071 case NM_P16_SHIFT:
22072 {
22073 int shift = extract32(ctx->opcode, 0, 3);
22074 uint32_t opc = 0;
22075 shift = (shift == 0) ? 8 : shift;
22076
22077 switch (extract32(ctx->opcode, 3, 1)) {
22078 case NM_SLL16:
22079 opc = OPC_SLL;
22080 break;
22081 case NM_SRL16:
22082 opc = OPC_SRL;
22083 break;
22084 }
22085 gen_shift_imm(ctx, opc, rt, rs, shift);
22086 }
22087 break;
22088 case NM_P16C:
22089 switch (ctx->opcode & 1) {
22090 case NM_POOL16C_0:
22091 gen_pool16c_nanomips_insn(ctx);
22092 break;
22093 case NM_LWXS16:
22094 gen_ldxs(ctx, rt, rs, rd);
22095 break;
22096 }
22097 break;
22098 case NM_P16_A1:
22099 switch (extract32(ctx->opcode, 6, 1)) {
22100 case NM_ADDIUR1SP:
22101 imm = extract32(ctx->opcode, 0, 6) << 2;
22102 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
22103 break;
22104 default:
22105 generate_exception_end(ctx, EXCP_RI);
22106 break;
22107 }
22108 break;
22109 case NM_P16_A2:
22110 switch (extract32(ctx->opcode, 3, 1)) {
22111 case NM_ADDIUR2:
22112 imm = extract32(ctx->opcode, 0, 3) << 2;
22113 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
22114 break;
22115 case NM_P_ADDIURS5:
22116 rt = extract32(ctx->opcode, 5, 5);
22117 if (rt != 0) {
22118
22119 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
22120 (extract32(ctx->opcode, 0, 3));
22121 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
22122 }
22123 break;
22124 }
22125 break;
22126 case NM_P16_ADDU:
22127 switch (ctx->opcode & 0x1) {
22128 case NM_ADDU16:
22129 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
22130 break;
22131 case NM_SUBU16:
22132 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
22133 break;
22134 }
22135 break;
22136 case NM_P16_4X4:
22137 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22138 extract32(ctx->opcode, 5, 3);
22139 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22140 extract32(ctx->opcode, 0, 3);
22141 rt = decode_gpr_gpr4(rt);
22142 rs = decode_gpr_gpr4(rs);
22143 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22144 (extract32(ctx->opcode, 3, 1))) {
22145 case NM_ADDU4X4:
22146 check_nms(ctx);
22147 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22148 break;
22149 case NM_MUL4X4:
22150 check_nms(ctx);
22151 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22152 break;
22153 default:
22154 generate_exception_end(ctx, EXCP_RI);
22155 break;
22156 }
22157 break;
22158 case NM_LI16:
22159 {
22160 int imm = extract32(ctx->opcode, 0, 7);
22161 imm = (imm == 0x7f ? -1 : imm);
22162 if (rt != 0) {
22163 tcg_gen_movi_tl(cpu_gpr[rt], imm);
22164 }
22165 }
22166 break;
22167 case NM_ANDI16:
22168 {
22169 uint32_t u = extract32(ctx->opcode, 0, 4);
22170 u = (u == 12) ? 0xff :
22171 (u == 13) ? 0xffff : u;
22172 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22173 }
22174 break;
22175 case NM_P16_LB:
22176 offset = extract32(ctx->opcode, 0, 2);
22177 switch (extract32(ctx->opcode, 2, 2)) {
22178 case NM_LB16:
22179 gen_ld(ctx, OPC_LB, rt, rs, offset);
22180 break;
22181 case NM_SB16:
22182 rt = decode_gpr_gpr3_src_store(
22183 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22184 gen_st(ctx, OPC_SB, rt, rs, offset);
22185 break;
22186 case NM_LBU16:
22187 gen_ld(ctx, OPC_LBU, rt, rs, offset);
22188 break;
22189 default:
22190 generate_exception_end(ctx, EXCP_RI);
22191 break;
22192 }
22193 break;
22194 case NM_P16_LH:
22195 offset = extract32(ctx->opcode, 1, 2) << 1;
22196 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22197 case NM_LH16:
22198 gen_ld(ctx, OPC_LH, rt, rs, offset);
22199 break;
22200 case NM_SH16:
22201 rt = decode_gpr_gpr3_src_store(
22202 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22203 gen_st(ctx, OPC_SH, rt, rs, offset);
22204 break;
22205 case NM_LHU16:
22206 gen_ld(ctx, OPC_LHU, rt, rs, offset);
22207 break;
22208 default:
22209 generate_exception_end(ctx, EXCP_RI);
22210 break;
22211 }
22212 break;
22213 case NM_LW16:
22214 offset = extract32(ctx->opcode, 0, 4) << 2;
22215 gen_ld(ctx, OPC_LW, rt, rs, offset);
22216 break;
22217 case NM_LWSP16:
22218 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22219 offset = extract32(ctx->opcode, 0, 5) << 2;
22220 gen_ld(ctx, OPC_LW, rt, 29, offset);
22221 break;
22222 case NM_LW4X4:
22223 check_nms(ctx);
22224 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22225 extract32(ctx->opcode, 5, 3);
22226 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22227 extract32(ctx->opcode, 0, 3);
22228 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22229 (extract32(ctx->opcode, 8, 1) << 2);
22230 rt = decode_gpr_gpr4(rt);
22231 rs = decode_gpr_gpr4(rs);
22232 gen_ld(ctx, OPC_LW, rt, rs, offset);
22233 break;
22234 case NM_SW4X4:
22235 check_nms(ctx);
22236 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22237 extract32(ctx->opcode, 5, 3);
22238 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22239 extract32(ctx->opcode, 0, 3);
22240 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22241 (extract32(ctx->opcode, 8, 1) << 2);
22242 rt = decode_gpr_gpr4_zero(rt);
22243 rs = decode_gpr_gpr4(rs);
22244 gen_st(ctx, OPC_SW, rt, rs, offset);
22245 break;
22246 case NM_LWGP16:
22247 offset = extract32(ctx->opcode, 0, 7) << 2;
22248 gen_ld(ctx, OPC_LW, rt, 28, offset);
22249 break;
22250 case NM_SWSP16:
22251 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22252 offset = extract32(ctx->opcode, 0, 5) << 2;
22253 gen_st(ctx, OPC_SW, rt, 29, offset);
22254 break;
22255 case NM_SW16:
22256 rt = decode_gpr_gpr3_src_store(
22257 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22258 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22259 offset = extract32(ctx->opcode, 0, 4) << 2;
22260 gen_st(ctx, OPC_SW, rt, rs, offset);
22261 break;
22262 case NM_SWGP16:
22263 rt = decode_gpr_gpr3_src_store(
22264 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22265 offset = extract32(ctx->opcode, 0, 7) << 2;
22266 gen_st(ctx, OPC_SW, rt, 28, offset);
22267 break;
22268 case NM_BC16:
22269 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22270 (sextract32(ctx->opcode, 0, 1) << 10) |
22271 (extract32(ctx->opcode, 1, 9) << 1));
22272 break;
22273 case NM_BALC16:
22274 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22275 (sextract32(ctx->opcode, 0, 1) << 10) |
22276 (extract32(ctx->opcode, 1, 9) << 1));
22277 break;
22278 case NM_BEQZC16:
22279 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22280 (sextract32(ctx->opcode, 0, 1) << 7) |
22281 (extract32(ctx->opcode, 1, 6) << 1));
22282 break;
22283 case NM_BNEZC16:
22284 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22285 (sextract32(ctx->opcode, 0, 1) << 7) |
22286 (extract32(ctx->opcode, 1, 6) << 1));
22287 break;
22288 case NM_P16_BR:
22289 switch (ctx->opcode & 0xf) {
22290 case 0:
22291
22292 switch (extract32(ctx->opcode, 4, 1)) {
22293 case NM_JRC:
22294 gen_compute_branch_nm(ctx, OPC_JR, 2,
22295 extract32(ctx->opcode, 5, 5), 0, 0);
22296 break;
22297 case NM_JALRC16:
22298 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22299 extract32(ctx->opcode, 5, 5), 31, 0);
22300 break;
22301 }
22302 break;
22303 default:
22304 {
22305
22306 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22307 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22308 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22309 extract32(ctx->opcode, 0, 4) << 1);
22310 }
22311 break;
22312 }
22313 break;
22314 case NM_P16_SR:
22315 {
22316 int count = extract32(ctx->opcode, 0, 4);
22317 int u = extract32(ctx->opcode, 4, 4) << 4;
22318
22319 rt = 30 + extract32(ctx->opcode, 9, 1);
22320 switch (extract32(ctx->opcode, 8, 1)) {
22321 case NM_SAVE16:
22322 gen_save(ctx, rt, count, 0, u);
22323 break;
22324 case NM_RESTORE_JRC16:
22325 gen_restore(ctx, rt, count, 0, u);
22326 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22327 break;
22328 }
22329 }
22330 break;
22331 case NM_MOVEP:
22332 case NM_MOVEPREV:
22333 check_nms(ctx);
22334 {
22335 static const int gpr2reg1[] = {4, 5, 6, 7};
22336 static const int gpr2reg2[] = {5, 6, 7, 8};
22337 int re;
22338 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22339 extract32(ctx->opcode, 8, 1);
22340 int r1 = gpr2reg1[rd2];
22341 int r2 = gpr2reg2[rd2];
22342 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22343 extract32(ctx->opcode, 0, 3);
22344 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22345 extract32(ctx->opcode, 5, 3);
22346 TCGv t0 = tcg_temp_new();
22347 TCGv t1 = tcg_temp_new();
22348 if (op == NM_MOVEP) {
22349 rd = r1;
22350 re = r2;
22351 rs = decode_gpr_gpr4_zero(r3);
22352 rt = decode_gpr_gpr4_zero(r4);
22353 } else {
22354 rd = decode_gpr_gpr4(r3);
22355 re = decode_gpr_gpr4(r4);
22356 rs = r1;
22357 rt = r2;
22358 }
22359 gen_load_gpr(t0, rs);
22360 gen_load_gpr(t1, rt);
22361 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22362 tcg_gen_mov_tl(cpu_gpr[re], t1);
22363 tcg_temp_free(t0);
22364 tcg_temp_free(t1);
22365 }
22366 break;
22367 default:
22368 return decode_nanomips_32_48_opc(env, ctx);
22369 }
22370
22371 return 2;
22372}
22373
22374
22375
22376
22377#if defined(TARGET_MIPS64)
22378
22379
22380
22381#endif
22382
22383
22384static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22385 int rd, int base, int offset)
22386{
22387 TCGv t0;
22388
22389 check_dsp(ctx);
22390 t0 = tcg_temp_new();
22391
22392 if (base == 0) {
22393 gen_load_gpr(t0, offset);
22394 } else if (offset == 0) {
22395 gen_load_gpr(t0, base);
22396 } else {
22397 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22398 }
22399
22400 switch (opc) {
22401 case OPC_LBUX:
22402 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22403 gen_store_gpr(t0, rd);
22404 break;
22405 case OPC_LHX:
22406 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22407 gen_store_gpr(t0, rd);
22408 break;
22409 case OPC_LWX:
22410 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22411 gen_store_gpr(t0, rd);
22412 break;
22413#if defined(TARGET_MIPS64)
22414 case OPC_LDX:
22415 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22416 gen_store_gpr(t0, rd);
22417 break;
22418#endif
22419 }
22420 tcg_temp_free(t0);
22421}
22422
22423static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22424 int ret, int v1, int v2)
22425{
22426 TCGv v1_t;
22427 TCGv v2_t;
22428
22429 if (ret == 0) {
22430
22431 return;
22432 }
22433
22434 v1_t = tcg_temp_new();
22435 v2_t = tcg_temp_new();
22436
22437 gen_load_gpr(v1_t, v1);
22438 gen_load_gpr(v2_t, v2);
22439
22440 switch (op1) {
22441
22442 case OPC_MULT_G_2E:
22443 check_dsp_r2(ctx);
22444 switch (op2) {
22445 case OPC_ADDUH_QB:
22446 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22447 break;
22448 case OPC_ADDUH_R_QB:
22449 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22450 break;
22451 case OPC_ADDQH_PH:
22452 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22453 break;
22454 case OPC_ADDQH_R_PH:
22455 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22456 break;
22457 case OPC_ADDQH_W:
22458 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22459 break;
22460 case OPC_ADDQH_R_W:
22461 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22462 break;
22463 case OPC_SUBUH_QB:
22464 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22465 break;
22466 case OPC_SUBUH_R_QB:
22467 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22468 break;
22469 case OPC_SUBQH_PH:
22470 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22471 break;
22472 case OPC_SUBQH_R_PH:
22473 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22474 break;
22475 case OPC_SUBQH_W:
22476 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22477 break;
22478 case OPC_SUBQH_R_W:
22479 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22480 break;
22481 }
22482 break;
22483 case OPC_ABSQ_S_PH_DSP:
22484 switch (op2) {
22485 case OPC_ABSQ_S_QB:
22486 check_dsp_r2(ctx);
22487 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22488 break;
22489 case OPC_ABSQ_S_PH:
22490 check_dsp(ctx);
22491 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22492 break;
22493 case OPC_ABSQ_S_W:
22494 check_dsp(ctx);
22495 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22496 break;
22497 case OPC_PRECEQ_W_PHL:
22498 check_dsp(ctx);
22499 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22500 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22501 break;
22502 case OPC_PRECEQ_W_PHR:
22503 check_dsp(ctx);
22504 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22505 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22506 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22507 break;
22508 case OPC_PRECEQU_PH_QBL:
22509 check_dsp(ctx);
22510 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22511 break;
22512 case OPC_PRECEQU_PH_QBR:
22513 check_dsp(ctx);
22514 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22515 break;
22516 case OPC_PRECEQU_PH_QBLA:
22517 check_dsp(ctx);
22518 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22519 break;
22520 case OPC_PRECEQU_PH_QBRA:
22521 check_dsp(ctx);
22522 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22523 break;
22524 case OPC_PRECEU_PH_QBL:
22525 check_dsp(ctx);
22526 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22527 break;
22528 case OPC_PRECEU_PH_QBR:
22529 check_dsp(ctx);
22530 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22531 break;
22532 case OPC_PRECEU_PH_QBLA:
22533 check_dsp(ctx);
22534 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22535 break;
22536 case OPC_PRECEU_PH_QBRA:
22537 check_dsp(ctx);
22538 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22539 break;
22540 }
22541 break;
22542 case OPC_ADDU_QB_DSP:
22543 switch (op2) {
22544 case OPC_ADDQ_PH:
22545 check_dsp(ctx);
22546 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22547 break;
22548 case OPC_ADDQ_S_PH:
22549 check_dsp(ctx);
22550 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22551 break;
22552 case OPC_ADDQ_S_W:
22553 check_dsp(ctx);
22554 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22555 break;
22556 case OPC_ADDU_QB:
22557 check_dsp(ctx);
22558 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22559 break;
22560 case OPC_ADDU_S_QB:
22561 check_dsp(ctx);
22562 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22563 break;
22564 case OPC_ADDU_PH:
22565 check_dsp_r2(ctx);
22566 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22567 break;
22568 case OPC_ADDU_S_PH:
22569 check_dsp_r2(ctx);
22570 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22571 break;
22572 case OPC_SUBQ_PH:
22573 check_dsp(ctx);
22574 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22575 break;
22576 case OPC_SUBQ_S_PH:
22577 check_dsp(ctx);
22578 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22579 break;
22580 case OPC_SUBQ_S_W:
22581 check_dsp(ctx);
22582 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22583 break;
22584 case OPC_SUBU_QB:
22585 check_dsp(ctx);
22586 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22587 break;
22588 case OPC_SUBU_S_QB:
22589 check_dsp(ctx);
22590 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22591 break;
22592 case OPC_SUBU_PH:
22593 check_dsp_r2(ctx);
22594 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22595 break;
22596 case OPC_SUBU_S_PH:
22597 check_dsp_r2(ctx);
22598 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22599 break;
22600 case OPC_ADDSC:
22601 check_dsp(ctx);
22602 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22603 break;
22604 case OPC_ADDWC:
22605 check_dsp(ctx);
22606 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22607 break;
22608 case OPC_MODSUB:
22609 check_dsp(ctx);
22610 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22611 break;
22612 case OPC_RADDU_W_QB:
22613 check_dsp(ctx);
22614 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22615 break;
22616 }
22617 break;
22618 case OPC_CMPU_EQ_QB_DSP:
22619 switch (op2) {
22620 case OPC_PRECR_QB_PH:
22621 check_dsp_r2(ctx);
22622 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22623 break;
22624 case OPC_PRECRQ_QB_PH:
22625 check_dsp(ctx);
22626 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22627 break;
22628 case OPC_PRECR_SRA_PH_W:
22629 check_dsp_r2(ctx);
22630 {
22631 TCGv_i32 sa_t = tcg_const_i32(v2);
22632 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22633 cpu_gpr[ret]);
22634 tcg_temp_free_i32(sa_t);
22635 break;
22636 }
22637 case OPC_PRECR_SRA_R_PH_W:
22638 check_dsp_r2(ctx);
22639 {
22640 TCGv_i32 sa_t = tcg_const_i32(v2);
22641 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22642 cpu_gpr[ret]);
22643 tcg_temp_free_i32(sa_t);
22644 break;
22645 }
22646 case OPC_PRECRQ_PH_W:
22647 check_dsp(ctx);
22648 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22649 break;
22650 case OPC_PRECRQ_RS_PH_W:
22651 check_dsp(ctx);
22652 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22653 break;
22654 case OPC_PRECRQU_S_QB_PH:
22655 check_dsp(ctx);
22656 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22657 break;
22658 }
22659 break;
22660#ifdef TARGET_MIPS64
22661 case OPC_ABSQ_S_QH_DSP:
22662 switch (op2) {
22663 case OPC_PRECEQ_L_PWL:
22664 check_dsp(ctx);
22665 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22666 break;
22667 case OPC_PRECEQ_L_PWR:
22668 check_dsp(ctx);
22669 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22670 break;
22671 case OPC_PRECEQ_PW_QHL:
22672 check_dsp(ctx);
22673 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22674 break;
22675 case OPC_PRECEQ_PW_QHR:
22676 check_dsp(ctx);
22677 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22678 break;
22679 case OPC_PRECEQ_PW_QHLA:
22680 check_dsp(ctx);
22681 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22682 break;
22683 case OPC_PRECEQ_PW_QHRA:
22684 check_dsp(ctx);
22685 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22686 break;
22687 case OPC_PRECEQU_QH_OBL:
22688 check_dsp(ctx);
22689 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22690 break;
22691 case OPC_PRECEQU_QH_OBR:
22692 check_dsp(ctx);
22693 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22694 break;
22695 case OPC_PRECEQU_QH_OBLA:
22696 check_dsp(ctx);
22697 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22698 break;
22699 case OPC_PRECEQU_QH_OBRA:
22700 check_dsp(ctx);
22701 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22702 break;
22703 case OPC_PRECEU_QH_OBL:
22704 check_dsp(ctx);
22705 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22706 break;
22707 case OPC_PRECEU_QH_OBR:
22708 check_dsp(ctx);
22709 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22710 break;
22711 case OPC_PRECEU_QH_OBLA:
22712 check_dsp(ctx);
22713 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22714 break;
22715 case OPC_PRECEU_QH_OBRA:
22716 check_dsp(ctx);
22717 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22718 break;
22719 case OPC_ABSQ_S_OB:
22720 check_dsp_r2(ctx);
22721 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22722 break;
22723 case OPC_ABSQ_S_PW:
22724 check_dsp(ctx);
22725 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22726 break;
22727 case OPC_ABSQ_S_QH:
22728 check_dsp(ctx);
22729 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22730 break;
22731 }
22732 break;
22733 case OPC_ADDU_OB_DSP:
22734 switch (op2) {
22735 case OPC_RADDU_L_OB:
22736 check_dsp(ctx);
22737 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22738 break;
22739 case OPC_SUBQ_PW:
22740 check_dsp(ctx);
22741 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22742 break;
22743 case OPC_SUBQ_S_PW:
22744 check_dsp(ctx);
22745 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22746 break;
22747 case OPC_SUBQ_QH:
22748 check_dsp(ctx);
22749 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22750 break;
22751 case OPC_SUBQ_S_QH:
22752 check_dsp(ctx);
22753 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22754 break;
22755 case OPC_SUBU_OB:
22756 check_dsp(ctx);
22757 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22758 break;
22759 case OPC_SUBU_S_OB:
22760 check_dsp(ctx);
22761 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22762 break;
22763 case OPC_SUBU_QH:
22764 check_dsp_r2(ctx);
22765 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22766 break;
22767 case OPC_SUBU_S_QH:
22768 check_dsp_r2(ctx);
22769 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22770 break;
22771 case OPC_SUBUH_OB:
22772 check_dsp_r2(ctx);
22773 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22774 break;
22775 case OPC_SUBUH_R_OB:
22776 check_dsp_r2(ctx);
22777 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22778 break;
22779 case OPC_ADDQ_PW:
22780 check_dsp(ctx);
22781 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22782 break;
22783 case OPC_ADDQ_S_PW:
22784 check_dsp(ctx);
22785 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22786 break;
22787 case OPC_ADDQ_QH:
22788 check_dsp(ctx);
22789 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22790 break;
22791 case OPC_ADDQ_S_QH:
22792 check_dsp(ctx);
22793 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22794 break;
22795 case OPC_ADDU_OB:
22796 check_dsp(ctx);
22797 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22798 break;
22799 case OPC_ADDU_S_OB:
22800 check_dsp(ctx);
22801 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22802 break;
22803 case OPC_ADDU_QH:
22804 check_dsp_r2(ctx);
22805 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22806 break;
22807 case OPC_ADDU_S_QH:
22808 check_dsp_r2(ctx);
22809 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22810 break;
22811 case OPC_ADDUH_OB:
22812 check_dsp_r2(ctx);
22813 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22814 break;
22815 case OPC_ADDUH_R_OB:
22816 check_dsp_r2(ctx);
22817 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22818 break;
22819 }
22820 break;
22821 case OPC_CMPU_EQ_OB_DSP:
22822 switch (op2) {
22823 case OPC_PRECR_OB_QH:
22824 check_dsp_r2(ctx);
22825 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22826 break;
22827 case OPC_PRECR_SRA_QH_PW:
22828 check_dsp_r2(ctx);
22829 {
22830 TCGv_i32 ret_t = tcg_const_i32(ret);
22831 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22832 tcg_temp_free_i32(ret_t);
22833 break;
22834 }
22835 case OPC_PRECR_SRA_R_QH_PW:
22836 check_dsp_r2(ctx);
22837 {
22838 TCGv_i32 sa_v = tcg_const_i32(ret);
22839 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22840 tcg_temp_free_i32(sa_v);
22841 break;
22842 }
22843 case OPC_PRECRQ_OB_QH:
22844 check_dsp(ctx);
22845 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22846 break;
22847 case OPC_PRECRQ_PW_L:
22848 check_dsp(ctx);
22849 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22850 break;
22851 case OPC_PRECRQ_QH_PW:
22852 check_dsp(ctx);
22853 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22854 break;
22855 case OPC_PRECRQ_RS_QH_PW:
22856 check_dsp(ctx);
22857 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22858 break;
22859 case OPC_PRECRQU_S_OB_QH:
22860 check_dsp(ctx);
22861 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22862 break;
22863 }
22864 break;
22865#endif
22866 }
22867
22868 tcg_temp_free(v1_t);
22869 tcg_temp_free(v2_t);
22870}
22871
22872static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22873 int ret, int v1, int v2)
22874{
22875 uint32_t op2;
22876 TCGv t0;
22877 TCGv v1_t;
22878 TCGv v2_t;
22879
22880 if (ret == 0) {
22881
22882 return;
22883 }
22884
22885 t0 = tcg_temp_new();
22886 v1_t = tcg_temp_new();
22887 v2_t = tcg_temp_new();
22888
22889 tcg_gen_movi_tl(t0, v1);
22890 gen_load_gpr(v1_t, v1);
22891 gen_load_gpr(v2_t, v2);
22892
22893 switch (opc) {
22894 case OPC_SHLL_QB_DSP:
22895 {
22896 op2 = MASK_SHLL_QB(ctx->opcode);
22897 switch (op2) {
22898 case OPC_SHLL_QB:
22899 check_dsp(ctx);
22900 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22901 break;
22902 case OPC_SHLLV_QB:
22903 check_dsp(ctx);
22904 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22905 break;
22906 case OPC_SHLL_PH:
22907 check_dsp(ctx);
22908 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22909 break;
22910 case OPC_SHLLV_PH:
22911 check_dsp(ctx);
22912 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22913 break;
22914 case OPC_SHLL_S_PH:
22915 check_dsp(ctx);
22916 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22917 break;
22918 case OPC_SHLLV_S_PH:
22919 check_dsp(ctx);
22920 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22921 break;
22922 case OPC_SHLL_S_W:
22923 check_dsp(ctx);
22924 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22925 break;
22926 case OPC_SHLLV_S_W:
22927 check_dsp(ctx);
22928 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22929 break;
22930 case OPC_SHRL_QB:
22931 check_dsp(ctx);
22932 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22933 break;
22934 case OPC_SHRLV_QB:
22935 check_dsp(ctx);
22936 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22937 break;
22938 case OPC_SHRL_PH:
22939 check_dsp_r2(ctx);
22940 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22941 break;
22942 case OPC_SHRLV_PH:
22943 check_dsp_r2(ctx);
22944 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22945 break;
22946 case OPC_SHRA_QB:
22947 check_dsp_r2(ctx);
22948 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22949 break;
22950 case OPC_SHRA_R_QB:
22951 check_dsp_r2(ctx);
22952 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22953 break;
22954 case OPC_SHRAV_QB:
22955 check_dsp_r2(ctx);
22956 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22957 break;
22958 case OPC_SHRAV_R_QB:
22959 check_dsp_r2(ctx);
22960 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22961 break;
22962 case OPC_SHRA_PH:
22963 check_dsp(ctx);
22964 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22965 break;
22966 case OPC_SHRA_R_PH:
22967 check_dsp(ctx);
22968 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22969 break;
22970 case OPC_SHRAV_PH:
22971 check_dsp(ctx);
22972 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22973 break;
22974 case OPC_SHRAV_R_PH:
22975 check_dsp(ctx);
22976 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22977 break;
22978 case OPC_SHRA_R_W:
22979 check_dsp(ctx);
22980 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22981 break;
22982 case OPC_SHRAV_R_W:
22983 check_dsp(ctx);
22984 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22985 break;
22986 default:
22987 MIPS_INVAL("MASK SHLL.QB");
22988 generate_exception_end(ctx, EXCP_RI);
22989 break;
22990 }
22991 break;
22992 }
22993#ifdef TARGET_MIPS64
22994 case OPC_SHLL_OB_DSP:
22995 op2 = MASK_SHLL_OB(ctx->opcode);
22996 switch (op2) {
22997 case OPC_SHLL_PW:
22998 check_dsp(ctx);
22999 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23000 break;
23001 case OPC_SHLLV_PW:
23002 check_dsp(ctx);
23003 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23004 break;
23005 case OPC_SHLL_S_PW:
23006 check_dsp(ctx);
23007 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23008 break;
23009 case OPC_SHLLV_S_PW:
23010 check_dsp(ctx);
23011 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23012 break;
23013 case OPC_SHLL_OB:
23014 check_dsp(ctx);
23015 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
23016 break;
23017 case OPC_SHLLV_OB:
23018 check_dsp(ctx);
23019 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23020 break;
23021 case OPC_SHLL_QH:
23022 check_dsp(ctx);
23023 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23024 break;
23025 case OPC_SHLLV_QH:
23026 check_dsp(ctx);
23027 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23028 break;
23029 case OPC_SHLL_S_QH:
23030 check_dsp(ctx);
23031 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23032 break;
23033 case OPC_SHLLV_S_QH:
23034 check_dsp(ctx);
23035 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23036 break;
23037 case OPC_SHRA_OB:
23038 check_dsp_r2(ctx);
23039 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
23040 break;
23041 case OPC_SHRAV_OB:
23042 check_dsp_r2(ctx);
23043 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
23044 break;
23045 case OPC_SHRA_R_OB:
23046 check_dsp_r2(ctx);
23047 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
23048 break;
23049 case OPC_SHRAV_R_OB:
23050 check_dsp_r2(ctx);
23051 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
23052 break;
23053 case OPC_SHRA_PW:
23054 check_dsp(ctx);
23055 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
23056 break;
23057 case OPC_SHRAV_PW:
23058 check_dsp(ctx);
23059 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
23060 break;
23061 case OPC_SHRA_R_PW:
23062 check_dsp(ctx);
23063 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
23064 break;
23065 case OPC_SHRAV_R_PW:
23066 check_dsp(ctx);
23067 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
23068 break;
23069 case OPC_SHRA_QH:
23070 check_dsp(ctx);
23071 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
23072 break;
23073 case OPC_SHRAV_QH:
23074 check_dsp(ctx);
23075 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
23076 break;
23077 case OPC_SHRA_R_QH:
23078 check_dsp(ctx);
23079 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
23080 break;
23081 case OPC_SHRAV_R_QH:
23082 check_dsp(ctx);
23083 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
23084 break;
23085 case OPC_SHRL_OB:
23086 check_dsp(ctx);
23087 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
23088 break;
23089 case OPC_SHRLV_OB:
23090 check_dsp(ctx);
23091 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
23092 break;
23093 case OPC_SHRL_QH:
23094 check_dsp_r2(ctx);
23095 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
23096 break;
23097 case OPC_SHRLV_QH:
23098 check_dsp_r2(ctx);
23099 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
23100 break;
23101 default:
23102 MIPS_INVAL("MASK SHLL.OB");
23103 generate_exception_end(ctx, EXCP_RI);
23104 break;
23105 }
23106 break;
23107#endif
23108 }
23109
23110 tcg_temp_free(t0);
23111 tcg_temp_free(v1_t);
23112 tcg_temp_free(v2_t);
23113}
23114
23115static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
23116 int ret, int v1, int v2, int check_ret)
23117{
23118 TCGv_i32 t0;
23119 TCGv v1_t;
23120 TCGv v2_t;
23121
23122 if ((ret == 0) && (check_ret == 1)) {
23123
23124 return;
23125 }
23126
23127 t0 = tcg_temp_new_i32();
23128 v1_t = tcg_temp_new();
23129 v2_t = tcg_temp_new();
23130
23131 tcg_gen_movi_i32(t0, ret);
23132 gen_load_gpr(v1_t, v1);
23133 gen_load_gpr(v2_t, v2);
23134
23135 switch (op1) {
23136
23137
23138
23139
23140 case OPC_MULT_G_2E:
23141 check_dsp_r2(ctx);
23142 switch (op2) {
23143 case OPC_MUL_PH:
23144 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23145 break;
23146 case OPC_MUL_S_PH:
23147 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23148 break;
23149 case OPC_MULQ_S_W:
23150 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23151 break;
23152 case OPC_MULQ_RS_W:
23153 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23154 break;
23155 }
23156 break;
23157 case OPC_DPA_W_PH_DSP:
23158 switch (op2) {
23159 case OPC_DPAU_H_QBL:
23160 check_dsp(ctx);
23161 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23162 break;
23163 case OPC_DPAU_H_QBR:
23164 check_dsp(ctx);
23165 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23166 break;
23167 case OPC_DPSU_H_QBL:
23168 check_dsp(ctx);
23169 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23170 break;
23171 case OPC_DPSU_H_QBR:
23172 check_dsp(ctx);
23173 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23174 break;
23175 case OPC_DPA_W_PH:
23176 check_dsp_r2(ctx);
23177 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23178 break;
23179 case OPC_DPAX_W_PH:
23180 check_dsp_r2(ctx);
23181 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23182 break;
23183 case OPC_DPAQ_S_W_PH:
23184 check_dsp(ctx);
23185 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23186 break;
23187 case OPC_DPAQX_S_W_PH:
23188 check_dsp_r2(ctx);
23189 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23190 break;
23191 case OPC_DPAQX_SA_W_PH:
23192 check_dsp_r2(ctx);
23193 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23194 break;
23195 case OPC_DPS_W_PH:
23196 check_dsp_r2(ctx);
23197 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23198 break;
23199 case OPC_DPSX_W_PH:
23200 check_dsp_r2(ctx);
23201 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23202 break;
23203 case OPC_DPSQ_S_W_PH:
23204 check_dsp(ctx);
23205 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23206 break;
23207 case OPC_DPSQX_S_W_PH:
23208 check_dsp_r2(ctx);
23209 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23210 break;
23211 case OPC_DPSQX_SA_W_PH:
23212 check_dsp_r2(ctx);
23213 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23214 break;
23215 case OPC_MULSAQ_S_W_PH:
23216 check_dsp(ctx);
23217 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23218 break;
23219 case OPC_DPAQ_SA_L_W:
23220 check_dsp(ctx);
23221 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23222 break;
23223 case OPC_DPSQ_SA_L_W:
23224 check_dsp(ctx);
23225 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23226 break;
23227 case OPC_MAQ_S_W_PHL:
23228 check_dsp(ctx);
23229 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23230 break;
23231 case OPC_MAQ_S_W_PHR:
23232 check_dsp(ctx);
23233 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23234 break;
23235 case OPC_MAQ_SA_W_PHL:
23236 check_dsp(ctx);
23237 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23238 break;
23239 case OPC_MAQ_SA_W_PHR:
23240 check_dsp(ctx);
23241 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23242 break;
23243 case OPC_MULSA_W_PH:
23244 check_dsp_r2(ctx);
23245 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23246 break;
23247 }
23248 break;
23249#ifdef TARGET_MIPS64
23250 case OPC_DPAQ_W_QH_DSP:
23251 {
23252 int ac = ret & 0x03;
23253 tcg_gen_movi_i32(t0, ac);
23254
23255 switch (op2) {
23256 case OPC_DMADD:
23257 check_dsp(ctx);
23258 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23259 break;
23260 case OPC_DMADDU:
23261 check_dsp(ctx);
23262 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23263 break;
23264 case OPC_DMSUB:
23265 check_dsp(ctx);
23266 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23267 break;
23268 case OPC_DMSUBU:
23269 check_dsp(ctx);
23270 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23271 break;
23272 case OPC_DPA_W_QH:
23273 check_dsp_r2(ctx);
23274 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23275 break;
23276 case OPC_DPAQ_S_W_QH:
23277 check_dsp(ctx);
23278 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23279 break;
23280 case OPC_DPAQ_SA_L_PW:
23281 check_dsp(ctx);
23282 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23283 break;
23284 case OPC_DPAU_H_OBL:
23285 check_dsp(ctx);
23286 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23287 break;
23288 case OPC_DPAU_H_OBR:
23289 check_dsp(ctx);
23290 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23291 break;
23292 case OPC_DPS_W_QH:
23293 check_dsp_r2(ctx);
23294 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23295 break;
23296 case OPC_DPSQ_S_W_QH:
23297 check_dsp(ctx);
23298 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23299 break;
23300 case OPC_DPSQ_SA_L_PW:
23301 check_dsp(ctx);
23302 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23303 break;
23304 case OPC_DPSU_H_OBL:
23305 check_dsp(ctx);
23306 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23307 break;
23308 case OPC_DPSU_H_OBR:
23309 check_dsp(ctx);
23310 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23311 break;
23312 case OPC_MAQ_S_L_PWL:
23313 check_dsp(ctx);
23314 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23315 break;
23316 case OPC_MAQ_S_L_PWR:
23317 check_dsp(ctx);
23318 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23319 break;
23320 case OPC_MAQ_S_W_QHLL:
23321 check_dsp(ctx);
23322 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23323 break;
23324 case OPC_MAQ_SA_W_QHLL:
23325 check_dsp(ctx);
23326 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23327 break;
23328 case OPC_MAQ_S_W_QHLR:
23329 check_dsp(ctx);
23330 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23331 break;
23332 case OPC_MAQ_SA_W_QHLR:
23333 check_dsp(ctx);
23334 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23335 break;
23336 case OPC_MAQ_S_W_QHRL:
23337 check_dsp(ctx);
23338 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23339 break;
23340 case OPC_MAQ_SA_W_QHRL:
23341 check_dsp(ctx);
23342 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23343 break;
23344 case OPC_MAQ_S_W_QHRR:
23345 check_dsp(ctx);
23346 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23347 break;
23348 case OPC_MAQ_SA_W_QHRR:
23349 check_dsp(ctx);
23350 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23351 break;
23352 case OPC_MULSAQ_S_L_PW:
23353 check_dsp(ctx);
23354 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23355 break;
23356 case OPC_MULSAQ_S_W_QH:
23357 check_dsp(ctx);
23358 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23359 break;
23360 }
23361 }
23362 break;
23363#endif
23364 case OPC_ADDU_QB_DSP:
23365 switch (op2) {
23366 case OPC_MULEU_S_PH_QBL:
23367 check_dsp(ctx);
23368 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23369 break;
23370 case OPC_MULEU_S_PH_QBR:
23371 check_dsp(ctx);
23372 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23373 break;
23374 case OPC_MULQ_RS_PH:
23375 check_dsp(ctx);
23376 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23377 break;
23378 case OPC_MULEQ_S_W_PHL:
23379 check_dsp(ctx);
23380 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23381 break;
23382 case OPC_MULEQ_S_W_PHR:
23383 check_dsp(ctx);
23384 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23385 break;
23386 case OPC_MULQ_S_PH:
23387 check_dsp_r2(ctx);
23388 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23389 break;
23390 }
23391 break;
23392#ifdef TARGET_MIPS64
23393 case OPC_ADDU_OB_DSP:
23394 switch (op2) {
23395 case OPC_MULEQ_S_PW_QHL:
23396 check_dsp(ctx);
23397 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23398 break;
23399 case OPC_MULEQ_S_PW_QHR:
23400 check_dsp(ctx);
23401 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23402 break;
23403 case OPC_MULEU_S_QH_OBL:
23404 check_dsp(ctx);
23405 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23406 break;
23407 case OPC_MULEU_S_QH_OBR:
23408 check_dsp(ctx);
23409 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23410 break;
23411 case OPC_MULQ_RS_QH:
23412 check_dsp(ctx);
23413 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23414 break;
23415 }
23416 break;
23417#endif
23418 }
23419
23420 tcg_temp_free_i32(t0);
23421 tcg_temp_free(v1_t);
23422 tcg_temp_free(v2_t);
23423}
23424
23425static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23426 int ret, int val)
23427{
23428 int16_t imm;
23429 TCGv t0;
23430 TCGv val_t;
23431
23432 if (ret == 0) {
23433
23434 return;
23435 }
23436
23437 t0 = tcg_temp_new();
23438 val_t = tcg_temp_new();
23439 gen_load_gpr(val_t, val);
23440
23441 switch (op1) {
23442 case OPC_ABSQ_S_PH_DSP:
23443 switch (op2) {
23444 case OPC_BITREV:
23445 check_dsp(ctx);
23446 gen_helper_bitrev(cpu_gpr[ret], val_t);
23447 break;
23448 case OPC_REPL_QB:
23449 check_dsp(ctx);
23450 {
23451 target_long result;
23452 imm = (ctx->opcode >> 16) & 0xFF;
23453 result = (uint32_t)imm << 24 |
23454 (uint32_t)imm << 16 |
23455 (uint32_t)imm << 8 |
23456 (uint32_t)imm;
23457 result = (int32_t)result;
23458 tcg_gen_movi_tl(cpu_gpr[ret], result);
23459 }
23460 break;
23461 case OPC_REPLV_QB:
23462 check_dsp(ctx);
23463 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23464 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23465 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23466 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23467 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23468 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23469 break;
23470 case OPC_REPL_PH:
23471 check_dsp(ctx);
23472 {
23473 imm = (ctx->opcode >> 16) & 0x03FF;
23474 imm = (int16_t)(imm << 6) >> 6;
23475 tcg_gen_movi_tl(cpu_gpr[ret], \
23476 (target_long)((int32_t)imm << 16 | \
23477 (uint16_t)imm));
23478 }
23479 break;
23480 case OPC_REPLV_PH:
23481 check_dsp(ctx);
23482 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23483 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23484 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23485 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23486 break;
23487 }
23488 break;
23489#ifdef TARGET_MIPS64
23490 case OPC_ABSQ_S_QH_DSP:
23491 switch (op2) {
23492 case OPC_REPL_OB:
23493 check_dsp(ctx);
23494 {
23495 target_long temp;
23496
23497 imm = (ctx->opcode >> 16) & 0xFF;
23498 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23499 temp = (temp << 16) | temp;
23500 temp = (temp << 32) | temp;
23501 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23502 break;
23503 }
23504 case OPC_REPL_PW:
23505 check_dsp(ctx);
23506 {
23507 target_long temp;
23508
23509 imm = (ctx->opcode >> 16) & 0x03FF;
23510 imm = (int16_t)(imm << 6) >> 6;
23511 temp = ((target_long)imm << 32) \
23512 | ((target_long)imm & 0xFFFFFFFF);
23513 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23514 break;
23515 }
23516 case OPC_REPL_QH:
23517 check_dsp(ctx);
23518 {
23519 target_long temp;
23520
23521 imm = (ctx->opcode >> 16) & 0x03FF;
23522 imm = (int16_t)(imm << 6) >> 6;
23523
23524 temp = ((uint64_t)(uint16_t)imm << 48) |
23525 ((uint64_t)(uint16_t)imm << 32) |
23526 ((uint64_t)(uint16_t)imm << 16) |
23527 (uint64_t)(uint16_t)imm;
23528 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23529 break;
23530 }
23531 case OPC_REPLV_OB:
23532 check_dsp(ctx);
23533 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23534 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23535 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23536 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23537 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23538 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23539 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23540 break;
23541 case OPC_REPLV_PW:
23542 check_dsp(ctx);
23543 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23544 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23545 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23546 break;
23547 case OPC_REPLV_QH:
23548 check_dsp(ctx);
23549 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23550 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23551 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23552 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23553 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23554 break;
23555 }
23556 break;
23557#endif
23558 }
23559 tcg_temp_free(t0);
23560 tcg_temp_free(val_t);
23561}
23562
23563static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23564 uint32_t op1, uint32_t op2,
23565 int ret, int v1, int v2, int check_ret)
23566{
23567 TCGv t1;
23568 TCGv v1_t;
23569 TCGv v2_t;
23570
23571 if ((ret == 0) && (check_ret == 1)) {
23572
23573 return;
23574 }
23575
23576 t1 = tcg_temp_new();
23577 v1_t = tcg_temp_new();
23578 v2_t = tcg_temp_new();
23579
23580 gen_load_gpr(v1_t, v1);
23581 gen_load_gpr(v2_t, v2);
23582
23583 switch (op1) {
23584 case OPC_CMPU_EQ_QB_DSP:
23585 switch (op2) {
23586 case OPC_CMPU_EQ_QB:
23587 check_dsp(ctx);
23588 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23589 break;
23590 case OPC_CMPU_LT_QB:
23591 check_dsp(ctx);
23592 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23593 break;
23594 case OPC_CMPU_LE_QB:
23595 check_dsp(ctx);
23596 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23597 break;
23598 case OPC_CMPGU_EQ_QB:
23599 check_dsp(ctx);
23600 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23601 break;
23602 case OPC_CMPGU_LT_QB:
23603 check_dsp(ctx);
23604 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23605 break;
23606 case OPC_CMPGU_LE_QB:
23607 check_dsp(ctx);
23608 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23609 break;
23610 case OPC_CMPGDU_EQ_QB:
23611 check_dsp_r2(ctx);
23612 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23613 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23614 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23615 tcg_gen_shli_tl(t1, t1, 24);
23616 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23617 break;
23618 case OPC_CMPGDU_LT_QB:
23619 check_dsp_r2(ctx);
23620 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23621 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23622 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23623 tcg_gen_shli_tl(t1, t1, 24);
23624 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23625 break;
23626 case OPC_CMPGDU_LE_QB:
23627 check_dsp_r2(ctx);
23628 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23629 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23630 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23631 tcg_gen_shli_tl(t1, t1, 24);
23632 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23633 break;
23634 case OPC_CMP_EQ_PH:
23635 check_dsp(ctx);
23636 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23637 break;
23638 case OPC_CMP_LT_PH:
23639 check_dsp(ctx);
23640 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23641 break;
23642 case OPC_CMP_LE_PH:
23643 check_dsp(ctx);
23644 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23645 break;
23646 case OPC_PICK_QB:
23647 check_dsp(ctx);
23648 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23649 break;
23650 case OPC_PICK_PH:
23651 check_dsp(ctx);
23652 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23653 break;
23654 case OPC_PACKRL_PH:
23655 check_dsp(ctx);
23656 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23657 break;
23658 }
23659 break;
23660#ifdef TARGET_MIPS64
23661 case OPC_CMPU_EQ_OB_DSP:
23662 switch (op2) {
23663 case OPC_CMP_EQ_PW:
23664 check_dsp(ctx);
23665 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23666 break;
23667 case OPC_CMP_LT_PW:
23668 check_dsp(ctx);
23669 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23670 break;
23671 case OPC_CMP_LE_PW:
23672 check_dsp(ctx);
23673 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23674 break;
23675 case OPC_CMP_EQ_QH:
23676 check_dsp(ctx);
23677 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23678 break;
23679 case OPC_CMP_LT_QH:
23680 check_dsp(ctx);
23681 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23682 break;
23683 case OPC_CMP_LE_QH:
23684 check_dsp(ctx);
23685 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23686 break;
23687 case OPC_CMPGDU_EQ_OB:
23688 check_dsp_r2(ctx);
23689 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23690 break;
23691 case OPC_CMPGDU_LT_OB:
23692 check_dsp_r2(ctx);
23693 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23694 break;
23695 case OPC_CMPGDU_LE_OB:
23696 check_dsp_r2(ctx);
23697 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23698 break;
23699 case OPC_CMPGU_EQ_OB:
23700 check_dsp(ctx);
23701 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23702 break;
23703 case OPC_CMPGU_LT_OB:
23704 check_dsp(ctx);
23705 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23706 break;
23707 case OPC_CMPGU_LE_OB:
23708 check_dsp(ctx);
23709 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23710 break;
23711 case OPC_CMPU_EQ_OB:
23712 check_dsp(ctx);
23713 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23714 break;
23715 case OPC_CMPU_LT_OB:
23716 check_dsp(ctx);
23717 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23718 break;
23719 case OPC_CMPU_LE_OB:
23720 check_dsp(ctx);
23721 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23722 break;
23723 case OPC_PACKRL_PW:
23724 check_dsp(ctx);
23725 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23726 break;
23727 case OPC_PICK_OB:
23728 check_dsp(ctx);
23729 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23730 break;
23731 case OPC_PICK_PW:
23732 check_dsp(ctx);
23733 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23734 break;
23735 case OPC_PICK_QH:
23736 check_dsp(ctx);
23737 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23738 break;
23739 }
23740 break;
23741#endif
23742 }
23743
23744 tcg_temp_free(t1);
23745 tcg_temp_free(v1_t);
23746 tcg_temp_free(v2_t);
23747}
23748
23749static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23750 uint32_t op1, int rt, int rs, int sa)
23751{
23752 TCGv t0;
23753
23754 check_dsp_r2(ctx);
23755
23756 if (rt == 0) {
23757
23758 return;
23759 }
23760
23761 t0 = tcg_temp_new();
23762 gen_load_gpr(t0, rs);
23763
23764 switch (op1) {
23765 case OPC_APPEND_DSP:
23766 switch (MASK_APPEND(ctx->opcode)) {
23767 case OPC_APPEND:
23768 if (sa != 0) {
23769 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23770 }
23771 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23772 break;
23773 case OPC_PREPEND:
23774 if (sa != 0) {
23775 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23776 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23777 tcg_gen_shli_tl(t0, t0, 32 - sa);
23778 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23779 }
23780 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23781 break;
23782 case OPC_BALIGN:
23783 sa &= 3;
23784 if (sa != 0 && sa != 2) {
23785 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23786 tcg_gen_ext32u_tl(t0, t0);
23787 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23788 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23789 }
23790 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23791 break;
23792 default:
23793 MIPS_INVAL("MASK APPEND");
23794 generate_exception_end(ctx, EXCP_RI);
23795 break;
23796 }
23797 break;
23798#ifdef TARGET_MIPS64
23799 case OPC_DAPPEND_DSP:
23800 switch (MASK_DAPPEND(ctx->opcode)) {
23801 case OPC_DAPPEND:
23802 if (sa != 0) {
23803 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23804 }
23805 break;
23806 case OPC_PREPENDD:
23807 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23808 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23809 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23810 break;
23811 case OPC_PREPENDW:
23812 if (sa != 0) {
23813 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23814 tcg_gen_shli_tl(t0, t0, 64 - sa);
23815 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23816 }
23817 break;
23818 case OPC_DBALIGN:
23819 sa &= 7;
23820 if (sa != 0 && sa != 2 && sa != 4) {
23821 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23822 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23823 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23824 }
23825 break;
23826 default:
23827 MIPS_INVAL("MASK DAPPEND");
23828 generate_exception_end(ctx, EXCP_RI);
23829 break;
23830 }
23831 break;
23832#endif
23833 }
23834 tcg_temp_free(t0);
23835}
23836
23837static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23838 int ret, int v1, int v2, int check_ret)
23839
23840{
23841 TCGv t0;
23842 TCGv t1;
23843 TCGv v1_t;
23844 TCGv v2_t;
23845 int16_t imm;
23846
23847 if ((ret == 0) && (check_ret == 1)) {
23848
23849 return;
23850 }
23851
23852 t0 = tcg_temp_new();
23853 t1 = tcg_temp_new();
23854 v1_t = tcg_temp_new();
23855 v2_t = tcg_temp_new();
23856
23857 gen_load_gpr(v1_t, v1);
23858 gen_load_gpr(v2_t, v2);
23859
23860 switch (op1) {
23861 case OPC_EXTR_W_DSP:
23862 check_dsp(ctx);
23863 switch (op2) {
23864 case OPC_EXTR_W:
23865 tcg_gen_movi_tl(t0, v2);
23866 tcg_gen_movi_tl(t1, v1);
23867 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23868 break;
23869 case OPC_EXTR_R_W:
23870 tcg_gen_movi_tl(t0, v2);
23871 tcg_gen_movi_tl(t1, v1);
23872 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23873 break;
23874 case OPC_EXTR_RS_W:
23875 tcg_gen_movi_tl(t0, v2);
23876 tcg_gen_movi_tl(t1, v1);
23877 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23878 break;
23879 case OPC_EXTR_S_H:
23880 tcg_gen_movi_tl(t0, v2);
23881 tcg_gen_movi_tl(t1, v1);
23882 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23883 break;
23884 case OPC_EXTRV_S_H:
23885 tcg_gen_movi_tl(t0, v2);
23886 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23887 break;
23888 case OPC_EXTRV_W:
23889 tcg_gen_movi_tl(t0, v2);
23890 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23891 break;
23892 case OPC_EXTRV_R_W:
23893 tcg_gen_movi_tl(t0, v2);
23894 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23895 break;
23896 case OPC_EXTRV_RS_W:
23897 tcg_gen_movi_tl(t0, v2);
23898 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23899 break;
23900 case OPC_EXTP:
23901 tcg_gen_movi_tl(t0, v2);
23902 tcg_gen_movi_tl(t1, v1);
23903 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23904 break;
23905 case OPC_EXTPV:
23906 tcg_gen_movi_tl(t0, v2);
23907 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23908 break;
23909 case OPC_EXTPDP:
23910 tcg_gen_movi_tl(t0, v2);
23911 tcg_gen_movi_tl(t1, v1);
23912 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23913 break;
23914 case OPC_EXTPDPV:
23915 tcg_gen_movi_tl(t0, v2);
23916 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23917 break;
23918 case OPC_SHILO:
23919 imm = (ctx->opcode >> 20) & 0x3F;
23920 tcg_gen_movi_tl(t0, ret);
23921 tcg_gen_movi_tl(t1, imm);
23922 gen_helper_shilo(t0, t1, cpu_env);
23923 break;
23924 case OPC_SHILOV:
23925 tcg_gen_movi_tl(t0, ret);
23926 gen_helper_shilo(t0, v1_t, cpu_env);
23927 break;
23928 case OPC_MTHLIP:
23929 tcg_gen_movi_tl(t0, ret);
23930 gen_helper_mthlip(t0, v1_t, cpu_env);
23931 break;
23932 case OPC_WRDSP:
23933 imm = (ctx->opcode >> 11) & 0x3FF;
23934 tcg_gen_movi_tl(t0, imm);
23935 gen_helper_wrdsp(v1_t, t0, cpu_env);
23936 break;
23937 case OPC_RDDSP:
23938 imm = (ctx->opcode >> 16) & 0x03FF;
23939 tcg_gen_movi_tl(t0, imm);
23940 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23941 break;
23942 }
23943 break;
23944#ifdef TARGET_MIPS64
23945 case OPC_DEXTR_W_DSP:
23946 check_dsp(ctx);
23947 switch (op2) {
23948 case OPC_DMTHLIP:
23949 tcg_gen_movi_tl(t0, ret);
23950 gen_helper_dmthlip(v1_t, t0, cpu_env);
23951 break;
23952 case OPC_DSHILO:
23953 {
23954 int shift = (ctx->opcode >> 19) & 0x7F;
23955 int ac = (ctx->opcode >> 11) & 0x03;
23956 tcg_gen_movi_tl(t0, shift);
23957 tcg_gen_movi_tl(t1, ac);
23958 gen_helper_dshilo(t0, t1, cpu_env);
23959 break;
23960 }
23961 case OPC_DSHILOV:
23962 {
23963 int ac = (ctx->opcode >> 11) & 0x03;
23964 tcg_gen_movi_tl(t0, ac);
23965 gen_helper_dshilo(v1_t, t0, cpu_env);
23966 break;
23967 }
23968 case OPC_DEXTP:
23969 tcg_gen_movi_tl(t0, v2);
23970 tcg_gen_movi_tl(t1, v1);
23971
23972 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23973 break;
23974 case OPC_DEXTPV:
23975 tcg_gen_movi_tl(t0, v2);
23976 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23977 break;
23978 case OPC_DEXTPDP:
23979 tcg_gen_movi_tl(t0, v2);
23980 tcg_gen_movi_tl(t1, v1);
23981 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23982 break;
23983 case OPC_DEXTPDPV:
23984 tcg_gen_movi_tl(t0, v2);
23985 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23986 break;
23987 case OPC_DEXTR_L:
23988 tcg_gen_movi_tl(t0, v2);
23989 tcg_gen_movi_tl(t1, v1);
23990 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23991 break;
23992 case OPC_DEXTR_R_L:
23993 tcg_gen_movi_tl(t0, v2);
23994 tcg_gen_movi_tl(t1, v1);
23995 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23996 break;
23997 case OPC_DEXTR_RS_L:
23998 tcg_gen_movi_tl(t0, v2);
23999 tcg_gen_movi_tl(t1, v1);
24000 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
24001 break;
24002 case OPC_DEXTR_W:
24003 tcg_gen_movi_tl(t0, v2);
24004 tcg_gen_movi_tl(t1, v1);
24005 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
24006 break;
24007 case OPC_DEXTR_R_W:
24008 tcg_gen_movi_tl(t0, v2);
24009 tcg_gen_movi_tl(t1, v1);
24010 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24011 break;
24012 case OPC_DEXTR_RS_W:
24013 tcg_gen_movi_tl(t0, v2);
24014 tcg_gen_movi_tl(t1, v1);
24015 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24016 break;
24017 case OPC_DEXTR_S_H:
24018 tcg_gen_movi_tl(t0, v2);
24019 tcg_gen_movi_tl(t1, v1);
24020 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24021 break;
24022 case OPC_DEXTRV_S_H:
24023 tcg_gen_movi_tl(t0, v2);
24024 tcg_gen_movi_tl(t1, v1);
24025 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24026 break;
24027 case OPC_DEXTRV_L:
24028 tcg_gen_movi_tl(t0, v2);
24029 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24030 break;
24031 case OPC_DEXTRV_R_L:
24032 tcg_gen_movi_tl(t0, v2);
24033 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24034 break;
24035 case OPC_DEXTRV_RS_L:
24036 tcg_gen_movi_tl(t0, v2);
24037 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24038 break;
24039 case OPC_DEXTRV_W:
24040 tcg_gen_movi_tl(t0, v2);
24041 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24042 break;
24043 case OPC_DEXTRV_R_W:
24044 tcg_gen_movi_tl(t0, v2);
24045 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24046 break;
24047 case OPC_DEXTRV_RS_W:
24048 tcg_gen_movi_tl(t0, v2);
24049 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24050 break;
24051 }
24052 break;
24053#endif
24054 }
24055
24056 tcg_temp_free(t0);
24057 tcg_temp_free(t1);
24058 tcg_temp_free(v1_t);
24059 tcg_temp_free(v2_t);
24060}
24061
24062
24063
24064static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
24065{
24066 int rs, rt, rd, sa;
24067 uint32_t op1, op2;
24068
24069 rs = (ctx->opcode >> 21) & 0x1f;
24070 rt = (ctx->opcode >> 16) & 0x1f;
24071 rd = (ctx->opcode >> 11) & 0x1f;
24072 sa = (ctx->opcode >> 6) & 0x1f;
24073
24074 op1 = MASK_SPECIAL(ctx->opcode);
24075 switch (op1) {
24076 case OPC_LSA:
24077 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24078 break;
24079 case OPC_MULT:
24080 case OPC_MULTU:
24081 case OPC_DIV:
24082 case OPC_DIVU:
24083 op2 = MASK_R6_MULDIV(ctx->opcode);
24084 switch (op2) {
24085 case R6_OPC_MUL:
24086 case R6_OPC_MUH:
24087 case R6_OPC_MULU:
24088 case R6_OPC_MUHU:
24089 case R6_OPC_DIV:
24090 case R6_OPC_MOD:
24091 case R6_OPC_DIVU:
24092 case R6_OPC_MODU:
24093 gen_r6_muldiv(ctx, op2, rd, rs, rt);
24094 break;
24095 default:
24096 MIPS_INVAL("special_r6 muldiv");
24097 generate_exception_end(ctx, EXCP_RI);
24098 break;
24099 }
24100 break;
24101 case OPC_SELEQZ:
24102 case OPC_SELNEZ:
24103 gen_cond_move(ctx, op1, rd, rs, rt);
24104 break;
24105 case R6_OPC_CLO:
24106 case R6_OPC_CLZ:
24107 if (rt == 0 && sa == 1) {
24108
24109
24110
24111
24112 gen_cl(ctx, op1, rd, rs);
24113 } else {
24114 generate_exception_end(ctx, EXCP_RI);
24115 }
24116 break;
24117 case R6_OPC_SDBBP:
24118 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24119 gen_helper_do_semihosting(cpu_env);
24120 } else {
24121 if (ctx->hflags & MIPS_HFLAG_SBRI) {
24122 generate_exception_end(ctx, EXCP_RI);
24123 } else {
24124 generate_exception_end(ctx, EXCP_DBp);
24125 }
24126 }
24127 break;
24128#if defined(TARGET_MIPS64)
24129 case OPC_DLSA:
24130 check_mips_64(ctx);
24131 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24132 break;
24133 case R6_OPC_DCLO:
24134 case R6_OPC_DCLZ:
24135 if (rt == 0 && sa == 1) {
24136
24137
24138
24139
24140 check_mips_64(ctx);
24141 gen_cl(ctx, op1, rd, rs);
24142 } else {
24143 generate_exception_end(ctx, EXCP_RI);
24144 }
24145 break;
24146 case OPC_DMULT:
24147 case OPC_DMULTU:
24148 case OPC_DDIV:
24149 case OPC_DDIVU:
24150
24151 op2 = MASK_R6_MULDIV(ctx->opcode);
24152 switch (op2) {
24153 case R6_OPC_DMUL:
24154 case R6_OPC_DMUH:
24155 case R6_OPC_DMULU:
24156 case R6_OPC_DMUHU:
24157 case R6_OPC_DDIV:
24158 case R6_OPC_DMOD:
24159 case R6_OPC_DDIVU:
24160 case R6_OPC_DMODU:
24161 check_mips_64(ctx);
24162 gen_r6_muldiv(ctx, op2, rd, rs, rt);
24163 break;
24164 default:
24165 MIPS_INVAL("special_r6 muldiv");
24166 generate_exception_end(ctx, EXCP_RI);
24167 break;
24168 }
24169 break;
24170#endif
24171 default:
24172 MIPS_INVAL("special_r6");
24173 generate_exception_end(ctx, EXCP_RI);
24174 break;
24175 }
24176}
24177
24178static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24179{
24180 int rs = extract32(ctx->opcode, 21, 5);
24181 int rt = extract32(ctx->opcode, 16, 5);
24182 int rd = extract32(ctx->opcode, 11, 5);
24183 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24184
24185 switch (op1) {
24186 case OPC_MOVN:
24187 case OPC_MOVZ:
24188 gen_cond_move(ctx, op1, rd, rs, rt);
24189 break;
24190 case OPC_MFHI:
24191 case OPC_MFLO:
24192 gen_HILO(ctx, op1, 0, rd);
24193 break;
24194 case OPC_MTHI:
24195 case OPC_MTLO:
24196 gen_HILO(ctx, op1, 0, rs);
24197 break;
24198 case OPC_MULT:
24199 case OPC_MULTU:
24200 gen_mul_txx9(ctx, op1, rd, rs, rt);
24201 break;
24202 case OPC_DIV:
24203 case OPC_DIVU:
24204 gen_muldiv(ctx, op1, 0, rs, rt);
24205 break;
24206#if defined(TARGET_MIPS64)
24207 case OPC_DMULT:
24208 case OPC_DMULTU:
24209 case OPC_DDIV:
24210 case OPC_DDIVU:
24211 check_insn_opc_user_only(ctx, INSN_R5900);
24212 gen_muldiv(ctx, op1, 0, rs, rt);
24213 break;
24214#endif
24215 case OPC_JR:
24216 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24217 break;
24218 default:
24219 MIPS_INVAL("special_tx79");
24220 generate_exception_end(ctx, EXCP_RI);
24221 break;
24222 }
24223}
24224
24225static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24226{
24227 int rs, rt, rd, sa;
24228 uint32_t op1;
24229
24230 rs = (ctx->opcode >> 21) & 0x1f;
24231 rt = (ctx->opcode >> 16) & 0x1f;
24232 rd = (ctx->opcode >> 11) & 0x1f;
24233 sa = (ctx->opcode >> 6) & 0x1f;
24234
24235 op1 = MASK_SPECIAL(ctx->opcode);
24236 switch (op1) {
24237 case OPC_MOVN:
24238 case OPC_MOVZ:
24239 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24240 INSN_LOONGSON2E | INSN_LOONGSON2F);
24241 gen_cond_move(ctx, op1, rd, rs, rt);
24242 break;
24243 case OPC_MFHI:
24244 case OPC_MFLO:
24245 gen_HILO(ctx, op1, rs & 3, rd);
24246 break;
24247 case OPC_MTHI:
24248 case OPC_MTLO:
24249 gen_HILO(ctx, op1, rd & 3, rs);
24250 break;
24251 case OPC_MOVCI:
24252 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24253 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24254 check_cp1_enabled(ctx);
24255 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24256 (ctx->opcode >> 16) & 1);
24257 } else {
24258 generate_exception_err(ctx, EXCP_CpU, 1);
24259 }
24260 break;
24261 case OPC_MULT:
24262 case OPC_MULTU:
24263 if (sa) {
24264 check_insn(ctx, INSN_VR54XX);
24265 op1 = MASK_MUL_VR54XX(ctx->opcode);
24266 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24267 } else {
24268 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24269 }
24270 break;
24271 case OPC_DIV:
24272 case OPC_DIVU:
24273 gen_muldiv(ctx, op1, 0, rs, rt);
24274 break;
24275#if defined(TARGET_MIPS64)
24276 case OPC_DMULT:
24277 case OPC_DMULTU:
24278 case OPC_DDIV:
24279 case OPC_DDIVU:
24280 check_insn(ctx, ISA_MIPS3);
24281 check_mips_64(ctx);
24282 gen_muldiv(ctx, op1, 0, rs, rt);
24283 break;
24284#endif
24285 case OPC_JR:
24286 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24287 break;
24288 case OPC_SPIM:
24289#ifdef MIPS_STRICT_STANDARD
24290 MIPS_INVAL("SPIM");
24291 generate_exception_end(ctx, EXCP_RI);
24292#else
24293
24294 MIPS_INVAL("spim (unofficial)");
24295 generate_exception_end(ctx, EXCP_RI);
24296#endif
24297 break;
24298 default:
24299 MIPS_INVAL("special_legacy");
24300 generate_exception_end(ctx, EXCP_RI);
24301 break;
24302 }
24303}
24304
24305static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24306{
24307 int rs, rt, rd, sa;
24308 uint32_t op1;
24309
24310 rs = (ctx->opcode >> 21) & 0x1f;
24311 rt = (ctx->opcode >> 16) & 0x1f;
24312 rd = (ctx->opcode >> 11) & 0x1f;
24313 sa = (ctx->opcode >> 6) & 0x1f;
24314
24315 op1 = MASK_SPECIAL(ctx->opcode);
24316 switch (op1) {
24317 case OPC_SLL:
24318 if (sa == 5 && rd == 0 &&
24319 rs == 0 && rt == 0) {
24320 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24321 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24322 generate_exception_end(ctx, EXCP_RI);
24323 break;
24324 }
24325 }
24326
24327 case OPC_SRA:
24328 gen_shift_imm(ctx, op1, rd, rt, sa);
24329 break;
24330 case OPC_SRL:
24331 switch ((ctx->opcode >> 21) & 0x1f) {
24332 case 1:
24333
24334 if (ctx->insn_flags & ISA_MIPS32R2) {
24335 op1 = OPC_ROTR;
24336 }
24337
24338 case 0:
24339 gen_shift_imm(ctx, op1, rd, rt, sa);
24340 break;
24341 default:
24342 generate_exception_end(ctx, EXCP_RI);
24343 break;
24344 }
24345 break;
24346 case OPC_ADD:
24347 case OPC_ADDU:
24348 case OPC_SUB:
24349 case OPC_SUBU:
24350 gen_arith(ctx, op1, rd, rs, rt);
24351 break;
24352 case OPC_SLLV:
24353 case OPC_SRAV:
24354 gen_shift(ctx, op1, rd, rs, rt);
24355 break;
24356 case OPC_SRLV:
24357 switch ((ctx->opcode >> 6) & 0x1f) {
24358 case 1:
24359
24360 if (ctx->insn_flags & ISA_MIPS32R2) {
24361 op1 = OPC_ROTRV;
24362 }
24363
24364 case 0:
24365 gen_shift(ctx, op1, rd, rs, rt);
24366 break;
24367 default:
24368 generate_exception_end(ctx, EXCP_RI);
24369 break;
24370 }
24371 break;
24372 case OPC_SLT:
24373 case OPC_SLTU:
24374 gen_slt(ctx, op1, rd, rs, rt);
24375 break;
24376 case OPC_AND:
24377 case OPC_OR:
24378 case OPC_NOR:
24379 case OPC_XOR:
24380 gen_logic(ctx, op1, rd, rs, rt);
24381 break;
24382 case OPC_JALR:
24383 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24384 break;
24385 case OPC_TGE:
24386 case OPC_TGEU:
24387 case OPC_TLT:
24388 case OPC_TLTU:
24389 case OPC_TEQ:
24390 case OPC_TNE:
24391 check_insn(ctx, ISA_MIPS2);
24392 gen_trap(ctx, op1, rs, rt, -1);
24393 break;
24394 case OPC_LSA:
24395 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24396 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24397 decode_opc_special_r6(env, ctx);
24398 } else {
24399
24400#ifdef MIPS_STRICT_STANDARD
24401 MIPS_INVAL("PMON / selsl");
24402 generate_exception_end(ctx, EXCP_RI);
24403#else
24404 gen_helper_0e0i(pmon, sa);
24405#endif
24406 }
24407 break;
24408 case OPC_SYSCALL:
24409 generate_exception_end(ctx, EXCP_SYSCALL);
24410 break;
24411 case OPC_BREAK:
24412 generate_exception_end(ctx, EXCP_BREAK);
24413 break;
24414 case OPC_SYNC:
24415 check_insn(ctx, ISA_MIPS2);
24416 gen_sync(extract32(ctx->opcode, 6, 5));
24417 break;
24418
24419#if defined(TARGET_MIPS64)
24420
24421 case OPC_DSLL:
24422 case OPC_DSRA:
24423 case OPC_DSLL32:
24424 case OPC_DSRA32:
24425 check_insn(ctx, ISA_MIPS3);
24426 check_mips_64(ctx);
24427 gen_shift_imm(ctx, op1, rd, rt, sa);
24428 break;
24429 case OPC_DSRL:
24430 switch ((ctx->opcode >> 21) & 0x1f) {
24431 case 1:
24432
24433 if (ctx->insn_flags & ISA_MIPS32R2) {
24434 op1 = OPC_DROTR;
24435 }
24436
24437 case 0:
24438 check_insn(ctx, ISA_MIPS3);
24439 check_mips_64(ctx);
24440 gen_shift_imm(ctx, op1, rd, rt, sa);
24441 break;
24442 default:
24443 generate_exception_end(ctx, EXCP_RI);
24444 break;
24445 }
24446 break;
24447 case OPC_DSRL32:
24448 switch ((ctx->opcode >> 21) & 0x1f) {
24449 case 1:
24450
24451 if (ctx->insn_flags & ISA_MIPS32R2) {
24452 op1 = OPC_DROTR32;
24453 }
24454
24455 case 0:
24456 check_insn(ctx, ISA_MIPS3);
24457 check_mips_64(ctx);
24458 gen_shift_imm(ctx, op1, rd, rt, sa);
24459 break;
24460 default:
24461 generate_exception_end(ctx, EXCP_RI);
24462 break;
24463 }
24464 break;
24465 case OPC_DADD:
24466 case OPC_DADDU:
24467 case OPC_DSUB:
24468 case OPC_DSUBU:
24469 check_insn(ctx, ISA_MIPS3);
24470 check_mips_64(ctx);
24471 gen_arith(ctx, op1, rd, rs, rt);
24472 break;
24473 case OPC_DSLLV:
24474 case OPC_DSRAV:
24475 check_insn(ctx, ISA_MIPS3);
24476 check_mips_64(ctx);
24477 gen_shift(ctx, op1, rd, rs, rt);
24478 break;
24479 case OPC_DSRLV:
24480 switch ((ctx->opcode >> 6) & 0x1f) {
24481 case 1:
24482
24483 if (ctx->insn_flags & ISA_MIPS32R2) {
24484 op1 = OPC_DROTRV;
24485 }
24486
24487 case 0:
24488 check_insn(ctx, ISA_MIPS3);
24489 check_mips_64(ctx);
24490 gen_shift(ctx, op1, rd, rs, rt);
24491 break;
24492 default:
24493 generate_exception_end(ctx, EXCP_RI);
24494 break;
24495 }
24496 break;
24497 case OPC_DLSA:
24498 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24499 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24500 decode_opc_special_r6(env, ctx);
24501 }
24502 break;
24503#endif
24504 default:
24505 if (ctx->insn_flags & ISA_MIPS32R6) {
24506 decode_opc_special_r6(env, ctx);
24507 } else if (ctx->insn_flags & INSN_R5900) {
24508 decode_opc_special_tx79(env, ctx);
24509 } else {
24510 decode_opc_special_legacy(env, ctx);
24511 }
24512 }
24513}
24514
24515
24516#if defined(TARGET_MIPS64)
24517
24518
24519
24520
24521
24522
24523
24524
24525
24526
24527
24528
24529
24530
24531
24532
24533
24534
24535
24536
24537
24538
24539
24540
24541
24542
24543
24544
24545
24546static void gen_mmi_pcpyh(DisasContext *ctx)
24547{
24548 uint32_t pd, rt, rd;
24549 uint32_t opcode;
24550
24551 opcode = ctx->opcode;
24552
24553 pd = extract32(opcode, 21, 5);
24554 rt = extract32(opcode, 16, 5);
24555 rd = extract32(opcode, 11, 5);
24556
24557 if (unlikely(pd != 0)) {
24558 generate_exception_end(ctx, EXCP_RI);
24559 } else if (rd == 0) {
24560
24561 } else if (rt == 0) {
24562 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24563 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24564 } else {
24565 TCGv_i64 t0 = tcg_temp_new();
24566 TCGv_i64 t1 = tcg_temp_new();
24567 uint64_t mask = (1ULL << 16) - 1;
24568
24569 tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24570 tcg_gen_movi_i64(t1, 0);
24571 tcg_gen_or_i64(t1, t0, t1);
24572 tcg_gen_shli_i64(t0, t0, 16);
24573 tcg_gen_or_i64(t1, t0, t1);
24574 tcg_gen_shli_i64(t0, t0, 16);
24575 tcg_gen_or_i64(t1, t0, t1);
24576 tcg_gen_shli_i64(t0, t0, 16);
24577 tcg_gen_or_i64(t1, t0, t1);
24578
24579 tcg_gen_mov_i64(cpu_gpr[rd], t1);
24580
24581 tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24582 tcg_gen_movi_i64(t1, 0);
24583 tcg_gen_or_i64(t1, t0, t1);
24584 tcg_gen_shli_i64(t0, t0, 16);
24585 tcg_gen_or_i64(t1, t0, t1);
24586 tcg_gen_shli_i64(t0, t0, 16);
24587 tcg_gen_or_i64(t1, t0, t1);
24588 tcg_gen_shli_i64(t0, t0, 16);
24589 tcg_gen_or_i64(t1, t0, t1);
24590
24591 tcg_gen_mov_i64(cpu_mmr[rd], t1);
24592
24593 tcg_temp_free(t0);
24594 tcg_temp_free(t1);
24595 }
24596}
24597
24598
24599
24600
24601
24602
24603
24604
24605
24606
24607
24608static void gen_mmi_pcpyld(DisasContext *ctx)
24609{
24610 uint32_t rs, rt, rd;
24611 uint32_t opcode;
24612
24613 opcode = ctx->opcode;
24614
24615 rs = extract32(opcode, 21, 5);
24616 rt = extract32(opcode, 16, 5);
24617 rd = extract32(opcode, 11, 5);
24618
24619 if (rd == 0) {
24620
24621 } else {
24622 if (rs == 0) {
24623 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24624 } else {
24625 tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24626 }
24627 if (rt == 0) {
24628 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24629 } else {
24630 if (rd != rt) {
24631 tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24632 }
24633 }
24634 }
24635}
24636
24637
24638
24639
24640
24641
24642
24643
24644
24645
24646
24647static void gen_mmi_pcpyud(DisasContext *ctx)
24648{
24649 uint32_t rs, rt, rd;
24650 uint32_t opcode;
24651
24652 opcode = ctx->opcode;
24653
24654 rs = extract32(opcode, 21, 5);
24655 rt = extract32(opcode, 16, 5);
24656 rd = extract32(opcode, 11, 5);
24657
24658 if (rd == 0) {
24659
24660 } else {
24661 if (rs == 0) {
24662 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24663 } else {
24664 tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24665 }
24666 if (rt == 0) {
24667 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24668 } else {
24669 if (rd != rt) {
24670 tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24671 }
24672 }
24673 }
24674}
24675
24676#endif
24677
24678
24679#if !defined(TARGET_MIPS64)
24680
24681
24682#define MXU_APTN1_A 0
24683#define MXU_APTN1_S 1
24684
24685
24686#define MXU_APTN2_AA 0
24687#define MXU_APTN2_AS 1
24688#define MXU_APTN2_SA 2
24689#define MXU_APTN2_SS 3
24690
24691
24692#define MXU_EPTN2_AA 0
24693#define MXU_EPTN2_AS 1
24694#define MXU_EPTN2_SA 2
24695#define MXU_EPTN2_SS 3
24696
24697
24698#define MXU_OPTN2_PTN0 0
24699#define MXU_OPTN2_PTN1 1
24700#define MXU_OPTN2_PTN2 2
24701#define MXU_OPTN2_PTN3 3
24702
24703#define MXU_OPTN2_WW 0
24704#define MXU_OPTN2_LW 1
24705#define MXU_OPTN2_HW 2
24706#define MXU_OPTN2_XW 3
24707
24708
24709#define MXU_OPTN3_PTN0 0
24710#define MXU_OPTN3_PTN1 1
24711#define MXU_OPTN3_PTN2 2
24712#define MXU_OPTN3_PTN3 3
24713#define MXU_OPTN3_PTN4 4
24714#define MXU_OPTN3_PTN5 5
24715#define MXU_OPTN3_PTN6 6
24716#define MXU_OPTN3_PTN7 7
24717
24718
24719
24720
24721
24722static void gen_mxu_s32i2m(DisasContext *ctx)
24723{
24724 TCGv t0;
24725 uint32_t XRa, Rb;
24726
24727 t0 = tcg_temp_new();
24728
24729 XRa = extract32(ctx->opcode, 6, 5);
24730 Rb = extract32(ctx->opcode, 16, 5);
24731
24732 gen_load_gpr(t0, Rb);
24733 if (XRa <= 15) {
24734 gen_store_mxu_gpr(t0, XRa);
24735 } else if (XRa == 16) {
24736 gen_store_mxu_cr(t0);
24737 }
24738
24739 tcg_temp_free(t0);
24740}
24741
24742
24743
24744
24745static void gen_mxu_s32m2i(DisasContext *ctx)
24746{
24747 TCGv t0;
24748 uint32_t XRa, Rb;
24749
24750 t0 = tcg_temp_new();
24751
24752 XRa = extract32(ctx->opcode, 6, 5);
24753 Rb = extract32(ctx->opcode, 16, 5);
24754
24755 if (XRa <= 15) {
24756 gen_load_mxu_gpr(t0, XRa);
24757 } else if (XRa == 16) {
24758 gen_load_mxu_cr(t0);
24759 }
24760
24761 gen_store_gpr(t0, Rb);
24762
24763 tcg_temp_free(t0);
24764}
24765
24766
24767
24768
24769static void gen_mxu_s8ldd(DisasContext *ctx)
24770{
24771 TCGv t0, t1;
24772 uint32_t XRa, Rb, s8, optn3;
24773
24774 t0 = tcg_temp_new();
24775 t1 = tcg_temp_new();
24776
24777 XRa = extract32(ctx->opcode, 6, 4);
24778 s8 = extract32(ctx->opcode, 10, 8);
24779 optn3 = extract32(ctx->opcode, 18, 3);
24780 Rb = extract32(ctx->opcode, 21, 5);
24781
24782 gen_load_gpr(t0, Rb);
24783 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24784
24785 switch (optn3) {
24786
24787 case MXU_OPTN3_PTN0:
24788 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24789 gen_load_mxu_gpr(t0, XRa);
24790 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24791 break;
24792
24793 case MXU_OPTN3_PTN1:
24794 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24795 gen_load_mxu_gpr(t0, XRa);
24796 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24797 break;
24798
24799 case MXU_OPTN3_PTN2:
24800 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24801 gen_load_mxu_gpr(t0, XRa);
24802 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24803 break;
24804
24805 case MXU_OPTN3_PTN3:
24806 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24807 gen_load_mxu_gpr(t0, XRa);
24808 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24809 break;
24810
24811 case MXU_OPTN3_PTN4:
24812 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24813 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24814 break;
24815
24816 case MXU_OPTN3_PTN5:
24817 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24818 tcg_gen_shli_tl(t1, t1, 8);
24819 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24820 break;
24821
24822 case MXU_OPTN3_PTN6:
24823 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24824 tcg_gen_mov_tl(t0, t1);
24825 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24826 tcg_gen_shli_tl(t1, t1, 16);
24827 tcg_gen_or_tl(t0, t0, t1);
24828 break;
24829
24830 case MXU_OPTN3_PTN7:
24831 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24832 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24833 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24834 break;
24835 }
24836
24837 gen_store_mxu_gpr(t0, XRa);
24838
24839 tcg_temp_free(t0);
24840 tcg_temp_free(t1);
24841}
24842
24843
24844
24845
24846static void gen_mxu_d16mul(DisasContext *ctx)
24847{
24848 TCGv t0, t1, t2, t3;
24849 uint32_t XRa, XRb, XRc, XRd, optn2;
24850
24851 t0 = tcg_temp_new();
24852 t1 = tcg_temp_new();
24853 t2 = tcg_temp_new();
24854 t3 = tcg_temp_new();
24855
24856 XRa = extract32(ctx->opcode, 6, 4);
24857 XRb = extract32(ctx->opcode, 10, 4);
24858 XRc = extract32(ctx->opcode, 14, 4);
24859 XRd = extract32(ctx->opcode, 18, 4);
24860 optn2 = extract32(ctx->opcode, 22, 2);
24861
24862 gen_load_mxu_gpr(t1, XRb);
24863 tcg_gen_sextract_tl(t0, t1, 0, 16);
24864 tcg_gen_sextract_tl(t1, t1, 16, 16);
24865 gen_load_mxu_gpr(t3, XRc);
24866 tcg_gen_sextract_tl(t2, t3, 0, 16);
24867 tcg_gen_sextract_tl(t3, t3, 16, 16);
24868
24869 switch (optn2) {
24870 case MXU_OPTN2_WW:
24871 tcg_gen_mul_tl(t3, t1, t3);
24872 tcg_gen_mul_tl(t2, t0, t2);
24873 break;
24874 case MXU_OPTN2_LW:
24875 tcg_gen_mul_tl(t3, t0, t3);
24876 tcg_gen_mul_tl(t2, t0, t2);
24877 break;
24878 case MXU_OPTN2_HW:
24879 tcg_gen_mul_tl(t3, t1, t3);
24880 tcg_gen_mul_tl(t2, t1, t2);
24881 break;
24882 case MXU_OPTN2_XW:
24883 tcg_gen_mul_tl(t3, t0, t3);
24884 tcg_gen_mul_tl(t2, t1, t2);
24885 break;
24886 }
24887 gen_store_mxu_gpr(t3, XRa);
24888 gen_store_mxu_gpr(t2, XRd);
24889
24890 tcg_temp_free(t0);
24891 tcg_temp_free(t1);
24892 tcg_temp_free(t2);
24893 tcg_temp_free(t3);
24894}
24895
24896
24897
24898
24899
24900static void gen_mxu_d16mac(DisasContext *ctx)
24901{
24902 TCGv t0, t1, t2, t3;
24903 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24904
24905 t0 = tcg_temp_new();
24906 t1 = tcg_temp_new();
24907 t2 = tcg_temp_new();
24908 t3 = tcg_temp_new();
24909
24910 XRa = extract32(ctx->opcode, 6, 4);
24911 XRb = extract32(ctx->opcode, 10, 4);
24912 XRc = extract32(ctx->opcode, 14, 4);
24913 XRd = extract32(ctx->opcode, 18, 4);
24914 optn2 = extract32(ctx->opcode, 22, 2);
24915 aptn2 = extract32(ctx->opcode, 24, 2);
24916
24917 gen_load_mxu_gpr(t1, XRb);
24918 tcg_gen_sextract_tl(t0, t1, 0, 16);
24919 tcg_gen_sextract_tl(t1, t1, 16, 16);
24920
24921 gen_load_mxu_gpr(t3, XRc);
24922 tcg_gen_sextract_tl(t2, t3, 0, 16);
24923 tcg_gen_sextract_tl(t3, t3, 16, 16);
24924
24925 switch (optn2) {
24926 case MXU_OPTN2_WW:
24927 tcg_gen_mul_tl(t3, t1, t3);
24928 tcg_gen_mul_tl(t2, t0, t2);
24929 break;
24930 case MXU_OPTN2_LW:
24931 tcg_gen_mul_tl(t3, t0, t3);
24932 tcg_gen_mul_tl(t2, t0, t2);
24933 break;
24934 case MXU_OPTN2_HW:
24935 tcg_gen_mul_tl(t3, t1, t3);
24936 tcg_gen_mul_tl(t2, t1, t2);
24937 break;
24938 case MXU_OPTN2_XW:
24939 tcg_gen_mul_tl(t3, t0, t3);
24940 tcg_gen_mul_tl(t2, t1, t2);
24941 break;
24942 }
24943 gen_load_mxu_gpr(t0, XRa);
24944 gen_load_mxu_gpr(t1, XRd);
24945
24946 switch (aptn2) {
24947 case MXU_APTN2_AA:
24948 tcg_gen_add_tl(t3, t0, t3);
24949 tcg_gen_add_tl(t2, t1, t2);
24950 break;
24951 case MXU_APTN2_AS:
24952 tcg_gen_add_tl(t3, t0, t3);
24953 tcg_gen_sub_tl(t2, t1, t2);
24954 break;
24955 case MXU_APTN2_SA:
24956 tcg_gen_sub_tl(t3, t0, t3);
24957 tcg_gen_add_tl(t2, t1, t2);
24958 break;
24959 case MXU_APTN2_SS:
24960 tcg_gen_sub_tl(t3, t0, t3);
24961 tcg_gen_sub_tl(t2, t1, t2);
24962 break;
24963 }
24964 gen_store_mxu_gpr(t3, XRa);
24965 gen_store_mxu_gpr(t2, XRd);
24966
24967 tcg_temp_free(t0);
24968 tcg_temp_free(t1);
24969 tcg_temp_free(t2);
24970 tcg_temp_free(t3);
24971}
24972
24973
24974
24975
24976
24977static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24978{
24979 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24980 uint32_t XRa, XRb, XRc, XRd, sel;
24981
24982 t0 = tcg_temp_new();
24983 t1 = tcg_temp_new();
24984 t2 = tcg_temp_new();
24985 t3 = tcg_temp_new();
24986 t4 = tcg_temp_new();
24987 t5 = tcg_temp_new();
24988 t6 = tcg_temp_new();
24989 t7 = tcg_temp_new();
24990
24991 XRa = extract32(ctx->opcode, 6, 4);
24992 XRb = extract32(ctx->opcode, 10, 4);
24993 XRc = extract32(ctx->opcode, 14, 4);
24994 XRd = extract32(ctx->opcode, 18, 4);
24995 sel = extract32(ctx->opcode, 22, 2);
24996
24997 gen_load_mxu_gpr(t3, XRb);
24998 gen_load_mxu_gpr(t7, XRc);
24999
25000 if (sel == 0x2) {
25001
25002 tcg_gen_ext8s_tl(t0, t3);
25003 tcg_gen_shri_tl(t3, t3, 8);
25004 tcg_gen_ext8s_tl(t1, t3);
25005 tcg_gen_shri_tl(t3, t3, 8);
25006 tcg_gen_ext8s_tl(t2, t3);
25007 tcg_gen_shri_tl(t3, t3, 8);
25008 tcg_gen_ext8s_tl(t3, t3);
25009 } else {
25010
25011 tcg_gen_ext8u_tl(t0, t3);
25012 tcg_gen_shri_tl(t3, t3, 8);
25013 tcg_gen_ext8u_tl(t1, t3);
25014 tcg_gen_shri_tl(t3, t3, 8);
25015 tcg_gen_ext8u_tl(t2, t3);
25016 tcg_gen_shri_tl(t3, t3, 8);
25017 tcg_gen_ext8u_tl(t3, t3);
25018 }
25019
25020 tcg_gen_ext8u_tl(t4, t7);
25021 tcg_gen_shri_tl(t7, t7, 8);
25022 tcg_gen_ext8u_tl(t5, t7);
25023 tcg_gen_shri_tl(t7, t7, 8);
25024 tcg_gen_ext8u_tl(t6, t7);
25025 tcg_gen_shri_tl(t7, t7, 8);
25026 tcg_gen_ext8u_tl(t7, t7);
25027
25028 tcg_gen_mul_tl(t0, t0, t4);
25029 tcg_gen_mul_tl(t1, t1, t5);
25030 tcg_gen_mul_tl(t2, t2, t6);
25031 tcg_gen_mul_tl(t3, t3, t7);
25032
25033 tcg_gen_andi_tl(t0, t0, 0xFFFF);
25034 tcg_gen_andi_tl(t1, t1, 0xFFFF);
25035 tcg_gen_andi_tl(t2, t2, 0xFFFF);
25036 tcg_gen_andi_tl(t3, t3, 0xFFFF);
25037
25038 tcg_gen_shli_tl(t1, t1, 16);
25039 tcg_gen_shli_tl(t3, t3, 16);
25040
25041 tcg_gen_or_tl(t0, t0, t1);
25042 tcg_gen_or_tl(t1, t2, t3);
25043
25044 gen_store_mxu_gpr(t0, XRd);
25045 gen_store_mxu_gpr(t1, XRa);
25046
25047 tcg_temp_free(t0);
25048 tcg_temp_free(t1);
25049 tcg_temp_free(t2);
25050 tcg_temp_free(t3);
25051 tcg_temp_free(t4);
25052 tcg_temp_free(t5);
25053 tcg_temp_free(t6);
25054 tcg_temp_free(t7);
25055}
25056
25057
25058
25059
25060
25061static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
25062{
25063 TCGv t0, t1;
25064 uint32_t XRa, Rb, s12, sel;
25065
25066 t0 = tcg_temp_new();
25067 t1 = tcg_temp_new();
25068
25069 XRa = extract32(ctx->opcode, 6, 4);
25070 s12 = extract32(ctx->opcode, 10, 10);
25071 sel = extract32(ctx->opcode, 20, 1);
25072 Rb = extract32(ctx->opcode, 21, 5);
25073
25074 gen_load_gpr(t0, Rb);
25075
25076 tcg_gen_movi_tl(t1, s12);
25077 tcg_gen_shli_tl(t1, t1, 2);
25078 if (s12 & 0x200) {
25079 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
25080 }
25081 tcg_gen_add_tl(t1, t0, t1);
25082 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
25083
25084 if (sel == 1) {
25085
25086 tcg_gen_bswap32_tl(t1, t1);
25087 }
25088 gen_store_mxu_gpr(t1, XRa);
25089
25090 tcg_temp_free(t0);
25091 tcg_temp_free(t1);
25092}
25093
25094
25095
25096
25097
25098
25099
25100
25101
25102
25103
25104
25105
25106
25107
25108
25109
25110
25111
25112static void gen_mxu_S32NOR(DisasContext *ctx)
25113{
25114 uint32_t pad, XRc, XRb, XRa;
25115
25116 pad = extract32(ctx->opcode, 21, 5);
25117 XRc = extract32(ctx->opcode, 14, 4);
25118 XRb = extract32(ctx->opcode, 10, 4);
25119 XRa = extract32(ctx->opcode, 6, 4);
25120
25121 if (unlikely(pad != 0)) {
25122
25123 } else if (unlikely(XRa == 0)) {
25124
25125 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25126
25127 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
25128 } else if (unlikely(XRb == 0)) {
25129
25130 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25131 } else if (unlikely(XRc == 0)) {
25132
25133 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25134 } else if (unlikely(XRb == XRc)) {
25135
25136 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25137 } else {
25138
25139 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25140 }
25141}
25142
25143
25144
25145
25146
25147
25148
25149
25150
25151
25152
25153static void gen_mxu_S32AND(DisasContext *ctx)
25154{
25155 uint32_t pad, XRc, XRb, XRa;
25156
25157 pad = extract32(ctx->opcode, 21, 5);
25158 XRc = extract32(ctx->opcode, 14, 4);
25159 XRb = extract32(ctx->opcode, 10, 4);
25160 XRa = extract32(ctx->opcode, 6, 4);
25161
25162 if (unlikely(pad != 0)) {
25163
25164 } else if (unlikely(XRa == 0)) {
25165
25166 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25167
25168 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25169 } else if (unlikely(XRb == XRc)) {
25170
25171 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25172 } else {
25173
25174 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25175 }
25176}
25177
25178
25179
25180
25181
25182
25183
25184
25185
25186
25187
25188static void gen_mxu_S32OR(DisasContext *ctx)
25189{
25190 uint32_t pad, XRc, XRb, XRa;
25191
25192 pad = extract32(ctx->opcode, 21, 5);
25193 XRc = extract32(ctx->opcode, 14, 4);
25194 XRb = extract32(ctx->opcode, 10, 4);
25195 XRa = extract32(ctx->opcode, 6, 4);
25196
25197 if (unlikely(pad != 0)) {
25198
25199 } else if (unlikely(XRa == 0)) {
25200
25201 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25202
25203 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25204 } else if (unlikely(XRb == 0)) {
25205
25206 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25207 } else if (unlikely(XRc == 0)) {
25208
25209 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25210 } else if (unlikely(XRb == XRc)) {
25211
25212 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25213 } else {
25214
25215 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25216 }
25217}
25218
25219
25220
25221
25222
25223
25224
25225
25226
25227
25228
25229static void gen_mxu_S32XOR(DisasContext *ctx)
25230{
25231 uint32_t pad, XRc, XRb, XRa;
25232
25233 pad = extract32(ctx->opcode, 21, 5);
25234 XRc = extract32(ctx->opcode, 14, 4);
25235 XRb = extract32(ctx->opcode, 10, 4);
25236 XRa = extract32(ctx->opcode, 6, 4);
25237
25238 if (unlikely(pad != 0)) {
25239
25240 } else if (unlikely(XRa == 0)) {
25241
25242 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25243
25244 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25245 } else if (unlikely(XRb == 0)) {
25246
25247 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25248 } else if (unlikely(XRc == 0)) {
25249
25250 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25251 } else if (unlikely(XRb == XRc)) {
25252
25253 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25254 } else {
25255
25256 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25257 }
25258}
25259
25260
25261
25262
25263
25264
25265
25266
25267
25268
25269
25270
25271
25272
25273
25274
25275
25276
25277
25278
25279
25280
25281
25282
25283static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25284{
25285 uint32_t pad, opc, XRc, XRb, XRa;
25286
25287 pad = extract32(ctx->opcode, 21, 5);
25288 opc = extract32(ctx->opcode, 18, 3);
25289 XRc = extract32(ctx->opcode, 14, 4);
25290 XRb = extract32(ctx->opcode, 10, 4);
25291 XRa = extract32(ctx->opcode, 6, 4);
25292
25293 if (unlikely(pad != 0)) {
25294
25295 } else if (unlikely(XRa == 0)) {
25296
25297 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25298
25299 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25300 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25301
25302 uint32_t XRx = XRb ? XRb : XRc;
25303
25304 if (opc == OPC_MXU_S32MAX) {
25305 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25306 } else {
25307 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25308 }
25309 } else if (unlikely(XRb == XRc)) {
25310
25311 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25312 } else {
25313
25314 if (opc == OPC_MXU_S32MAX) {
25315 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25316 mxu_gpr[XRc - 1]);
25317 } else {
25318 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25319 mxu_gpr[XRc - 1]);
25320 }
25321 }
25322}
25323
25324
25325
25326
25327
25328
25329
25330
25331
25332
25333
25334
25335
25336
25337
25338static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25339{
25340 uint32_t pad, opc, XRc, XRb, XRa;
25341
25342 pad = extract32(ctx->opcode, 21, 5);
25343 opc = extract32(ctx->opcode, 18, 3);
25344 XRc = extract32(ctx->opcode, 14, 4);
25345 XRb = extract32(ctx->opcode, 10, 4);
25346 XRa = extract32(ctx->opcode, 6, 4);
25347
25348 if (unlikely(pad != 0)) {
25349
25350 } else if (unlikely(XRc == 0)) {
25351
25352 } else if (unlikely((XRb == 0) && (XRa == 0))) {
25353
25354 tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25355 } else if (unlikely((XRb == 0) || (XRa == 0))) {
25356
25357 uint32_t XRx = XRb ? XRb : XRc;
25358
25359 TCGv_i32 t0 = tcg_temp_new();
25360 TCGv_i32 t1 = tcg_const_i32(0);
25361
25362
25363 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25364 if (opc == OPC_MXU_D16MAX) {
25365 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25366 } else {
25367 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25368 }
25369
25370
25371 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25372
25373 tcg_gen_shli_i32(t0, t0, 16);
25374
25375 if (opc == OPC_MXU_D16MAX) {
25376 tcg_gen_smax_i32(t0, t0, t1);
25377 } else {
25378 tcg_gen_smin_i32(t0, t0, t1);
25379 }
25380
25381 tcg_gen_shri_i32(t0, t0, 16);
25382
25383 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25384
25385 tcg_temp_free(t1);
25386 tcg_temp_free(t0);
25387 } else if (unlikely(XRb == XRc)) {
25388
25389 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25390 } else {
25391
25392 TCGv_i32 t0 = tcg_temp_new();
25393 TCGv_i32 t1 = tcg_temp_new();
25394
25395
25396 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25397 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25398 if (opc == OPC_MXU_D16MAX) {
25399 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25400 } else {
25401 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25402 }
25403
25404
25405 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25406 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25407
25408 tcg_gen_shli_i32(t0, t0, 16);
25409 tcg_gen_shli_i32(t1, t1, 16);
25410
25411 if (opc == OPC_MXU_D16MAX) {
25412 tcg_gen_smax_i32(t0, t0, t1);
25413 } else {
25414 tcg_gen_smin_i32(t0, t0, t1);
25415 }
25416
25417 tcg_gen_shri_i32(t0, t0, 16);
25418
25419 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25420
25421 tcg_temp_free(t1);
25422 tcg_temp_free(t0);
25423 }
25424}
25425
25426
25427
25428
25429
25430
25431
25432
25433
25434
25435
25436
25437
25438
25439
25440static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25441{
25442 uint32_t pad, opc, XRc, XRb, XRa;
25443
25444 pad = extract32(ctx->opcode, 21, 5);
25445 opc = extract32(ctx->opcode, 18, 3);
25446 XRc = extract32(ctx->opcode, 14, 4);
25447 XRb = extract32(ctx->opcode, 10, 4);
25448 XRa = extract32(ctx->opcode, 6, 4);
25449
25450 if (unlikely(pad != 0)) {
25451
25452 } else if (unlikely(XRa == 0)) {
25453
25454 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25455
25456 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25457 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25458
25459 uint32_t XRx = XRb ? XRb : XRc;
25460
25461 TCGv_i32 t0 = tcg_temp_new();
25462 TCGv_i32 t1 = tcg_const_i32(0);
25463 int32_t i;
25464
25465
25466 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25467 if (opc == OPC_MXU_Q8MAX) {
25468 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25469 } else {
25470 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25471 }
25472
25473
25474 for (i = 2; i >= 0; i--) {
25475
25476 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25477
25478 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25479
25480 if (opc == OPC_MXU_Q8MAX) {
25481 tcg_gen_smax_i32(t0, t0, t1);
25482 } else {
25483 tcg_gen_smin_i32(t0, t0, t1);
25484 }
25485
25486 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25487
25488 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25489 }
25490
25491 tcg_temp_free(t1);
25492 tcg_temp_free(t0);
25493 } else if (unlikely(XRb == XRc)) {
25494
25495 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25496 } else {
25497
25498 TCGv_i32 t0 = tcg_temp_new();
25499 TCGv_i32 t1 = tcg_temp_new();
25500 int32_t i;
25501
25502
25503 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25504 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25505 if (opc == OPC_MXU_Q8MAX) {
25506 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25507 } else {
25508 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25509 }
25510
25511
25512 for (i = 2; i >= 0; i--) {
25513
25514 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25515 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25516
25517 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25518 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25519
25520 if (opc == OPC_MXU_Q8MAX) {
25521 tcg_gen_smax_i32(t0, t0, t1);
25522 } else {
25523 tcg_gen_smin_i32(t0, t0, t1);
25524 }
25525
25526 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25527
25528 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25529 }
25530
25531 tcg_temp_free(t1);
25532 tcg_temp_free(t0);
25533 }
25534}
25535
25536
25537
25538
25539
25540
25541
25542
25543
25544
25545
25546
25547
25548
25549
25550
25551
25552
25553
25554
25555static void gen_mxu_S32ALNI(DisasContext *ctx)
25556{
25557 uint32_t optn3, pad, XRc, XRb, XRa;
25558
25559 optn3 = extract32(ctx->opcode, 23, 3);
25560 pad = extract32(ctx->opcode, 21, 2);
25561 XRc = extract32(ctx->opcode, 14, 4);
25562 XRb = extract32(ctx->opcode, 10, 4);
25563 XRa = extract32(ctx->opcode, 6, 4);
25564
25565 if (unlikely(pad != 0)) {
25566
25567 } else if (unlikely(XRa == 0)) {
25568
25569 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25570
25571 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25572 } else if (unlikely(XRb == 0)) {
25573
25574 switch (optn3) {
25575 case MXU_OPTN3_PTN0:
25576 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25577 break;
25578 case MXU_OPTN3_PTN1:
25579 case MXU_OPTN3_PTN2:
25580 case MXU_OPTN3_PTN3:
25581 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25582 8 * (4 - optn3));
25583 break;
25584 case MXU_OPTN3_PTN4:
25585 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25586 break;
25587 }
25588 } else if (unlikely(XRc == 0)) {
25589
25590 switch (optn3) {
25591 case MXU_OPTN3_PTN0:
25592 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25593 break;
25594 case MXU_OPTN3_PTN1:
25595 case MXU_OPTN3_PTN2:
25596 case MXU_OPTN3_PTN3:
25597 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25598 break;
25599 case MXU_OPTN3_PTN4:
25600 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25601 break;
25602 }
25603 } else if (unlikely(XRb == XRc)) {
25604
25605 switch (optn3) {
25606 case MXU_OPTN3_PTN0:
25607 case MXU_OPTN3_PTN4:
25608 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25609 break;
25610 case MXU_OPTN3_PTN1:
25611 case MXU_OPTN3_PTN2:
25612 case MXU_OPTN3_PTN3:
25613 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25614 break;
25615 }
25616 } else {
25617
25618 switch (optn3) {
25619 case MXU_OPTN3_PTN0:
25620 {
25621
25622
25623
25624
25625
25626
25627
25628
25629
25630 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25631 }
25632 break;
25633 case MXU_OPTN3_PTN1:
25634 {
25635
25636
25637
25638
25639
25640
25641
25642
25643
25644 TCGv_i32 t0 = tcg_temp_new();
25645 TCGv_i32 t1 = tcg_temp_new();
25646
25647 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25648 tcg_gen_shli_i32(t0, t0, 8);
25649
25650 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25651 tcg_gen_shri_i32(t1, t1, 24);
25652
25653 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25654
25655 tcg_temp_free(t1);
25656 tcg_temp_free(t0);
25657 }
25658 break;
25659 case MXU_OPTN3_PTN2:
25660 {
25661
25662
25663
25664
25665
25666
25667
25668
25669
25670 TCGv_i32 t0 = tcg_temp_new();
25671 TCGv_i32 t1 = tcg_temp_new();
25672
25673 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25674 tcg_gen_shli_i32(t0, t0, 16);
25675
25676 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25677 tcg_gen_shri_i32(t1, t1, 16);
25678
25679 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25680
25681 tcg_temp_free(t1);
25682 tcg_temp_free(t0);
25683 }
25684 break;
25685 case MXU_OPTN3_PTN3:
25686 {
25687
25688
25689
25690
25691
25692
25693
25694
25695
25696 TCGv_i32 t0 = tcg_temp_new();
25697 TCGv_i32 t1 = tcg_temp_new();
25698
25699 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25700 tcg_gen_shli_i32(t0, t0, 24);
25701
25702 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25703 tcg_gen_shri_i32(t1, t1, 8);
25704
25705 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25706
25707 tcg_temp_free(t1);
25708 tcg_temp_free(t0);
25709 }
25710 break;
25711 case MXU_OPTN3_PTN4:
25712 {
25713
25714
25715
25716
25717
25718
25719
25720
25721
25722 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25723 }
25724 break;
25725 }
25726 }
25727}
25728
25729
25730
25731
25732
25733
25734
25735
25736
25737
25738
25739
25740
25741
25742
25743
25744
25745static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25746{
25747 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25748
25749 switch (opcode) {
25750 case OPC_MXU_S32MAX:
25751 case OPC_MXU_S32MIN:
25752 gen_mxu_S32MAX_S32MIN(ctx);
25753 break;
25754 case OPC_MXU_D16MAX:
25755 case OPC_MXU_D16MIN:
25756 gen_mxu_D16MAX_D16MIN(ctx);
25757 break;
25758 case OPC_MXU_Q8MAX:
25759 case OPC_MXU_Q8MIN:
25760 gen_mxu_Q8MAX_Q8MIN(ctx);
25761 break;
25762 case OPC_MXU_Q8SLT:
25763
25764 MIPS_INVAL("OPC_MXU_Q8SLT");
25765 generate_exception_end(ctx, EXCP_RI);
25766 break;
25767 case OPC_MXU_Q8SLTU:
25768
25769 MIPS_INVAL("OPC_MXU_Q8SLTU");
25770 generate_exception_end(ctx, EXCP_RI);
25771 break;
25772 default:
25773 MIPS_INVAL("decode_opc_mxu");
25774 generate_exception_end(ctx, EXCP_RI);
25775 break;
25776 }
25777}
25778
25779
25780
25781
25782
25783
25784
25785
25786
25787
25788
25789
25790
25791
25792
25793
25794
25795
25796static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25797{
25798 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25799
25800 switch (opcode) {
25801 case OPC_MXU_S32SLT:
25802
25803 MIPS_INVAL("OPC_MXU_S32SLT");
25804 generate_exception_end(ctx, EXCP_RI);
25805 break;
25806 case OPC_MXU_D16SLT:
25807
25808 MIPS_INVAL("OPC_MXU_D16SLT");
25809 generate_exception_end(ctx, EXCP_RI);
25810 break;
25811 case OPC_MXU_D16AVG:
25812
25813 MIPS_INVAL("OPC_MXU_D16AVG");
25814 generate_exception_end(ctx, EXCP_RI);
25815 break;
25816 case OPC_MXU_D16AVGR:
25817
25818 MIPS_INVAL("OPC_MXU_D16AVGR");
25819 generate_exception_end(ctx, EXCP_RI);
25820 break;
25821 case OPC_MXU_Q8AVG:
25822
25823 MIPS_INVAL("OPC_MXU_Q8AVG");
25824 generate_exception_end(ctx, EXCP_RI);
25825 break;
25826 case OPC_MXU_Q8AVGR:
25827
25828 MIPS_INVAL("OPC_MXU_Q8AVGR");
25829 generate_exception_end(ctx, EXCP_RI);
25830 break;
25831 case OPC_MXU_Q8ADD:
25832
25833 MIPS_INVAL("OPC_MXU_Q8ADD");
25834 generate_exception_end(ctx, EXCP_RI);
25835 break;
25836 default:
25837 MIPS_INVAL("decode_opc_mxu");
25838 generate_exception_end(ctx, EXCP_RI);
25839 break;
25840 }
25841}
25842
25843
25844
25845
25846
25847
25848
25849
25850
25851
25852
25853static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25854{
25855 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25856
25857 switch (opcode) {
25858 case OPC_MXU_S32CPS:
25859
25860 MIPS_INVAL("OPC_MXU_S32CPS");
25861 generate_exception_end(ctx, EXCP_RI);
25862 break;
25863 case OPC_MXU_D16CPS:
25864
25865 MIPS_INVAL("OPC_MXU_D16CPS");
25866 generate_exception_end(ctx, EXCP_RI);
25867 break;
25868 case OPC_MXU_Q8ABD:
25869
25870 MIPS_INVAL("OPC_MXU_Q8ABD");
25871 generate_exception_end(ctx, EXCP_RI);
25872 break;
25873 case OPC_MXU_Q16SAT:
25874
25875 MIPS_INVAL("OPC_MXU_Q16SAT");
25876 generate_exception_end(ctx, EXCP_RI);
25877 break;
25878 default:
25879 MIPS_INVAL("decode_opc_mxu");
25880 generate_exception_end(ctx, EXCP_RI);
25881 break;
25882 }
25883}
25884
25885
25886
25887
25888
25889
25890
25891
25892
25893
25894
25895
25896
25897
25898
25899
25900
25901
25902static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25903{
25904 uint32_t opcode = extract32(ctx->opcode, 24, 2);
25905
25906 switch (opcode) {
25907 case OPC_MXU_D16MULF:
25908
25909 MIPS_INVAL("OPC_MXU_D16MULF");
25910 generate_exception_end(ctx, EXCP_RI);
25911 break;
25912 case OPC_MXU_D16MULE:
25913
25914 MIPS_INVAL("OPC_MXU_D16MULE");
25915 generate_exception_end(ctx, EXCP_RI);
25916 break;
25917 default:
25918 MIPS_INVAL("decode_opc_mxu");
25919 generate_exception_end(ctx, EXCP_RI);
25920 break;
25921 }
25922}
25923
25924
25925
25926
25927
25928
25929
25930
25931
25932
25933
25934static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25935{
25936 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25937
25938 switch (opcode) {
25939 case OPC_MXU_S32LDD:
25940 case OPC_MXU_S32LDDR:
25941 gen_mxu_s32ldd_s32lddr(ctx);
25942 break;
25943 default:
25944 MIPS_INVAL("decode_opc_mxu");
25945 generate_exception_end(ctx, EXCP_RI);
25946 break;
25947 }
25948}
25949
25950
25951
25952
25953
25954
25955
25956
25957
25958
25959
25960static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25961{
25962 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25963
25964 switch (opcode) {
25965 case OPC_MXU_S32STD:
25966
25967 MIPS_INVAL("OPC_MXU_S32STD");
25968 generate_exception_end(ctx, EXCP_RI);
25969 break;
25970 case OPC_MXU_S32STDR:
25971
25972 MIPS_INVAL("OPC_MXU_S32STDR");
25973 generate_exception_end(ctx, EXCP_RI);
25974 break;
25975 default:
25976 MIPS_INVAL("decode_opc_mxu");
25977 generate_exception_end(ctx, EXCP_RI);
25978 break;
25979 }
25980}
25981
25982
25983
25984
25985
25986
25987
25988
25989
25990
25991
25992static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25993{
25994 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25995
25996 switch (opcode) {
25997 case OPC_MXU_S32LDDV:
25998
25999 MIPS_INVAL("OPC_MXU_S32LDDV");
26000 generate_exception_end(ctx, EXCP_RI);
26001 break;
26002 case OPC_MXU_S32LDDVR:
26003
26004 MIPS_INVAL("OPC_MXU_S32LDDVR");
26005 generate_exception_end(ctx, EXCP_RI);
26006 break;
26007 default:
26008 MIPS_INVAL("decode_opc_mxu");
26009 generate_exception_end(ctx, EXCP_RI);
26010 break;
26011 }
26012}
26013
26014
26015
26016
26017
26018
26019
26020
26021
26022
26023
26024static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
26025{
26026 uint32_t opcode = extract32(ctx->opcode, 10, 4);
26027
26028 switch (opcode) {
26029 case OPC_MXU_S32STDV:
26030
26031 MIPS_INVAL("OPC_MXU_S32TDV");
26032 generate_exception_end(ctx, EXCP_RI);
26033 break;
26034 case OPC_MXU_S32STDVR:
26035
26036 MIPS_INVAL("OPC_MXU_S32TDVR");
26037 generate_exception_end(ctx, EXCP_RI);
26038 break;
26039 default:
26040 MIPS_INVAL("decode_opc_mxu");
26041 generate_exception_end(ctx, EXCP_RI);
26042 break;
26043 }
26044}
26045
26046
26047
26048
26049
26050
26051
26052
26053
26054
26055
26056static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
26057{
26058 uint32_t opcode = extract32(ctx->opcode, 20, 1);
26059
26060 switch (opcode) {
26061 case OPC_MXU_S32LDI:
26062
26063 MIPS_INVAL("OPC_MXU_S32LDI");
26064 generate_exception_end(ctx, EXCP_RI);
26065 break;
26066 case OPC_MXU_S32LDIR:
26067
26068 MIPS_INVAL("OPC_MXU_S32LDIR");
26069 generate_exception_end(ctx, EXCP_RI);
26070 break;
26071 default:
26072 MIPS_INVAL("decode_opc_mxu");
26073 generate_exception_end(ctx, EXCP_RI);
26074 break;
26075 }
26076}
26077
26078
26079
26080
26081
26082
26083
26084
26085
26086
26087
26088static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
26089{
26090 uint32_t opcode = extract32(ctx->opcode, 5, 0);
26091
26092 switch (opcode) {
26093 case OPC_MXU_S32SDI:
26094
26095 MIPS_INVAL("OPC_MXU_S32SDI");
26096 generate_exception_end(ctx, EXCP_RI);
26097 break;
26098 case OPC_MXU_S32SDIR:
26099
26100 MIPS_INVAL("OPC_MXU_S32SDIR");
26101 generate_exception_end(ctx, EXCP_RI);
26102 break;
26103 default:
26104 MIPS_INVAL("decode_opc_mxu");
26105 generate_exception_end(ctx, EXCP_RI);
26106 break;
26107 }
26108}
26109
26110
26111
26112
26113
26114
26115
26116
26117
26118
26119
26120static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
26121{
26122 uint32_t opcode = extract32(ctx->opcode, 5, 0);
26123
26124 switch (opcode) {
26125 case OPC_MXU_S32LDIV:
26126
26127 MIPS_INVAL("OPC_MXU_S32LDIV");
26128 generate_exception_end(ctx, EXCP_RI);
26129 break;
26130 case OPC_MXU_S32LDIVR:
26131
26132 MIPS_INVAL("OPC_MXU_S32LDIVR");
26133 generate_exception_end(ctx, EXCP_RI);
26134 break;
26135 default:
26136 MIPS_INVAL("decode_opc_mxu");
26137 generate_exception_end(ctx, EXCP_RI);
26138 break;
26139 }
26140}
26141
26142
26143
26144
26145
26146
26147
26148
26149
26150
26151
26152static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
26153{
26154 uint32_t opcode = extract32(ctx->opcode, 10, 4);
26155
26156 switch (opcode) {
26157 case OPC_MXU_S32SDIV:
26158
26159 MIPS_INVAL("OPC_MXU_S32SDIV");
26160 generate_exception_end(ctx, EXCP_RI);
26161 break;
26162 case OPC_MXU_S32SDIVR:
26163
26164 MIPS_INVAL("OPC_MXU_S32SDIVR");
26165 generate_exception_end(ctx, EXCP_RI);
26166 break;
26167 default:
26168 MIPS_INVAL("decode_opc_mxu");
26169 generate_exception_end(ctx, EXCP_RI);
26170 break;
26171 }
26172}
26173
26174
26175
26176
26177
26178
26179
26180
26181
26182
26183
26184static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26185{
26186 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26187
26188 switch (opcode) {
26189 case OPC_MXU_D32ACC:
26190
26191 MIPS_INVAL("OPC_MXU_D32ACC");
26192 generate_exception_end(ctx, EXCP_RI);
26193 break;
26194 case OPC_MXU_D32ACCM:
26195
26196 MIPS_INVAL("OPC_MXU_D32ACCM");
26197 generate_exception_end(ctx, EXCP_RI);
26198 break;
26199 case OPC_MXU_D32ASUM:
26200
26201 MIPS_INVAL("OPC_MXU_D32ASUM");
26202 generate_exception_end(ctx, EXCP_RI);
26203 break;
26204 default:
26205 MIPS_INVAL("decode_opc_mxu");
26206 generate_exception_end(ctx, EXCP_RI);
26207 break;
26208 }
26209}
26210
26211
26212
26213
26214
26215
26216
26217
26218
26219
26220
26221static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26222{
26223 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26224
26225 switch (opcode) {
26226 case OPC_MXU_Q16ACC:
26227
26228 MIPS_INVAL("OPC_MXU_Q16ACC");
26229 generate_exception_end(ctx, EXCP_RI);
26230 break;
26231 case OPC_MXU_Q16ACCM:
26232
26233 MIPS_INVAL("OPC_MXU_Q16ACCM");
26234 generate_exception_end(ctx, EXCP_RI);
26235 break;
26236 case OPC_MXU_Q16ASUM:
26237
26238 MIPS_INVAL("OPC_MXU_Q16ASUM");
26239 generate_exception_end(ctx, EXCP_RI);
26240 break;
26241 default:
26242 MIPS_INVAL("decode_opc_mxu");
26243 generate_exception_end(ctx, EXCP_RI);
26244 break;
26245 }
26246}
26247
26248
26249
26250
26251
26252
26253
26254
26255
26256
26257
26258
26259
26260
26261
26262
26263
26264
26265static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26266{
26267 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26268
26269 switch (opcode) {
26270 case OPC_MXU_Q8ADDE:
26271
26272 MIPS_INVAL("OPC_MXU_Q8ADDE");
26273 generate_exception_end(ctx, EXCP_RI);
26274 break;
26275 case OPC_MXU_D8SUM:
26276
26277 MIPS_INVAL("OPC_MXU_D8SUM");
26278 generate_exception_end(ctx, EXCP_RI);
26279 break;
26280 case OPC_MXU_D8SUMC:
26281
26282 MIPS_INVAL("OPC_MXU_D8SUMC");
26283 generate_exception_end(ctx, EXCP_RI);
26284 break;
26285 default:
26286 MIPS_INVAL("decode_opc_mxu");
26287 generate_exception_end(ctx, EXCP_RI);
26288 break;
26289 }
26290}
26291
26292
26293
26294
26295
26296
26297
26298
26299
26300
26301
26302
26303
26304
26305
26306
26307
26308
26309static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26310{
26311 uint32_t opcode = extract32(ctx->opcode, 14, 2);
26312
26313 switch (opcode) {
26314 case OPC_MXU_S32MUL:
26315
26316 MIPS_INVAL("OPC_MXU_S32MUL");
26317 generate_exception_end(ctx, EXCP_RI);
26318 break;
26319 case OPC_MXU_S32MULU:
26320
26321 MIPS_INVAL("OPC_MXU_S32MULU");
26322 generate_exception_end(ctx, EXCP_RI);
26323 break;
26324 case OPC_MXU_S32EXTR:
26325
26326 MIPS_INVAL("OPC_MXU_S32EXTR");
26327 generate_exception_end(ctx, EXCP_RI);
26328 break;
26329 case OPC_MXU_S32EXTRV:
26330
26331 MIPS_INVAL("OPC_MXU_S32EXTRV");
26332 generate_exception_end(ctx, EXCP_RI);
26333 break;
26334 default:
26335 MIPS_INVAL("decode_opc_mxu");
26336 generate_exception_end(ctx, EXCP_RI);
26337 break;
26338 }
26339}
26340
26341
26342
26343
26344
26345
26346
26347
26348
26349
26350
26351
26352
26353
26354
26355
26356
26357
26358
26359
26360
26361
26362
26363
26364
26365
26366
26367
26368
26369
26370
26371
26372
26373
26374
26375
26376static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26377{
26378 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26379
26380 switch (opcode) {
26381 case OPC_MXU_D32SARW:
26382
26383 MIPS_INVAL("OPC_MXU_D32SARW");
26384 generate_exception_end(ctx, EXCP_RI);
26385 break;
26386 case OPC_MXU_S32ALN:
26387
26388 MIPS_INVAL("OPC_MXU_S32ALN");
26389 generate_exception_end(ctx, EXCP_RI);
26390 break;
26391 case OPC_MXU_S32ALNI:
26392 gen_mxu_S32ALNI(ctx);
26393 break;
26394 case OPC_MXU_S32LUI:
26395
26396 MIPS_INVAL("OPC_MXU_S32LUI");
26397 generate_exception_end(ctx, EXCP_RI);
26398 break;
26399 case OPC_MXU_S32NOR:
26400 gen_mxu_S32NOR(ctx);
26401 break;
26402 case OPC_MXU_S32AND:
26403 gen_mxu_S32AND(ctx);
26404 break;
26405 case OPC_MXU_S32OR:
26406 gen_mxu_S32OR(ctx);
26407 break;
26408 case OPC_MXU_S32XOR:
26409 gen_mxu_S32XOR(ctx);
26410 break;
26411 default:
26412 MIPS_INVAL("decode_opc_mxu");
26413 generate_exception_end(ctx, EXCP_RI);
26414 break;
26415 }
26416}
26417
26418
26419
26420
26421
26422
26423
26424
26425
26426
26427
26428static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26429{
26430 uint32_t opcode = extract32(ctx->opcode, 6, 2);
26431
26432 switch (opcode) {
26433 case OPC_MXU_LXW:
26434
26435 MIPS_INVAL("OPC_MXU_LXW");
26436 generate_exception_end(ctx, EXCP_RI);
26437 break;
26438 case OPC_MXU_LXH:
26439
26440 MIPS_INVAL("OPC_MXU_LXH");
26441 generate_exception_end(ctx, EXCP_RI);
26442 break;
26443 case OPC_MXU_LXHU:
26444
26445 MIPS_INVAL("OPC_MXU_LXHU");
26446 generate_exception_end(ctx, EXCP_RI);
26447 break;
26448 case OPC_MXU_LXB:
26449
26450 MIPS_INVAL("OPC_MXU_LXB");
26451 generate_exception_end(ctx, EXCP_RI);
26452 break;
26453 case OPC_MXU_LXBU:
26454
26455 MIPS_INVAL("OPC_MXU_LXBU");
26456 generate_exception_end(ctx, EXCP_RI);
26457 break;
26458 default:
26459 MIPS_INVAL("decode_opc_mxu");
26460 generate_exception_end(ctx, EXCP_RI);
26461 break;
26462 }
26463}
26464
26465
26466
26467
26468
26469
26470
26471
26472
26473
26474static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26475{
26476 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26477
26478 switch (opcode) {
26479 case OPC_MXU_D32SLLV:
26480
26481 MIPS_INVAL("OPC_MXU_D32SLLV");
26482 generate_exception_end(ctx, EXCP_RI);
26483 break;
26484 case OPC_MXU_D32SLRV:
26485
26486 MIPS_INVAL("OPC_MXU_D32SLRV");
26487 generate_exception_end(ctx, EXCP_RI);
26488 break;
26489 case OPC_MXU_D32SARV:
26490
26491 MIPS_INVAL("OPC_MXU_D32SARV");
26492 generate_exception_end(ctx, EXCP_RI);
26493 break;
26494 case OPC_MXU_Q16SLLV:
26495
26496 MIPS_INVAL("OPC_MXU_Q16SLLV");
26497 generate_exception_end(ctx, EXCP_RI);
26498 break;
26499 case OPC_MXU_Q16SLRV:
26500
26501 MIPS_INVAL("OPC_MXU_Q16SLRV");
26502 generate_exception_end(ctx, EXCP_RI);
26503 break;
26504 case OPC_MXU_Q16SARV:
26505
26506 MIPS_INVAL("OPC_MXU_Q16SARV");
26507 generate_exception_end(ctx, EXCP_RI);
26508 break;
26509 default:
26510 MIPS_INVAL("decode_opc_mxu");
26511 generate_exception_end(ctx, EXCP_RI);
26512 break;
26513 }
26514}
26515
26516
26517
26518
26519
26520
26521
26522
26523
26524
26525
26526static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26527{
26528 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26529
26530 switch (opcode) {
26531 case OPC_MXU_Q8MUL:
26532 case OPC_MXU_Q8MULSU:
26533 gen_mxu_q8mul_q8mulsu(ctx);
26534 break;
26535 default:
26536 MIPS_INVAL("decode_opc_mxu");
26537 generate_exception_end(ctx, EXCP_RI);
26538 break;
26539 }
26540}
26541
26542
26543
26544
26545
26546
26547
26548
26549
26550
26551
26552static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26553{
26554 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26555
26556 switch (opcode) {
26557 case OPC_MXU_Q8MOVZ:
26558
26559 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26560 generate_exception_end(ctx, EXCP_RI);
26561 break;
26562 case OPC_MXU_Q8MOVN:
26563
26564 MIPS_INVAL("OPC_MXU_Q8MOVN");
26565 generate_exception_end(ctx, EXCP_RI);
26566 break;
26567 case OPC_MXU_D16MOVZ:
26568
26569 MIPS_INVAL("OPC_MXU_D16MOVZ");
26570 generate_exception_end(ctx, EXCP_RI);
26571 break;
26572 case OPC_MXU_D16MOVN:
26573
26574 MIPS_INVAL("OPC_MXU_D16MOVN");
26575 generate_exception_end(ctx, EXCP_RI);
26576 break;
26577 case OPC_MXU_S32MOVZ:
26578
26579 MIPS_INVAL("OPC_MXU_S32MOVZ");
26580 generate_exception_end(ctx, EXCP_RI);
26581 break;
26582 case OPC_MXU_S32MOVN:
26583
26584 MIPS_INVAL("OPC_MXU_S32MOVN");
26585 generate_exception_end(ctx, EXCP_RI);
26586 break;
26587 default:
26588 MIPS_INVAL("decode_opc_mxu");
26589 generate_exception_end(ctx, EXCP_RI);
26590 break;
26591 }
26592}
26593
26594
26595
26596
26597
26598
26599
26600
26601
26602
26603
26604static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26605{
26606 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26607
26608 switch (opcode) {
26609 case OPC_MXU_Q8MAC:
26610
26611 MIPS_INVAL("OPC_MXU_Q8MAC");
26612 generate_exception_end(ctx, EXCP_RI);
26613 break;
26614 case OPC_MXU_Q8MACSU:
26615
26616 MIPS_INVAL("OPC_MXU_Q8MACSU");
26617 generate_exception_end(ctx, EXCP_RI);
26618 break;
26619 default:
26620 MIPS_INVAL("decode_opc_mxu");
26621 generate_exception_end(ctx, EXCP_RI);
26622 break;
26623 }
26624}
26625
26626
26627
26628
26629
26630
26631
26632
26633
26634
26635
26636static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26637{
26638
26639
26640
26641
26642
26643 uint32_t opcode = extract32(ctx->opcode, 0, 6);
26644
26645 if (opcode == OPC__MXU_MUL) {
26646 uint32_t rs, rt, rd, op1;
26647
26648 rs = extract32(ctx->opcode, 21, 5);
26649 rt = extract32(ctx->opcode, 16, 5);
26650 rd = extract32(ctx->opcode, 11, 5);
26651 op1 = MASK_SPECIAL2(ctx->opcode);
26652
26653 gen_arith(ctx, op1, rd, rs, rt);
26654
26655 return;
26656 }
26657
26658 if (opcode == OPC_MXU_S32M2I) {
26659 gen_mxu_s32m2i(ctx);
26660 return;
26661 }
26662
26663 if (opcode == OPC_MXU_S32I2M) {
26664 gen_mxu_s32i2m(ctx);
26665 return;
26666 }
26667
26668 {
26669 TCGv t_mxu_cr = tcg_temp_new();
26670 TCGLabel *l_exit = gen_new_label();
26671
26672 gen_load_mxu_cr(t_mxu_cr);
26673 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26674 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26675
26676 switch (opcode) {
26677 case OPC_MXU_S32MADD:
26678
26679 MIPS_INVAL("OPC_MXU_S32MADD");
26680 generate_exception_end(ctx, EXCP_RI);
26681 break;
26682 case OPC_MXU_S32MADDU:
26683
26684 MIPS_INVAL("OPC_MXU_S32MADDU");
26685 generate_exception_end(ctx, EXCP_RI);
26686 break;
26687 case OPC_MXU__POOL00:
26688 decode_opc_mxu__pool00(env, ctx);
26689 break;
26690 case OPC_MXU_S32MSUB:
26691
26692 MIPS_INVAL("OPC_MXU_S32MSUB");
26693 generate_exception_end(ctx, EXCP_RI);
26694 break;
26695 case OPC_MXU_S32MSUBU:
26696
26697 MIPS_INVAL("OPC_MXU_S32MSUBU");
26698 generate_exception_end(ctx, EXCP_RI);
26699 break;
26700 case OPC_MXU__POOL01:
26701 decode_opc_mxu__pool01(env, ctx);
26702 break;
26703 case OPC_MXU__POOL02:
26704 decode_opc_mxu__pool02(env, ctx);
26705 break;
26706 case OPC_MXU_D16MUL:
26707 gen_mxu_d16mul(ctx);
26708 break;
26709 case OPC_MXU__POOL03:
26710 decode_opc_mxu__pool03(env, ctx);
26711 break;
26712 case OPC_MXU_D16MAC:
26713 gen_mxu_d16mac(ctx);
26714 break;
26715 case OPC_MXU_D16MACF:
26716
26717 MIPS_INVAL("OPC_MXU_D16MACF");
26718 generate_exception_end(ctx, EXCP_RI);
26719 break;
26720 case OPC_MXU_D16MADL:
26721
26722 MIPS_INVAL("OPC_MXU_D16MADL");
26723 generate_exception_end(ctx, EXCP_RI);
26724 break;
26725 case OPC_MXU_S16MAD:
26726
26727 MIPS_INVAL("OPC_MXU_S16MAD");
26728 generate_exception_end(ctx, EXCP_RI);
26729 break;
26730 case OPC_MXU_Q16ADD:
26731
26732 MIPS_INVAL("OPC_MXU_Q16ADD");
26733 generate_exception_end(ctx, EXCP_RI);
26734 break;
26735 case OPC_MXU_D16MACE:
26736
26737 MIPS_INVAL("OPC_MXU_D16MACE");
26738 generate_exception_end(ctx, EXCP_RI);
26739 break;
26740 case OPC_MXU__POOL04:
26741 decode_opc_mxu__pool04(env, ctx);
26742 break;
26743 case OPC_MXU__POOL05:
26744 decode_opc_mxu__pool05(env, ctx);
26745 break;
26746 case OPC_MXU__POOL06:
26747 decode_opc_mxu__pool06(env, ctx);
26748 break;
26749 case OPC_MXU__POOL07:
26750 decode_opc_mxu__pool07(env, ctx);
26751 break;
26752 case OPC_MXU__POOL08:
26753 decode_opc_mxu__pool08(env, ctx);
26754 break;
26755 case OPC_MXU__POOL09:
26756 decode_opc_mxu__pool09(env, ctx);
26757 break;
26758 case OPC_MXU__POOL10:
26759 decode_opc_mxu__pool10(env, ctx);
26760 break;
26761 case OPC_MXU__POOL11:
26762 decode_opc_mxu__pool11(env, ctx);
26763 break;
26764 case OPC_MXU_D32ADD:
26765
26766 MIPS_INVAL("OPC_MXU_D32ADD");
26767 generate_exception_end(ctx, EXCP_RI);
26768 break;
26769 case OPC_MXU__POOL12:
26770 decode_opc_mxu__pool12(env, ctx);
26771 break;
26772 case OPC_MXU__POOL13:
26773 decode_opc_mxu__pool13(env, ctx);
26774 break;
26775 case OPC_MXU__POOL14:
26776 decode_opc_mxu__pool14(env, ctx);
26777 break;
26778 case OPC_MXU_Q8ACCE:
26779
26780 MIPS_INVAL("OPC_MXU_Q8ACCE");
26781 generate_exception_end(ctx, EXCP_RI);
26782 break;
26783 case OPC_MXU_S8LDD:
26784 gen_mxu_s8ldd(ctx);
26785 break;
26786 case OPC_MXU_S8STD:
26787
26788 MIPS_INVAL("OPC_MXU_S8STD");
26789 generate_exception_end(ctx, EXCP_RI);
26790 break;
26791 case OPC_MXU_S8LDI:
26792
26793 MIPS_INVAL("OPC_MXU_S8LDI");
26794 generate_exception_end(ctx, EXCP_RI);
26795 break;
26796 case OPC_MXU_S8SDI:
26797
26798 MIPS_INVAL("OPC_MXU_S8SDI");
26799 generate_exception_end(ctx, EXCP_RI);
26800 break;
26801 case OPC_MXU__POOL15:
26802 decode_opc_mxu__pool15(env, ctx);
26803 break;
26804 case OPC_MXU__POOL16:
26805 decode_opc_mxu__pool16(env, ctx);
26806 break;
26807 case OPC_MXU__POOL17:
26808 decode_opc_mxu__pool17(env, ctx);
26809 break;
26810 case OPC_MXU_S16LDD:
26811
26812 MIPS_INVAL("OPC_MXU_S16LDD");
26813 generate_exception_end(ctx, EXCP_RI);
26814 break;
26815 case OPC_MXU_S16STD:
26816
26817 MIPS_INVAL("OPC_MXU_S16STD");
26818 generate_exception_end(ctx, EXCP_RI);
26819 break;
26820 case OPC_MXU_S16LDI:
26821
26822 MIPS_INVAL("OPC_MXU_S16LDI");
26823 generate_exception_end(ctx, EXCP_RI);
26824 break;
26825 case OPC_MXU_S16SDI:
26826
26827 MIPS_INVAL("OPC_MXU_S16SDI");
26828 generate_exception_end(ctx, EXCP_RI);
26829 break;
26830 case OPC_MXU_D32SLL:
26831
26832 MIPS_INVAL("OPC_MXU_D32SLL");
26833 generate_exception_end(ctx, EXCP_RI);
26834 break;
26835 case OPC_MXU_D32SLR:
26836
26837 MIPS_INVAL("OPC_MXU_D32SLR");
26838 generate_exception_end(ctx, EXCP_RI);
26839 break;
26840 case OPC_MXU_D32SARL:
26841
26842 MIPS_INVAL("OPC_MXU_D32SARL");
26843 generate_exception_end(ctx, EXCP_RI);
26844 break;
26845 case OPC_MXU_D32SAR:
26846
26847 MIPS_INVAL("OPC_MXU_D32SAR");
26848 generate_exception_end(ctx, EXCP_RI);
26849 break;
26850 case OPC_MXU_Q16SLL:
26851
26852 MIPS_INVAL("OPC_MXU_Q16SLL");
26853 generate_exception_end(ctx, EXCP_RI);
26854 break;
26855 case OPC_MXU_Q16SLR:
26856
26857 MIPS_INVAL("OPC_MXU_Q16SLR");
26858 generate_exception_end(ctx, EXCP_RI);
26859 break;
26860 case OPC_MXU__POOL18:
26861 decode_opc_mxu__pool18(env, ctx);
26862 break;
26863 case OPC_MXU_Q16SAR:
26864
26865 MIPS_INVAL("OPC_MXU_Q16SAR");
26866 generate_exception_end(ctx, EXCP_RI);
26867 break;
26868 case OPC_MXU__POOL19:
26869 decode_opc_mxu__pool19(env, ctx);
26870 break;
26871 case OPC_MXU__POOL20:
26872 decode_opc_mxu__pool20(env, ctx);
26873 break;
26874 case OPC_MXU__POOL21:
26875 decode_opc_mxu__pool21(env, ctx);
26876 break;
26877 case OPC_MXU_Q16SCOP:
26878
26879 MIPS_INVAL("OPC_MXU_Q16SCOP");
26880 generate_exception_end(ctx, EXCP_RI);
26881 break;
26882 case OPC_MXU_Q8MADL:
26883
26884 MIPS_INVAL("OPC_MXU_Q8MADL");
26885 generate_exception_end(ctx, EXCP_RI);
26886 break;
26887 case OPC_MXU_S32SFL:
26888
26889 MIPS_INVAL("OPC_MXU_S32SFL");
26890 generate_exception_end(ctx, EXCP_RI);
26891 break;
26892 case OPC_MXU_Q8SAD:
26893
26894 MIPS_INVAL("OPC_MXU_Q8SAD");
26895 generate_exception_end(ctx, EXCP_RI);
26896 break;
26897 default:
26898 MIPS_INVAL("decode_opc_mxu");
26899 generate_exception_end(ctx, EXCP_RI);
26900 }
26901
26902 gen_set_label(l_exit);
26903 tcg_temp_free(t_mxu_cr);
26904 }
26905}
26906
26907#endif
26908
26909
26910static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26911{
26912 int rs, rt, rd;
26913 uint32_t op1;
26914
26915 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26916
26917 rs = (ctx->opcode >> 21) & 0x1f;
26918 rt = (ctx->opcode >> 16) & 0x1f;
26919 rd = (ctx->opcode >> 11) & 0x1f;
26920
26921 op1 = MASK_SPECIAL2(ctx->opcode);
26922 switch (op1) {
26923 case OPC_MADD:
26924 case OPC_MADDU:
26925 case OPC_MSUB:
26926 case OPC_MSUBU:
26927 check_insn(ctx, ISA_MIPS32);
26928 gen_muldiv(ctx, op1, rd & 3, rs, rt);
26929 break;
26930 case OPC_MUL:
26931 gen_arith(ctx, op1, rd, rs, rt);
26932 break;
26933 case OPC_DIV_G_2F:
26934 case OPC_DIVU_G_2F:
26935 case OPC_MULT_G_2F:
26936 case OPC_MULTU_G_2F:
26937 case OPC_MOD_G_2F:
26938 case OPC_MODU_G_2F:
26939 check_insn(ctx, INSN_LOONGSON2F);
26940 gen_loongson_integer(ctx, op1, rd, rs, rt);
26941 break;
26942 case OPC_CLO:
26943 case OPC_CLZ:
26944 check_insn(ctx, ISA_MIPS32);
26945 gen_cl(ctx, op1, rd, rs);
26946 break;
26947 case OPC_SDBBP:
26948 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26949 gen_helper_do_semihosting(cpu_env);
26950 } else {
26951
26952
26953
26954
26955 check_insn(ctx, ISA_MIPS32);
26956 generate_exception_end(ctx, EXCP_DBp);
26957 }
26958 break;
26959#if defined(TARGET_MIPS64)
26960 case OPC_DCLO:
26961 case OPC_DCLZ:
26962 check_insn(ctx, ISA_MIPS64);
26963 check_mips_64(ctx);
26964 gen_cl(ctx, op1, rd, rs);
26965 break;
26966 case OPC_DMULT_G_2F:
26967 case OPC_DMULTU_G_2F:
26968 case OPC_DDIV_G_2F:
26969 case OPC_DDIVU_G_2F:
26970 case OPC_DMOD_G_2F:
26971 case OPC_DMODU_G_2F:
26972 check_insn(ctx, INSN_LOONGSON2F);
26973 gen_loongson_integer(ctx, op1, rd, rs, rt);
26974 break;
26975#endif
26976 default:
26977 MIPS_INVAL("special2_legacy");
26978 generate_exception_end(ctx, EXCP_RI);
26979 break;
26980 }
26981}
26982
26983static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26984{
26985 int rs, rt, rd, sa;
26986 uint32_t op1, op2;
26987 int16_t imm;
26988
26989 rs = (ctx->opcode >> 21) & 0x1f;
26990 rt = (ctx->opcode >> 16) & 0x1f;
26991 rd = (ctx->opcode >> 11) & 0x1f;
26992 sa = (ctx->opcode >> 6) & 0x1f;
26993 imm = (int16_t)ctx->opcode >> 7;
26994
26995 op1 = MASK_SPECIAL3(ctx->opcode);
26996 switch (op1) {
26997 case R6_OPC_PREF:
26998 if (rt >= 24) {
26999
27000 generate_exception_end(ctx, EXCP_RI);
27001 }
27002
27003 break;
27004 case R6_OPC_CACHE:
27005 check_cp0_enabled(ctx);
27006 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27007 gen_cache_operation(ctx, rt, rs, imm);
27008 }
27009 break;
27010 case R6_OPC_SC:
27011 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
27012 break;
27013 case R6_OPC_LL:
27014 gen_ld(ctx, op1, rt, rs, imm);
27015 break;
27016 case OPC_BSHFL:
27017 {
27018 if (rd == 0) {
27019
27020 break;
27021 }
27022 op2 = MASK_BSHFL(ctx->opcode);
27023 switch (op2) {
27024 case OPC_ALIGN:
27025 case OPC_ALIGN_1:
27026 case OPC_ALIGN_2:
27027 case OPC_ALIGN_3:
27028 gen_align(ctx, 32, rd, rs, rt, sa & 3);
27029 break;
27030 case OPC_BITSWAP:
27031 gen_bitswap(ctx, op2, rd, rt);
27032 break;
27033 }
27034 }
27035 break;
27036#if defined(TARGET_MIPS64)
27037 case R6_OPC_SCD:
27038 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
27039 break;
27040 case R6_OPC_LLD:
27041 gen_ld(ctx, op1, rt, rs, imm);
27042 break;
27043 case OPC_DBSHFL:
27044 check_mips_64(ctx);
27045 {
27046 if (rd == 0) {
27047
27048 break;
27049 }
27050 op2 = MASK_DBSHFL(ctx->opcode);
27051 switch (op2) {
27052 case OPC_DALIGN:
27053 case OPC_DALIGN_1:
27054 case OPC_DALIGN_2:
27055 case OPC_DALIGN_3:
27056 case OPC_DALIGN_4:
27057 case OPC_DALIGN_5:
27058 case OPC_DALIGN_6:
27059 case OPC_DALIGN_7:
27060 gen_align(ctx, 64, rd, rs, rt, sa & 7);
27061 break;
27062 case OPC_DBITSWAP:
27063 gen_bitswap(ctx, op2, rd, rt);
27064 break;
27065 }
27066
27067 }
27068 break;
27069#endif
27070 default:
27071 MIPS_INVAL("special3_r6");
27072 generate_exception_end(ctx, EXCP_RI);
27073 break;
27074 }
27075}
27076
27077static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
27078{
27079 int rs, rt, rd;
27080 uint32_t op1, op2;
27081
27082 rs = (ctx->opcode >> 21) & 0x1f;
27083 rt = (ctx->opcode >> 16) & 0x1f;
27084 rd = (ctx->opcode >> 11) & 0x1f;
27085
27086 op1 = MASK_SPECIAL3(ctx->opcode);
27087 switch (op1) {
27088 case OPC_DIV_G_2E:
27089 case OPC_DIVU_G_2E:
27090 case OPC_MOD_G_2E:
27091 case OPC_MODU_G_2E:
27092 case OPC_MULT_G_2E:
27093 case OPC_MULTU_G_2E:
27094
27095
27096
27097
27098 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
27099 op2 = MASK_ADDUH_QB(ctx->opcode);
27100 switch (op2) {
27101 case OPC_ADDUH_QB:
27102 case OPC_ADDUH_R_QB:
27103 case OPC_ADDQH_PH:
27104 case OPC_ADDQH_R_PH:
27105 case OPC_ADDQH_W:
27106 case OPC_ADDQH_R_W:
27107 case OPC_SUBUH_QB:
27108 case OPC_SUBUH_R_QB:
27109 case OPC_SUBQH_PH:
27110 case OPC_SUBQH_R_PH:
27111 case OPC_SUBQH_W:
27112 case OPC_SUBQH_R_W:
27113 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27114 break;
27115 case OPC_MUL_PH:
27116 case OPC_MUL_S_PH:
27117 case OPC_MULQ_S_W:
27118 case OPC_MULQ_RS_W:
27119 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27120 break;
27121 default:
27122 MIPS_INVAL("MASK ADDUH.QB");
27123 generate_exception_end(ctx, EXCP_RI);
27124 break;
27125 }
27126 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
27127 gen_loongson_integer(ctx, op1, rd, rs, rt);
27128 } else {
27129 generate_exception_end(ctx, EXCP_RI);
27130 }
27131 break;
27132 case OPC_LX_DSP:
27133 op2 = MASK_LX(ctx->opcode);
27134 switch (op2) {
27135#if defined(TARGET_MIPS64)
27136 case OPC_LDX:
27137#endif
27138 case OPC_LBUX:
27139 case OPC_LHX:
27140 case OPC_LWX:
27141 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
27142 break;
27143 default:
27144 MIPS_INVAL("MASK LX");
27145 generate_exception_end(ctx, EXCP_RI);
27146 break;
27147 }
27148 break;
27149 case OPC_ABSQ_S_PH_DSP:
27150 op2 = MASK_ABSQ_S_PH(ctx->opcode);
27151 switch (op2) {
27152 case OPC_ABSQ_S_QB:
27153 case OPC_ABSQ_S_PH:
27154 case OPC_ABSQ_S_W:
27155 case OPC_PRECEQ_W_PHL:
27156 case OPC_PRECEQ_W_PHR:
27157 case OPC_PRECEQU_PH_QBL:
27158 case OPC_PRECEQU_PH_QBR:
27159 case OPC_PRECEQU_PH_QBLA:
27160 case OPC_PRECEQU_PH_QBRA:
27161 case OPC_PRECEU_PH_QBL:
27162 case OPC_PRECEU_PH_QBR:
27163 case OPC_PRECEU_PH_QBLA:
27164 case OPC_PRECEU_PH_QBRA:
27165 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27166 break;
27167 case OPC_BITREV:
27168 case OPC_REPL_QB:
27169 case OPC_REPLV_QB:
27170 case OPC_REPL_PH:
27171 case OPC_REPLV_PH:
27172 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27173 break;
27174 default:
27175 MIPS_INVAL("MASK ABSQ_S.PH");
27176 generate_exception_end(ctx, EXCP_RI);
27177 break;
27178 }
27179 break;
27180 case OPC_ADDU_QB_DSP:
27181 op2 = MASK_ADDU_QB(ctx->opcode);
27182 switch (op2) {
27183 case OPC_ADDQ_PH:
27184 case OPC_ADDQ_S_PH:
27185 case OPC_ADDQ_S_W:
27186 case OPC_ADDU_QB:
27187 case OPC_ADDU_S_QB:
27188 case OPC_ADDU_PH:
27189 case OPC_ADDU_S_PH:
27190 case OPC_SUBQ_PH:
27191 case OPC_SUBQ_S_PH:
27192 case OPC_SUBQ_S_W:
27193 case OPC_SUBU_QB:
27194 case OPC_SUBU_S_QB:
27195 case OPC_SUBU_PH:
27196 case OPC_SUBU_S_PH:
27197 case OPC_ADDSC:
27198 case OPC_ADDWC:
27199 case OPC_MODSUB:
27200 case OPC_RADDU_W_QB:
27201 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27202 break;
27203 case OPC_MULEU_S_PH_QBL:
27204 case OPC_MULEU_S_PH_QBR:
27205 case OPC_MULQ_RS_PH:
27206 case OPC_MULEQ_S_W_PHL:
27207 case OPC_MULEQ_S_W_PHR:
27208 case OPC_MULQ_S_PH:
27209 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27210 break;
27211 default:
27212 MIPS_INVAL("MASK ADDU.QB");
27213 generate_exception_end(ctx, EXCP_RI);
27214 break;
27215
27216 }
27217 break;
27218 case OPC_CMPU_EQ_QB_DSP:
27219 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27220 switch (op2) {
27221 case OPC_PRECR_SRA_PH_W:
27222 case OPC_PRECR_SRA_R_PH_W:
27223 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27224 break;
27225 case OPC_PRECR_QB_PH:
27226 case OPC_PRECRQ_QB_PH:
27227 case OPC_PRECRQ_PH_W:
27228 case OPC_PRECRQ_RS_PH_W:
27229 case OPC_PRECRQU_S_QB_PH:
27230 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27231 break;
27232 case OPC_CMPU_EQ_QB:
27233 case OPC_CMPU_LT_QB:
27234 case OPC_CMPU_LE_QB:
27235 case OPC_CMP_EQ_PH:
27236 case OPC_CMP_LT_PH:
27237 case OPC_CMP_LE_PH:
27238 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27239 break;
27240 case OPC_CMPGU_EQ_QB:
27241 case OPC_CMPGU_LT_QB:
27242 case OPC_CMPGU_LE_QB:
27243 case OPC_CMPGDU_EQ_QB:
27244 case OPC_CMPGDU_LT_QB:
27245 case OPC_CMPGDU_LE_QB:
27246 case OPC_PICK_QB:
27247 case OPC_PICK_PH:
27248 case OPC_PACKRL_PH:
27249 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27250 break;
27251 default:
27252 MIPS_INVAL("MASK CMPU.EQ.QB");
27253 generate_exception_end(ctx, EXCP_RI);
27254 break;
27255 }
27256 break;
27257 case OPC_SHLL_QB_DSP:
27258 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27259 break;
27260 case OPC_DPA_W_PH_DSP:
27261 op2 = MASK_DPA_W_PH(ctx->opcode);
27262 switch (op2) {
27263 case OPC_DPAU_H_QBL:
27264 case OPC_DPAU_H_QBR:
27265 case OPC_DPSU_H_QBL:
27266 case OPC_DPSU_H_QBR:
27267 case OPC_DPA_W_PH:
27268 case OPC_DPAX_W_PH:
27269 case OPC_DPAQ_S_W_PH:
27270 case OPC_DPAQX_S_W_PH:
27271 case OPC_DPAQX_SA_W_PH:
27272 case OPC_DPS_W_PH:
27273 case OPC_DPSX_W_PH:
27274 case OPC_DPSQ_S_W_PH:
27275 case OPC_DPSQX_S_W_PH:
27276 case OPC_DPSQX_SA_W_PH:
27277 case OPC_MULSAQ_S_W_PH:
27278 case OPC_DPAQ_SA_L_W:
27279 case OPC_DPSQ_SA_L_W:
27280 case OPC_MAQ_S_W_PHL:
27281 case OPC_MAQ_S_W_PHR:
27282 case OPC_MAQ_SA_W_PHL:
27283 case OPC_MAQ_SA_W_PHR:
27284 case OPC_MULSA_W_PH:
27285 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27286 break;
27287 default:
27288 MIPS_INVAL("MASK DPAW.PH");
27289 generate_exception_end(ctx, EXCP_RI);
27290 break;
27291 }
27292 break;
27293 case OPC_INSV_DSP:
27294 op2 = MASK_INSV(ctx->opcode);
27295 switch (op2) {
27296 case OPC_INSV:
27297 check_dsp(ctx);
27298 {
27299 TCGv t0, t1;
27300
27301 if (rt == 0) {
27302 break;
27303 }
27304
27305 t0 = tcg_temp_new();
27306 t1 = tcg_temp_new();
27307
27308 gen_load_gpr(t0, rt);
27309 gen_load_gpr(t1, rs);
27310
27311 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27312
27313 tcg_temp_free(t0);
27314 tcg_temp_free(t1);
27315 break;
27316 }
27317 default:
27318 MIPS_INVAL("MASK INSV");
27319 generate_exception_end(ctx, EXCP_RI);
27320 break;
27321 }
27322 break;
27323 case OPC_APPEND_DSP:
27324 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27325 break;
27326 case OPC_EXTR_W_DSP:
27327 op2 = MASK_EXTR_W(ctx->opcode);
27328 switch (op2) {
27329 case OPC_EXTR_W:
27330 case OPC_EXTR_R_W:
27331 case OPC_EXTR_RS_W:
27332 case OPC_EXTR_S_H:
27333 case OPC_EXTRV_S_H:
27334 case OPC_EXTRV_W:
27335 case OPC_EXTRV_R_W:
27336 case OPC_EXTRV_RS_W:
27337 case OPC_EXTP:
27338 case OPC_EXTPV:
27339 case OPC_EXTPDP:
27340 case OPC_EXTPDPV:
27341 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27342 break;
27343 case OPC_RDDSP:
27344 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27345 break;
27346 case OPC_SHILO:
27347 case OPC_SHILOV:
27348 case OPC_MTHLIP:
27349 case OPC_WRDSP:
27350 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27351 break;
27352 default:
27353 MIPS_INVAL("MASK EXTR.W");
27354 generate_exception_end(ctx, EXCP_RI);
27355 break;
27356 }
27357 break;
27358#if defined(TARGET_MIPS64)
27359 case OPC_DDIV_G_2E:
27360 case OPC_DDIVU_G_2E:
27361 case OPC_DMULT_G_2E:
27362 case OPC_DMULTU_G_2E:
27363 case OPC_DMOD_G_2E:
27364 case OPC_DMODU_G_2E:
27365 check_insn(ctx, INSN_LOONGSON2E);
27366 gen_loongson_integer(ctx, op1, rd, rs, rt);
27367 break;
27368 case OPC_ABSQ_S_QH_DSP:
27369 op2 = MASK_ABSQ_S_QH(ctx->opcode);
27370 switch (op2) {
27371 case OPC_PRECEQ_L_PWL:
27372 case OPC_PRECEQ_L_PWR:
27373 case OPC_PRECEQ_PW_QHL:
27374 case OPC_PRECEQ_PW_QHR:
27375 case OPC_PRECEQ_PW_QHLA:
27376 case OPC_PRECEQ_PW_QHRA:
27377 case OPC_PRECEQU_QH_OBL:
27378 case OPC_PRECEQU_QH_OBR:
27379 case OPC_PRECEQU_QH_OBLA:
27380 case OPC_PRECEQU_QH_OBRA:
27381 case OPC_PRECEU_QH_OBL:
27382 case OPC_PRECEU_QH_OBR:
27383 case OPC_PRECEU_QH_OBLA:
27384 case OPC_PRECEU_QH_OBRA:
27385 case OPC_ABSQ_S_OB:
27386 case OPC_ABSQ_S_PW:
27387 case OPC_ABSQ_S_QH:
27388 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27389 break;
27390 case OPC_REPL_OB:
27391 case OPC_REPL_PW:
27392 case OPC_REPL_QH:
27393 case OPC_REPLV_OB:
27394 case OPC_REPLV_PW:
27395 case OPC_REPLV_QH:
27396 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27397 break;
27398 default:
27399 MIPS_INVAL("MASK ABSQ_S.QH");
27400 generate_exception_end(ctx, EXCP_RI);
27401 break;
27402 }
27403 break;
27404 case OPC_ADDU_OB_DSP:
27405 op2 = MASK_ADDU_OB(ctx->opcode);
27406 switch (op2) {
27407 case OPC_RADDU_L_OB:
27408 case OPC_SUBQ_PW:
27409 case OPC_SUBQ_S_PW:
27410 case OPC_SUBQ_QH:
27411 case OPC_SUBQ_S_QH:
27412 case OPC_SUBU_OB:
27413 case OPC_SUBU_S_OB:
27414 case OPC_SUBU_QH:
27415 case OPC_SUBU_S_QH:
27416 case OPC_SUBUH_OB:
27417 case OPC_SUBUH_R_OB:
27418 case OPC_ADDQ_PW:
27419 case OPC_ADDQ_S_PW:
27420 case OPC_ADDQ_QH:
27421 case OPC_ADDQ_S_QH:
27422 case OPC_ADDU_OB:
27423 case OPC_ADDU_S_OB:
27424 case OPC_ADDU_QH:
27425 case OPC_ADDU_S_QH:
27426 case OPC_ADDUH_OB:
27427 case OPC_ADDUH_R_OB:
27428 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27429 break;
27430 case OPC_MULEQ_S_PW_QHL:
27431 case OPC_MULEQ_S_PW_QHR:
27432 case OPC_MULEU_S_QH_OBL:
27433 case OPC_MULEU_S_QH_OBR:
27434 case OPC_MULQ_RS_QH:
27435 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27436 break;
27437 default:
27438 MIPS_INVAL("MASK ADDU.OB");
27439 generate_exception_end(ctx, EXCP_RI);
27440 break;
27441 }
27442 break;
27443 case OPC_CMPU_EQ_OB_DSP:
27444 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27445 switch (op2) {
27446 case OPC_PRECR_SRA_QH_PW:
27447 case OPC_PRECR_SRA_R_QH_PW:
27448
27449 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27450 break;
27451 case OPC_PRECR_OB_QH:
27452 case OPC_PRECRQ_OB_QH:
27453 case OPC_PRECRQ_PW_L:
27454 case OPC_PRECRQ_QH_PW:
27455 case OPC_PRECRQ_RS_QH_PW:
27456 case OPC_PRECRQU_S_OB_QH:
27457 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27458 break;
27459 case OPC_CMPU_EQ_OB:
27460 case OPC_CMPU_LT_OB:
27461 case OPC_CMPU_LE_OB:
27462 case OPC_CMP_EQ_QH:
27463 case OPC_CMP_LT_QH:
27464 case OPC_CMP_LE_QH:
27465 case OPC_CMP_EQ_PW:
27466 case OPC_CMP_LT_PW:
27467 case OPC_CMP_LE_PW:
27468 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27469 break;
27470 case OPC_CMPGDU_EQ_OB:
27471 case OPC_CMPGDU_LT_OB:
27472 case OPC_CMPGDU_LE_OB:
27473 case OPC_CMPGU_EQ_OB:
27474 case OPC_CMPGU_LT_OB:
27475 case OPC_CMPGU_LE_OB:
27476 case OPC_PACKRL_PW:
27477 case OPC_PICK_OB:
27478 case OPC_PICK_PW:
27479 case OPC_PICK_QH:
27480 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27481 break;
27482 default:
27483 MIPS_INVAL("MASK CMPU_EQ.OB");
27484 generate_exception_end(ctx, EXCP_RI);
27485 break;
27486 }
27487 break;
27488 case OPC_DAPPEND_DSP:
27489 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27490 break;
27491 case OPC_DEXTR_W_DSP:
27492 op2 = MASK_DEXTR_W(ctx->opcode);
27493 switch (op2) {
27494 case OPC_DEXTP:
27495 case OPC_DEXTPDP:
27496 case OPC_DEXTPDPV:
27497 case OPC_DEXTPV:
27498 case OPC_DEXTR_L:
27499 case OPC_DEXTR_R_L:
27500 case OPC_DEXTR_RS_L:
27501 case OPC_DEXTR_W:
27502 case OPC_DEXTR_R_W:
27503 case OPC_DEXTR_RS_W:
27504 case OPC_DEXTR_S_H:
27505 case OPC_DEXTRV_L:
27506 case OPC_DEXTRV_R_L:
27507 case OPC_DEXTRV_RS_L:
27508 case OPC_DEXTRV_S_H:
27509 case OPC_DEXTRV_W:
27510 case OPC_DEXTRV_R_W:
27511 case OPC_DEXTRV_RS_W:
27512 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27513 break;
27514 case OPC_DMTHLIP:
27515 case OPC_DSHILO:
27516 case OPC_DSHILOV:
27517 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27518 break;
27519 default:
27520 MIPS_INVAL("MASK EXTR.W");
27521 generate_exception_end(ctx, EXCP_RI);
27522 break;
27523 }
27524 break;
27525 case OPC_DPAQ_W_QH_DSP:
27526 op2 = MASK_DPAQ_W_QH(ctx->opcode);
27527 switch (op2) {
27528 case OPC_DPAU_H_OBL:
27529 case OPC_DPAU_H_OBR:
27530 case OPC_DPSU_H_OBL:
27531 case OPC_DPSU_H_OBR:
27532 case OPC_DPA_W_QH:
27533 case OPC_DPAQ_S_W_QH:
27534 case OPC_DPS_W_QH:
27535 case OPC_DPSQ_S_W_QH:
27536 case OPC_MULSAQ_S_W_QH:
27537 case OPC_DPAQ_SA_L_PW:
27538 case OPC_DPSQ_SA_L_PW:
27539 case OPC_MULSAQ_S_L_PW:
27540 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27541 break;
27542 case OPC_MAQ_S_W_QHLL:
27543 case OPC_MAQ_S_W_QHLR:
27544 case OPC_MAQ_S_W_QHRL:
27545 case OPC_MAQ_S_W_QHRR:
27546 case OPC_MAQ_SA_W_QHLL:
27547 case OPC_MAQ_SA_W_QHLR:
27548 case OPC_MAQ_SA_W_QHRL:
27549 case OPC_MAQ_SA_W_QHRR:
27550 case OPC_MAQ_S_L_PWL:
27551 case OPC_MAQ_S_L_PWR:
27552 case OPC_DMADD:
27553 case OPC_DMADDU:
27554 case OPC_DMSUB:
27555 case OPC_DMSUBU:
27556 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27557 break;
27558 default:
27559 MIPS_INVAL("MASK DPAQ.W.QH");
27560 generate_exception_end(ctx, EXCP_RI);
27561 break;
27562 }
27563 break;
27564 case OPC_DINSV_DSP:
27565 op2 = MASK_INSV(ctx->opcode);
27566 switch (op2) {
27567 case OPC_DINSV:
27568 {
27569 TCGv t0, t1;
27570
27571 if (rt == 0) {
27572 break;
27573 }
27574 check_dsp(ctx);
27575
27576 t0 = tcg_temp_new();
27577 t1 = tcg_temp_new();
27578
27579 gen_load_gpr(t0, rt);
27580 gen_load_gpr(t1, rs);
27581
27582 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27583
27584 tcg_temp_free(t0);
27585 tcg_temp_free(t1);
27586 break;
27587 }
27588 default:
27589 MIPS_INVAL("MASK DINSV");
27590 generate_exception_end(ctx, EXCP_RI);
27591 break;
27592 }
27593 break;
27594 case OPC_SHLL_OB_DSP:
27595 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27596 break;
27597#endif
27598 default:
27599 MIPS_INVAL("special3_legacy");
27600 generate_exception_end(ctx, EXCP_RI);
27601 break;
27602 }
27603}
27604
27605
27606#if defined(TARGET_MIPS64)
27607
27608static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27609{
27610 uint32_t opc = MASK_MMI0(ctx->opcode);
27611
27612 switch (opc) {
27613 case MMI_OPC_0_PADDW:
27614 case MMI_OPC_0_PSUBW:
27615 case MMI_OPC_0_PCGTW:
27616 case MMI_OPC_0_PMAXW:
27617 case MMI_OPC_0_PADDH:
27618 case MMI_OPC_0_PSUBH:
27619 case MMI_OPC_0_PCGTH:
27620 case MMI_OPC_0_PMAXH:
27621 case MMI_OPC_0_PADDB:
27622 case MMI_OPC_0_PSUBB:
27623 case MMI_OPC_0_PCGTB:
27624 case MMI_OPC_0_PADDSW:
27625 case MMI_OPC_0_PSUBSW:
27626 case MMI_OPC_0_PEXTLW:
27627 case MMI_OPC_0_PPACW:
27628 case MMI_OPC_0_PADDSH:
27629 case MMI_OPC_0_PSUBSH:
27630 case MMI_OPC_0_PEXTLH:
27631 case MMI_OPC_0_PPACH:
27632 case MMI_OPC_0_PADDSB:
27633 case MMI_OPC_0_PSUBSB:
27634 case MMI_OPC_0_PEXTLB:
27635 case MMI_OPC_0_PPACB:
27636 case MMI_OPC_0_PEXT5:
27637 case MMI_OPC_0_PPAC5:
27638 generate_exception_end(ctx, EXCP_RI);
27639 break;
27640 default:
27641 MIPS_INVAL("TX79 MMI class MMI0");
27642 generate_exception_end(ctx, EXCP_RI);
27643 break;
27644 }
27645}
27646
27647static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27648{
27649 uint32_t opc = MASK_MMI1(ctx->opcode);
27650
27651 switch (opc) {
27652 case MMI_OPC_1_PABSW:
27653 case MMI_OPC_1_PCEQW:
27654 case MMI_OPC_1_PMINW:
27655 case MMI_OPC_1_PADSBH:
27656 case MMI_OPC_1_PABSH:
27657 case MMI_OPC_1_PCEQH:
27658 case MMI_OPC_1_PMINH:
27659 case MMI_OPC_1_PCEQB:
27660 case MMI_OPC_1_PADDUW:
27661 case MMI_OPC_1_PSUBUW:
27662 case MMI_OPC_1_PEXTUW:
27663 case MMI_OPC_1_PADDUH:
27664 case MMI_OPC_1_PSUBUH:
27665 case MMI_OPC_1_PEXTUH:
27666 case MMI_OPC_1_PADDUB:
27667 case MMI_OPC_1_PSUBUB:
27668 case MMI_OPC_1_PEXTUB:
27669 case MMI_OPC_1_QFSRV:
27670 generate_exception_end(ctx, EXCP_RI);
27671 break;
27672 default:
27673 MIPS_INVAL("TX79 MMI class MMI1");
27674 generate_exception_end(ctx, EXCP_RI);
27675 break;
27676 }
27677}
27678
27679static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27680{
27681 uint32_t opc = MASK_MMI2(ctx->opcode);
27682
27683 switch (opc) {
27684 case MMI_OPC_2_PMADDW:
27685 case MMI_OPC_2_PSLLVW:
27686 case MMI_OPC_2_PSRLVW:
27687 case MMI_OPC_2_PMSUBW:
27688 case MMI_OPC_2_PMFHI:
27689 case MMI_OPC_2_PMFLO:
27690 case MMI_OPC_2_PINTH:
27691 case MMI_OPC_2_PMULTW:
27692 case MMI_OPC_2_PDIVW:
27693 case MMI_OPC_2_PMADDH:
27694 case MMI_OPC_2_PHMADH:
27695 case MMI_OPC_2_PAND:
27696 case MMI_OPC_2_PXOR:
27697 case MMI_OPC_2_PMSUBH:
27698 case MMI_OPC_2_PHMSBH:
27699 case MMI_OPC_2_PEXEH:
27700 case MMI_OPC_2_PREVH:
27701 case MMI_OPC_2_PMULTH:
27702 case MMI_OPC_2_PDIVBW:
27703 case MMI_OPC_2_PEXEW:
27704 case MMI_OPC_2_PROT3W:
27705 generate_exception_end(ctx, EXCP_RI);
27706 break;
27707 case MMI_OPC_2_PCPYLD:
27708 gen_mmi_pcpyld(ctx);
27709 break;
27710 default:
27711 MIPS_INVAL("TX79 MMI class MMI2");
27712 generate_exception_end(ctx, EXCP_RI);
27713 break;
27714 }
27715}
27716
27717static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27718{
27719 uint32_t opc = MASK_MMI3(ctx->opcode);
27720
27721 switch (opc) {
27722 case MMI_OPC_3_PMADDUW:
27723 case MMI_OPC_3_PSRAVW:
27724 case MMI_OPC_3_PMTHI:
27725 case MMI_OPC_3_PMTLO:
27726 case MMI_OPC_3_PINTEH:
27727 case MMI_OPC_3_PMULTUW:
27728 case MMI_OPC_3_PDIVUW:
27729 case MMI_OPC_3_POR:
27730 case MMI_OPC_3_PNOR:
27731 case MMI_OPC_3_PEXCH:
27732 case MMI_OPC_3_PEXCW:
27733 generate_exception_end(ctx, EXCP_RI);
27734 break;
27735 case MMI_OPC_3_PCPYH:
27736 gen_mmi_pcpyh(ctx);
27737 break;
27738 case MMI_OPC_3_PCPYUD:
27739 gen_mmi_pcpyud(ctx);
27740 break;
27741 default:
27742 MIPS_INVAL("TX79 MMI class MMI3");
27743 generate_exception_end(ctx, EXCP_RI);
27744 break;
27745 }
27746}
27747
27748static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27749{
27750 uint32_t opc = MASK_MMI(ctx->opcode);
27751 int rs = extract32(ctx->opcode, 21, 5);
27752 int rt = extract32(ctx->opcode, 16, 5);
27753 int rd = extract32(ctx->opcode, 11, 5);
27754
27755 switch (opc) {
27756 case MMI_OPC_CLASS_MMI0:
27757 decode_mmi0(env, ctx);
27758 break;
27759 case MMI_OPC_CLASS_MMI1:
27760 decode_mmi1(env, ctx);
27761 break;
27762 case MMI_OPC_CLASS_MMI2:
27763 decode_mmi2(env, ctx);
27764 break;
27765 case MMI_OPC_CLASS_MMI3:
27766 decode_mmi3(env, ctx);
27767 break;
27768 case MMI_OPC_MULT1:
27769 case MMI_OPC_MULTU1:
27770 case MMI_OPC_MADD:
27771 case MMI_OPC_MADDU:
27772 case MMI_OPC_MADD1:
27773 case MMI_OPC_MADDU1:
27774 gen_mul_txx9(ctx, opc, rd, rs, rt);
27775 break;
27776 case MMI_OPC_DIV1:
27777 case MMI_OPC_DIVU1:
27778 gen_div1_tx79(ctx, opc, rs, rt);
27779 break;
27780 case MMI_OPC_MTLO1:
27781 case MMI_OPC_MTHI1:
27782 gen_HILO1_tx79(ctx, opc, rs);
27783 break;
27784 case MMI_OPC_MFLO1:
27785 case MMI_OPC_MFHI1:
27786 gen_HILO1_tx79(ctx, opc, rd);
27787 break;
27788 case MMI_OPC_PLZCW:
27789 case MMI_OPC_PMFHL:
27790 case MMI_OPC_PMTHL:
27791 case MMI_OPC_PSLLH:
27792 case MMI_OPC_PSRLH:
27793 case MMI_OPC_PSRAH:
27794 case MMI_OPC_PSLLW:
27795 case MMI_OPC_PSRLW:
27796 case MMI_OPC_PSRAW:
27797 generate_exception_end(ctx, EXCP_RI);
27798 break;
27799 default:
27800 MIPS_INVAL("TX79 MMI class");
27801 generate_exception_end(ctx, EXCP_RI);
27802 break;
27803 }
27804}
27805
27806static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27807{
27808 generate_exception_end(ctx, EXCP_RI);
27809}
27810
27811static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27812{
27813 generate_exception_end(ctx, EXCP_RI);
27814}
27815
27816
27817
27818
27819
27820
27821
27822
27823
27824
27825
27826
27827
27828
27829
27830
27831
27832
27833
27834
27835
27836
27837static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27838{
27839 int base = extract32(ctx->opcode, 21, 5);
27840 int rt = extract32(ctx->opcode, 16, 5);
27841 int offset = extract32(ctx->opcode, 0, 16);
27842
27843#ifdef CONFIG_USER_ONLY
27844 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27845 uint32_t op2 = extract32(ctx->opcode, 6, 5);
27846
27847 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27848 int rd = extract32(ctx->opcode, 11, 5);
27849
27850 gen_rdhwr(ctx, rt, rd, 0);
27851 return;
27852 }
27853#endif
27854
27855 gen_mmi_sq(ctx, base, rt, offset);
27856}
27857
27858#endif
27859
27860static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27861{
27862 int rs, rt, rd, sa;
27863 uint32_t op1, op2;
27864 int16_t imm;
27865
27866 rs = (ctx->opcode >> 21) & 0x1f;
27867 rt = (ctx->opcode >> 16) & 0x1f;
27868 rd = (ctx->opcode >> 11) & 0x1f;
27869 sa = (ctx->opcode >> 6) & 0x1f;
27870 imm = sextract32(ctx->opcode, 7, 9);
27871
27872 op1 = MASK_SPECIAL3(ctx->opcode);
27873
27874
27875
27876
27877
27878
27879 if (ctx->eva) {
27880 switch (op1) {
27881 case OPC_LWLE:
27882 case OPC_LWRE:
27883 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27884
27885 case OPC_LBUE:
27886 case OPC_LHUE:
27887 case OPC_LBE:
27888 case OPC_LHE:
27889 case OPC_LLE:
27890 case OPC_LWE:
27891 check_cp0_enabled(ctx);
27892 gen_ld(ctx, op1, rt, rs, imm);
27893 return;
27894 case OPC_SWLE:
27895 case OPC_SWRE:
27896 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27897
27898 case OPC_SBE:
27899 case OPC_SHE:
27900 case OPC_SWE:
27901 check_cp0_enabled(ctx);
27902 gen_st(ctx, op1, rt, rs, imm);
27903 return;
27904 case OPC_SCE:
27905 check_cp0_enabled(ctx);
27906 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27907 return;
27908 case OPC_CACHEE:
27909 check_cp0_enabled(ctx);
27910 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27911 gen_cache_operation(ctx, rt, rs, imm);
27912 }
27913
27914 return;
27915 case OPC_PREFE:
27916 check_cp0_enabled(ctx);
27917
27918 return;
27919 }
27920 }
27921
27922 switch (op1) {
27923 case OPC_EXT:
27924 case OPC_INS:
27925 check_insn(ctx, ISA_MIPS32R2);
27926 gen_bitops(ctx, op1, rt, rs, sa, rd);
27927 break;
27928 case OPC_BSHFL:
27929 op2 = MASK_BSHFL(ctx->opcode);
27930 switch (op2) {
27931 case OPC_ALIGN:
27932 case OPC_ALIGN_1:
27933 case OPC_ALIGN_2:
27934 case OPC_ALIGN_3:
27935 case OPC_BITSWAP:
27936 check_insn(ctx, ISA_MIPS32R6);
27937 decode_opc_special3_r6(env, ctx);
27938 break;
27939 default:
27940 check_insn(ctx, ISA_MIPS32R2);
27941 gen_bshfl(ctx, op2, rt, rd);
27942 break;
27943 }
27944 break;
27945#if defined(TARGET_MIPS64)
27946 case OPC_DEXTM:
27947 case OPC_DEXTU:
27948 case OPC_DEXT:
27949 case OPC_DINSM:
27950 case OPC_DINSU:
27951 case OPC_DINS:
27952 check_insn(ctx, ISA_MIPS64R2);
27953 check_mips_64(ctx);
27954 gen_bitops(ctx, op1, rt, rs, sa, rd);
27955 break;
27956 case OPC_DBSHFL:
27957 op2 = MASK_DBSHFL(ctx->opcode);
27958 switch (op2) {
27959 case OPC_DALIGN:
27960 case OPC_DALIGN_1:
27961 case OPC_DALIGN_2:
27962 case OPC_DALIGN_3:
27963 case OPC_DALIGN_4:
27964 case OPC_DALIGN_5:
27965 case OPC_DALIGN_6:
27966 case OPC_DALIGN_7:
27967 case OPC_DBITSWAP:
27968 check_insn(ctx, ISA_MIPS32R6);
27969 decode_opc_special3_r6(env, ctx);
27970 break;
27971 default:
27972 check_insn(ctx, ISA_MIPS64R2);
27973 check_mips_64(ctx);
27974 op2 = MASK_DBSHFL(ctx->opcode);
27975 gen_bshfl(ctx, op2, rt, rd);
27976 break;
27977 }
27978 break;
27979#endif
27980 case OPC_RDHWR:
27981 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27982 break;
27983 case OPC_FORK:
27984 check_mt(ctx);
27985 {
27986 TCGv t0 = tcg_temp_new();
27987 TCGv t1 = tcg_temp_new();
27988
27989 gen_load_gpr(t0, rt);
27990 gen_load_gpr(t1, rs);
27991 gen_helper_fork(t0, t1);
27992 tcg_temp_free(t0);
27993 tcg_temp_free(t1);
27994 }
27995 break;
27996 case OPC_YIELD:
27997 check_mt(ctx);
27998 {
27999 TCGv t0 = tcg_temp_new();
28000
28001 gen_load_gpr(t0, rs);
28002 gen_helper_yield(t0, cpu_env, t0);
28003 gen_store_gpr(t0, rd);
28004 tcg_temp_free(t0);
28005 }
28006 break;
28007 default:
28008 if (ctx->insn_flags & ISA_MIPS32R6) {
28009 decode_opc_special3_r6(env, ctx);
28010 } else {
28011 decode_opc_special3_legacy(env, ctx);
28012 }
28013 }
28014}
28015
28016
28017static inline int check_msa_access(DisasContext *ctx)
28018{
28019 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
28020 !(ctx->hflags & MIPS_HFLAG_F64))) {
28021 generate_exception_end(ctx, EXCP_RI);
28022 return 0;
28023 }
28024
28025 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
28026 if (ctx->insn_flags & ASE_MSA) {
28027 generate_exception_end(ctx, EXCP_MSADIS);
28028 return 0;
28029 } else {
28030 generate_exception_end(ctx, EXCP_RI);
28031 return 0;
28032 }
28033 }
28034 return 1;
28035}
28036
28037static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
28038{
28039
28040
28041 uint64_t eval_zero_or_big = 0;
28042 uint64_t eval_big = 0;
28043 TCGv_i64 t0 = tcg_temp_new_i64();
28044 TCGv_i64 t1 = tcg_temp_new_i64();
28045 switch (df) {
28046 case DF_BYTE:
28047 eval_zero_or_big = 0x0101010101010101ULL;
28048 eval_big = 0x8080808080808080ULL;
28049 break;
28050 case DF_HALF:
28051 eval_zero_or_big = 0x0001000100010001ULL;
28052 eval_big = 0x8000800080008000ULL;
28053 break;
28054 case DF_WORD:
28055 eval_zero_or_big = 0x0000000100000001ULL;
28056 eval_big = 0x8000000080000000ULL;
28057 break;
28058 case DF_DOUBLE:
28059 eval_zero_or_big = 0x0000000000000001ULL;
28060 eval_big = 0x8000000000000000ULL;
28061 break;
28062 }
28063 tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big);
28064 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]);
28065 tcg_gen_andi_i64(t0, t0, eval_big);
28066 tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big);
28067 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]);
28068 tcg_gen_andi_i64(t1, t1, eval_big);
28069 tcg_gen_or_i64(t0, t0, t1);
28070
28071
28072 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
28073 tcg_gen_trunc_i64_tl(tresult, t0);
28074 tcg_temp_free_i64(t0);
28075 tcg_temp_free_i64(t1);
28076}
28077
28078static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
28079{
28080 uint8_t df = (ctx->opcode >> 21) & 0x3;
28081 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28082 int64_t s16 = (int16_t)ctx->opcode;
28083
28084 check_msa_access(ctx);
28085
28086 if (ctx->hflags & MIPS_HFLAG_BMASK) {
28087 generate_exception_end(ctx, EXCP_RI);
28088 return;
28089 }
28090 switch (op1) {
28091 case OPC_BZ_V:
28092 case OPC_BNZ_V:
28093 {
28094 TCGv_i64 t0 = tcg_temp_new_i64();
28095 tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
28096 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
28097 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
28098 tcg_gen_trunc_i64_tl(bcond, t0);
28099 tcg_temp_free_i64(t0);
28100 }
28101 break;
28102 case OPC_BZ_B:
28103 case OPC_BZ_H:
28104 case OPC_BZ_W:
28105 case OPC_BZ_D:
28106 gen_check_zero_element(bcond, df, wt);
28107 break;
28108 case OPC_BNZ_B:
28109 case OPC_BNZ_H:
28110 case OPC_BNZ_W:
28111 case OPC_BNZ_D:
28112 gen_check_zero_element(bcond, df, wt);
28113 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
28114 break;
28115 }
28116
28117 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
28118
28119 ctx->hflags |= MIPS_HFLAG_BC;
28120 ctx->hflags |= MIPS_HFLAG_BDS32;
28121}
28122
28123static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
28124{
28125#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28126 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
28127 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28128 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28129
28130 TCGv_i32 twd = tcg_const_i32(wd);
28131 TCGv_i32 tws = tcg_const_i32(ws);
28132 TCGv_i32 ti8 = tcg_const_i32(i8);
28133
28134 switch (MASK_MSA_I8(ctx->opcode)) {
28135 case OPC_ANDI_B:
28136 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
28137 break;
28138 case OPC_ORI_B:
28139 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
28140 break;
28141 case OPC_NORI_B:
28142 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
28143 break;
28144 case OPC_XORI_B:
28145 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
28146 break;
28147 case OPC_BMNZI_B:
28148 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
28149 break;
28150 case OPC_BMZI_B:
28151 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
28152 break;
28153 case OPC_BSELI_B:
28154 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
28155 break;
28156 case OPC_SHF_B:
28157 case OPC_SHF_H:
28158 case OPC_SHF_W:
28159 {
28160 uint8_t df = (ctx->opcode >> 24) & 0x3;
28161 if (df == DF_DOUBLE) {
28162 generate_exception_end(ctx, EXCP_RI);
28163 } else {
28164 TCGv_i32 tdf = tcg_const_i32(df);
28165 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
28166 tcg_temp_free_i32(tdf);
28167 }
28168 }
28169 break;
28170 default:
28171 MIPS_INVAL("MSA instruction");
28172 generate_exception_end(ctx, EXCP_RI);
28173 break;
28174 }
28175
28176 tcg_temp_free_i32(twd);
28177 tcg_temp_free_i32(tws);
28178 tcg_temp_free_i32(ti8);
28179}
28180
28181static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28182{
28183#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28184 uint8_t df = (ctx->opcode >> 21) & 0x3;
28185 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28186 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28187 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28188 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28189
28190 TCGv_i32 tdf = tcg_const_i32(df);
28191 TCGv_i32 twd = tcg_const_i32(wd);
28192 TCGv_i32 tws = tcg_const_i32(ws);
28193 TCGv_i32 timm = tcg_temp_new_i32();
28194 tcg_gen_movi_i32(timm, u5);
28195
28196 switch (MASK_MSA_I5(ctx->opcode)) {
28197 case OPC_ADDVI_df:
28198 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28199 break;
28200 case OPC_SUBVI_df:
28201 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28202 break;
28203 case OPC_MAXI_S_df:
28204 tcg_gen_movi_i32(timm, s5);
28205 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28206 break;
28207 case OPC_MAXI_U_df:
28208 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28209 break;
28210 case OPC_MINI_S_df:
28211 tcg_gen_movi_i32(timm, s5);
28212 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28213 break;
28214 case OPC_MINI_U_df:
28215 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28216 break;
28217 case OPC_CEQI_df:
28218 tcg_gen_movi_i32(timm, s5);
28219 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28220 break;
28221 case OPC_CLTI_S_df:
28222 tcg_gen_movi_i32(timm, s5);
28223 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28224 break;
28225 case OPC_CLTI_U_df:
28226 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28227 break;
28228 case OPC_CLEI_S_df:
28229 tcg_gen_movi_i32(timm, s5);
28230 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28231 break;
28232 case OPC_CLEI_U_df:
28233 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28234 break;
28235 case OPC_LDI_df:
28236 {
28237 int32_t s10 = sextract32(ctx->opcode, 11, 10);
28238 tcg_gen_movi_i32(timm, s10);
28239 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28240 }
28241 break;
28242 default:
28243 MIPS_INVAL("MSA instruction");
28244 generate_exception_end(ctx, EXCP_RI);
28245 break;
28246 }
28247
28248 tcg_temp_free_i32(tdf);
28249 tcg_temp_free_i32(twd);
28250 tcg_temp_free_i32(tws);
28251 tcg_temp_free_i32(timm);
28252}
28253
28254static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28255{
28256#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28257 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28258 uint32_t df = 0, m = 0;
28259 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28260 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28261
28262 TCGv_i32 tdf;
28263 TCGv_i32 tm;
28264 TCGv_i32 twd;
28265 TCGv_i32 tws;
28266
28267 if ((dfm & 0x40) == 0x00) {
28268 m = dfm & 0x3f;
28269 df = DF_DOUBLE;
28270 } else if ((dfm & 0x60) == 0x40) {
28271 m = dfm & 0x1f;
28272 df = DF_WORD;
28273 } else if ((dfm & 0x70) == 0x60) {
28274 m = dfm & 0x0f;
28275 df = DF_HALF;
28276 } else if ((dfm & 0x78) == 0x70) {
28277 m = dfm & 0x7;
28278 df = DF_BYTE;
28279 } else {
28280 generate_exception_end(ctx, EXCP_RI);
28281 return;
28282 }
28283
28284 tdf = tcg_const_i32(df);
28285 tm = tcg_const_i32(m);
28286 twd = tcg_const_i32(wd);
28287 tws = tcg_const_i32(ws);
28288
28289 switch (MASK_MSA_BIT(ctx->opcode)) {
28290 case OPC_SLLI_df:
28291 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28292 break;
28293 case OPC_SRAI_df:
28294 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28295 break;
28296 case OPC_SRLI_df:
28297 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28298 break;
28299 case OPC_BCLRI_df:
28300 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28301 break;
28302 case OPC_BSETI_df:
28303 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28304 break;
28305 case OPC_BNEGI_df:
28306 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28307 break;
28308 case OPC_BINSLI_df:
28309 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28310 break;
28311 case OPC_BINSRI_df:
28312 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28313 break;
28314 case OPC_SAT_S_df:
28315 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28316 break;
28317 case OPC_SAT_U_df:
28318 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28319 break;
28320 case OPC_SRARI_df:
28321 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28322 break;
28323 case OPC_SRLRI_df:
28324 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
28325 break;
28326 default:
28327 MIPS_INVAL("MSA instruction");
28328 generate_exception_end(ctx, EXCP_RI);
28329 break;
28330 }
28331
28332 tcg_temp_free_i32(tdf);
28333 tcg_temp_free_i32(tm);
28334 tcg_temp_free_i32(twd);
28335 tcg_temp_free_i32(tws);
28336}
28337
28338static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28339{
28340#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28341 uint8_t df = (ctx->opcode >> 21) & 0x3;
28342 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28343 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28344 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28345
28346 TCGv_i32 tdf = tcg_const_i32(df);
28347 TCGv_i32 twd = tcg_const_i32(wd);
28348 TCGv_i32 tws = tcg_const_i32(ws);
28349 TCGv_i32 twt = tcg_const_i32(wt);
28350
28351 switch (MASK_MSA_3R(ctx->opcode)) {
28352 case OPC_SLL_df:
28353 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28354 break;
28355 case OPC_ADDV_df:
28356 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28357 break;
28358 case OPC_CEQ_df:
28359 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28360 break;
28361 case OPC_ADD_A_df:
28362 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28363 break;
28364 case OPC_SUBS_S_df:
28365 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28366 break;
28367 case OPC_MULV_df:
28368 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28369 break;
28370 case OPC_SLD_df:
28371 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28372 break;
28373 case OPC_VSHF_df:
28374 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28375 break;
28376 case OPC_SRA_df:
28377 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28378 break;
28379 case OPC_SUBV_df:
28380 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28381 break;
28382 case OPC_ADDS_A_df:
28383 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28384 break;
28385 case OPC_SUBS_U_df:
28386 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28387 break;
28388 case OPC_MADDV_df:
28389 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28390 break;
28391 case OPC_SPLAT_df:
28392 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28393 break;
28394 case OPC_SRAR_df:
28395 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28396 break;
28397 case OPC_SRL_df:
28398 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28399 break;
28400 case OPC_MAX_S_df:
28401 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28402 break;
28403 case OPC_CLT_S_df:
28404 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28405 break;
28406 case OPC_ADDS_S_df:
28407 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28408 break;
28409 case OPC_SUBSUS_U_df:
28410 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28411 break;
28412 case OPC_MSUBV_df:
28413 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28414 break;
28415 case OPC_PCKEV_df:
28416 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28417 break;
28418 case OPC_SRLR_df:
28419 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28420 break;
28421 case OPC_BCLR_df:
28422 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28423 break;
28424 case OPC_MAX_U_df:
28425 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28426 break;
28427 case OPC_CLT_U_df:
28428 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28429 break;
28430 case OPC_ADDS_U_df:
28431 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28432 break;
28433 case OPC_SUBSUU_S_df:
28434 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28435 break;
28436 case OPC_PCKOD_df:
28437 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28438 break;
28439 case OPC_BSET_df:
28440 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28441 break;
28442 case OPC_MIN_S_df:
28443 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28444 break;
28445 case OPC_CLE_S_df:
28446 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28447 break;
28448 case OPC_AVE_S_df:
28449 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28450 break;
28451 case OPC_ASUB_S_df:
28452 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28453 break;
28454 case OPC_DIV_S_df:
28455 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28456 break;
28457 case OPC_ILVL_df:
28458 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28459 break;
28460 case OPC_BNEG_df:
28461 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28462 break;
28463 case OPC_MIN_U_df:
28464 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28465 break;
28466 case OPC_CLE_U_df:
28467 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28468 break;
28469 case OPC_AVE_U_df:
28470 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28471 break;
28472 case OPC_ASUB_U_df:
28473 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28474 break;
28475 case OPC_DIV_U_df:
28476 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28477 break;
28478 case OPC_ILVR_df:
28479 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28480 break;
28481 case OPC_BINSL_df:
28482 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28483 break;
28484 case OPC_MAX_A_df:
28485 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28486 break;
28487 case OPC_AVER_S_df:
28488 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28489 break;
28490 case OPC_MOD_S_df:
28491 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28492 break;
28493 case OPC_ILVEV_df:
28494 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28495 break;
28496 case OPC_BINSR_df:
28497 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28498 break;
28499 case OPC_MIN_A_df:
28500 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28501 break;
28502 case OPC_AVER_U_df:
28503 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28504 break;
28505 case OPC_MOD_U_df:
28506 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28507 break;
28508 case OPC_ILVOD_df:
28509 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28510 break;
28511
28512 case OPC_DOTP_S_df:
28513 case OPC_DOTP_U_df:
28514 case OPC_DPADD_S_df:
28515 case OPC_DPADD_U_df:
28516 case OPC_DPSUB_S_df:
28517 case OPC_HADD_S_df:
28518 case OPC_DPSUB_U_df:
28519 case OPC_HADD_U_df:
28520 case OPC_HSUB_S_df:
28521 case OPC_HSUB_U_df:
28522 if (df == DF_BYTE) {
28523 generate_exception_end(ctx, EXCP_RI);
28524 break;
28525 }
28526 switch (MASK_MSA_3R(ctx->opcode)) {
28527 case OPC_DOTP_S_df:
28528 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28529 break;
28530 case OPC_DOTP_U_df:
28531 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28532 break;
28533 case OPC_DPADD_S_df:
28534 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28535 break;
28536 case OPC_DPADD_U_df:
28537 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28538 break;
28539 case OPC_DPSUB_S_df:
28540 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28541 break;
28542 case OPC_HADD_S_df:
28543 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28544 break;
28545 case OPC_DPSUB_U_df:
28546 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28547 break;
28548 case OPC_HADD_U_df:
28549 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28550 break;
28551 case OPC_HSUB_S_df:
28552 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28553 break;
28554 case OPC_HSUB_U_df:
28555 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28556 break;
28557 }
28558 break;
28559 default:
28560 MIPS_INVAL("MSA instruction");
28561 generate_exception_end(ctx, EXCP_RI);
28562 break;
28563 }
28564 tcg_temp_free_i32(twd);
28565 tcg_temp_free_i32(tws);
28566 tcg_temp_free_i32(twt);
28567 tcg_temp_free_i32(tdf);
28568}
28569
28570static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28571{
28572#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28573 uint8_t source = (ctx->opcode >> 11) & 0x1f;
28574 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28575 TCGv telm = tcg_temp_new();
28576 TCGv_i32 tsr = tcg_const_i32(source);
28577 TCGv_i32 tdt = tcg_const_i32(dest);
28578
28579 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28580 case OPC_CTCMSA:
28581 gen_load_gpr(telm, source);
28582 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28583 break;
28584 case OPC_CFCMSA:
28585 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28586 gen_store_gpr(telm, dest);
28587 break;
28588 case OPC_MOVE_V:
28589 gen_helper_msa_move_v(cpu_env, tdt, tsr);
28590 break;
28591 default:
28592 MIPS_INVAL("MSA instruction");
28593 generate_exception_end(ctx, EXCP_RI);
28594 break;
28595 }
28596
28597 tcg_temp_free(telm);
28598 tcg_temp_free_i32(tdt);
28599 tcg_temp_free_i32(tsr);
28600}
28601
28602static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28603 uint32_t n)
28604{
28605#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28606 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28607 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28608
28609 TCGv_i32 tws = tcg_const_i32(ws);
28610 TCGv_i32 twd = tcg_const_i32(wd);
28611 TCGv_i32 tn = tcg_const_i32(n);
28612 TCGv_i32 tdf = tcg_const_i32(df);
28613
28614 switch (MASK_MSA_ELM(ctx->opcode)) {
28615 case OPC_SLDI_df:
28616 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28617 break;
28618 case OPC_SPLATI_df:
28619 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28620 break;
28621 case OPC_INSVE_df:
28622 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28623 break;
28624 case OPC_COPY_S_df:
28625 case OPC_COPY_U_df:
28626 case OPC_INSERT_df:
28627#if !defined(TARGET_MIPS64)
28628
28629 if (df == DF_DOUBLE) {
28630 generate_exception_end(ctx, EXCP_RI);
28631 break;
28632 }
28633 if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
28634 (df == DF_WORD)) {
28635 generate_exception_end(ctx, EXCP_RI);
28636 break;
28637 }
28638#endif
28639 switch (MASK_MSA_ELM(ctx->opcode)) {
28640 case OPC_COPY_S_df:
28641 if (likely(wd != 0)) {
28642 switch (df) {
28643 case DF_BYTE:
28644 gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
28645 break;
28646 case DF_HALF:
28647 gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
28648 break;
28649 case DF_WORD:
28650 gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
28651 break;
28652#if defined(TARGET_MIPS64)
28653 case DF_DOUBLE:
28654 gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
28655 break;
28656#endif
28657 default:
28658 assert(0);
28659 }
28660 }
28661 break;
28662 case OPC_COPY_U_df:
28663 if (likely(wd != 0)) {
28664 switch (df) {
28665 case DF_BYTE:
28666 gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
28667 break;
28668 case DF_HALF:
28669 gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
28670 break;
28671#if defined(TARGET_MIPS64)
28672 case DF_WORD:
28673 gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
28674 break;
28675#endif
28676 default:
28677 assert(0);
28678 }
28679 }
28680 break;
28681 case OPC_INSERT_df:
28682 switch (df) {
28683 case DF_BYTE:
28684 gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
28685 break;
28686 case DF_HALF:
28687 gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
28688 break;
28689 case DF_WORD:
28690 gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
28691 break;
28692#if defined(TARGET_MIPS64)
28693 case DF_DOUBLE:
28694 gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
28695 break;
28696#endif
28697 default:
28698 assert(0);
28699 }
28700 break;
28701 }
28702 break;
28703 default:
28704 MIPS_INVAL("MSA instruction");
28705 generate_exception_end(ctx, EXCP_RI);
28706 }
28707 tcg_temp_free_i32(twd);
28708 tcg_temp_free_i32(tws);
28709 tcg_temp_free_i32(tn);
28710 tcg_temp_free_i32(tdf);
28711}
28712
28713static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28714{
28715 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28716 uint32_t df = 0, n = 0;
28717
28718 if ((dfn & 0x30) == 0x00) {
28719 n = dfn & 0x0f;
28720 df = DF_BYTE;
28721 } else if ((dfn & 0x38) == 0x20) {
28722 n = dfn & 0x07;
28723 df = DF_HALF;
28724 } else if ((dfn & 0x3c) == 0x30) {
28725 n = dfn & 0x03;
28726 df = DF_WORD;
28727 } else if ((dfn & 0x3e) == 0x38) {
28728 n = dfn & 0x01;
28729 df = DF_DOUBLE;
28730 } else if (dfn == 0x3E) {
28731
28732 gen_msa_elm_3e(env, ctx);
28733 return;
28734 } else {
28735 generate_exception_end(ctx, EXCP_RI);
28736 return;
28737 }
28738
28739 gen_msa_elm_df(env, ctx, df, n);
28740}
28741
28742static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28743{
28744#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28745 uint8_t df = (ctx->opcode >> 21) & 0x1;
28746 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28747 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28748 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28749
28750 TCGv_i32 twd = tcg_const_i32(wd);
28751 TCGv_i32 tws = tcg_const_i32(ws);
28752 TCGv_i32 twt = tcg_const_i32(wt);
28753 TCGv_i32 tdf = tcg_temp_new_i32();
28754
28755
28756 tcg_gen_movi_i32(tdf, df + 2);
28757
28758 switch (MASK_MSA_3RF(ctx->opcode)) {
28759 case OPC_FCAF_df:
28760 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28761 break;
28762 case OPC_FADD_df:
28763 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28764 break;
28765 case OPC_FCUN_df:
28766 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28767 break;
28768 case OPC_FSUB_df:
28769 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28770 break;
28771 case OPC_FCOR_df:
28772 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28773 break;
28774 case OPC_FCEQ_df:
28775 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28776 break;
28777 case OPC_FMUL_df:
28778 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28779 break;
28780 case OPC_FCUNE_df:
28781 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28782 break;
28783 case OPC_FCUEQ_df:
28784 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28785 break;
28786 case OPC_FDIV_df:
28787 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28788 break;
28789 case OPC_FCNE_df:
28790 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28791 break;
28792 case OPC_FCLT_df:
28793 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28794 break;
28795 case OPC_FMADD_df:
28796 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28797 break;
28798 case OPC_MUL_Q_df:
28799 tcg_gen_movi_i32(tdf, df + 1);
28800 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28801 break;
28802 case OPC_FCULT_df:
28803 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28804 break;
28805 case OPC_FMSUB_df:
28806 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28807 break;
28808 case OPC_MADD_Q_df:
28809 tcg_gen_movi_i32(tdf, df + 1);
28810 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28811 break;
28812 case OPC_FCLE_df:
28813 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28814 break;
28815 case OPC_MSUB_Q_df:
28816 tcg_gen_movi_i32(tdf, df + 1);
28817 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28818 break;
28819 case OPC_FCULE_df:
28820 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28821 break;
28822 case OPC_FEXP2_df:
28823 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28824 break;
28825 case OPC_FSAF_df:
28826 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28827 break;
28828 case OPC_FEXDO_df:
28829 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28830 break;
28831 case OPC_FSUN_df:
28832 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28833 break;
28834 case OPC_FSOR_df:
28835 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28836 break;
28837 case OPC_FSEQ_df:
28838 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28839 break;
28840 case OPC_FTQ_df:
28841 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28842 break;
28843 case OPC_FSUNE_df:
28844 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28845 break;
28846 case OPC_FSUEQ_df:
28847 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28848 break;
28849 case OPC_FSNE_df:
28850 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28851 break;
28852 case OPC_FSLT_df:
28853 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28854 break;
28855 case OPC_FMIN_df:
28856 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28857 break;
28858 case OPC_MULR_Q_df:
28859 tcg_gen_movi_i32(tdf, df + 1);
28860 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28861 break;
28862 case OPC_FSULT_df:
28863 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28864 break;
28865 case OPC_FMIN_A_df:
28866 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28867 break;
28868 case OPC_MADDR_Q_df:
28869 tcg_gen_movi_i32(tdf, df + 1);
28870 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28871 break;
28872 case OPC_FSLE_df:
28873 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28874 break;
28875 case OPC_FMAX_df:
28876 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28877 break;
28878 case OPC_MSUBR_Q_df:
28879 tcg_gen_movi_i32(tdf, df + 1);
28880 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28881 break;
28882 case OPC_FSULE_df:
28883 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28884 break;
28885 case OPC_FMAX_A_df:
28886 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28887 break;
28888 default:
28889 MIPS_INVAL("MSA instruction");
28890 generate_exception_end(ctx, EXCP_RI);
28891 break;
28892 }
28893
28894 tcg_temp_free_i32(twd);
28895 tcg_temp_free_i32(tws);
28896 tcg_temp_free_i32(twt);
28897 tcg_temp_free_i32(tdf);
28898}
28899
28900static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28901{
28902#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28903 (op & (0x7 << 18)))
28904 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28905 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28906 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28907 uint8_t df = (ctx->opcode >> 16) & 0x3;
28908 TCGv_i32 twd = tcg_const_i32(wd);
28909 TCGv_i32 tws = tcg_const_i32(ws);
28910 TCGv_i32 twt = tcg_const_i32(wt);
28911 TCGv_i32 tdf = tcg_const_i32(df);
28912
28913 switch (MASK_MSA_2R(ctx->opcode)) {
28914 case OPC_FILL_df:
28915#if !defined(TARGET_MIPS64)
28916
28917 if (df == DF_DOUBLE) {
28918 generate_exception_end(ctx, EXCP_RI);
28919 break;
28920 }
28921#endif
28922 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws);
28923 break;
28924 case OPC_PCNT_df:
28925 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28926 break;
28927 case OPC_NLOC_df:
28928 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28929 break;
28930 case OPC_NLZC_df:
28931 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28932 break;
28933 default:
28934 MIPS_INVAL("MSA instruction");
28935 generate_exception_end(ctx, EXCP_RI);
28936 break;
28937 }
28938
28939 tcg_temp_free_i32(twd);
28940 tcg_temp_free_i32(tws);
28941 tcg_temp_free_i32(twt);
28942 tcg_temp_free_i32(tdf);
28943}
28944
28945static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28946{
28947#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28948 (op & (0xf << 17)))
28949 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28950 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28951 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28952 uint8_t df = (ctx->opcode >> 16) & 0x1;
28953 TCGv_i32 twd = tcg_const_i32(wd);
28954 TCGv_i32 tws = tcg_const_i32(ws);
28955 TCGv_i32 twt = tcg_const_i32(wt);
28956
28957 TCGv_i32 tdf = tcg_const_i32(df + 2);
28958
28959 switch (MASK_MSA_2RF(ctx->opcode)) {
28960 case OPC_FCLASS_df:
28961 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28962 break;
28963 case OPC_FTRUNC_S_df:
28964 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28965 break;
28966 case OPC_FTRUNC_U_df:
28967 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28968 break;
28969 case OPC_FSQRT_df:
28970 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28971 break;
28972 case OPC_FRSQRT_df:
28973 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28974 break;
28975 case OPC_FRCP_df:
28976 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28977 break;
28978 case OPC_FRINT_df:
28979 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28980 break;
28981 case OPC_FLOG2_df:
28982 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28983 break;
28984 case OPC_FEXUPL_df:
28985 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28986 break;
28987 case OPC_FEXUPR_df:
28988 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28989 break;
28990 case OPC_FFQL_df:
28991 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28992 break;
28993 case OPC_FFQR_df:
28994 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28995 break;
28996 case OPC_FTINT_S_df:
28997 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28998 break;
28999 case OPC_FTINT_U_df:
29000 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
29001 break;
29002 case OPC_FFINT_S_df:
29003 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
29004 break;
29005 case OPC_FFINT_U_df:
29006 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
29007 break;
29008 }
29009
29010 tcg_temp_free_i32(twd);
29011 tcg_temp_free_i32(tws);
29012 tcg_temp_free_i32(twt);
29013 tcg_temp_free_i32(tdf);
29014}
29015
29016static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
29017{
29018#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29019 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29020 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29021 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29022 TCGv_i32 twd = tcg_const_i32(wd);
29023 TCGv_i32 tws = tcg_const_i32(ws);
29024 TCGv_i32 twt = tcg_const_i32(wt);
29025
29026 switch (MASK_MSA_VEC(ctx->opcode)) {
29027 case OPC_AND_V:
29028 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
29029 break;
29030 case OPC_OR_V:
29031 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
29032 break;
29033 case OPC_NOR_V:
29034 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
29035 break;
29036 case OPC_XOR_V:
29037 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
29038 break;
29039 case OPC_BMNZ_V:
29040 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
29041 break;
29042 case OPC_BMZ_V:
29043 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
29044 break;
29045 case OPC_BSEL_V:
29046 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
29047 break;
29048 default:
29049 MIPS_INVAL("MSA instruction");
29050 generate_exception_end(ctx, EXCP_RI);
29051 break;
29052 }
29053
29054 tcg_temp_free_i32(twd);
29055 tcg_temp_free_i32(tws);
29056 tcg_temp_free_i32(twt);
29057}
29058
29059static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
29060{
29061 switch (MASK_MSA_VEC(ctx->opcode)) {
29062 case OPC_AND_V:
29063 case OPC_OR_V:
29064 case OPC_NOR_V:
29065 case OPC_XOR_V:
29066 case OPC_BMNZ_V:
29067 case OPC_BMZ_V:
29068 case OPC_BSEL_V:
29069 gen_msa_vec_v(env, ctx);
29070 break;
29071 case OPC_MSA_2R:
29072 gen_msa_2r(env, ctx);
29073 break;
29074 case OPC_MSA_2RF:
29075 gen_msa_2rf(env, ctx);
29076 break;
29077 default:
29078 MIPS_INVAL("MSA instruction");
29079 generate_exception_end(ctx, EXCP_RI);
29080 break;
29081 }
29082}
29083
29084static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
29085{
29086 uint32_t opcode = ctx->opcode;
29087 check_insn(ctx, ASE_MSA);
29088 check_msa_access(ctx);
29089
29090 switch (MASK_MSA_MINOR(opcode)) {
29091 case OPC_MSA_I8_00:
29092 case OPC_MSA_I8_01:
29093 case OPC_MSA_I8_02:
29094 gen_msa_i8(env, ctx);
29095 break;
29096 case OPC_MSA_I5_06:
29097 case OPC_MSA_I5_07:
29098 gen_msa_i5(env, ctx);
29099 break;
29100 case OPC_MSA_BIT_09:
29101 case OPC_MSA_BIT_0A:
29102 gen_msa_bit(env, ctx);
29103 break;
29104 case OPC_MSA_3R_0D:
29105 case OPC_MSA_3R_0E:
29106 case OPC_MSA_3R_0F:
29107 case OPC_MSA_3R_10:
29108 case OPC_MSA_3R_11:
29109 case OPC_MSA_3R_12:
29110 case OPC_MSA_3R_13:
29111 case OPC_MSA_3R_14:
29112 case OPC_MSA_3R_15:
29113 gen_msa_3r(env, ctx);
29114 break;
29115 case OPC_MSA_ELM:
29116 gen_msa_elm(env, ctx);
29117 break;
29118 case OPC_MSA_3RF_1A:
29119 case OPC_MSA_3RF_1B:
29120 case OPC_MSA_3RF_1C:
29121 gen_msa_3rf(env, ctx);
29122 break;
29123 case OPC_MSA_VEC:
29124 gen_msa_vec(env, ctx);
29125 break;
29126 case OPC_LD_B:
29127 case OPC_LD_H:
29128 case OPC_LD_W:
29129 case OPC_LD_D:
29130 case OPC_ST_B:
29131 case OPC_ST_H:
29132 case OPC_ST_W:
29133 case OPC_ST_D:
29134 {
29135 int32_t s10 = sextract32(ctx->opcode, 16, 10);
29136 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
29137 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29138 uint8_t df = (ctx->opcode >> 0) & 0x3;
29139
29140 TCGv_i32 twd = tcg_const_i32(wd);
29141 TCGv taddr = tcg_temp_new();
29142 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
29143
29144 switch (MASK_MSA_MINOR(opcode)) {
29145 case OPC_LD_B:
29146 gen_helper_msa_ld_b(cpu_env, twd, taddr);
29147 break;
29148 case OPC_LD_H:
29149 gen_helper_msa_ld_h(cpu_env, twd, taddr);
29150 break;
29151 case OPC_LD_W:
29152 gen_helper_msa_ld_w(cpu_env, twd, taddr);
29153 break;
29154 case OPC_LD_D:
29155 gen_helper_msa_ld_d(cpu_env, twd, taddr);
29156 break;
29157 case OPC_ST_B:
29158 gen_helper_msa_st_b(cpu_env, twd, taddr);
29159 break;
29160 case OPC_ST_H:
29161 gen_helper_msa_st_h(cpu_env, twd, taddr);
29162 break;
29163 case OPC_ST_W:
29164 gen_helper_msa_st_w(cpu_env, twd, taddr);
29165 break;
29166 case OPC_ST_D:
29167 gen_helper_msa_st_d(cpu_env, twd, taddr);
29168 break;
29169 }
29170
29171 tcg_temp_free_i32(twd);
29172 tcg_temp_free(taddr);
29173 }
29174 break;
29175 default:
29176 MIPS_INVAL("MSA instruction");
29177 generate_exception_end(ctx, EXCP_RI);
29178 break;
29179 }
29180
29181}
29182
29183static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
29184{
29185 int32_t offset;
29186 int rs, rt, rd, sa;
29187 uint32_t op, op1;
29188 int16_t imm;
29189
29190
29191 if (ctx->base.pc_next & 0x3) {
29192 env->CP0_BadVAddr = ctx->base.pc_next;
29193 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
29194 return;
29195 }
29196
29197
29198 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
29199 TCGLabel *l1 = gen_new_label();
29200
29201 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
29202 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
29203 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
29204 gen_set_label(l1);
29205 }
29206
29207 op = MASK_OP_MAJOR(ctx->opcode);
29208 rs = (ctx->opcode >> 21) & 0x1f;
29209 rt = (ctx->opcode >> 16) & 0x1f;
29210 rd = (ctx->opcode >> 11) & 0x1f;
29211 sa = (ctx->opcode >> 6) & 0x1f;
29212 imm = (int16_t)ctx->opcode;
29213 switch (op) {
29214 case OPC_SPECIAL:
29215 decode_opc_special(env, ctx);
29216 break;
29217 case OPC_SPECIAL2:
29218#if defined(TARGET_MIPS64)
29219 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
29220 decode_mmi(env, ctx);
29221#else
29222 if (ctx->insn_flags & ASE_MXU) {
29223 decode_opc_mxu(env, ctx);
29224#endif
29225 } else {
29226 decode_opc_special2_legacy(env, ctx);
29227 }
29228 break;
29229 case OPC_SPECIAL3:
29230#if defined(TARGET_MIPS64)
29231 if (ctx->insn_flags & INSN_R5900) {
29232 decode_mmi_sq(env, ctx);
29233 } else {
29234 decode_opc_special3(env, ctx);
29235 }
29236#else
29237 decode_opc_special3(env, ctx);
29238#endif
29239 break;
29240 case OPC_REGIMM:
29241 op1 = MASK_REGIMM(ctx->opcode);
29242 switch (op1) {
29243 case OPC_BLTZL:
29244 case OPC_BGEZL:
29245 case OPC_BLTZALL:
29246 case OPC_BGEZALL:
29247 check_insn(ctx, ISA_MIPS2);
29248 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29249
29250 case OPC_BLTZ:
29251 case OPC_BGEZ:
29252 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29253 break;
29254 case OPC_BLTZAL:
29255 case OPC_BGEZAL:
29256 if (ctx->insn_flags & ISA_MIPS32R6) {
29257 if (rs == 0) {
29258
29259 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
29260 } else {
29261 generate_exception_end(ctx, EXCP_RI);
29262 }
29263 } else {
29264 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29265 }
29266 break;
29267 case OPC_TGEI:
29268 case OPC_TGEIU:
29269 case OPC_TLTI:
29270 case OPC_TLTIU:
29271 case OPC_TEQI:
29272
29273 case OPC_TNEI:
29274 check_insn(ctx, ISA_MIPS2);
29275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29276 gen_trap(ctx, op1, rs, -1, imm);
29277 break;
29278 case OPC_SIGRIE:
29279 check_insn(ctx, ISA_MIPS32R6);
29280 generate_exception_end(ctx, EXCP_RI);
29281 break;
29282 case OPC_SYNCI:
29283 check_insn(ctx, ISA_MIPS32R2);
29284
29285
29286
29287
29288 ctx->base.is_jmp = DISAS_STOP;
29289 break;
29290 case OPC_BPOSGE32:
29291#if defined(TARGET_MIPS64)
29292 case OPC_BPOSGE64:
29293#endif
29294 check_dsp(ctx);
29295 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
29296 break;
29297#if defined(TARGET_MIPS64)
29298 case OPC_DAHI:
29299 check_insn(ctx, ISA_MIPS32R6);
29300 check_mips_64(ctx);
29301 if (rs != 0) {
29302 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
29303 }
29304 break;
29305 case OPC_DATI:
29306 check_insn(ctx, ISA_MIPS32R6);
29307 check_mips_64(ctx);
29308 if (rs != 0) {
29309 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
29310 }
29311 break;
29312#endif
29313 default:
29314 MIPS_INVAL("regimm");
29315 generate_exception_end(ctx, EXCP_RI);
29316 break;
29317 }
29318 break;
29319 case OPC_CP0:
29320 check_cp0_enabled(ctx);
29321 op1 = MASK_CP0(ctx->opcode);
29322 switch (op1) {
29323 case OPC_MFC0:
29324 case OPC_MTC0:
29325 case OPC_MFTR:
29326 case OPC_MTTR:
29327 case OPC_MFHC0:
29328 case OPC_MTHC0:
29329#if defined(TARGET_MIPS64)
29330 case OPC_DMFC0:
29331 case OPC_DMTC0:
29332#endif
29333#ifndef CONFIG_USER_ONLY
29334 gen_cp0(env, ctx, op1, rt, rd);
29335#endif
29336 break;
29337 case OPC_C0:
29338 case OPC_C0_1:
29339 case OPC_C0_2:
29340 case OPC_C0_3:
29341 case OPC_C0_4:
29342 case OPC_C0_5:
29343 case OPC_C0_6:
29344 case OPC_C0_7:
29345 case OPC_C0_8:
29346 case OPC_C0_9:
29347 case OPC_C0_A:
29348 case OPC_C0_B:
29349 case OPC_C0_C:
29350 case OPC_C0_D:
29351 case OPC_C0_E:
29352 case OPC_C0_F:
29353#ifndef CONFIG_USER_ONLY
29354 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
29355#endif
29356 break;
29357 case OPC_MFMC0:
29358#ifndef CONFIG_USER_ONLY
29359 {
29360 uint32_t op2;
29361 TCGv t0 = tcg_temp_new();
29362
29363 op2 = MASK_MFMC0(ctx->opcode);
29364 switch (op2) {
29365 case OPC_DMT:
29366 check_cp0_mt(ctx);
29367 gen_helper_dmt(t0);
29368 gen_store_gpr(t0, rt);
29369 break;
29370 case OPC_EMT:
29371 check_cp0_mt(ctx);
29372 gen_helper_emt(t0);
29373 gen_store_gpr(t0, rt);
29374 break;
29375 case OPC_DVPE:
29376 check_cp0_mt(ctx);
29377 gen_helper_dvpe(t0, cpu_env);
29378 gen_store_gpr(t0, rt);
29379 break;
29380 case OPC_EVPE:
29381 check_cp0_mt(ctx);
29382 gen_helper_evpe(t0, cpu_env);
29383 gen_store_gpr(t0, rt);
29384 break;
29385 case OPC_DVP:
29386 check_insn(ctx, ISA_MIPS32R6);
29387 if (ctx->vp) {
29388 gen_helper_dvp(t0, cpu_env);
29389 gen_store_gpr(t0, rt);
29390 }
29391 break;
29392 case OPC_EVP:
29393 check_insn(ctx, ISA_MIPS32R6);
29394 if (ctx->vp) {
29395 gen_helper_evp(t0, cpu_env);
29396 gen_store_gpr(t0, rt);
29397 }
29398 break;
29399 case OPC_DI:
29400 check_insn(ctx, ISA_MIPS32R2);
29401 save_cpu_state(ctx, 1);
29402 gen_helper_di(t0, cpu_env);
29403 gen_store_gpr(t0, rt);
29404
29405
29406
29407
29408 ctx->base.is_jmp = DISAS_STOP;
29409 break;
29410 case OPC_EI:
29411 check_insn(ctx, ISA_MIPS32R2);
29412 save_cpu_state(ctx, 1);
29413 gen_helper_ei(t0, cpu_env);
29414 gen_store_gpr(t0, rt);
29415
29416
29417
29418
29419 gen_save_pc(ctx->base.pc_next + 4);
29420 ctx->base.is_jmp = DISAS_EXIT;
29421 break;
29422 default:
29423 MIPS_INVAL("mfmc0");
29424 generate_exception_end(ctx, EXCP_RI);
29425 break;
29426 }
29427 tcg_temp_free(t0);
29428 }
29429#endif
29430 break;
29431 case OPC_RDPGPR:
29432 check_insn(ctx, ISA_MIPS32R2);
29433 gen_load_srsgpr(rt, rd);
29434 break;
29435 case OPC_WRPGPR:
29436 check_insn(ctx, ISA_MIPS32R2);
29437 gen_store_srsgpr(rt, rd);
29438 break;
29439 default:
29440 MIPS_INVAL("cp0");
29441 generate_exception_end(ctx, EXCP_RI);
29442 break;
29443 }
29444 break;
29445 case OPC_BOVC:
29446 if (ctx->insn_flags & ISA_MIPS32R6) {
29447
29448 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29449 } else {
29450
29451
29452 gen_arith_imm(ctx, op, rt, rs, imm);
29453 }
29454 break;
29455 case OPC_ADDIU:
29456 gen_arith_imm(ctx, op, rt, rs, imm);
29457 break;
29458 case OPC_SLTI:
29459 case OPC_SLTIU:
29460 gen_slt_imm(ctx, op, rt, rs, imm);
29461 break;
29462 case OPC_ANDI:
29463 case OPC_LUI:
29464 case OPC_ORI:
29465 case OPC_XORI:
29466 gen_logic_imm(ctx, op, rt, rs, imm);
29467 break;
29468 case OPC_J:
29469 case OPC_JAL:
29470 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29471 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29472 break;
29473
29474 case OPC_BLEZC:
29475 if (ctx->insn_flags & ISA_MIPS32R6) {
29476 if (rt == 0) {
29477 generate_exception_end(ctx, EXCP_RI);
29478 break;
29479 }
29480
29481 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29482 } else {
29483
29484 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29485 }
29486 break;
29487 case OPC_BGTZC:
29488 if (ctx->insn_flags & ISA_MIPS32R6) {
29489 if (rt == 0) {
29490 generate_exception_end(ctx, EXCP_RI);
29491 break;
29492 }
29493
29494 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29495 } else {
29496
29497 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29498 }
29499 break;
29500 case OPC_BLEZALC:
29501 if (rt == 0) {
29502
29503 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29504 } else {
29505 check_insn(ctx, ISA_MIPS32R6);
29506
29507 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29508 }
29509 break;
29510 case OPC_BGTZALC:
29511 if (rt == 0) {
29512
29513 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29514 } else {
29515 check_insn(ctx, ISA_MIPS32R6);
29516
29517 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29518 }
29519 break;
29520 case OPC_BEQL:
29521 case OPC_BNEL:
29522 check_insn(ctx, ISA_MIPS2);
29523 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29524
29525 case OPC_BEQ:
29526 case OPC_BNE:
29527 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29528 break;
29529 case OPC_LL:
29530 check_insn(ctx, ISA_MIPS2);
29531 if (ctx->insn_flags & INSN_R5900) {
29532 check_insn_opc_user_only(ctx, INSN_R5900);
29533 }
29534
29535 case OPC_LWL:
29536 case OPC_LWR:
29537 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29538
29539 case OPC_LB:
29540 case OPC_LH:
29541 case OPC_LW:
29542 case OPC_LWPC:
29543 case OPC_LBU:
29544 case OPC_LHU:
29545 gen_ld(ctx, op, rt, rs, imm);
29546 break;
29547 case OPC_SWL:
29548 case OPC_SWR:
29549 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29550
29551 case OPC_SB:
29552 case OPC_SH:
29553 case OPC_SW:
29554 gen_st(ctx, op, rt, rs, imm);
29555 break;
29556 case OPC_SC:
29557 check_insn(ctx, ISA_MIPS2);
29558 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29559 if (ctx->insn_flags & INSN_R5900) {
29560 check_insn_opc_user_only(ctx, INSN_R5900);
29561 }
29562 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29563 break;
29564 case OPC_CACHE:
29565 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29566 check_cp0_enabled(ctx);
29567 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29568 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29569 gen_cache_operation(ctx, rt, rs, imm);
29570 }
29571
29572 break;
29573 case OPC_PREF:
29574 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29575 if (ctx->insn_flags & INSN_R5900) {
29576
29577 } else {
29578 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29579
29580 }
29581 break;
29582
29583
29584 case OPC_LWC1:
29585 case OPC_LDC1:
29586 case OPC_SWC1:
29587 case OPC_SDC1:
29588 gen_cop1_ldst(ctx, op, rt, rs, imm);
29589 break;
29590
29591 case OPC_CP1:
29592 op1 = MASK_CP1(ctx->opcode);
29593
29594 switch (op1) {
29595 case OPC_MFHC1:
29596 case OPC_MTHC1:
29597 check_cp1_enabled(ctx);
29598 check_insn(ctx, ISA_MIPS32R2);
29599
29600 case OPC_MFC1:
29601 case OPC_CFC1:
29602 case OPC_MTC1:
29603 case OPC_CTC1:
29604 check_cp1_enabled(ctx);
29605 gen_cp1(ctx, op1, rt, rd);
29606 break;
29607#if defined(TARGET_MIPS64)
29608 case OPC_DMFC1:
29609 case OPC_DMTC1:
29610 check_cp1_enabled(ctx);
29611 check_insn(ctx, ISA_MIPS3);
29612 check_mips_64(ctx);
29613 gen_cp1(ctx, op1, rt, rd);
29614 break;
29615#endif
29616 case OPC_BC1EQZ:
29617 check_cp1_enabled(ctx);
29618 if (ctx->insn_flags & ISA_MIPS32R6) {
29619
29620 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29621 rt, imm << 2, 4);
29622 } else {
29623
29624 check_cop1x(ctx);
29625 check_insn(ctx, ASE_MIPS3D);
29626 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29627 (rt >> 2) & 0x7, imm << 2);
29628 }
29629 break;
29630 case OPC_BC1NEZ:
29631 check_cp1_enabled(ctx);
29632 check_insn(ctx, ISA_MIPS32R6);
29633 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29634 rt, imm << 2, 4);
29635 break;
29636 case OPC_BC1ANY4:
29637 check_cp1_enabled(ctx);
29638 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29639 check_cop1x(ctx);
29640 check_insn(ctx, ASE_MIPS3D);
29641
29642 case OPC_BC1:
29643 check_cp1_enabled(ctx);
29644 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29645 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29646 (rt >> 2) & 0x7, imm << 2);
29647 break;
29648 case OPC_PS_FMT:
29649 check_ps(ctx);
29650
29651 case OPC_S_FMT:
29652 case OPC_D_FMT:
29653 check_cp1_enabled(ctx);
29654 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29655 (imm >> 8) & 0x7);
29656 break;
29657 case OPC_W_FMT:
29658 case OPC_L_FMT:
29659 {
29660 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29661 check_cp1_enabled(ctx);
29662 if (ctx->insn_flags & ISA_MIPS32R6) {
29663 switch (r6_op) {
29664 case R6_OPC_CMP_AF_S:
29665 case R6_OPC_CMP_UN_S:
29666 case R6_OPC_CMP_EQ_S:
29667 case R6_OPC_CMP_UEQ_S:
29668 case R6_OPC_CMP_LT_S:
29669 case R6_OPC_CMP_ULT_S:
29670 case R6_OPC_CMP_LE_S:
29671 case R6_OPC_CMP_ULE_S:
29672 case R6_OPC_CMP_SAF_S:
29673 case R6_OPC_CMP_SUN_S:
29674 case R6_OPC_CMP_SEQ_S:
29675 case R6_OPC_CMP_SEUQ_S:
29676 case R6_OPC_CMP_SLT_S:
29677 case R6_OPC_CMP_SULT_S:
29678 case R6_OPC_CMP_SLE_S:
29679 case R6_OPC_CMP_SULE_S:
29680 case R6_OPC_CMP_OR_S:
29681 case R6_OPC_CMP_UNE_S:
29682 case R6_OPC_CMP_NE_S:
29683 case R6_OPC_CMP_SOR_S:
29684 case R6_OPC_CMP_SUNE_S:
29685 case R6_OPC_CMP_SNE_S:
29686 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29687 break;
29688 case R6_OPC_CMP_AF_D:
29689 case R6_OPC_CMP_UN_D:
29690 case R6_OPC_CMP_EQ_D:
29691 case R6_OPC_CMP_UEQ_D:
29692 case R6_OPC_CMP_LT_D:
29693 case R6_OPC_CMP_ULT_D:
29694 case R6_OPC_CMP_LE_D:
29695 case R6_OPC_CMP_ULE_D:
29696 case R6_OPC_CMP_SAF_D:
29697 case R6_OPC_CMP_SUN_D:
29698 case R6_OPC_CMP_SEQ_D:
29699 case R6_OPC_CMP_SEUQ_D:
29700 case R6_OPC_CMP_SLT_D:
29701 case R6_OPC_CMP_SULT_D:
29702 case R6_OPC_CMP_SLE_D:
29703 case R6_OPC_CMP_SULE_D:
29704 case R6_OPC_CMP_OR_D:
29705 case R6_OPC_CMP_UNE_D:
29706 case R6_OPC_CMP_NE_D:
29707 case R6_OPC_CMP_SOR_D:
29708 case R6_OPC_CMP_SUNE_D:
29709 case R6_OPC_CMP_SNE_D:
29710 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29711 break;
29712 default:
29713 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29714 rt, rd, sa, (imm >> 8) & 0x7);
29715
29716 break;
29717 }
29718 } else {
29719 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29720 (imm >> 8) & 0x7);
29721 }
29722 break;
29723 }
29724 case OPC_BZ_V:
29725 case OPC_BNZ_V:
29726 case OPC_BZ_B:
29727 case OPC_BZ_H:
29728 case OPC_BZ_W:
29729 case OPC_BZ_D:
29730 case OPC_BNZ_B:
29731 case OPC_BNZ_H:
29732 case OPC_BNZ_W:
29733 case OPC_BNZ_D:
29734 check_insn(ctx, ASE_MSA);
29735 gen_msa_branch(env, ctx, op1);
29736 break;
29737 default:
29738 MIPS_INVAL("cp1");
29739 generate_exception_end(ctx, EXCP_RI);
29740 break;
29741 }
29742 break;
29743
29744
29745 case OPC_BC:
29746 case OPC_BALC:
29747 if (ctx->insn_flags & ISA_MIPS32R6) {
29748
29749 gen_compute_compact_branch(ctx, op, 0, 0,
29750 sextract32(ctx->opcode << 2, 0, 28));
29751 } else {
29752
29753
29754 generate_exception_err(ctx, EXCP_CpU, 2);
29755 }
29756 break;
29757 case OPC_BEQZC:
29758 case OPC_BNEZC:
29759 if (ctx->insn_flags & ISA_MIPS32R6) {
29760 if (rs != 0) {
29761
29762 gen_compute_compact_branch(ctx, op, rs, 0,
29763 sextract32(ctx->opcode << 2, 0, 23));
29764 } else {
29765
29766 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29767 }
29768 } else {
29769
29770
29771 generate_exception_err(ctx, EXCP_CpU, 2);
29772 }
29773 break;
29774 case OPC_CP2:
29775 check_insn(ctx, INSN_LOONGSON2F);
29776
29777 gen_loongson_multimedia(ctx, sa, rd, rt);
29778 break;
29779
29780 case OPC_CP3:
29781 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29782 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29783 check_cp1_enabled(ctx);
29784 op1 = MASK_CP3(ctx->opcode);
29785 switch (op1) {
29786 case OPC_LUXC1:
29787 case OPC_SUXC1:
29788 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29789
29790 case OPC_LWXC1:
29791 case OPC_LDXC1:
29792 case OPC_SWXC1:
29793 case OPC_SDXC1:
29794 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29795 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29796 break;
29797 case OPC_PREFX:
29798 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29799
29800 break;
29801 case OPC_ALNV_PS:
29802 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29803
29804 case OPC_MADD_S:
29805 case OPC_MADD_D:
29806 case OPC_MADD_PS:
29807 case OPC_MSUB_S:
29808 case OPC_MSUB_D:
29809 case OPC_MSUB_PS:
29810 case OPC_NMADD_S:
29811 case OPC_NMADD_D:
29812 case OPC_NMADD_PS:
29813 case OPC_NMSUB_S:
29814 case OPC_NMSUB_D:
29815 case OPC_NMSUB_PS:
29816 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29817 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29818 break;
29819 default:
29820 MIPS_INVAL("cp3");
29821 generate_exception_end(ctx, EXCP_RI);
29822 break;
29823 }
29824 } else {
29825 generate_exception_err(ctx, EXCP_CpU, 1);
29826 }
29827 break;
29828
29829#if defined(TARGET_MIPS64)
29830
29831 case OPC_LLD:
29832 if (ctx->insn_flags & INSN_R5900) {
29833 check_insn_opc_user_only(ctx, INSN_R5900);
29834 }
29835
29836 case OPC_LDL:
29837 case OPC_LDR:
29838 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29839
29840 case OPC_LWU:
29841 case OPC_LD:
29842 check_insn(ctx, ISA_MIPS3);
29843 check_mips_64(ctx);
29844 gen_ld(ctx, op, rt, rs, imm);
29845 break;
29846 case OPC_SDL:
29847 case OPC_SDR:
29848 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29849
29850 case OPC_SD:
29851 check_insn(ctx, ISA_MIPS3);
29852 check_mips_64(ctx);
29853 gen_st(ctx, op, rt, rs, imm);
29854 break;
29855 case OPC_SCD:
29856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29857 check_insn(ctx, ISA_MIPS3);
29858 if (ctx->insn_flags & INSN_R5900) {
29859 check_insn_opc_user_only(ctx, INSN_R5900);
29860 }
29861 check_mips_64(ctx);
29862 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29863 break;
29864 case OPC_BNVC:
29865 if (ctx->insn_flags & ISA_MIPS32R6) {
29866
29867 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29868 } else {
29869
29870 check_insn(ctx, ISA_MIPS3);
29871 check_mips_64(ctx);
29872 gen_arith_imm(ctx, op, rt, rs, imm);
29873 }
29874 break;
29875 case OPC_DADDIU:
29876 check_insn(ctx, ISA_MIPS3);
29877 check_mips_64(ctx);
29878 gen_arith_imm(ctx, op, rt, rs, imm);
29879 break;
29880#else
29881 case OPC_BNVC:
29882 if (ctx->insn_flags & ISA_MIPS32R6) {
29883 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29884 } else {
29885 MIPS_INVAL("major opcode");
29886 generate_exception_end(ctx, EXCP_RI);
29887 }
29888 break;
29889#endif
29890 case OPC_DAUI:
29891 if (ctx->insn_flags & ISA_MIPS32R6) {
29892#if defined(TARGET_MIPS64)
29893
29894 check_mips_64(ctx);
29895 if (rs == 0) {
29896 generate_exception(ctx, EXCP_RI);
29897 } else if (rt != 0) {
29898 TCGv t0 = tcg_temp_new();
29899 gen_load_gpr(t0, rs);
29900 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29901 tcg_temp_free(t0);
29902 }
29903#else
29904 generate_exception_end(ctx, EXCP_RI);
29905 MIPS_INVAL("major opcode");
29906#endif
29907 } else {
29908
29909 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29910 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29911 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29912 }
29913 break;
29914 case OPC_MSA:
29915 if (ctx->insn_flags & INSN_R5900) {
29916#if defined(TARGET_MIPS64)
29917 gen_mmi_lq(env, ctx);
29918#endif
29919 } else {
29920
29921 gen_msa(env, ctx);
29922 }
29923 break;
29924 case OPC_PCREL:
29925 check_insn(ctx, ISA_MIPS32R6);
29926 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29927 break;
29928 default:
29929 MIPS_INVAL("major opcode");
29930 generate_exception_end(ctx, EXCP_RI);
29931 break;
29932 }
29933}
29934
29935static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29936{
29937 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29938 CPUMIPSState *env = cs->env_ptr;
29939
29940 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29941 ctx->saved_pc = -1;
29942 ctx->insn_flags = env->insn_flags;
29943 ctx->CP0_Config1 = env->CP0_Config1;
29944 ctx->CP0_Config2 = env->CP0_Config2;
29945 ctx->CP0_Config3 = env->CP0_Config3;
29946 ctx->CP0_Config5 = env->CP0_Config5;
29947 ctx->btarget = 0;
29948 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29949 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29950 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29951 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29952 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29953 ctx->PAMask = env->PAMask;
29954 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29955 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29956 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29957 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29958 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29959
29960 ctx->hflags = (uint32_t)ctx->base.tb->flags;
29961 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29962 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29963 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29964 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29965 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29966 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29967 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29968 restore_cpu_state(env, ctx);
29969#ifdef CONFIG_USER_ONLY
29970 ctx->mem_idx = MIPS_HFLAG_UM;
29971#else
29972 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29973#endif
29974 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29975 MO_UNALN : MO_ALIGN;
29976
29977 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29978 ctx->hflags);
29979}
29980
29981static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29982{
29983}
29984
29985static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29986{
29987 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29988
29989 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29990 ctx->btarget);
29991}
29992
29993static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29994 const CPUBreakpoint *bp)
29995{
29996 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29997
29998 save_cpu_state(ctx, 1);
29999 ctx->base.is_jmp = DISAS_NORETURN;
30000 gen_helper_raise_exception_debug(cpu_env);
30001
30002
30003
30004
30005
30006
30007 ctx->base.pc_next += 4;
30008 return true;
30009}
30010
30011static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
30012{
30013 CPUMIPSState *env = cs->env_ptr;
30014 DisasContext *ctx = container_of(dcbase, DisasContext, base);
30015 int insn_bytes;
30016 int is_slot;
30017
30018 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
30019 if (ctx->insn_flags & ISA_NANOMIPS32) {
30020 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30021 insn_bytes = decode_nanomips_opc(env, ctx);
30022 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
30023 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
30024 insn_bytes = 4;
30025 decode_opc(env, ctx);
30026 } else if (ctx->insn_flags & ASE_MICROMIPS) {
30027 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30028 insn_bytes = decode_micromips_opc(env, ctx);
30029 } else if (ctx->insn_flags & ASE_MIPS16) {
30030 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30031 insn_bytes = decode_mips16_opc(env, ctx);
30032 } else {
30033 generate_exception_end(ctx, EXCP_RI);
30034 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
30035 return;
30036 }
30037
30038 if (ctx->hflags & MIPS_HFLAG_BMASK) {
30039 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
30040 MIPS_HFLAG_FBNSLOT))) {
30041
30042
30043
30044
30045 is_slot = 1;
30046 }
30047 if ((ctx->hflags & MIPS_HFLAG_M16) &&
30048 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
30049
30050
30051
30052
30053 is_slot = 1;
30054 }
30055 }
30056 if (is_slot) {
30057 gen_branch(ctx, insn_bytes);
30058 }
30059 ctx->base.pc_next += insn_bytes;
30060
30061 if (ctx->base.is_jmp != DISAS_NEXT) {
30062 return;
30063 }
30064
30065
30066
30067
30068
30069
30070 if (ctx->base.singlestep_enabled &&
30071 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
30072 ctx->base.is_jmp = DISAS_TOO_MANY;
30073 }
30074 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
30075 ctx->base.is_jmp = DISAS_TOO_MANY;
30076 }
30077}
30078
30079static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
30080{
30081 DisasContext *ctx = container_of(dcbase, DisasContext, base);
30082
30083 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
30084 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
30085 gen_helper_raise_exception_debug(cpu_env);
30086 } else {
30087 switch (ctx->base.is_jmp) {
30088 case DISAS_STOP:
30089 gen_save_pc(ctx->base.pc_next);
30090 tcg_gen_lookup_and_goto_ptr();
30091 break;
30092 case DISAS_NEXT:
30093 case DISAS_TOO_MANY:
30094 save_cpu_state(ctx, 0);
30095 gen_goto_tb(ctx, 0, ctx->base.pc_next);
30096 break;
30097 case DISAS_EXIT:
30098 tcg_gen_exit_tb(NULL, 0);
30099 break;
30100 case DISAS_NORETURN:
30101 break;
30102 default:
30103 g_assert_not_reached();
30104 }
30105 }
30106}
30107
30108static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
30109{
30110 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
30111 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
30112}
30113
30114static const TranslatorOps mips_tr_ops = {
30115 .init_disas_context = mips_tr_init_disas_context,
30116 .tb_start = mips_tr_tb_start,
30117 .insn_start = mips_tr_insn_start,
30118 .breakpoint_check = mips_tr_breakpoint_check,
30119 .translate_insn = mips_tr_translate_insn,
30120 .tb_stop = mips_tr_tb_stop,
30121 .disas_log = mips_tr_disas_log,
30122};
30123
30124void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
30125{
30126 DisasContext ctx;
30127
30128 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
30129}
30130
30131static void fpu_dump_state(CPUMIPSState *env, FILE *f, int flags)
30132{
30133 int i;
30134 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
30135
30136#define printfpr(fp) \
30137 do { \
30138 if (is_fpu64) \
30139 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30140 " fd:%13g fs:%13g psu: %13g\n", \
30141 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
30142 (double)(fp)->fd, \
30143 (double)(fp)->fs[FP_ENDIAN_IDX], \
30144 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
30145 else { \
30146 fpr_t tmp; \
30147 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
30148 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
30149 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30150 " fd:%13g fs:%13g psu:%13g\n", \
30151 tmp.w[FP_ENDIAN_IDX], tmp.d, \
30152 (double)tmp.fd, \
30153 (double)tmp.fs[FP_ENDIAN_IDX], \
30154 (double)tmp.fs[!FP_ENDIAN_IDX]); \
30155 } \
30156 } while(0)
30157
30158
30159 qemu_fprintf(f,
30160 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
30161 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
30162 get_float_exception_flags(&env->active_fpu.fp_status));
30163 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
30164 qemu_fprintf(f, "%3s: ", fregnames[i]);
30165 printfpr(&env->active_fpu.fpr[i]);
30166 }
30167
30168#undef printfpr
30169}
30170
30171void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
30172{
30173 MIPSCPU *cpu = MIPS_CPU(cs);
30174 CPUMIPSState *env = &cpu->env;
30175 int i;
30176
30177 qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
30178 " LO=0x" TARGET_FMT_lx " ds %04x "
30179 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
30180 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
30181 env->hflags, env->btarget, env->bcond);
30182 for (i = 0; i < 32; i++) {
30183 if ((i & 3) == 0) {
30184 qemu_fprintf(f, "GPR%02d:", i);
30185 }
30186 qemu_fprintf(f, " %s " TARGET_FMT_lx,
30187 regnames[i], env->active_tc.gpr[i]);
30188 if ((i & 3) == 3) {
30189 qemu_fprintf(f, "\n");
30190 }
30191 }
30192
30193 qemu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
30194 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
30195 qemu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
30196 PRIx64 "\n",
30197 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
30198 qemu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
30199 env->CP0_Config2, env->CP0_Config3);
30200 qemu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
30201 env->CP0_Config4, env->CP0_Config5);
30202 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
30203 fpu_dump_state(env, f, flags);
30204 }
30205}
30206
30207void mips_tcg_init(void)
30208{
30209 int i;
30210
30211 cpu_gpr[0] = NULL;
30212 for (i = 1; i < 32; i++)
30213 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
30214 offsetof(CPUMIPSState, active_tc.gpr[i]),
30215 regnames[i]);
30216
30217 for (i = 0; i < 32; i++) {
30218 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
30219 msa_wr_d[i * 2] =
30220 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
30221
30222
30223
30224
30225 fpu_f64[i] = msa_wr_d[i * 2];
30226 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
30227 msa_wr_d[i * 2 + 1] =
30228 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
30229 }
30230
30231 cpu_PC = tcg_global_mem_new(cpu_env,
30232 offsetof(CPUMIPSState, active_tc.PC), "PC");
30233 for (i = 0; i < MIPS_DSP_ACC; i++) {
30234 cpu_HI[i] = tcg_global_mem_new(cpu_env,
30235 offsetof(CPUMIPSState, active_tc.HI[i]),
30236 regnames_HI[i]);
30237 cpu_LO[i] = tcg_global_mem_new(cpu_env,
30238 offsetof(CPUMIPSState, active_tc.LO[i]),
30239 regnames_LO[i]);
30240 }
30241 cpu_dspctrl = tcg_global_mem_new(cpu_env,
30242 offsetof(CPUMIPSState, active_tc.DSPControl),
30243 "DSPControl");
30244 bcond = tcg_global_mem_new(cpu_env,
30245 offsetof(CPUMIPSState, bcond), "bcond");
30246 btarget = tcg_global_mem_new(cpu_env,
30247 offsetof(CPUMIPSState, btarget), "btarget");
30248 hflags = tcg_global_mem_new_i32(cpu_env,
30249 offsetof(CPUMIPSState, hflags), "hflags");
30250
30251 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
30252 offsetof(CPUMIPSState, active_fpu.fcr0),
30253 "fcr0");
30254 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
30255 offsetof(CPUMIPSState, active_fpu.fcr31),
30256 "fcr31");
30257 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
30258 "lladdr");
30259 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
30260 "llval");
30261
30262#if defined(TARGET_MIPS64)
30263 cpu_mmr[0] = NULL;
30264 for (i = 1; i < 32; i++) {
30265 cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
30266 offsetof(CPUMIPSState,
30267 active_tc.mmr[i]),
30268 regnames[i]);
30269 }
30270#endif
30271
30272#if !defined(TARGET_MIPS64)
30273 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
30274 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
30275 offsetof(CPUMIPSState,
30276 active_tc.mxu_gpr[i]),
30277 mxuregnames[i]);
30278 }
30279
30280 mxu_CR = tcg_global_mem_new(cpu_env,
30281 offsetof(CPUMIPSState, active_tc.mxu_cr),
30282 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
30283#endif
30284}
30285
30286#include "translate_init.inc.c"
30287
30288void cpu_mips_realize_env(CPUMIPSState *env)
30289{
30290 env->exception_base = (int32_t)0xBFC00000;
30291
30292#ifndef CONFIG_USER_ONLY
30293 mmu_init(env, env->cpu_model);
30294#endif
30295 fpu_init(env, env->cpu_model);
30296 mvp_init(env, env->cpu_model);
30297}
30298
30299bool cpu_supports_cps_smp(const char *cpu_type)
30300{
30301 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30302 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
30303}
30304
30305bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
30306{
30307 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30308 return (mcc->cpu_def->insn_flags & isa) != 0;
30309}
30310
30311void cpu_set_exception_base(int vp_index, target_ulong address)
30312{
30313 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
30314 vp->env.exception_base = address;
30315}
30316
30317void cpu_state_reset(CPUMIPSState *env)
30318{
30319 CPUState *cs = env_cpu(env);
30320
30321
30322 env->CP0_PRid = env->cpu_model->CP0_PRid;
30323 env->CP0_Config0 = env->cpu_model->CP0_Config0;
30324#ifdef TARGET_WORDS_BIGENDIAN
30325 env->CP0_Config0 |= (1 << CP0C0_BE);
30326#endif
30327 env->CP0_Config1 = env->cpu_model->CP0_Config1;
30328 env->CP0_Config2 = env->cpu_model->CP0_Config2;
30329 env->CP0_Config3 = env->cpu_model->CP0_Config3;
30330 env->CP0_Config4 = env->cpu_model->CP0_Config4;
30331 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
30332 env->CP0_Config5 = env->cpu_model->CP0_Config5;
30333 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
30334 env->CP0_Config6 = env->cpu_model->CP0_Config6;
30335 env->CP0_Config7 = env->cpu_model->CP0_Config7;
30336 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
30337 << env->cpu_model->CP0_LLAddr_shift;
30338 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
30339 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
30340 env->CCRes = env->cpu_model->CCRes;
30341 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
30342 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
30343 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
30344 env->current_tc = 0;
30345 env->SEGBITS = env->cpu_model->SEGBITS;
30346 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
30347#if defined(TARGET_MIPS64)
30348 if (env->cpu_model->insn_flags & ISA_MIPS3) {
30349 env->SEGMask |= 3ULL << 62;
30350 }
30351#endif
30352 env->PABITS = env->cpu_model->PABITS;
30353 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
30354 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
30355 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
30356 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
30357 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
30358 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
30359 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
30360 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
30361 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
30362 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
30363 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
30364 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
30365 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
30366 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
30367 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
30368 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
30369 env->msair = env->cpu_model->MSAIR;
30370 env->insn_flags = env->cpu_model->insn_flags;
30371
30372#if defined(CONFIG_USER_ONLY)
30373 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
30374# ifdef TARGET_MIPS64
30375
30376 env->CP0_Status |= (1 << CP0St_PX);
30377# endif
30378# ifdef TARGET_ABI_MIPSN64
30379
30380 env->CP0_Status |= (1 << CP0St_UX);
30381# endif
30382
30383
30384
30385
30386 env->CP0_HWREna |= 0x0000000F;
30387 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
30388 env->CP0_Status |= (1 << CP0St_CU1);
30389 }
30390 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
30391 env->CP0_Status |= (1 << CP0St_MX);
30392 }
30393# if defined(TARGET_MIPS64)
30394
30395 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
30396 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
30397 env->CP0_Status |= (1 << CP0St_FR);
30398 }
30399# endif
30400#else
30401 if (env->hflags & MIPS_HFLAG_BMASK) {
30402
30403
30404
30405
30406 env->CP0_ErrorEPC = (env->active_tc.PC
30407 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30408 } else {
30409 env->CP0_ErrorEPC = env->active_tc.PC;
30410 }
30411 env->active_tc.PC = env->exception_base;
30412 env->CP0_Random = env->tlb->nb_tlb - 1;
30413 env->tlb->tlb_in_use = env->tlb->nb_tlb;
30414 env->CP0_Wired = 0;
30415 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30416 env->CP0_EBase = (cs->cpu_index & 0x3FF);
30417 if (mips_um_ksegs_enabled()) {
30418 env->CP0_EBase |= 0x40000000;
30419 } else {
30420 env->CP0_EBase |= (int32_t)0x80000000;
30421 }
30422 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30423 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30424 }
30425 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30426 0x3ff : 0xff;
30427 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30428
30429
30430
30431
30432 env->CP0_IntCtl = 0xe0000000;
30433 {
30434 int i;
30435
30436 for (i = 0; i < 7; i++) {
30437 env->CP0_WatchLo[i] = 0;
30438 env->CP0_WatchHi[i] = 0x80000000;
30439 }
30440 env->CP0_WatchLo[7] = 0;
30441 env->CP0_WatchHi[7] = 0;
30442 }
30443
30444 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30445
30446 cpu_mips_store_count(env, 1);
30447
30448 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30449 int i;
30450
30451
30452 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30453 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30454 env->tcs[i].CP0_TCHalt = 1;
30455 }
30456 env->active_tc.CP0_TCHalt = 1;
30457 cs->halted = 1;
30458
30459 if (cs->cpu_index == 0) {
30460
30461 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30462 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30463
30464
30465 cs->halted = 0;
30466 env->active_tc.CP0_TCHalt = 0;
30467 env->tcs[0].CP0_TCHalt = 0;
30468
30469 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30470 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30471 }
30472 }
30473
30474
30475
30476
30477
30478
30479 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
30480
30481 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30482
30483 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30484 (2 << CP0SC_C);
30485
30486 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30487 (3 << CP0SC_C)) << 16;
30488
30489 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30490 (1 << CP0SC_EU) | (2 << CP0SC_C);
30491
30492 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30493 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30494
30495 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30496#endif
30497 if ((env->insn_flags & ISA_MIPS32R6) &&
30498 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30499
30500 env->CP0_Status |= (1 << CP0St_FR);
30501 }
30502
30503 if (env->insn_flags & ISA_MIPS32R6) {
30504
30505 env->CP0_PWSize = 0x40;
30506
30507
30508
30509
30510
30511 env->CP0_PWField = 0x0C30C302;
30512 } else {
30513
30514
30515
30516
30517
30518 env->CP0_PWField = 0x02;
30519 }
30520
30521 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30522
30523 env->hflags |= MIPS_HFLAG_M16;
30524 }
30525
30526
30527 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30528 msa_reset(env);
30529 }
30530
30531 compute_hflags(env);
30532 restore_fp_status(env);
30533 restore_pamask(env);
30534 cs->exception_index = EXCP_NONE;
30535
30536 if (semihosting_get_argc()) {
30537
30538 env->active_tc.gpr[4] = -1;
30539 }
30540}
30541
30542void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30543 target_ulong *data)
30544{
30545 env->active_tc.PC = data[0];
30546 env->hflags &= ~MIPS_HFLAG_BMASK;
30547 env->hflags |= data[1];
30548 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30549 case MIPS_HFLAG_BR:
30550 break;
30551 case MIPS_HFLAG_BC:
30552 case MIPS_HFLAG_BL:
30553 case MIPS_HFLAG_B:
30554 env->btarget = data[2];
30555 break;
30556 }
30557}
30558