1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "cpu.h"
27#include "internal.h"
28#include "tcg/tcg-op.h"
29#include "exec/translator.h"
30#include "exec/helper-proto.h"
31#include "exec/helper-gen.h"
32#include "semihosting/semihost.h"
33
34#include "trace.h"
35#include "exec/translator.h"
36#include "exec/log.h"
37#include "qemu/qemu-print.h"
38#include "fpu_helper.h"
39#include "translate.h"
40
41
42
43
44
45
46#define STUB_HELPER(NAME, ...) \
47 static inline void gen_helper_##NAME(__VA_ARGS__) \
48 { g_assert_not_reached(); }
49
50#ifdef CONFIG_USER_ONLY
51STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
52#endif
53
54enum {
55
56 OPC_SPECIAL = (0x00 << 26),
57 OPC_REGIMM = (0x01 << 26),
58 OPC_CP0 = (0x10 << 26),
59 OPC_CP2 = (0x12 << 26),
60 OPC_CP3 = (0x13 << 26),
61 OPC_SPECIAL2 = (0x1C << 26),
62 OPC_SPECIAL3 = (0x1F << 26),
63
64 OPC_ADDI = (0x08 << 26),
65 OPC_ADDIU = (0x09 << 26),
66 OPC_SLTI = (0x0A << 26),
67 OPC_SLTIU = (0x0B << 26),
68
69 OPC_ANDI = (0x0C << 26),
70 OPC_ORI = (0x0D << 26),
71 OPC_XORI = (0x0E << 26),
72 OPC_LUI = (0x0F << 26),
73
74 OPC_DADDI = (0x18 << 26),
75 OPC_DADDIU = (0x19 << 26),
76
77 OPC_J = (0x02 << 26),
78 OPC_JAL = (0x03 << 26),
79 OPC_BEQ = (0x04 << 26),
80 OPC_BEQL = (0x14 << 26),
81 OPC_BNE = (0x05 << 26),
82 OPC_BNEL = (0x15 << 26),
83 OPC_BLEZ = (0x06 << 26),
84 OPC_BLEZL = (0x16 << 26),
85 OPC_BGTZ = (0x07 << 26),
86 OPC_BGTZL = (0x17 << 26),
87 OPC_JALX = (0x1D << 26),
88 OPC_DAUI = (0x1D << 26),
89
90 OPC_LDL = (0x1A << 26),
91 OPC_LDR = (0x1B << 26),
92 OPC_LB = (0x20 << 26),
93 OPC_LH = (0x21 << 26),
94 OPC_LWL = (0x22 << 26),
95 OPC_LW = (0x23 << 26),
96 OPC_LWPC = OPC_LW | 0x5,
97 OPC_LBU = (0x24 << 26),
98 OPC_LHU = (0x25 << 26),
99 OPC_LWR = (0x26 << 26),
100 OPC_LWU = (0x27 << 26),
101 OPC_SB = (0x28 << 26),
102 OPC_SH = (0x29 << 26),
103 OPC_SWL = (0x2A << 26),
104 OPC_SW = (0x2B << 26),
105 OPC_SDL = (0x2C << 26),
106 OPC_SDR = (0x2D << 26),
107 OPC_SWR = (0x2E << 26),
108 OPC_LL = (0x30 << 26),
109 OPC_LLD = (0x34 << 26),
110 OPC_LD = (0x37 << 26),
111 OPC_LDPC = OPC_LD | 0x5,
112 OPC_SC = (0x38 << 26),
113 OPC_SCD = (0x3C << 26),
114 OPC_SD = (0x3F << 26),
115
116 OPC_LWC1 = (0x31 << 26),
117 OPC_LWC2 = (0x32 << 26),
118 OPC_LDC1 = (0x35 << 26),
119 OPC_LDC2 = (0x36 << 26),
120 OPC_SWC1 = (0x39 << 26),
121 OPC_SWC2 = (0x3A << 26),
122 OPC_SDC1 = (0x3D << 26),
123 OPC_SDC2 = (0x3E << 26),
124
125 OPC_BLEZALC = (0x06 << 26),
126 OPC_BGEZALC = (0x06 << 26),
127 OPC_BGEUC = (0x06 << 26),
128 OPC_BGTZALC = (0x07 << 26),
129 OPC_BLTZALC = (0x07 << 26),
130 OPC_BLTUC = (0x07 << 26),
131 OPC_BOVC = (0x08 << 26),
132 OPC_BEQZALC = (0x08 << 26),
133 OPC_BEQC = (0x08 << 26),
134 OPC_BLEZC = (0x16 << 26),
135 OPC_BGEZC = (0x16 << 26),
136 OPC_BGEC = (0x16 << 26),
137 OPC_BGTZC = (0x17 << 26),
138 OPC_BLTZC = (0x17 << 26),
139 OPC_BLTC = (0x17 << 26),
140 OPC_BNVC = (0x18 << 26),
141 OPC_BNEZALC = (0x18 << 26),
142 OPC_BNEC = (0x18 << 26),
143 OPC_BC = (0x32 << 26),
144 OPC_BEQZC = (0x36 << 26),
145 OPC_JIC = (0x36 << 26),
146 OPC_BALC = (0x3A << 26),
147 OPC_BNEZC = (0x3E << 26),
148 OPC_JIALC = (0x3E << 26),
149
150 OPC_MDMX = (0x1E << 26),
151
152 OPC_CACHE = (0x2F << 26),
153 OPC_PREF = (0x33 << 26),
154
155 OPC_PCREL = (0x3B << 26),
156};
157
158
159#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
160#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
161enum {
162
163 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
164 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
165 OPC_LWUPC = OPC_PCREL | (2 << 19),
166
167
168 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
169 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
170
171
172 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
173};
174
175
176#define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
177
178enum {
179
180 OPC_SLL = 0x00 | OPC_SPECIAL,
181
182
183
184 OPC_SRL = 0x02 | OPC_SPECIAL,
185 OPC_ROTR = OPC_SRL | (1 << 21),
186 OPC_SRA = 0x03 | OPC_SPECIAL,
187 OPC_SLLV = 0x04 | OPC_SPECIAL,
188 OPC_SRLV = 0x06 | OPC_SPECIAL,
189 OPC_ROTRV = OPC_SRLV | (1 << 6),
190 OPC_SRAV = 0x07 | OPC_SPECIAL,
191 OPC_DSLLV = 0x14 | OPC_SPECIAL,
192 OPC_DSRLV = 0x16 | OPC_SPECIAL,
193 OPC_DROTRV = OPC_DSRLV | (1 << 6),
194 OPC_DSRAV = 0x17 | OPC_SPECIAL,
195 OPC_DSLL = 0x38 | OPC_SPECIAL,
196 OPC_DSRL = 0x3A | OPC_SPECIAL,
197 OPC_DROTR = OPC_DSRL | (1 << 21),
198 OPC_DSRA = 0x3B | OPC_SPECIAL,
199 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
200 OPC_DSRL32 = 0x3E | OPC_SPECIAL,
201 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
202 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
203
204 OPC_MULT = 0x18 | OPC_SPECIAL,
205 OPC_MULTU = 0x19 | OPC_SPECIAL,
206 OPC_DIV = 0x1A | OPC_SPECIAL,
207 OPC_DIVU = 0x1B | OPC_SPECIAL,
208 OPC_DMULT = 0x1C | OPC_SPECIAL,
209 OPC_DMULTU = 0x1D | OPC_SPECIAL,
210 OPC_DDIV = 0x1E | OPC_SPECIAL,
211 OPC_DDIVU = 0x1F | OPC_SPECIAL,
212
213
214 OPC_ADD = 0x20 | OPC_SPECIAL,
215 OPC_ADDU = 0x21 | OPC_SPECIAL,
216 OPC_SUB = 0x22 | OPC_SPECIAL,
217 OPC_SUBU = 0x23 | OPC_SPECIAL,
218 OPC_AND = 0x24 | OPC_SPECIAL,
219 OPC_OR = 0x25 | OPC_SPECIAL,
220 OPC_XOR = 0x26 | OPC_SPECIAL,
221 OPC_NOR = 0x27 | OPC_SPECIAL,
222 OPC_SLT = 0x2A | OPC_SPECIAL,
223 OPC_SLTU = 0x2B | OPC_SPECIAL,
224 OPC_DADD = 0x2C | OPC_SPECIAL,
225 OPC_DADDU = 0x2D | OPC_SPECIAL,
226 OPC_DSUB = 0x2E | OPC_SPECIAL,
227 OPC_DSUBU = 0x2F | OPC_SPECIAL,
228
229 OPC_JR = 0x08 | OPC_SPECIAL,
230 OPC_JALR = 0x09 | OPC_SPECIAL,
231
232 OPC_TGE = 0x30 | OPC_SPECIAL,
233 OPC_TGEU = 0x31 | OPC_SPECIAL,
234 OPC_TLT = 0x32 | OPC_SPECIAL,
235 OPC_TLTU = 0x33 | OPC_SPECIAL,
236 OPC_TEQ = 0x34 | OPC_SPECIAL,
237 OPC_TNE = 0x36 | OPC_SPECIAL,
238
239 OPC_MFHI = 0x10 | OPC_SPECIAL,
240 OPC_MTHI = 0x11 | OPC_SPECIAL,
241 OPC_MFLO = 0x12 | OPC_SPECIAL,
242 OPC_MTLO = 0x13 | OPC_SPECIAL,
243
244 OPC_MOVZ = 0x0A | OPC_SPECIAL,
245 OPC_MOVN = 0x0B | OPC_SPECIAL,
246
247 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
248 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
249
250 OPC_MOVCI = 0x01 | OPC_SPECIAL,
251
252
253 OPC_PMON = 0x05 | OPC_SPECIAL,
254 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
255 OPC_BREAK = 0x0D | OPC_SPECIAL,
256 OPC_SPIM = 0x0E | OPC_SPECIAL,
257 OPC_SYNC = 0x0F | OPC_SPECIAL,
258
259 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
260 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
261 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
262 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
263};
264
265
266
267
268
269#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
270
271enum {
272 R6_OPC_MUL = OPC_MULT | (2 << 6),
273 R6_OPC_MUH = OPC_MULT | (3 << 6),
274 R6_OPC_MULU = OPC_MULTU | (2 << 6),
275 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
276 R6_OPC_DIV = OPC_DIV | (2 << 6),
277 R6_OPC_MOD = OPC_DIV | (3 << 6),
278 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
279 R6_OPC_MODU = OPC_DIVU | (3 << 6),
280
281 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
282 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
283 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
284 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
285 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
286 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
287 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
288 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
289
290 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
291 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
292 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
293 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
294 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
295};
296
297
298#define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
299
300enum {
301 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
302 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
303 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
304 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
305 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
306 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
307 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
308 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
309 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
310 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
311 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
312 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
313 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
314 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
315 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
316 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
317
318 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
319 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
320};
321
322
323#define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
324
325enum {
326
327 OPC_MADD = 0x00 | OPC_SPECIAL2,
328 OPC_MADDU = 0x01 | OPC_SPECIAL2,
329 OPC_MUL = 0x02 | OPC_SPECIAL2,
330 OPC_MSUB = 0x04 | OPC_SPECIAL2,
331 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
332
333 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
334 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
335 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
336 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
337 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
338 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
339 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
340 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
341 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
342 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
343 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
344 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
345
346 OPC_CLZ = 0x20 | OPC_SPECIAL2,
347 OPC_CLO = 0x21 | OPC_SPECIAL2,
348 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
349 OPC_DCLO = 0x25 | OPC_SPECIAL2,
350
351 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
352};
353
354
355#define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
356
357enum {
358 OPC_EXT = 0x00 | OPC_SPECIAL3,
359 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
360 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
361 OPC_DEXT = 0x03 | OPC_SPECIAL3,
362 OPC_INS = 0x04 | OPC_SPECIAL3,
363 OPC_DINSM = 0x05 | OPC_SPECIAL3,
364 OPC_DINSU = 0x06 | OPC_SPECIAL3,
365 OPC_DINS = 0x07 | OPC_SPECIAL3,
366 OPC_FORK = 0x08 | OPC_SPECIAL3,
367 OPC_YIELD = 0x09 | OPC_SPECIAL3,
368 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
369 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
370 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
371 OPC_GINV = 0x3D | OPC_SPECIAL3,
372
373
374 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
375 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
376 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
377 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
378 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
379 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
380 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
381 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
382 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
383 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
384 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
385 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
386
387
388 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
389
390 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
391 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
392 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
393 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
394
395
396 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
397 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
398
399 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
400 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
401
402
403
404 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
405 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
406
407 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
408 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
409
410 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
411 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
412
413 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
414 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
415
416
417 OPC_LWLE = 0x19 | OPC_SPECIAL3,
418 OPC_LWRE = 0x1A | OPC_SPECIAL3,
419 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
420 OPC_SBE = 0x1C | OPC_SPECIAL3,
421 OPC_SHE = 0x1D | OPC_SPECIAL3,
422 OPC_SCE = 0x1E | OPC_SPECIAL3,
423 OPC_SWE = 0x1F | OPC_SPECIAL3,
424 OPC_SWLE = 0x21 | OPC_SPECIAL3,
425 OPC_SWRE = 0x22 | OPC_SPECIAL3,
426 OPC_PREFE = 0x23 | OPC_SPECIAL3,
427 OPC_LBUE = 0x28 | OPC_SPECIAL3,
428 OPC_LHUE = 0x29 | OPC_SPECIAL3,
429 OPC_LBE = 0x2C | OPC_SPECIAL3,
430 OPC_LHE = 0x2D | OPC_SPECIAL3,
431 OPC_LLE = 0x2E | OPC_SPECIAL3,
432 OPC_LWE = 0x2F | OPC_SPECIAL3,
433
434
435 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
436 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
437 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
438 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
439 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
440 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
441};
442
443
444#define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
445enum {
446 OPC_GSLQ = 0x0020 | OPC_LWC2,
447 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
448 OPC_GSSHFL = OPC_LWC2,
449 OPC_GSSQ = 0x0020 | OPC_SWC2,
450 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
451 OPC_GSSHFS = OPC_SWC2,
452};
453
454
455#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
456enum {
457 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
458 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
459 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
460 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
461 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
462 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
463 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
464 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
465};
466
467
468#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
469
470enum {
471 OPC_GSLBX = 0x0 | OPC_LDC2,
472 OPC_GSLHX = 0x1 | OPC_LDC2,
473 OPC_GSLWX = 0x2 | OPC_LDC2,
474 OPC_GSLDX = 0x3 | OPC_LDC2,
475 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
476 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
477 OPC_GSSBX = 0x0 | OPC_SDC2,
478 OPC_GSSHX = 0x1 | OPC_SDC2,
479 OPC_GSSWX = 0x2 | OPC_SDC2,
480 OPC_GSSDX = 0x3 | OPC_SDC2,
481 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
482 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
483};
484
485
486#define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
487
488enum {
489 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
490 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
491 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
492 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL,
493 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
494 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
495 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
496 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL
497};
498
499
500#define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
501
502enum {
503 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
504 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
505 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL,
506 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
507 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
508 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
509 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
510 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
511 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
512 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
513 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL,
514};
515
516
517enum {
518 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
519 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
520};
521
522#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
523
524enum {
525 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
526 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
527 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
528 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
529};
530
531#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
532enum {
533
534 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
535 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
536 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
537 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
538 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
539 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
540 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
541 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
542 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
543 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
544 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
545 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
546 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
547 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
548 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
549 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
550 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
551 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
552
553 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
554 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
555 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
556 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
557 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
558 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
559};
560
561#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
562#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
563enum {
564
565 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
566 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
567 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
568 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
569 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
570 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
571 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
572 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
573 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
574 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
575 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
576 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
577
578 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
579 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
580 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
581 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
582};
583
584#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
585enum {
586
587 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
588 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
589 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
590 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
591 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
592 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
593 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
594 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
595 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
596 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
597 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
598 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
599 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
600
601 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
602 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
603 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
604 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
605 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
606};
607
608#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
609enum {
610
611 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
612 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
613 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
614 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
615 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
616 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
617 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
618
619 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
620 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
621 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
622 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
623 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
624 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
625 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
626 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
627 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
628 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
629 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
630 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
631 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
633 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
634};
635
636#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637enum {
638
639 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
640 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
641 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
642 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
643 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
644 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
645 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
646 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
647 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
648 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
649 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
650 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
651 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
652 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
653 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
654 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
655 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
656 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
657 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
658 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
659 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
660 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
661};
662
663#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
664enum {
665
666 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
667 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
668 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
669 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
670 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
671 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
672 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
673 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
674 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
675 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
676 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
677 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
678 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
679 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
680 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
681 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
682 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
683 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
684 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
685 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
686 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
687 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
688};
689
690#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
691enum {
692
693 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
694};
695
696#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
697enum {
698
699 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
700 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
701 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
702};
703
704#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705enum {
706
707 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
708 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
709 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
710 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
711 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
712 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
713 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
714 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
715 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
716 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
717 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
718 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
719 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
720 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
721 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
722 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
723 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
724};
725
726#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
727enum {
728
729 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
730 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
731 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
732 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
733 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
734 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
735 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
736 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
737 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
738 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
739 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
740 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
741 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
742 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
743 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
744 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
745 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
746
747 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
748 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
749 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
752 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
753};
754
755#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
756enum {
757
758 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
759 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
760 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
761 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
762 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
763
764 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
765 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
766 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
767 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
768 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
769 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
770 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
771 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
772 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
773 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
774 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
775 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
776 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
777 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
778 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
779 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
780 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
781 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
782 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
783 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
784 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
785};
786
787#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
788enum {
789
790 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
793 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
794 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
795 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
796 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
797 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
798 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
799 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
800 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
801 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
802 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
803 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
804 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
805 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
806 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
807 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
808 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
809
810 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
817 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
818};
819
820#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
821enum {
822
823 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
824 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
825 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
826 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
827};
828
829#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830enum {
831
832 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
833 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
834 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
835 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
836 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
837 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
838 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
839 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
840 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
841 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
842 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
843 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
844 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
845 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
846 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
847 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
848 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
849 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
850 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
851 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
852 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
853};
854
855#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
856enum {
857
858 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
859};
860
861#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
862enum {
863
864 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
865 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
866 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
867 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
868 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
869 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
870 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
871 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
872 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
873 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
874 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
875 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
876 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
877 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
878 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
879 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
880 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
881 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
882 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
883 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
884 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
889 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
890};
891
892#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
893enum {
894
895 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
896 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
897 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
898 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
899 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
900 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
901 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
902 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
903 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
904 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
905 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
906 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
907 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
908 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
909 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
910 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
911 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
912 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
913 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
914 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
915 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
920 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
921};
922
923
924#define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
925
926enum {
927 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
928 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
929 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
930 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
931 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
932 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
933 OPC_MFTR = (0x08 << 21) | OPC_CP0,
934 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
935 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
936 OPC_MTTR = (0x0C << 21) | OPC_CP0,
937 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
938 OPC_C0 = (0x10 << 21) | OPC_CP0,
939 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
940 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
941 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
942 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
943 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
944 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
945 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
946 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
947 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
948 OPC_C0_A = (0x1A << 21) | OPC_CP0,
949 OPC_C0_B = (0x1B << 21) | OPC_CP0,
950 OPC_C0_C = (0x1C << 21) | OPC_CP0,
951 OPC_C0_D = (0x1D << 21) | OPC_CP0,
952 OPC_C0_E = (0x1E << 21) | OPC_CP0,
953 OPC_C0_F = (0x1F << 21) | OPC_CP0,
954};
955
956
957#define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
958
959enum {
960 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
961 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
962 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
963 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
964 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
965 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
966 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
967 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
968};
969
970
971#define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
972
973enum {
974 OPC_TLBR = 0x01 | OPC_C0,
975 OPC_TLBWI = 0x02 | OPC_C0,
976 OPC_TLBINV = 0x03 | OPC_C0,
977 OPC_TLBINVF = 0x04 | OPC_C0,
978 OPC_TLBWR = 0x06 | OPC_C0,
979 OPC_TLBP = 0x08 | OPC_C0,
980 OPC_RFE = 0x10 | OPC_C0,
981 OPC_ERET = 0x18 | OPC_C0,
982 OPC_DERET = 0x1F | OPC_C0,
983 OPC_WAIT = 0x20 | OPC_C0,
984};
985
986#define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
987
988enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1000};
1001
1002#define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1013
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1022
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1031
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1040
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1047
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
1099#define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1100
1101enum {
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
1117 OPC_NMADD_D = 0x31 | OPC_CP3,
1118 OPC_NMADD_PS = 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS = 0x3E | OPC_CP3,
1122};
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160enum {
1161 MMI_OPC_CLASS_MMI = 0x1C << 26,
1162 MMI_OPC_SQ = 0x1F << 26,
1163};
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1188enum {
1189 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI,
1190 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI,
1191 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI,
1192 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI,
1193 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI,
1194 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI,
1195 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1196 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1197};
1198
1199
1200TCGv cpu_gpr[32], cpu_PC;
1201
1202
1203
1204
1205TCGv_i64 cpu_gpr_hi[32];
1206TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1207static TCGv cpu_dspctrl, btarget;
1208TCGv bcond;
1209static TCGv cpu_lladdr, cpu_llval;
1210static TCGv_i32 hflags;
1211TCGv_i32 fpu_fcr0, fpu_fcr31;
1212TCGv_i64 fpu_f64[32];
1213
1214#include "exec/gen-icount.h"
1215
1216#define DISAS_STOP DISAS_TARGET_0
1217#define DISAS_EXIT DISAS_TARGET_1
1218
1219static const char regnames_HI[][4] = {
1220 "HI0", "HI1", "HI2", "HI3",
1221};
1222
1223static const char regnames_LO[][4] = {
1224 "LO0", "LO1", "LO2", "LO3",
1225};
1226
1227
1228void gen_load_gpr(TCGv t, int reg)
1229{
1230 if (reg == 0) {
1231 tcg_gen_movi_tl(t, 0);
1232 } else {
1233 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1234 }
1235}
1236
1237void gen_store_gpr(TCGv t, int reg)
1238{
1239 if (reg != 0) {
1240 tcg_gen_mov_tl(cpu_gpr[reg], t);
1241 }
1242}
1243
1244#if defined(TARGET_MIPS64)
1245void gen_load_gpr_hi(TCGv_i64 t, int reg)
1246{
1247 if (reg == 0) {
1248 tcg_gen_movi_i64(t, 0);
1249 } else {
1250 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1251 }
1252}
1253
1254void gen_store_gpr_hi(TCGv_i64 t, int reg)
1255{
1256 if (reg != 0) {
1257 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1258 }
1259}
1260#endif
1261
1262
1263static inline void gen_load_srsgpr(int from, int to)
1264{
1265 TCGv t0 = tcg_temp_new();
1266
1267 if (from == 0) {
1268 tcg_gen_movi_tl(t0, 0);
1269 } else {
1270 TCGv_i32 t2 = tcg_temp_new_i32();
1271 TCGv_ptr addr = tcg_temp_new_ptr();
1272
1273 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1274 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1275 tcg_gen_andi_i32(t2, t2, 0xf);
1276 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1277 tcg_gen_ext_i32_ptr(addr, t2);
1278 tcg_gen_add_ptr(addr, cpu_env, addr);
1279
1280 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1281 tcg_temp_free_ptr(addr);
1282 tcg_temp_free_i32(t2);
1283 }
1284 gen_store_gpr(t0, to);
1285 tcg_temp_free(t0);
1286}
1287
1288static inline void gen_store_srsgpr(int from, int to)
1289{
1290 if (to != 0) {
1291 TCGv t0 = tcg_temp_new();
1292 TCGv_i32 t2 = tcg_temp_new_i32();
1293 TCGv_ptr addr = tcg_temp_new_ptr();
1294
1295 gen_load_gpr(t0, from);
1296 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1297 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1298 tcg_gen_andi_i32(t2, t2, 0xf);
1299 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1300 tcg_gen_ext_i32_ptr(addr, t2);
1301 tcg_gen_add_ptr(addr, cpu_env, addr);
1302
1303 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1304 tcg_temp_free_ptr(addr);
1305 tcg_temp_free_i32(t2);
1306 tcg_temp_free(t0);
1307 }
1308}
1309
1310
1311static inline void gen_save_pc(target_ulong pc)
1312{
1313 tcg_gen_movi_tl(cpu_PC, pc);
1314}
1315
1316static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1317{
1318 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1319 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1320 gen_save_pc(ctx->base.pc_next);
1321 ctx->saved_pc = ctx->base.pc_next;
1322 }
1323 if (ctx->hflags != ctx->saved_hflags) {
1324 tcg_gen_movi_i32(hflags, ctx->hflags);
1325 ctx->saved_hflags = ctx->hflags;
1326 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1327 case MIPS_HFLAG_BR:
1328 break;
1329 case MIPS_HFLAG_BC:
1330 case MIPS_HFLAG_BL:
1331 case MIPS_HFLAG_B:
1332 tcg_gen_movi_tl(btarget, ctx->btarget);
1333 break;
1334 }
1335 }
1336}
1337
1338static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1339{
1340 ctx->saved_hflags = ctx->hflags;
1341 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1342 case MIPS_HFLAG_BR:
1343 break;
1344 case MIPS_HFLAG_BC:
1345 case MIPS_HFLAG_BL:
1346 case MIPS_HFLAG_B:
1347 ctx->btarget = env->btarget;
1348 break;
1349 }
1350}
1351
1352void generate_exception_err(DisasContext *ctx, int excp, int err)
1353{
1354 save_cpu_state(ctx, 1);
1355 gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1356 tcg_constant_i32(err));
1357 ctx->base.is_jmp = DISAS_NORETURN;
1358}
1359
1360void generate_exception(DisasContext *ctx, int excp)
1361{
1362 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
1363}
1364
1365void generate_exception_end(DisasContext *ctx, int excp)
1366{
1367 generate_exception_err(ctx, excp, 0);
1368}
1369
1370void generate_exception_break(DisasContext *ctx, int code)
1371{
1372#ifdef CONFIG_USER_ONLY
1373
1374 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
1375 offsetof(CPUMIPSState, error_code));
1376#endif
1377 generate_exception_end(ctx, EXCP_BREAK);
1378}
1379
1380void gen_reserved_instruction(DisasContext *ctx)
1381{
1382 generate_exception_end(ctx, EXCP_RI);
1383}
1384
1385
1386void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1387{
1388 if (ctx->hflags & MIPS_HFLAG_FRE) {
1389 generate_exception(ctx, EXCP_RI);
1390 }
1391 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1392}
1393
1394void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1395{
1396 TCGv_i64 t64;
1397 if (ctx->hflags & MIPS_HFLAG_FRE) {
1398 generate_exception(ctx, EXCP_RI);
1399 }
1400 t64 = tcg_temp_new_i64();
1401 tcg_gen_extu_i32_i64(t64, t);
1402 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1403 tcg_temp_free_i64(t64);
1404}
1405
1406static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1407{
1408 if (ctx->hflags & MIPS_HFLAG_F64) {
1409 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1410 } else {
1411 gen_load_fpr32(ctx, t, reg | 1);
1412 }
1413}
1414
1415static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1416{
1417 if (ctx->hflags & MIPS_HFLAG_F64) {
1418 TCGv_i64 t64 = tcg_temp_new_i64();
1419 tcg_gen_extu_i32_i64(t64, t);
1420 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1421 tcg_temp_free_i64(t64);
1422 } else {
1423 gen_store_fpr32(ctx, t, reg | 1);
1424 }
1425}
1426
1427void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1428{
1429 if (ctx->hflags & MIPS_HFLAG_F64) {
1430 tcg_gen_mov_i64(t, fpu_f64[reg]);
1431 } else {
1432 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1433 }
1434}
1435
1436void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1437{
1438 if (ctx->hflags & MIPS_HFLAG_F64) {
1439 tcg_gen_mov_i64(fpu_f64[reg], t);
1440 } else {
1441 TCGv_i64 t0;
1442 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1443 t0 = tcg_temp_new_i64();
1444 tcg_gen_shri_i64(t0, t, 32);
1445 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1446 tcg_temp_free_i64(t0);
1447 }
1448}
1449
1450int get_fp_bit(int cc)
1451{
1452 if (cc) {
1453 return 24 + cc;
1454 } else {
1455 return 23;
1456 }
1457}
1458
1459
1460void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1461{
1462 tcg_gen_add_tl(ret, arg0, arg1);
1463
1464#if defined(TARGET_MIPS64)
1465 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1466 tcg_gen_ext32s_i64(ret, ret);
1467 }
1468#endif
1469}
1470
1471static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1472 target_long ofs)
1473{
1474 tcg_gen_addi_tl(ret, base, ofs);
1475
1476#if defined(TARGET_MIPS64)
1477 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1478 tcg_gen_ext32s_i64(ret, ret);
1479 }
1480#endif
1481}
1482
1483
1484static target_long addr_add(DisasContext *ctx, target_long base,
1485 target_long offset)
1486{
1487 target_long sum = base + offset;
1488
1489#if defined(TARGET_MIPS64)
1490 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1491 sum = (int32_t)sum;
1492 }
1493#endif
1494 return sum;
1495}
1496
1497
1498void gen_move_low32(TCGv ret, TCGv_i64 arg)
1499{
1500#if defined(TARGET_MIPS64)
1501 tcg_gen_ext32s_i64(ret, arg);
1502#else
1503 tcg_gen_extrl_i64_i32(ret, arg);
1504#endif
1505}
1506
1507
1508void gen_move_high32(TCGv ret, TCGv_i64 arg)
1509{
1510#if defined(TARGET_MIPS64)
1511 tcg_gen_sari_i64(ret, arg, 32);
1512#else
1513 tcg_gen_extrh_i64_i32(ret, arg);
1514#endif
1515}
1516
1517bool check_cp0_enabled(DisasContext *ctx)
1518{
1519 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1520 generate_exception_end(ctx, EXCP_CpU);
1521 return false;
1522 }
1523 return true;
1524}
1525
1526void check_cp1_enabled(DisasContext *ctx)
1527{
1528 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1529 generate_exception_err(ctx, EXCP_CpU, 1);
1530 }
1531}
1532
1533
1534
1535
1536
1537
1538void check_cop1x(DisasContext *ctx)
1539{
1540 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1541 gen_reserved_instruction(ctx);
1542 }
1543}
1544
1545
1546
1547
1548
1549void check_cp1_64bitmode(DisasContext *ctx)
1550{
1551 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1552 gen_reserved_instruction(ctx);
1553 }
1554}
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567void check_cp1_registers(DisasContext *ctx, int regs)
1568{
1569 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1570 gen_reserved_instruction(ctx);
1571 }
1572}
1573
1574
1575
1576
1577
1578static inline void check_dsp(DisasContext *ctx)
1579{
1580 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1581 if (ctx->insn_flags & ASE_DSP) {
1582 generate_exception_end(ctx, EXCP_DSPDIS);
1583 } else {
1584 gen_reserved_instruction(ctx);
1585 }
1586 }
1587}
1588
1589static inline void check_dsp_r2(DisasContext *ctx)
1590{
1591 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1592 if (ctx->insn_flags & ASE_DSP) {
1593 generate_exception_end(ctx, EXCP_DSPDIS);
1594 } else {
1595 gen_reserved_instruction(ctx);
1596 }
1597 }
1598}
1599
1600static inline void check_dsp_r3(DisasContext *ctx)
1601{
1602 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1603 if (ctx->insn_flags & ASE_DSP) {
1604 generate_exception_end(ctx, EXCP_DSPDIS);
1605 } else {
1606 gen_reserved_instruction(ctx);
1607 }
1608 }
1609}
1610
1611
1612
1613
1614
1615void check_insn(DisasContext *ctx, uint64_t flags)
1616{
1617 if (unlikely(!(ctx->insn_flags & flags))) {
1618 gen_reserved_instruction(ctx);
1619 }
1620}
1621
1622
1623
1624
1625
1626
1627static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1628{
1629 if (unlikely(ctx->insn_flags & flags)) {
1630 gen_reserved_instruction(ctx);
1631 }
1632}
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1643{
1644#ifndef CONFIG_USER_ONLY
1645 check_insn_opc_removed(ctx, flags);
1646#endif
1647}
1648
1649
1650
1651
1652
1653static inline void check_ps(DisasContext *ctx)
1654{
1655 if (unlikely(!ctx->ps)) {
1656 generate_exception(ctx, EXCP_RI);
1657 }
1658 check_cp1_64bitmode(ctx);
1659}
1660
1661
1662
1663
1664
1665void check_mips_64(DisasContext *ctx)
1666{
1667 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1668 gen_reserved_instruction(ctx);
1669 }
1670}
1671
1672#ifndef CONFIG_USER_ONLY
1673static inline void check_mvh(DisasContext *ctx)
1674{
1675 if (unlikely(!ctx->mvh)) {
1676 generate_exception(ctx, EXCP_RI);
1677 }
1678}
1679#endif
1680
1681
1682
1683
1684
1685static inline void check_xnp(DisasContext *ctx)
1686{
1687 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1688 gen_reserved_instruction(ctx);
1689 }
1690}
1691
1692#ifndef CONFIG_USER_ONLY
1693
1694
1695
1696
1697static inline void check_pw(DisasContext *ctx)
1698{
1699 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1700 gen_reserved_instruction(ctx);
1701 }
1702}
1703#endif
1704
1705
1706
1707
1708
1709static inline void check_mt(DisasContext *ctx)
1710{
1711 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1712 gen_reserved_instruction(ctx);
1713 }
1714}
1715
1716#ifndef CONFIG_USER_ONLY
1717
1718
1719
1720
1721
1722
1723static inline void check_cp0_mt(DisasContext *ctx)
1724{
1725 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1726 generate_exception_end(ctx, EXCP_CpU);
1727 } else {
1728 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1729 gen_reserved_instruction(ctx);
1730 }
1731 }
1732}
1733#endif
1734
1735
1736
1737
1738
1739static inline void check_nms(DisasContext *ctx)
1740{
1741 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1742 gen_reserved_instruction(ctx);
1743 }
1744}
1745
1746
1747
1748
1749
1750
1751static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1752{
1753 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1754 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1755 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1756 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1757 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1758 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1759 gen_reserved_instruction(ctx);
1760 }
1761}
1762
1763
1764
1765
1766
1767static inline void check_eva(DisasContext *ctx)
1768{
1769 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1770 gen_reserved_instruction(ctx);
1771 }
1772}
1773
1774
1775
1776
1777
1778
1779
1780
1781#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1782#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1783#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1784static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1785 int ft, int fs, int cc) \
1786{ \
1787 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1788 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1789 switch (ifmt) { \
1790 case FMT_PS: \
1791 check_ps(ctx); \
1792 break; \
1793 case FMT_D: \
1794 if (abs) { \
1795 check_cop1x(ctx); \
1796 } \
1797 check_cp1_registers(ctx, fs | ft); \
1798 break; \
1799 case FMT_S: \
1800 if (abs) { \
1801 check_cop1x(ctx); \
1802 } \
1803 break; \
1804 } \
1805 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1806 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1807 switch (n) { \
1808 case 0: \
1809 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1810 break; \
1811 case 1: \
1812 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1813 break; \
1814 case 2: \
1815 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1816 break; \
1817 case 3: \
1818 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1819 break; \
1820 case 4: \
1821 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1822 break; \
1823 case 5: \
1824 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1825 break; \
1826 case 6: \
1827 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1828 break; \
1829 case 7: \
1830 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1831 break; \
1832 case 8: \
1833 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1834 break; \
1835 case 9: \
1836 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1837 break; \
1838 case 10: \
1839 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1840 break; \
1841 case 11: \
1842 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1843 break; \
1844 case 12: \
1845 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1846 break; \
1847 case 13: \
1848 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1849 break; \
1850 case 14: \
1851 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1852 break; \
1853 case 15: \
1854 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1855 break; \
1856 default: \
1857 abort(); \
1858 } \
1859 tcg_temp_free_i##bits(fp0); \
1860 tcg_temp_free_i##bits(fp1); \
1861}
1862
1863FOP_CONDS(, 0, d, FMT_D, 64)
1864FOP_CONDS(abs, 1, d, FMT_D, 64)
1865FOP_CONDS(, 0, s, FMT_S, 32)
1866FOP_CONDS(abs, 1, s, FMT_S, 32)
1867FOP_CONDS(, 0, ps, FMT_PS, 64)
1868FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1869#undef FOP_CONDS
1870
1871#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1872static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1873 int ft, int fs, int fd) \
1874{ \
1875 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1876 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1877 if (ifmt == FMT_D) { \
1878 check_cp1_registers(ctx, fs | ft | fd); \
1879 } \
1880 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1881 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1882 switch (n) { \
1883 case 0: \
1884 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1885 break; \
1886 case 1: \
1887 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1888 break; \
1889 case 2: \
1890 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1891 break; \
1892 case 3: \
1893 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1894 break; \
1895 case 4: \
1896 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1897 break; \
1898 case 5: \
1899 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1900 break; \
1901 case 6: \
1902 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1903 break; \
1904 case 7: \
1905 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1906 break; \
1907 case 8: \
1908 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1909 break; \
1910 case 9: \
1911 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1912 break; \
1913 case 10: \
1914 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1915 break; \
1916 case 11: \
1917 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1918 break; \
1919 case 12: \
1920 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1921 break; \
1922 case 13: \
1923 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1924 break; \
1925 case 14: \
1926 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1927 break; \
1928 case 15: \
1929 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1930 break; \
1931 case 17: \
1932 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1933 break; \
1934 case 18: \
1935 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1936 break; \
1937 case 19: \
1938 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1939 break; \
1940 case 25: \
1941 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1942 break; \
1943 case 26: \
1944 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1945 break; \
1946 case 27: \
1947 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1948 break; \
1949 default: \
1950 abort(); \
1951 } \
1952 STORE; \
1953 tcg_temp_free_i ## bits(fp0); \
1954 tcg_temp_free_i ## bits(fp1); \
1955}
1956
1957FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1958FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1959#undef FOP_CONDNS
1960#undef gen_ldcmp_fpr32
1961#undef gen_ldcmp_fpr64
1962
1963
1964#ifdef CONFIG_USER_ONLY
1965#define OP_LD_ATOMIC(insn, fname) \
1966static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1967 DisasContext *ctx) \
1968{ \
1969 TCGv t0 = tcg_temp_new(); \
1970 tcg_gen_mov_tl(t0, arg1); \
1971 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1972 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1973 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1974 tcg_temp_free(t0); \
1975}
1976#else
1977#define OP_LD_ATOMIC(insn, fname) \
1978static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1979 DisasContext *ctx) \
1980{ \
1981 gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \
1982}
1983#endif
1984OP_LD_ATOMIC(ll, ld32s);
1985#if defined(TARGET_MIPS64)
1986OP_LD_ATOMIC(lld, ld64);
1987#endif
1988#undef OP_LD_ATOMIC
1989
1990void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1991{
1992 if (base == 0) {
1993 tcg_gen_movi_tl(addr, offset);
1994 } else if (offset == 0) {
1995 gen_load_gpr(addr, base);
1996 } else {
1997 tcg_gen_movi_tl(addr, offset);
1998 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1999 }
2000}
2001
2002static target_ulong pc_relative_pc(DisasContext *ctx)
2003{
2004 target_ulong pc = ctx->base.pc_next;
2005
2006 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2007 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2008
2009 pc -= branch_bytes;
2010 }
2011
2012 pc &= ~(target_ulong)3;
2013 return pc;
2014}
2015
2016
2017static void gen_ld(DisasContext *ctx, uint32_t opc,
2018 int rt, int base, int offset)
2019{
2020 TCGv t0, t1, t2;
2021 int mem_idx = ctx->mem_idx;
2022
2023 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2024 INSN_LOONGSON3A)) {
2025
2026
2027
2028
2029
2030 return;
2031 }
2032
2033 t0 = tcg_temp_new();
2034 gen_base_offset_addr(ctx, t0, base, offset);
2035
2036 switch (opc) {
2037#if defined(TARGET_MIPS64)
2038 case OPC_LWU:
2039 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2040 ctx->default_tcg_memop_mask);
2041 gen_store_gpr(t0, rt);
2042 break;
2043 case OPC_LD:
2044 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ |
2045 ctx->default_tcg_memop_mask);
2046 gen_store_gpr(t0, rt);
2047 break;
2048 case OPC_LLD:
2049 case R6_OPC_LLD:
2050 op_ld_lld(t0, t0, mem_idx, ctx);
2051 gen_store_gpr(t0, rt);
2052 break;
2053 case OPC_LDL:
2054 t1 = tcg_temp_new();
2055
2056
2057
2058
2059 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2060 tcg_gen_andi_tl(t1, t0, 7);
2061 if (!cpu_is_bigendian(ctx)) {
2062 tcg_gen_xori_tl(t1, t1, 7);
2063 }
2064 tcg_gen_shli_tl(t1, t1, 3);
2065 tcg_gen_andi_tl(t0, t0, ~7);
2066 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2067 tcg_gen_shl_tl(t0, t0, t1);
2068 t2 = tcg_const_tl(-1);
2069 tcg_gen_shl_tl(t2, t2, t1);
2070 gen_load_gpr(t1, rt);
2071 tcg_gen_andc_tl(t1, t1, t2);
2072 tcg_temp_free(t2);
2073 tcg_gen_or_tl(t0, t0, t1);
2074 tcg_temp_free(t1);
2075 gen_store_gpr(t0, rt);
2076 break;
2077 case OPC_LDR:
2078 t1 = tcg_temp_new();
2079
2080
2081
2082
2083 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2084 tcg_gen_andi_tl(t1, t0, 7);
2085 if (cpu_is_bigendian(ctx)) {
2086 tcg_gen_xori_tl(t1, t1, 7);
2087 }
2088 tcg_gen_shli_tl(t1, t1, 3);
2089 tcg_gen_andi_tl(t0, t0, ~7);
2090 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2091 tcg_gen_shr_tl(t0, t0, t1);
2092 tcg_gen_xori_tl(t1, t1, 63);
2093 t2 = tcg_const_tl(0xfffffffffffffffeull);
2094 tcg_gen_shl_tl(t2, t2, t1);
2095 gen_load_gpr(t1, rt);
2096 tcg_gen_and_tl(t1, t1, t2);
2097 tcg_temp_free(t2);
2098 tcg_gen_or_tl(t0, t0, t1);
2099 tcg_temp_free(t1);
2100 gen_store_gpr(t0, rt);
2101 break;
2102 case OPC_LDPC:
2103 t1 = tcg_const_tl(pc_relative_pc(ctx));
2104 gen_op_addr_add(ctx, t0, t0, t1);
2105 tcg_temp_free(t1);
2106 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2107 gen_store_gpr(t0, rt);
2108 break;
2109#endif
2110 case OPC_LWPC:
2111 t1 = tcg_const_tl(pc_relative_pc(ctx));
2112 gen_op_addr_add(ctx, t0, t0, t1);
2113 tcg_temp_free(t1);
2114 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2115 gen_store_gpr(t0, rt);
2116 break;
2117 case OPC_LWE:
2118 mem_idx = MIPS_HFLAG_UM;
2119
2120 case OPC_LW:
2121 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2122 ctx->default_tcg_memop_mask);
2123 gen_store_gpr(t0, rt);
2124 break;
2125 case OPC_LHE:
2126 mem_idx = MIPS_HFLAG_UM;
2127
2128 case OPC_LH:
2129 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2130 ctx->default_tcg_memop_mask);
2131 gen_store_gpr(t0, rt);
2132 break;
2133 case OPC_LHUE:
2134 mem_idx = MIPS_HFLAG_UM;
2135
2136 case OPC_LHU:
2137 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2138 ctx->default_tcg_memop_mask);
2139 gen_store_gpr(t0, rt);
2140 break;
2141 case OPC_LBE:
2142 mem_idx = MIPS_HFLAG_UM;
2143
2144 case OPC_LB:
2145 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2146 gen_store_gpr(t0, rt);
2147 break;
2148 case OPC_LBUE:
2149 mem_idx = MIPS_HFLAG_UM;
2150
2151 case OPC_LBU:
2152 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2153 gen_store_gpr(t0, rt);
2154 break;
2155 case OPC_LWLE:
2156 mem_idx = MIPS_HFLAG_UM;
2157
2158 case OPC_LWL:
2159 t1 = tcg_temp_new();
2160
2161
2162
2163
2164 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2165 tcg_gen_andi_tl(t1, t0, 3);
2166 if (!cpu_is_bigendian(ctx)) {
2167 tcg_gen_xori_tl(t1, t1, 3);
2168 }
2169 tcg_gen_shli_tl(t1, t1, 3);
2170 tcg_gen_andi_tl(t0, t0, ~3);
2171 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2172 tcg_gen_shl_tl(t0, t0, t1);
2173 t2 = tcg_const_tl(-1);
2174 tcg_gen_shl_tl(t2, t2, t1);
2175 gen_load_gpr(t1, rt);
2176 tcg_gen_andc_tl(t1, t1, t2);
2177 tcg_temp_free(t2);
2178 tcg_gen_or_tl(t0, t0, t1);
2179 tcg_temp_free(t1);
2180 tcg_gen_ext32s_tl(t0, t0);
2181 gen_store_gpr(t0, rt);
2182 break;
2183 case OPC_LWRE:
2184 mem_idx = MIPS_HFLAG_UM;
2185
2186 case OPC_LWR:
2187 t1 = tcg_temp_new();
2188
2189
2190
2191
2192 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2193 tcg_gen_andi_tl(t1, t0, 3);
2194 if (cpu_is_bigendian(ctx)) {
2195 tcg_gen_xori_tl(t1, t1, 3);
2196 }
2197 tcg_gen_shli_tl(t1, t1, 3);
2198 tcg_gen_andi_tl(t0, t0, ~3);
2199 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2200 tcg_gen_shr_tl(t0, t0, t1);
2201 tcg_gen_xori_tl(t1, t1, 31);
2202 t2 = tcg_const_tl(0xfffffffeull);
2203 tcg_gen_shl_tl(t2, t2, t1);
2204 gen_load_gpr(t1, rt);
2205 tcg_gen_and_tl(t1, t1, t2);
2206 tcg_temp_free(t2);
2207 tcg_gen_or_tl(t0, t0, t1);
2208 tcg_temp_free(t1);
2209 tcg_gen_ext32s_tl(t0, t0);
2210 gen_store_gpr(t0, rt);
2211 break;
2212 case OPC_LLE:
2213 mem_idx = MIPS_HFLAG_UM;
2214
2215 case OPC_LL:
2216 case R6_OPC_LL:
2217 op_ld_ll(t0, t0, mem_idx, ctx);
2218 gen_store_gpr(t0, rt);
2219 break;
2220 }
2221 tcg_temp_free(t0);
2222}
2223
2224
2225static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2226 int base, int offset)
2227{
2228 TCGv t0 = tcg_temp_new();
2229 TCGv t1 = tcg_temp_new();
2230 int mem_idx = ctx->mem_idx;
2231
2232 gen_base_offset_addr(ctx, t0, base, offset);
2233 gen_load_gpr(t1, rt);
2234 switch (opc) {
2235#if defined(TARGET_MIPS64)
2236 case OPC_SD:
2237 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ |
2238 ctx->default_tcg_memop_mask);
2239 break;
2240 case OPC_SDL:
2241 gen_helper_0e2i(sdl, t1, t0, mem_idx);
2242 break;
2243 case OPC_SDR:
2244 gen_helper_0e2i(sdr, t1, t0, mem_idx);
2245 break;
2246#endif
2247 case OPC_SWE:
2248 mem_idx = MIPS_HFLAG_UM;
2249
2250 case OPC_SW:
2251 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2252 ctx->default_tcg_memop_mask);
2253 break;
2254 case OPC_SHE:
2255 mem_idx = MIPS_HFLAG_UM;
2256
2257 case OPC_SH:
2258 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2259 ctx->default_tcg_memop_mask);
2260 break;
2261 case OPC_SBE:
2262 mem_idx = MIPS_HFLAG_UM;
2263
2264 case OPC_SB:
2265 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2266 break;
2267 case OPC_SWLE:
2268 mem_idx = MIPS_HFLAG_UM;
2269
2270 case OPC_SWL:
2271 gen_helper_0e2i(swl, t1, t0, mem_idx);
2272 break;
2273 case OPC_SWRE:
2274 mem_idx = MIPS_HFLAG_UM;
2275
2276 case OPC_SWR:
2277 gen_helper_0e2i(swr, t1, t0, mem_idx);
2278 break;
2279 }
2280 tcg_temp_free(t0);
2281 tcg_temp_free(t1);
2282}
2283
2284
2285
2286static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2287 MemOp tcg_mo, bool eva)
2288{
2289 TCGv addr, t0, val;
2290 TCGLabel *l1 = gen_new_label();
2291 TCGLabel *done = gen_new_label();
2292
2293 t0 = tcg_temp_new();
2294 addr = tcg_temp_new();
2295
2296 gen_base_offset_addr(ctx, addr, base, offset);
2297 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2298 tcg_temp_free(addr);
2299 tcg_gen_movi_tl(t0, 0);
2300 gen_store_gpr(t0, rt);
2301 tcg_gen_br(done);
2302
2303 gen_set_label(l1);
2304
2305 val = tcg_temp_new();
2306 gen_load_gpr(val, rt);
2307 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2308 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2309 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2310 gen_store_gpr(t0, rt);
2311 tcg_temp_free(val);
2312
2313 gen_set_label(done);
2314 tcg_temp_free(t0);
2315}
2316
2317
2318static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2319 TCGv t0)
2320{
2321
2322
2323
2324
2325 switch (opc) {
2326 case OPC_LWC1:
2327 {
2328 TCGv_i32 fp0 = tcg_temp_new_i32();
2329 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2330 ctx->default_tcg_memop_mask);
2331 gen_store_fpr32(ctx, fp0, ft);
2332 tcg_temp_free_i32(fp0);
2333 }
2334 break;
2335 case OPC_SWC1:
2336 {
2337 TCGv_i32 fp0 = tcg_temp_new_i32();
2338 gen_load_fpr32(ctx, fp0, ft);
2339 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2340 ctx->default_tcg_memop_mask);
2341 tcg_temp_free_i32(fp0);
2342 }
2343 break;
2344 case OPC_LDC1:
2345 {
2346 TCGv_i64 fp0 = tcg_temp_new_i64();
2347 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2348 ctx->default_tcg_memop_mask);
2349 gen_store_fpr64(ctx, fp0, ft);
2350 tcg_temp_free_i64(fp0);
2351 }
2352 break;
2353 case OPC_SDC1:
2354 {
2355 TCGv_i64 fp0 = tcg_temp_new_i64();
2356 gen_load_fpr64(ctx, fp0, ft);
2357 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2358 ctx->default_tcg_memop_mask);
2359 tcg_temp_free_i64(fp0);
2360 }
2361 break;
2362 default:
2363 MIPS_INVAL("flt_ldst");
2364 gen_reserved_instruction(ctx);
2365 break;
2366 }
2367}
2368
2369static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2370 int rs, int16_t imm)
2371{
2372 TCGv t0 = tcg_temp_new();
2373
2374 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2375 check_cp1_enabled(ctx);
2376 switch (op) {
2377 case OPC_LDC1:
2378 case OPC_SDC1:
2379 check_insn(ctx, ISA_MIPS2);
2380
2381 default:
2382 gen_base_offset_addr(ctx, t0, rs, imm);
2383 gen_flt_ldst(ctx, op, rt, t0);
2384 }
2385 } else {
2386 generate_exception_err(ctx, EXCP_CpU, 1);
2387 }
2388 tcg_temp_free(t0);
2389}
2390
2391
2392static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2393 int rt, int rs, int imm)
2394{
2395 target_ulong uimm = (target_long)imm;
2396
2397 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2398
2399
2400
2401
2402 return;
2403 }
2404 switch (opc) {
2405 case OPC_ADDI:
2406 {
2407 TCGv t0 = tcg_temp_local_new();
2408 TCGv t1 = tcg_temp_new();
2409 TCGv t2 = tcg_temp_new();
2410 TCGLabel *l1 = gen_new_label();
2411
2412 gen_load_gpr(t1, rs);
2413 tcg_gen_addi_tl(t0, t1, uimm);
2414 tcg_gen_ext32s_tl(t0, t0);
2415
2416 tcg_gen_xori_tl(t1, t1, ~uimm);
2417 tcg_gen_xori_tl(t2, t0, uimm);
2418 tcg_gen_and_tl(t1, t1, t2);
2419 tcg_temp_free(t2);
2420 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2421 tcg_temp_free(t1);
2422
2423 generate_exception(ctx, EXCP_OVERFLOW);
2424 gen_set_label(l1);
2425 tcg_gen_ext32s_tl(t0, t0);
2426 gen_store_gpr(t0, rt);
2427 tcg_temp_free(t0);
2428 }
2429 break;
2430 case OPC_ADDIU:
2431 if (rs != 0) {
2432 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2433 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2434 } else {
2435 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2436 }
2437 break;
2438#if defined(TARGET_MIPS64)
2439 case OPC_DADDI:
2440 {
2441 TCGv t0 = tcg_temp_local_new();
2442 TCGv t1 = tcg_temp_new();
2443 TCGv t2 = tcg_temp_new();
2444 TCGLabel *l1 = gen_new_label();
2445
2446 gen_load_gpr(t1, rs);
2447 tcg_gen_addi_tl(t0, t1, uimm);
2448
2449 tcg_gen_xori_tl(t1, t1, ~uimm);
2450 tcg_gen_xori_tl(t2, t0, uimm);
2451 tcg_gen_and_tl(t1, t1, t2);
2452 tcg_temp_free(t2);
2453 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2454 tcg_temp_free(t1);
2455
2456 generate_exception(ctx, EXCP_OVERFLOW);
2457 gen_set_label(l1);
2458 gen_store_gpr(t0, rt);
2459 tcg_temp_free(t0);
2460 }
2461 break;
2462 case OPC_DADDIU:
2463 if (rs != 0) {
2464 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2465 } else {
2466 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2467 }
2468 break;
2469#endif
2470 }
2471}
2472
2473
2474static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2475 int rt, int rs, int16_t imm)
2476{
2477 target_ulong uimm;
2478
2479 if (rt == 0) {
2480
2481 return;
2482 }
2483 uimm = (uint16_t)imm;
2484 switch (opc) {
2485 case OPC_ANDI:
2486 if (likely(rs != 0)) {
2487 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2488 } else {
2489 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2490 }
2491 break;
2492 case OPC_ORI:
2493 if (rs != 0) {
2494 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2495 } else {
2496 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2497 }
2498 break;
2499 case OPC_XORI:
2500 if (likely(rs != 0)) {
2501 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2502 } else {
2503 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2504 }
2505 break;
2506 case OPC_LUI:
2507 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2508
2509 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2510 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2511 } else {
2512 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2513 }
2514 break;
2515
2516 default:
2517 break;
2518 }
2519}
2520
2521
2522static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2523 int rt, int rs, int16_t imm)
2524{
2525 target_ulong uimm = (target_long)imm;
2526 TCGv t0;
2527
2528 if (rt == 0) {
2529
2530 return;
2531 }
2532 t0 = tcg_temp_new();
2533 gen_load_gpr(t0, rs);
2534 switch (opc) {
2535 case OPC_SLTI:
2536 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2537 break;
2538 case OPC_SLTIU:
2539 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2540 break;
2541 }
2542 tcg_temp_free(t0);
2543}
2544
2545
2546static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2547 int rt, int rs, int16_t imm)
2548{
2549 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2550 TCGv t0;
2551
2552 if (rt == 0) {
2553
2554 return;
2555 }
2556
2557 t0 = tcg_temp_new();
2558 gen_load_gpr(t0, rs);
2559 switch (opc) {
2560 case OPC_SLL:
2561 tcg_gen_shli_tl(t0, t0, uimm);
2562 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2563 break;
2564 case OPC_SRA:
2565 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2566 break;
2567 case OPC_SRL:
2568 if (uimm != 0) {
2569 tcg_gen_ext32u_tl(t0, t0);
2570 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2571 } else {
2572 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2573 }
2574 break;
2575 case OPC_ROTR:
2576 if (uimm != 0) {
2577 TCGv_i32 t1 = tcg_temp_new_i32();
2578
2579 tcg_gen_trunc_tl_i32(t1, t0);
2580 tcg_gen_rotri_i32(t1, t1, uimm);
2581 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2582 tcg_temp_free_i32(t1);
2583 } else {
2584 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2585 }
2586 break;
2587#if defined(TARGET_MIPS64)
2588 case OPC_DSLL:
2589 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2590 break;
2591 case OPC_DSRA:
2592 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2593 break;
2594 case OPC_DSRL:
2595 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2596 break;
2597 case OPC_DROTR:
2598 if (uimm != 0) {
2599 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2600 } else {
2601 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2602 }
2603 break;
2604 case OPC_DSLL32:
2605 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2606 break;
2607 case OPC_DSRA32:
2608 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2609 break;
2610 case OPC_DSRL32:
2611 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2612 break;
2613 case OPC_DROTR32:
2614 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2615 break;
2616#endif
2617 }
2618 tcg_temp_free(t0);
2619}
2620
2621
2622static void gen_arith(DisasContext *ctx, uint32_t opc,
2623 int rd, int rs, int rt)
2624{
2625 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2626 && opc != OPC_DADD && opc != OPC_DSUB) {
2627
2628
2629
2630
2631 return;
2632 }
2633
2634 switch (opc) {
2635 case OPC_ADD:
2636 {
2637 TCGv t0 = tcg_temp_local_new();
2638 TCGv t1 = tcg_temp_new();
2639 TCGv t2 = tcg_temp_new();
2640 TCGLabel *l1 = gen_new_label();
2641
2642 gen_load_gpr(t1, rs);
2643 gen_load_gpr(t2, rt);
2644 tcg_gen_add_tl(t0, t1, t2);
2645 tcg_gen_ext32s_tl(t0, t0);
2646 tcg_gen_xor_tl(t1, t1, t2);
2647 tcg_gen_xor_tl(t2, t0, t2);
2648 tcg_gen_andc_tl(t1, t2, t1);
2649 tcg_temp_free(t2);
2650 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2651 tcg_temp_free(t1);
2652
2653 generate_exception(ctx, EXCP_OVERFLOW);
2654 gen_set_label(l1);
2655 gen_store_gpr(t0, rd);
2656 tcg_temp_free(t0);
2657 }
2658 break;
2659 case OPC_ADDU:
2660 if (rs != 0 && rt != 0) {
2661 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2662 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2663 } else if (rs == 0 && rt != 0) {
2664 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2665 } else if (rs != 0 && rt == 0) {
2666 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2667 } else {
2668 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2669 }
2670 break;
2671 case OPC_SUB:
2672 {
2673 TCGv t0 = tcg_temp_local_new();
2674 TCGv t1 = tcg_temp_new();
2675 TCGv t2 = tcg_temp_new();
2676 TCGLabel *l1 = gen_new_label();
2677
2678 gen_load_gpr(t1, rs);
2679 gen_load_gpr(t2, rt);
2680 tcg_gen_sub_tl(t0, t1, t2);
2681 tcg_gen_ext32s_tl(t0, t0);
2682 tcg_gen_xor_tl(t2, t1, t2);
2683 tcg_gen_xor_tl(t1, t0, t1);
2684 tcg_gen_and_tl(t1, t1, t2);
2685 tcg_temp_free(t2);
2686 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2687 tcg_temp_free(t1);
2688
2689
2690
2691
2692 generate_exception(ctx, EXCP_OVERFLOW);
2693 gen_set_label(l1);
2694 gen_store_gpr(t0, rd);
2695 tcg_temp_free(t0);
2696 }
2697 break;
2698 case OPC_SUBU:
2699 if (rs != 0 && rt != 0) {
2700 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2701 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2702 } else if (rs == 0 && rt != 0) {
2703 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2704 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2705 } else if (rs != 0 && rt == 0) {
2706 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2707 } else {
2708 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2709 }
2710 break;
2711#if defined(TARGET_MIPS64)
2712 case OPC_DADD:
2713 {
2714 TCGv t0 = tcg_temp_local_new();
2715 TCGv t1 = tcg_temp_new();
2716 TCGv t2 = tcg_temp_new();
2717 TCGLabel *l1 = gen_new_label();
2718
2719 gen_load_gpr(t1, rs);
2720 gen_load_gpr(t2, rt);
2721 tcg_gen_add_tl(t0, t1, t2);
2722 tcg_gen_xor_tl(t1, t1, t2);
2723 tcg_gen_xor_tl(t2, t0, t2);
2724 tcg_gen_andc_tl(t1, t2, t1);
2725 tcg_temp_free(t2);
2726 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2727 tcg_temp_free(t1);
2728
2729 generate_exception(ctx, EXCP_OVERFLOW);
2730 gen_set_label(l1);
2731 gen_store_gpr(t0, rd);
2732 tcg_temp_free(t0);
2733 }
2734 break;
2735 case OPC_DADDU:
2736 if (rs != 0 && rt != 0) {
2737 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2738 } else if (rs == 0 && rt != 0) {
2739 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2740 } else if (rs != 0 && rt == 0) {
2741 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2742 } else {
2743 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2744 }
2745 break;
2746 case OPC_DSUB:
2747 {
2748 TCGv t0 = tcg_temp_local_new();
2749 TCGv t1 = tcg_temp_new();
2750 TCGv t2 = tcg_temp_new();
2751 TCGLabel *l1 = gen_new_label();
2752
2753 gen_load_gpr(t1, rs);
2754 gen_load_gpr(t2, rt);
2755 tcg_gen_sub_tl(t0, t1, t2);
2756 tcg_gen_xor_tl(t2, t1, t2);
2757 tcg_gen_xor_tl(t1, t0, t1);
2758 tcg_gen_and_tl(t1, t1, t2);
2759 tcg_temp_free(t2);
2760 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2761 tcg_temp_free(t1);
2762
2763
2764
2765
2766 generate_exception(ctx, EXCP_OVERFLOW);
2767 gen_set_label(l1);
2768 gen_store_gpr(t0, rd);
2769 tcg_temp_free(t0);
2770 }
2771 break;
2772 case OPC_DSUBU:
2773 if (rs != 0 && rt != 0) {
2774 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2775 } else if (rs == 0 && rt != 0) {
2776 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2777 } else if (rs != 0 && rt == 0) {
2778 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2779 } else {
2780 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2781 }
2782 break;
2783#endif
2784 case OPC_MUL:
2785 if (likely(rs != 0 && rt != 0)) {
2786 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2787 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2788 } else {
2789 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2790 }
2791 break;
2792 }
2793}
2794
2795
2796static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2797 int rd, int rs, int rt)
2798{
2799 TCGv t0, t1, t2;
2800
2801 if (rd == 0) {
2802
2803 return;
2804 }
2805
2806 t0 = tcg_temp_new();
2807 gen_load_gpr(t0, rt);
2808 t1 = tcg_const_tl(0);
2809 t2 = tcg_temp_new();
2810 gen_load_gpr(t2, rs);
2811 switch (opc) {
2812 case OPC_MOVN:
2813 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2814 break;
2815 case OPC_MOVZ:
2816 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2817 break;
2818 case OPC_SELNEZ:
2819 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2820 break;
2821 case OPC_SELEQZ:
2822 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2823 break;
2824 }
2825 tcg_temp_free(t2);
2826 tcg_temp_free(t1);
2827 tcg_temp_free(t0);
2828}
2829
2830
2831static void gen_logic(DisasContext *ctx, uint32_t opc,
2832 int rd, int rs, int rt)
2833{
2834 if (rd == 0) {
2835
2836 return;
2837 }
2838
2839 switch (opc) {
2840 case OPC_AND:
2841 if (likely(rs != 0 && rt != 0)) {
2842 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2843 } else {
2844 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2845 }
2846 break;
2847 case OPC_NOR:
2848 if (rs != 0 && rt != 0) {
2849 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2850 } else if (rs == 0 && rt != 0) {
2851 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2852 } else if (rs != 0 && rt == 0) {
2853 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2854 } else {
2855 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2856 }
2857 break;
2858 case OPC_OR:
2859 if (likely(rs != 0 && rt != 0)) {
2860 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2861 } else if (rs == 0 && rt != 0) {
2862 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2863 } else if (rs != 0 && rt == 0) {
2864 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2865 } else {
2866 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2867 }
2868 break;
2869 case OPC_XOR:
2870 if (likely(rs != 0 && rt != 0)) {
2871 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2872 } else if (rs == 0 && rt != 0) {
2873 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2874 } else if (rs != 0 && rt == 0) {
2875 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2876 } else {
2877 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2878 }
2879 break;
2880 }
2881}
2882
2883
2884static void gen_slt(DisasContext *ctx, uint32_t opc,
2885 int rd, int rs, int rt)
2886{
2887 TCGv t0, t1;
2888
2889 if (rd == 0) {
2890
2891 return;
2892 }
2893
2894 t0 = tcg_temp_new();
2895 t1 = tcg_temp_new();
2896 gen_load_gpr(t0, rs);
2897 gen_load_gpr(t1, rt);
2898 switch (opc) {
2899 case OPC_SLT:
2900 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2901 break;
2902 case OPC_SLTU:
2903 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2904 break;
2905 }
2906 tcg_temp_free(t0);
2907 tcg_temp_free(t1);
2908}
2909
2910
2911static void gen_shift(DisasContext *ctx, uint32_t opc,
2912 int rd, int rs, int rt)
2913{
2914 TCGv t0, t1;
2915
2916 if (rd == 0) {
2917
2918
2919
2920
2921 return;
2922 }
2923
2924 t0 = tcg_temp_new();
2925 t1 = tcg_temp_new();
2926 gen_load_gpr(t0, rs);
2927 gen_load_gpr(t1, rt);
2928 switch (opc) {
2929 case OPC_SLLV:
2930 tcg_gen_andi_tl(t0, t0, 0x1f);
2931 tcg_gen_shl_tl(t0, t1, t0);
2932 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2933 break;
2934 case OPC_SRAV:
2935 tcg_gen_andi_tl(t0, t0, 0x1f);
2936 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2937 break;
2938 case OPC_SRLV:
2939 tcg_gen_ext32u_tl(t1, t1);
2940 tcg_gen_andi_tl(t0, t0, 0x1f);
2941 tcg_gen_shr_tl(t0, t1, t0);
2942 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2943 break;
2944 case OPC_ROTRV:
2945 {
2946 TCGv_i32 t2 = tcg_temp_new_i32();
2947 TCGv_i32 t3 = tcg_temp_new_i32();
2948
2949 tcg_gen_trunc_tl_i32(t2, t0);
2950 tcg_gen_trunc_tl_i32(t3, t1);
2951 tcg_gen_andi_i32(t2, t2, 0x1f);
2952 tcg_gen_rotr_i32(t2, t3, t2);
2953 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2954 tcg_temp_free_i32(t2);
2955 tcg_temp_free_i32(t3);
2956 }
2957 break;
2958#if defined(TARGET_MIPS64)
2959 case OPC_DSLLV:
2960 tcg_gen_andi_tl(t0, t0, 0x3f);
2961 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2962 break;
2963 case OPC_DSRAV:
2964 tcg_gen_andi_tl(t0, t0, 0x3f);
2965 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2966 break;
2967 case OPC_DSRLV:
2968 tcg_gen_andi_tl(t0, t0, 0x3f);
2969 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2970 break;
2971 case OPC_DROTRV:
2972 tcg_gen_andi_tl(t0, t0, 0x3f);
2973 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2974 break;
2975#endif
2976 }
2977 tcg_temp_free(t0);
2978 tcg_temp_free(t1);
2979}
2980
2981
2982static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2983{
2984 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2985
2986 return;
2987 }
2988
2989 if (acc != 0) {
2990 check_dsp(ctx);
2991 }
2992
2993 switch (opc) {
2994 case OPC_MFHI:
2995#if defined(TARGET_MIPS64)
2996 if (acc != 0) {
2997 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2998 } else
2999#endif
3000 {
3001 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3002 }
3003 break;
3004 case OPC_MFLO:
3005#if defined(TARGET_MIPS64)
3006 if (acc != 0) {
3007 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3008 } else
3009#endif
3010 {
3011 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3012 }
3013 break;
3014 case OPC_MTHI:
3015 if (reg != 0) {
3016#if defined(TARGET_MIPS64)
3017 if (acc != 0) {
3018 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3019 } else
3020#endif
3021 {
3022 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3023 }
3024 } else {
3025 tcg_gen_movi_tl(cpu_HI[acc], 0);
3026 }
3027 break;
3028 case OPC_MTLO:
3029 if (reg != 0) {
3030#if defined(TARGET_MIPS64)
3031 if (acc != 0) {
3032 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3033 } else
3034#endif
3035 {
3036 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3037 }
3038 } else {
3039 tcg_gen_movi_tl(cpu_LO[acc], 0);
3040 }
3041 break;
3042 }
3043}
3044
3045static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3046 MemOp memop)
3047{
3048 TCGv t0 = tcg_const_tl(addr);
3049 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3050 gen_store_gpr(t0, reg);
3051 tcg_temp_free(t0);
3052}
3053
3054static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3055 int rs)
3056{
3057 target_long offset;
3058 target_long addr;
3059
3060 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3061 case OPC_ADDIUPC:
3062 if (rs != 0) {
3063 offset = sextract32(ctx->opcode << 2, 0, 21);
3064 addr = addr_add(ctx, pc, offset);
3065 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3066 }
3067 break;
3068 case R6_OPC_LWPC:
3069 offset = sextract32(ctx->opcode << 2, 0, 21);
3070 addr = addr_add(ctx, pc, offset);
3071 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3072 break;
3073#if defined(TARGET_MIPS64)
3074 case OPC_LWUPC:
3075 check_mips_64(ctx);
3076 offset = sextract32(ctx->opcode << 2, 0, 21);
3077 addr = addr_add(ctx, pc, offset);
3078 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3079 break;
3080#endif
3081 default:
3082 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3083 case OPC_AUIPC:
3084 if (rs != 0) {
3085 offset = sextract32(ctx->opcode, 0, 16) << 16;
3086 addr = addr_add(ctx, pc, offset);
3087 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3088 }
3089 break;
3090 case OPC_ALUIPC:
3091 if (rs != 0) {
3092 offset = sextract32(ctx->opcode, 0, 16) << 16;
3093 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3094 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3095 }
3096 break;
3097#if defined(TARGET_MIPS64)
3098 case R6_OPC_LDPC:
3099 case R6_OPC_LDPC + (1 << 16):
3100 case R6_OPC_LDPC + (2 << 16):
3101 case R6_OPC_LDPC + (3 << 16):
3102 check_mips_64(ctx);
3103 offset = sextract32(ctx->opcode << 3, 0, 21);
3104 addr = addr_add(ctx, (pc & ~0x7), offset);
3105 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ);
3106 break;
3107#endif
3108 default:
3109 MIPS_INVAL("OPC_PCREL");
3110 gen_reserved_instruction(ctx);
3111 break;
3112 }
3113 break;
3114 }
3115}
3116
3117static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3118{
3119 TCGv t0, t1;
3120
3121 if (rd == 0) {
3122
3123 return;
3124 }
3125
3126 t0 = tcg_temp_new();
3127 t1 = tcg_temp_new();
3128
3129 gen_load_gpr(t0, rs);
3130 gen_load_gpr(t1, rt);
3131
3132 switch (opc) {
3133 case R6_OPC_DIV:
3134 {
3135 TCGv t2 = tcg_temp_new();
3136 TCGv t3 = tcg_temp_new();
3137 tcg_gen_ext32s_tl(t0, t0);
3138 tcg_gen_ext32s_tl(t1, t1);
3139 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3140 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3141 tcg_gen_and_tl(t2, t2, t3);
3142 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3143 tcg_gen_or_tl(t2, t2, t3);
3144 tcg_gen_movi_tl(t3, 0);
3145 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3146 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3147 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3148 tcg_temp_free(t3);
3149 tcg_temp_free(t2);
3150 }
3151 break;
3152 case R6_OPC_MOD:
3153 {
3154 TCGv t2 = tcg_temp_new();
3155 TCGv t3 = tcg_temp_new();
3156 tcg_gen_ext32s_tl(t0, t0);
3157 tcg_gen_ext32s_tl(t1, t1);
3158 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3159 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3160 tcg_gen_and_tl(t2, t2, t3);
3161 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3162 tcg_gen_or_tl(t2, t2, t3);
3163 tcg_gen_movi_tl(t3, 0);
3164 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3165 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3166 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3167 tcg_temp_free(t3);
3168 tcg_temp_free(t2);
3169 }
3170 break;
3171 case R6_OPC_DIVU:
3172 {
3173 TCGv t2 = tcg_const_tl(0);
3174 TCGv t3 = tcg_const_tl(1);
3175 tcg_gen_ext32u_tl(t0, t0);
3176 tcg_gen_ext32u_tl(t1, t1);
3177 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3178 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3179 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3180 tcg_temp_free(t3);
3181 tcg_temp_free(t2);
3182 }
3183 break;
3184 case R6_OPC_MODU:
3185 {
3186 TCGv t2 = tcg_const_tl(0);
3187 TCGv t3 = tcg_const_tl(1);
3188 tcg_gen_ext32u_tl(t0, t0);
3189 tcg_gen_ext32u_tl(t1, t1);
3190 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3191 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3192 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3193 tcg_temp_free(t3);
3194 tcg_temp_free(t2);
3195 }
3196 break;
3197 case R6_OPC_MUL:
3198 {
3199 TCGv_i32 t2 = tcg_temp_new_i32();
3200 TCGv_i32 t3 = tcg_temp_new_i32();
3201 tcg_gen_trunc_tl_i32(t2, t0);
3202 tcg_gen_trunc_tl_i32(t3, t1);
3203 tcg_gen_mul_i32(t2, t2, t3);
3204 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3205 tcg_temp_free_i32(t2);
3206 tcg_temp_free_i32(t3);
3207 }
3208 break;
3209 case R6_OPC_MUH:
3210 {
3211 TCGv_i32 t2 = tcg_temp_new_i32();
3212 TCGv_i32 t3 = tcg_temp_new_i32();
3213 tcg_gen_trunc_tl_i32(t2, t0);
3214 tcg_gen_trunc_tl_i32(t3, t1);
3215 tcg_gen_muls2_i32(t2, t3, t2, t3);
3216 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3217 tcg_temp_free_i32(t2);
3218 tcg_temp_free_i32(t3);
3219 }
3220 break;
3221 case R6_OPC_MULU:
3222 {
3223 TCGv_i32 t2 = tcg_temp_new_i32();
3224 TCGv_i32 t3 = tcg_temp_new_i32();
3225 tcg_gen_trunc_tl_i32(t2, t0);
3226 tcg_gen_trunc_tl_i32(t3, t1);
3227 tcg_gen_mul_i32(t2, t2, t3);
3228 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3229 tcg_temp_free_i32(t2);
3230 tcg_temp_free_i32(t3);
3231 }
3232 break;
3233 case R6_OPC_MUHU:
3234 {
3235 TCGv_i32 t2 = tcg_temp_new_i32();
3236 TCGv_i32 t3 = tcg_temp_new_i32();
3237 tcg_gen_trunc_tl_i32(t2, t0);
3238 tcg_gen_trunc_tl_i32(t3, t1);
3239 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3240 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3241 tcg_temp_free_i32(t2);
3242 tcg_temp_free_i32(t3);
3243 }
3244 break;
3245#if defined(TARGET_MIPS64)
3246 case R6_OPC_DDIV:
3247 {
3248 TCGv t2 = tcg_temp_new();
3249 TCGv t3 = tcg_temp_new();
3250 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3251 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3252 tcg_gen_and_tl(t2, t2, t3);
3253 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3254 tcg_gen_or_tl(t2, t2, t3);
3255 tcg_gen_movi_tl(t3, 0);
3256 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3257 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3258 tcg_temp_free(t3);
3259 tcg_temp_free(t2);
3260 }
3261 break;
3262 case R6_OPC_DMOD:
3263 {
3264 TCGv t2 = tcg_temp_new();
3265 TCGv t3 = tcg_temp_new();
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3267 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3268 tcg_gen_and_tl(t2, t2, t3);
3269 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3270 tcg_gen_or_tl(t2, t2, t3);
3271 tcg_gen_movi_tl(t3, 0);
3272 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3273 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3274 tcg_temp_free(t3);
3275 tcg_temp_free(t2);
3276 }
3277 break;
3278 case R6_OPC_DDIVU:
3279 {
3280 TCGv t2 = tcg_const_tl(0);
3281 TCGv t3 = tcg_const_tl(1);
3282 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3284 tcg_temp_free(t3);
3285 tcg_temp_free(t2);
3286 }
3287 break;
3288 case R6_OPC_DMODU:
3289 {
3290 TCGv t2 = tcg_const_tl(0);
3291 TCGv t3 = tcg_const_tl(1);
3292 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3293 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3294 tcg_temp_free(t3);
3295 tcg_temp_free(t2);
3296 }
3297 break;
3298 case R6_OPC_DMUL:
3299 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3300 break;
3301 case R6_OPC_DMUH:
3302 {
3303 TCGv t2 = tcg_temp_new();
3304 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3305 tcg_temp_free(t2);
3306 }
3307 break;
3308 case R6_OPC_DMULU:
3309 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3310 break;
3311 case R6_OPC_DMUHU:
3312 {
3313 TCGv t2 = tcg_temp_new();
3314 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3315 tcg_temp_free(t2);
3316 }
3317 break;
3318#endif
3319 default:
3320 MIPS_INVAL("r6 mul/div");
3321 gen_reserved_instruction(ctx);
3322 goto out;
3323 }
3324 out:
3325 tcg_temp_free(t0);
3326 tcg_temp_free(t1);
3327}
3328
3329#if defined(TARGET_MIPS64)
3330static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3331{
3332 TCGv t0, t1;
3333
3334 t0 = tcg_temp_new();
3335 t1 = tcg_temp_new();
3336
3337 gen_load_gpr(t0, rs);
3338 gen_load_gpr(t1, rt);
3339
3340 switch (opc) {
3341 case MMI_OPC_DIV1:
3342 {
3343 TCGv t2 = tcg_temp_new();
3344 TCGv t3 = tcg_temp_new();
3345 tcg_gen_ext32s_tl(t0, t0);
3346 tcg_gen_ext32s_tl(t1, t1);
3347 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3348 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3349 tcg_gen_and_tl(t2, t2, t3);
3350 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3351 tcg_gen_or_tl(t2, t2, t3);
3352 tcg_gen_movi_tl(t3, 0);
3353 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3354 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3355 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3356 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3357 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3358 tcg_temp_free(t3);
3359 tcg_temp_free(t2);
3360 }
3361 break;
3362 case MMI_OPC_DIVU1:
3363 {
3364 TCGv t2 = tcg_const_tl(0);
3365 TCGv t3 = tcg_const_tl(1);
3366 tcg_gen_ext32u_tl(t0, t0);
3367 tcg_gen_ext32u_tl(t1, t1);
3368 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3369 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3370 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3371 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3372 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3373 tcg_temp_free(t3);
3374 tcg_temp_free(t2);
3375 }
3376 break;
3377 default:
3378 MIPS_INVAL("div1 TX79");
3379 gen_reserved_instruction(ctx);
3380 goto out;
3381 }
3382 out:
3383 tcg_temp_free(t0);
3384 tcg_temp_free(t1);
3385}
3386#endif
3387
3388static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3389 int acc, int rs, int rt)
3390{
3391 TCGv t0, t1;
3392
3393 t0 = tcg_temp_new();
3394 t1 = tcg_temp_new();
3395
3396 gen_load_gpr(t0, rs);
3397 gen_load_gpr(t1, rt);
3398
3399 if (acc != 0) {
3400 check_dsp(ctx);
3401 }
3402
3403 switch (opc) {
3404 case OPC_DIV:
3405 {
3406 TCGv t2 = tcg_temp_new();
3407 TCGv t3 = tcg_temp_new();
3408 tcg_gen_ext32s_tl(t0, t0);
3409 tcg_gen_ext32s_tl(t1, t1);
3410 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3411 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3412 tcg_gen_and_tl(t2, t2, t3);
3413 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3414 tcg_gen_or_tl(t2, t2, t3);
3415 tcg_gen_movi_tl(t3, 0);
3416 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3417 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3418 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3419 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3420 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3421 tcg_temp_free(t3);
3422 tcg_temp_free(t2);
3423 }
3424 break;
3425 case OPC_DIVU:
3426 {
3427 TCGv t2 = tcg_const_tl(0);
3428 TCGv t3 = tcg_const_tl(1);
3429 tcg_gen_ext32u_tl(t0, t0);
3430 tcg_gen_ext32u_tl(t1, t1);
3431 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3432 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3433 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3434 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3435 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3436 tcg_temp_free(t3);
3437 tcg_temp_free(t2);
3438 }
3439 break;
3440 case OPC_MULT:
3441 {
3442 TCGv_i32 t2 = tcg_temp_new_i32();
3443 TCGv_i32 t3 = tcg_temp_new_i32();
3444 tcg_gen_trunc_tl_i32(t2, t0);
3445 tcg_gen_trunc_tl_i32(t3, t1);
3446 tcg_gen_muls2_i32(t2, t3, t2, t3);
3447 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3448 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3449 tcg_temp_free_i32(t2);
3450 tcg_temp_free_i32(t3);
3451 }
3452 break;
3453 case OPC_MULTU:
3454 {
3455 TCGv_i32 t2 = tcg_temp_new_i32();
3456 TCGv_i32 t3 = tcg_temp_new_i32();
3457 tcg_gen_trunc_tl_i32(t2, t0);
3458 tcg_gen_trunc_tl_i32(t3, t1);
3459 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3460 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3461 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3462 tcg_temp_free_i32(t2);
3463 tcg_temp_free_i32(t3);
3464 }
3465 break;
3466#if defined(TARGET_MIPS64)
3467 case OPC_DDIV:
3468 {
3469 TCGv t2 = tcg_temp_new();
3470 TCGv t3 = tcg_temp_new();
3471 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3472 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3473 tcg_gen_and_tl(t2, t2, t3);
3474 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3475 tcg_gen_or_tl(t2, t2, t3);
3476 tcg_gen_movi_tl(t3, 0);
3477 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3478 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3479 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3480 tcg_temp_free(t3);
3481 tcg_temp_free(t2);
3482 }
3483 break;
3484 case OPC_DDIVU:
3485 {
3486 TCGv t2 = tcg_const_tl(0);
3487 TCGv t3 = tcg_const_tl(1);
3488 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3489 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3490 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3491 tcg_temp_free(t3);
3492 tcg_temp_free(t2);
3493 }
3494 break;
3495 case OPC_DMULT:
3496 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3497 break;
3498 case OPC_DMULTU:
3499 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3500 break;
3501#endif
3502 case OPC_MADD:
3503 {
3504 TCGv_i64 t2 = tcg_temp_new_i64();
3505 TCGv_i64 t3 = tcg_temp_new_i64();
3506
3507 tcg_gen_ext_tl_i64(t2, t0);
3508 tcg_gen_ext_tl_i64(t3, t1);
3509 tcg_gen_mul_i64(t2, t2, t3);
3510 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3511 tcg_gen_add_i64(t2, t2, t3);
3512 tcg_temp_free_i64(t3);
3513 gen_move_low32(cpu_LO[acc], t2);
3514 gen_move_high32(cpu_HI[acc], t2);
3515 tcg_temp_free_i64(t2);
3516 }
3517 break;
3518 case OPC_MADDU:
3519 {
3520 TCGv_i64 t2 = tcg_temp_new_i64();
3521 TCGv_i64 t3 = tcg_temp_new_i64();
3522
3523 tcg_gen_ext32u_tl(t0, t0);
3524 tcg_gen_ext32u_tl(t1, t1);
3525 tcg_gen_extu_tl_i64(t2, t0);
3526 tcg_gen_extu_tl_i64(t3, t1);
3527 tcg_gen_mul_i64(t2, t2, t3);
3528 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3529 tcg_gen_add_i64(t2, t2, t3);
3530 tcg_temp_free_i64(t3);
3531 gen_move_low32(cpu_LO[acc], t2);
3532 gen_move_high32(cpu_HI[acc], t2);
3533 tcg_temp_free_i64(t2);
3534 }
3535 break;
3536 case OPC_MSUB:
3537 {
3538 TCGv_i64 t2 = tcg_temp_new_i64();
3539 TCGv_i64 t3 = tcg_temp_new_i64();
3540
3541 tcg_gen_ext_tl_i64(t2, t0);
3542 tcg_gen_ext_tl_i64(t3, t1);
3543 tcg_gen_mul_i64(t2, t2, t3);
3544 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3545 tcg_gen_sub_i64(t2, t3, t2);
3546 tcg_temp_free_i64(t3);
3547 gen_move_low32(cpu_LO[acc], t2);
3548 gen_move_high32(cpu_HI[acc], t2);
3549 tcg_temp_free_i64(t2);
3550 }
3551 break;
3552 case OPC_MSUBU:
3553 {
3554 TCGv_i64 t2 = tcg_temp_new_i64();
3555 TCGv_i64 t3 = tcg_temp_new_i64();
3556
3557 tcg_gen_ext32u_tl(t0, t0);
3558 tcg_gen_ext32u_tl(t1, t1);
3559 tcg_gen_extu_tl_i64(t2, t0);
3560 tcg_gen_extu_tl_i64(t3, t1);
3561 tcg_gen_mul_i64(t2, t2, t3);
3562 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3563 tcg_gen_sub_i64(t2, t3, t2);
3564 tcg_temp_free_i64(t3);
3565 gen_move_low32(cpu_LO[acc], t2);
3566 gen_move_high32(cpu_HI[acc], t2);
3567 tcg_temp_free_i64(t2);
3568 }
3569 break;
3570 default:
3571 MIPS_INVAL("mul/div");
3572 gen_reserved_instruction(ctx);
3573 goto out;
3574 }
3575 out:
3576 tcg_temp_free(t0);
3577 tcg_temp_free(t1);
3578}
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3607 int rd, int rs, int rt)
3608{
3609 TCGv t0 = tcg_temp_new();
3610 TCGv t1 = tcg_temp_new();
3611 int acc = 0;
3612
3613 gen_load_gpr(t0, rs);
3614 gen_load_gpr(t1, rt);
3615
3616 switch (opc) {
3617 case MMI_OPC_MULT1:
3618 acc = 1;
3619
3620 case OPC_MULT:
3621 {
3622 TCGv_i32 t2 = tcg_temp_new_i32();
3623 TCGv_i32 t3 = tcg_temp_new_i32();
3624 tcg_gen_trunc_tl_i32(t2, t0);
3625 tcg_gen_trunc_tl_i32(t3, t1);
3626 tcg_gen_muls2_i32(t2, t3, t2, t3);
3627 if (rd) {
3628 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3629 }
3630 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3631 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3632 tcg_temp_free_i32(t2);
3633 tcg_temp_free_i32(t3);
3634 }
3635 break;
3636 case MMI_OPC_MULTU1:
3637 acc = 1;
3638
3639 case OPC_MULTU:
3640 {
3641 TCGv_i32 t2 = tcg_temp_new_i32();
3642 TCGv_i32 t3 = tcg_temp_new_i32();
3643 tcg_gen_trunc_tl_i32(t2, t0);
3644 tcg_gen_trunc_tl_i32(t3, t1);
3645 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3646 if (rd) {
3647 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3648 }
3649 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3650 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3651 tcg_temp_free_i32(t2);
3652 tcg_temp_free_i32(t3);
3653 }
3654 break;
3655 case MMI_OPC_MADD1:
3656 acc = 1;
3657
3658 case MMI_OPC_MADD:
3659 {
3660 TCGv_i64 t2 = tcg_temp_new_i64();
3661 TCGv_i64 t3 = tcg_temp_new_i64();
3662
3663 tcg_gen_ext_tl_i64(t2, t0);
3664 tcg_gen_ext_tl_i64(t3, t1);
3665 tcg_gen_mul_i64(t2, t2, t3);
3666 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3667 tcg_gen_add_i64(t2, t2, t3);
3668 tcg_temp_free_i64(t3);
3669 gen_move_low32(cpu_LO[acc], t2);
3670 gen_move_high32(cpu_HI[acc], t2);
3671 if (rd) {
3672 gen_move_low32(cpu_gpr[rd], t2);
3673 }
3674 tcg_temp_free_i64(t2);
3675 }
3676 break;
3677 case MMI_OPC_MADDU1:
3678 acc = 1;
3679
3680 case MMI_OPC_MADDU:
3681 {
3682 TCGv_i64 t2 = tcg_temp_new_i64();
3683 TCGv_i64 t3 = tcg_temp_new_i64();
3684
3685 tcg_gen_ext32u_tl(t0, t0);
3686 tcg_gen_ext32u_tl(t1, t1);
3687 tcg_gen_extu_tl_i64(t2, t0);
3688 tcg_gen_extu_tl_i64(t3, t1);
3689 tcg_gen_mul_i64(t2, t2, t3);
3690 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3691 tcg_gen_add_i64(t2, t2, t3);
3692 tcg_temp_free_i64(t3);
3693 gen_move_low32(cpu_LO[acc], t2);
3694 gen_move_high32(cpu_HI[acc], t2);
3695 if (rd) {
3696 gen_move_low32(cpu_gpr[rd], t2);
3697 }
3698 tcg_temp_free_i64(t2);
3699 }
3700 break;
3701 default:
3702 MIPS_INVAL("mul/madd TXx9");
3703 gen_reserved_instruction(ctx);
3704 goto out;
3705 }
3706
3707 out:
3708 tcg_temp_free(t0);
3709 tcg_temp_free(t1);
3710}
3711
3712static void gen_cl(DisasContext *ctx, uint32_t opc,
3713 int rd, int rs)
3714{
3715 TCGv t0;
3716
3717 if (rd == 0) {
3718
3719 return;
3720 }
3721 t0 = cpu_gpr[rd];
3722 gen_load_gpr(t0, rs);
3723
3724 switch (opc) {
3725 case OPC_CLO:
3726 case R6_OPC_CLO:
3727#if defined(TARGET_MIPS64)
3728 case OPC_DCLO:
3729 case R6_OPC_DCLO:
3730#endif
3731 tcg_gen_not_tl(t0, t0);
3732 break;
3733 }
3734
3735 switch (opc) {
3736 case OPC_CLO:
3737 case R6_OPC_CLO:
3738 case OPC_CLZ:
3739 case R6_OPC_CLZ:
3740 tcg_gen_ext32u_tl(t0, t0);
3741 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3742 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3743 break;
3744#if defined(TARGET_MIPS64)
3745 case OPC_DCLO:
3746 case R6_OPC_DCLO:
3747 case OPC_DCLZ:
3748 case R6_OPC_DCLZ:
3749 tcg_gen_clzi_i64(t0, t0, 64);
3750 break;
3751#endif
3752 }
3753}
3754
3755
3756static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3757 int rd, int rs, int rt)
3758{
3759 TCGv t0, t1;
3760
3761 if (rd == 0) {
3762
3763 return;
3764 }
3765
3766 switch (opc) {
3767 case OPC_MULT_G_2E:
3768 case OPC_MULT_G_2F:
3769 case OPC_MULTU_G_2E:
3770 case OPC_MULTU_G_2F:
3771#if defined(TARGET_MIPS64)
3772 case OPC_DMULT_G_2E:
3773 case OPC_DMULT_G_2F:
3774 case OPC_DMULTU_G_2E:
3775 case OPC_DMULTU_G_2F:
3776#endif
3777 t0 = tcg_temp_new();
3778 t1 = tcg_temp_new();
3779 break;
3780 default:
3781 t0 = tcg_temp_local_new();
3782 t1 = tcg_temp_local_new();
3783 break;
3784 }
3785
3786 gen_load_gpr(t0, rs);
3787 gen_load_gpr(t1, rt);
3788
3789 switch (opc) {
3790 case OPC_MULT_G_2E:
3791 case OPC_MULT_G_2F:
3792 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3793 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3794 break;
3795 case OPC_MULTU_G_2E:
3796 case OPC_MULTU_G_2F:
3797 tcg_gen_ext32u_tl(t0, t0);
3798 tcg_gen_ext32u_tl(t1, t1);
3799 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3800 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3801 break;
3802 case OPC_DIV_G_2E:
3803 case OPC_DIV_G_2F:
3804 {
3805 TCGLabel *l1 = gen_new_label();
3806 TCGLabel *l2 = gen_new_label();
3807 TCGLabel *l3 = gen_new_label();
3808 tcg_gen_ext32s_tl(t0, t0);
3809 tcg_gen_ext32s_tl(t1, t1);
3810 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3811 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3812 tcg_gen_br(l3);
3813 gen_set_label(l1);
3814 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3815 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3816 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3817 tcg_gen_br(l3);
3818 gen_set_label(l2);
3819 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3820 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3821 gen_set_label(l3);
3822 }
3823 break;
3824 case OPC_DIVU_G_2E:
3825 case OPC_DIVU_G_2F:
3826 {
3827 TCGLabel *l1 = gen_new_label();
3828 TCGLabel *l2 = gen_new_label();
3829 tcg_gen_ext32u_tl(t0, t0);
3830 tcg_gen_ext32u_tl(t1, t1);
3831 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3832 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3833 tcg_gen_br(l2);
3834 gen_set_label(l1);
3835 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3836 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3837 gen_set_label(l2);
3838 }
3839 break;
3840 case OPC_MOD_G_2E:
3841 case OPC_MOD_G_2F:
3842 {
3843 TCGLabel *l1 = gen_new_label();
3844 TCGLabel *l2 = gen_new_label();
3845 TCGLabel *l3 = gen_new_label();
3846 tcg_gen_ext32u_tl(t0, t0);
3847 tcg_gen_ext32u_tl(t1, t1);
3848 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3849 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3850 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3851 gen_set_label(l1);
3852 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3853 tcg_gen_br(l3);
3854 gen_set_label(l2);
3855 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3856 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3857 gen_set_label(l3);
3858 }
3859 break;
3860 case OPC_MODU_G_2E:
3861 case OPC_MODU_G_2F:
3862 {
3863 TCGLabel *l1 = gen_new_label();
3864 TCGLabel *l2 = gen_new_label();
3865 tcg_gen_ext32u_tl(t0, t0);
3866 tcg_gen_ext32u_tl(t1, t1);
3867 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3868 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3869 tcg_gen_br(l2);
3870 gen_set_label(l1);
3871 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3872 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3873 gen_set_label(l2);
3874 }
3875 break;
3876#if defined(TARGET_MIPS64)
3877 case OPC_DMULT_G_2E:
3878 case OPC_DMULT_G_2F:
3879 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3880 break;
3881 case OPC_DMULTU_G_2E:
3882 case OPC_DMULTU_G_2F:
3883 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3884 break;
3885 case OPC_DDIV_G_2E:
3886 case OPC_DDIV_G_2F:
3887 {
3888 TCGLabel *l1 = gen_new_label();
3889 TCGLabel *l2 = gen_new_label();
3890 TCGLabel *l3 = gen_new_label();
3891 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3892 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3893 tcg_gen_br(l3);
3894 gen_set_label(l1);
3895 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3896 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3897 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3898 tcg_gen_br(l3);
3899 gen_set_label(l2);
3900 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3901 gen_set_label(l3);
3902 }
3903 break;
3904 case OPC_DDIVU_G_2E:
3905 case OPC_DDIVU_G_2F:
3906 {
3907 TCGLabel *l1 = gen_new_label();
3908 TCGLabel *l2 = gen_new_label();
3909 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3910 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3911 tcg_gen_br(l2);
3912 gen_set_label(l1);
3913 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3914 gen_set_label(l2);
3915 }
3916 break;
3917 case OPC_DMOD_G_2E:
3918 case OPC_DMOD_G_2F:
3919 {
3920 TCGLabel *l1 = gen_new_label();
3921 TCGLabel *l2 = gen_new_label();
3922 TCGLabel *l3 = gen_new_label();
3923 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3924 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3925 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3926 gen_set_label(l1);
3927 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3928 tcg_gen_br(l3);
3929 gen_set_label(l2);
3930 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3931 gen_set_label(l3);
3932 }
3933 break;
3934 case OPC_DMODU_G_2E:
3935 case OPC_DMODU_G_2F:
3936 {
3937 TCGLabel *l1 = gen_new_label();
3938 TCGLabel *l2 = gen_new_label();
3939 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3940 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3941 tcg_gen_br(l2);
3942 gen_set_label(l1);
3943 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3944 gen_set_label(l2);
3945 }
3946 break;
3947#endif
3948 }
3949
3950 tcg_temp_free(t0);
3951 tcg_temp_free(t1);
3952}
3953
3954
3955static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3956{
3957 uint32_t opc, shift_max;
3958 TCGv_i64 t0, t1;
3959 TCGCond cond;
3960
3961 opc = MASK_LMMI(ctx->opcode);
3962 switch (opc) {
3963 case OPC_ADD_CP2:
3964 case OPC_SUB_CP2:
3965 case OPC_DADD_CP2:
3966 case OPC_DSUB_CP2:
3967 t0 = tcg_temp_local_new_i64();
3968 t1 = tcg_temp_local_new_i64();
3969 break;
3970 default:
3971 t0 = tcg_temp_new_i64();
3972 t1 = tcg_temp_new_i64();
3973 break;
3974 }
3975
3976 check_cp1_enabled(ctx);
3977 gen_load_fpr64(ctx, t0, rs);
3978 gen_load_fpr64(ctx, t1, rt);
3979
3980 switch (opc) {
3981 case OPC_PADDSH:
3982 gen_helper_paddsh(t0, t0, t1);
3983 break;
3984 case OPC_PADDUSH:
3985 gen_helper_paddush(t0, t0, t1);
3986 break;
3987 case OPC_PADDH:
3988 gen_helper_paddh(t0, t0, t1);
3989 break;
3990 case OPC_PADDW:
3991 gen_helper_paddw(t0, t0, t1);
3992 break;
3993 case OPC_PADDSB:
3994 gen_helper_paddsb(t0, t0, t1);
3995 break;
3996 case OPC_PADDUSB:
3997 gen_helper_paddusb(t0, t0, t1);
3998 break;
3999 case OPC_PADDB:
4000 gen_helper_paddb(t0, t0, t1);
4001 break;
4002
4003 case OPC_PSUBSH:
4004 gen_helper_psubsh(t0, t0, t1);
4005 break;
4006 case OPC_PSUBUSH:
4007 gen_helper_psubush(t0, t0, t1);
4008 break;
4009 case OPC_PSUBH:
4010 gen_helper_psubh(t0, t0, t1);
4011 break;
4012 case OPC_PSUBW:
4013 gen_helper_psubw(t0, t0, t1);
4014 break;
4015 case OPC_PSUBSB:
4016 gen_helper_psubsb(t0, t0, t1);
4017 break;
4018 case OPC_PSUBUSB:
4019 gen_helper_psubusb(t0, t0, t1);
4020 break;
4021 case OPC_PSUBB:
4022 gen_helper_psubb(t0, t0, t1);
4023 break;
4024
4025 case OPC_PSHUFH:
4026 gen_helper_pshufh(t0, t0, t1);
4027 break;
4028 case OPC_PACKSSWH:
4029 gen_helper_packsswh(t0, t0, t1);
4030 break;
4031 case OPC_PACKSSHB:
4032 gen_helper_packsshb(t0, t0, t1);
4033 break;
4034 case OPC_PACKUSHB:
4035 gen_helper_packushb(t0, t0, t1);
4036 break;
4037
4038 case OPC_PUNPCKLHW:
4039 gen_helper_punpcklhw(t0, t0, t1);
4040 break;
4041 case OPC_PUNPCKHHW:
4042 gen_helper_punpckhhw(t0, t0, t1);
4043 break;
4044 case OPC_PUNPCKLBH:
4045 gen_helper_punpcklbh(t0, t0, t1);
4046 break;
4047 case OPC_PUNPCKHBH:
4048 gen_helper_punpckhbh(t0, t0, t1);
4049 break;
4050 case OPC_PUNPCKLWD:
4051 gen_helper_punpcklwd(t0, t0, t1);
4052 break;
4053 case OPC_PUNPCKHWD:
4054 gen_helper_punpckhwd(t0, t0, t1);
4055 break;
4056
4057 case OPC_PAVGH:
4058 gen_helper_pavgh(t0, t0, t1);
4059 break;
4060 case OPC_PAVGB:
4061 gen_helper_pavgb(t0, t0, t1);
4062 break;
4063 case OPC_PMAXSH:
4064 gen_helper_pmaxsh(t0, t0, t1);
4065 break;
4066 case OPC_PMINSH:
4067 gen_helper_pminsh(t0, t0, t1);
4068 break;
4069 case OPC_PMAXUB:
4070 gen_helper_pmaxub(t0, t0, t1);
4071 break;
4072 case OPC_PMINUB:
4073 gen_helper_pminub(t0, t0, t1);
4074 break;
4075
4076 case OPC_PCMPEQW:
4077 gen_helper_pcmpeqw(t0, t0, t1);
4078 break;
4079 case OPC_PCMPGTW:
4080 gen_helper_pcmpgtw(t0, t0, t1);
4081 break;
4082 case OPC_PCMPEQH:
4083 gen_helper_pcmpeqh(t0, t0, t1);
4084 break;
4085 case OPC_PCMPGTH:
4086 gen_helper_pcmpgth(t0, t0, t1);
4087 break;
4088 case OPC_PCMPEQB:
4089 gen_helper_pcmpeqb(t0, t0, t1);
4090 break;
4091 case OPC_PCMPGTB:
4092 gen_helper_pcmpgtb(t0, t0, t1);
4093 break;
4094
4095 case OPC_PSLLW:
4096 gen_helper_psllw(t0, t0, t1);
4097 break;
4098 case OPC_PSLLH:
4099 gen_helper_psllh(t0, t0, t1);
4100 break;
4101 case OPC_PSRLW:
4102 gen_helper_psrlw(t0, t0, t1);
4103 break;
4104 case OPC_PSRLH:
4105 gen_helper_psrlh(t0, t0, t1);
4106 break;
4107 case OPC_PSRAW:
4108 gen_helper_psraw(t0, t0, t1);
4109 break;
4110 case OPC_PSRAH:
4111 gen_helper_psrah(t0, t0, t1);
4112 break;
4113
4114 case OPC_PMULLH:
4115 gen_helper_pmullh(t0, t0, t1);
4116 break;
4117 case OPC_PMULHH:
4118 gen_helper_pmulhh(t0, t0, t1);
4119 break;
4120 case OPC_PMULHUH:
4121 gen_helper_pmulhuh(t0, t0, t1);
4122 break;
4123 case OPC_PMADDHW:
4124 gen_helper_pmaddhw(t0, t0, t1);
4125 break;
4126
4127 case OPC_PASUBUB:
4128 gen_helper_pasubub(t0, t0, t1);
4129 break;
4130 case OPC_BIADD:
4131 gen_helper_biadd(t0, t0);
4132 break;
4133 case OPC_PMOVMSKB:
4134 gen_helper_pmovmskb(t0, t0);
4135 break;
4136
4137 case OPC_PADDD:
4138 tcg_gen_add_i64(t0, t0, t1);
4139 break;
4140 case OPC_PSUBD:
4141 tcg_gen_sub_i64(t0, t0, t1);
4142 break;
4143 case OPC_XOR_CP2:
4144 tcg_gen_xor_i64(t0, t0, t1);
4145 break;
4146 case OPC_NOR_CP2:
4147 tcg_gen_nor_i64(t0, t0, t1);
4148 break;
4149 case OPC_AND_CP2:
4150 tcg_gen_and_i64(t0, t0, t1);
4151 break;
4152 case OPC_OR_CP2:
4153 tcg_gen_or_i64(t0, t0, t1);
4154 break;
4155
4156 case OPC_PANDN:
4157 tcg_gen_andc_i64(t0, t1, t0);
4158 break;
4159
4160 case OPC_PINSRH_0:
4161 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4162 break;
4163 case OPC_PINSRH_1:
4164 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4165 break;
4166 case OPC_PINSRH_2:
4167 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4168 break;
4169 case OPC_PINSRH_3:
4170 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4171 break;
4172
4173 case OPC_PEXTRH:
4174 tcg_gen_andi_i64(t1, t1, 3);
4175 tcg_gen_shli_i64(t1, t1, 4);
4176 tcg_gen_shr_i64(t0, t0, t1);
4177 tcg_gen_ext16u_i64(t0, t0);
4178 break;
4179
4180 case OPC_ADDU_CP2:
4181 tcg_gen_add_i64(t0, t0, t1);
4182 tcg_gen_ext32s_i64(t0, t0);
4183 break;
4184 case OPC_SUBU_CP2:
4185 tcg_gen_sub_i64(t0, t0, t1);
4186 tcg_gen_ext32s_i64(t0, t0);
4187 break;
4188
4189 case OPC_SLL_CP2:
4190 shift_max = 32;
4191 goto do_shift;
4192 case OPC_SRL_CP2:
4193 shift_max = 32;
4194 goto do_shift;
4195 case OPC_SRA_CP2:
4196 shift_max = 32;
4197 goto do_shift;
4198 case OPC_DSLL_CP2:
4199 shift_max = 64;
4200 goto do_shift;
4201 case OPC_DSRL_CP2:
4202 shift_max = 64;
4203 goto do_shift;
4204 case OPC_DSRA_CP2:
4205 shift_max = 64;
4206 goto do_shift;
4207 do_shift:
4208
4209 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4210
4211 switch (opc) {
4212 case OPC_SLL_CP2:
4213 case OPC_DSLL_CP2:
4214 tcg_gen_shl_i64(t0, t0, t1);
4215 break;
4216 case OPC_SRA_CP2:
4217 case OPC_DSRA_CP2:
4218
4219
4220
4221
4222 tcg_gen_sar_i64(t0, t0, t1);
4223 break;
4224 case OPC_SRL_CP2:
4225
4226 tcg_gen_ext32u_i64(t0, t0);
4227
4228 case OPC_DSRL_CP2:
4229 tcg_gen_shr_i64(t0, t0, t1);
4230 break;
4231 }
4232
4233 if (shift_max == 32) {
4234 tcg_gen_ext32s_i64(t0, t0);
4235 }
4236
4237
4238 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4239 tcg_gen_neg_i64(t1, t1);
4240 tcg_gen_and_i64(t0, t0, t1);
4241 break;
4242
4243 case OPC_ADD_CP2:
4244 case OPC_DADD_CP2:
4245 {
4246 TCGv_i64 t2 = tcg_temp_new_i64();
4247 TCGLabel *lab = gen_new_label();
4248
4249 tcg_gen_mov_i64(t2, t0);
4250 tcg_gen_add_i64(t0, t1, t2);
4251 if (opc == OPC_ADD_CP2) {
4252 tcg_gen_ext32s_i64(t0, t0);
4253 }
4254 tcg_gen_xor_i64(t1, t1, t2);
4255 tcg_gen_xor_i64(t2, t2, t0);
4256 tcg_gen_andc_i64(t1, t2, t1);
4257 tcg_temp_free_i64(t2);
4258 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4259 generate_exception(ctx, EXCP_OVERFLOW);
4260 gen_set_label(lab);
4261 break;
4262 }
4263
4264 case OPC_SUB_CP2:
4265 case OPC_DSUB_CP2:
4266 {
4267 TCGv_i64 t2 = tcg_temp_new_i64();
4268 TCGLabel *lab = gen_new_label();
4269
4270 tcg_gen_mov_i64(t2, t0);
4271 tcg_gen_sub_i64(t0, t1, t2);
4272 if (opc == OPC_SUB_CP2) {
4273 tcg_gen_ext32s_i64(t0, t0);
4274 }
4275 tcg_gen_xor_i64(t1, t1, t2);
4276 tcg_gen_xor_i64(t2, t2, t0);
4277 tcg_gen_and_i64(t1, t1, t2);
4278 tcg_temp_free_i64(t2);
4279 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4280 generate_exception(ctx, EXCP_OVERFLOW);
4281 gen_set_label(lab);
4282 break;
4283 }
4284
4285 case OPC_PMULUW:
4286 tcg_gen_ext32u_i64(t0, t0);
4287 tcg_gen_ext32u_i64(t1, t1);
4288 tcg_gen_mul_i64(t0, t0, t1);
4289 break;
4290
4291 case OPC_SEQU_CP2:
4292 case OPC_SEQ_CP2:
4293 cond = TCG_COND_EQ;
4294 goto do_cc_cond;
4295 break;
4296 case OPC_SLTU_CP2:
4297 cond = TCG_COND_LTU;
4298 goto do_cc_cond;
4299 break;
4300 case OPC_SLT_CP2:
4301 cond = TCG_COND_LT;
4302 goto do_cc_cond;
4303 break;
4304 case OPC_SLEU_CP2:
4305 cond = TCG_COND_LEU;
4306 goto do_cc_cond;
4307 break;
4308 case OPC_SLE_CP2:
4309 cond = TCG_COND_LE;
4310 do_cc_cond:
4311 {
4312 int cc = (ctx->opcode >> 8) & 0x7;
4313 TCGv_i64 t64 = tcg_temp_new_i64();
4314 TCGv_i32 t32 = tcg_temp_new_i32();
4315
4316 tcg_gen_setcond_i64(cond, t64, t0, t1);
4317 tcg_gen_extrl_i64_i32(t32, t64);
4318 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4319 get_fp_bit(cc), 1);
4320
4321 tcg_temp_free_i32(t32);
4322 tcg_temp_free_i64(t64);
4323 }
4324 goto no_rd;
4325 break;
4326 default:
4327 MIPS_INVAL("loongson_cp2");
4328 gen_reserved_instruction(ctx);
4329 return;
4330 }
4331
4332 gen_store_fpr64(ctx, t0, rd);
4333
4334no_rd:
4335 tcg_temp_free_i64(t0);
4336 tcg_temp_free_i64(t1);
4337}
4338
4339static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4340 int rs, int rd)
4341{
4342 TCGv t0, t1, t2;
4343 TCGv_i32 fp0;
4344#if defined(TARGET_MIPS64)
4345 int lsq_rt1 = ctx->opcode & 0x1f;
4346 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4347#endif
4348 int shf_offset = sextract32(ctx->opcode, 6, 8);
4349
4350 t0 = tcg_temp_new();
4351
4352 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4353#if defined(TARGET_MIPS64)
4354 case OPC_GSLQ:
4355 t1 = tcg_temp_new();
4356 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4357 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4358 ctx->default_tcg_memop_mask);
4359 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4360 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4361 ctx->default_tcg_memop_mask);
4362 gen_store_gpr(t1, rt);
4363 gen_store_gpr(t0, lsq_rt1);
4364 tcg_temp_free(t1);
4365 break;
4366 case OPC_GSLQC1:
4367 check_cp1_enabled(ctx);
4368 t1 = tcg_temp_new();
4369 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4370 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4371 ctx->default_tcg_memop_mask);
4372 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4373 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4374 ctx->default_tcg_memop_mask);
4375 gen_store_fpr64(ctx, t1, rt);
4376 gen_store_fpr64(ctx, t0, lsq_rt1);
4377 tcg_temp_free(t1);
4378 break;
4379 case OPC_GSSQ:
4380 t1 = tcg_temp_new();
4381 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4382 gen_load_gpr(t1, rt);
4383 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4384 ctx->default_tcg_memop_mask);
4385 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4386 gen_load_gpr(t1, lsq_rt1);
4387 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4388 ctx->default_tcg_memop_mask);
4389 tcg_temp_free(t1);
4390 break;
4391 case OPC_GSSQC1:
4392 check_cp1_enabled(ctx);
4393 t1 = tcg_temp_new();
4394 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4395 gen_load_fpr64(ctx, t1, rt);
4396 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4397 ctx->default_tcg_memop_mask);
4398 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4399 gen_load_fpr64(ctx, t1, lsq_rt1);
4400 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4401 ctx->default_tcg_memop_mask);
4402 tcg_temp_free(t1);
4403 break;
4404#endif
4405 case OPC_GSSHFL:
4406 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4407 case OPC_GSLWLC1:
4408 check_cp1_enabled(ctx);
4409 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4410 t1 = tcg_temp_new();
4411 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4412 tcg_gen_andi_tl(t1, t0, 3);
4413 if (!cpu_is_bigendian(ctx)) {
4414 tcg_gen_xori_tl(t1, t1, 3);
4415 }
4416 tcg_gen_shli_tl(t1, t1, 3);
4417 tcg_gen_andi_tl(t0, t0, ~3);
4418 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4419 tcg_gen_shl_tl(t0, t0, t1);
4420 t2 = tcg_const_tl(-1);
4421 tcg_gen_shl_tl(t2, t2, t1);
4422 fp0 = tcg_temp_new_i32();
4423 gen_load_fpr32(ctx, fp0, rt);
4424 tcg_gen_ext_i32_tl(t1, fp0);
4425 tcg_gen_andc_tl(t1, t1, t2);
4426 tcg_temp_free(t2);
4427 tcg_gen_or_tl(t0, t0, t1);
4428 tcg_temp_free(t1);
4429#if defined(TARGET_MIPS64)
4430 tcg_gen_extrl_i64_i32(fp0, t0);
4431#else
4432 tcg_gen_ext32s_tl(fp0, t0);
4433#endif
4434 gen_store_fpr32(ctx, fp0, rt);
4435 tcg_temp_free_i32(fp0);
4436 break;
4437 case OPC_GSLWRC1:
4438 check_cp1_enabled(ctx);
4439 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4440 t1 = tcg_temp_new();
4441 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4442 tcg_gen_andi_tl(t1, t0, 3);
4443 if (cpu_is_bigendian(ctx)) {
4444 tcg_gen_xori_tl(t1, t1, 3);
4445 }
4446 tcg_gen_shli_tl(t1, t1, 3);
4447 tcg_gen_andi_tl(t0, t0, ~3);
4448 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4449 tcg_gen_shr_tl(t0, t0, t1);
4450 tcg_gen_xori_tl(t1, t1, 31);
4451 t2 = tcg_const_tl(0xfffffffeull);
4452 tcg_gen_shl_tl(t2, t2, t1);
4453 fp0 = tcg_temp_new_i32();
4454 gen_load_fpr32(ctx, fp0, rt);
4455 tcg_gen_ext_i32_tl(t1, fp0);
4456 tcg_gen_and_tl(t1, t1, t2);
4457 tcg_temp_free(t2);
4458 tcg_gen_or_tl(t0, t0, t1);
4459 tcg_temp_free(t1);
4460#if defined(TARGET_MIPS64)
4461 tcg_gen_extrl_i64_i32(fp0, t0);
4462#else
4463 tcg_gen_ext32s_tl(fp0, t0);
4464#endif
4465 gen_store_fpr32(ctx, fp0, rt);
4466 tcg_temp_free_i32(fp0);
4467 break;
4468#if defined(TARGET_MIPS64)
4469 case OPC_GSLDLC1:
4470 check_cp1_enabled(ctx);
4471 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4472 t1 = tcg_temp_new();
4473 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4474 tcg_gen_andi_tl(t1, t0, 7);
4475 if (!cpu_is_bigendian(ctx)) {
4476 tcg_gen_xori_tl(t1, t1, 7);
4477 }
4478 tcg_gen_shli_tl(t1, t1, 3);
4479 tcg_gen_andi_tl(t0, t0, ~7);
4480 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4481 tcg_gen_shl_tl(t0, t0, t1);
4482 t2 = tcg_const_tl(-1);
4483 tcg_gen_shl_tl(t2, t2, t1);
4484 gen_load_fpr64(ctx, t1, rt);
4485 tcg_gen_andc_tl(t1, t1, t2);
4486 tcg_temp_free(t2);
4487 tcg_gen_or_tl(t0, t0, t1);
4488 tcg_temp_free(t1);
4489 gen_store_fpr64(ctx, t0, rt);
4490 break;
4491 case OPC_GSLDRC1:
4492 check_cp1_enabled(ctx);
4493 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4494 t1 = tcg_temp_new();
4495 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4496 tcg_gen_andi_tl(t1, t0, 7);
4497 if (cpu_is_bigendian(ctx)) {
4498 tcg_gen_xori_tl(t1, t1, 7);
4499 }
4500 tcg_gen_shli_tl(t1, t1, 3);
4501 tcg_gen_andi_tl(t0, t0, ~7);
4502 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4503 tcg_gen_shr_tl(t0, t0, t1);
4504 tcg_gen_xori_tl(t1, t1, 63);
4505 t2 = tcg_const_tl(0xfffffffffffffffeull);
4506 tcg_gen_shl_tl(t2, t2, t1);
4507 gen_load_fpr64(ctx, t1, rt);
4508 tcg_gen_and_tl(t1, t1, t2);
4509 tcg_temp_free(t2);
4510 tcg_gen_or_tl(t0, t0, t1);
4511 tcg_temp_free(t1);
4512 gen_store_fpr64(ctx, t0, rt);
4513 break;
4514#endif
4515 default:
4516 MIPS_INVAL("loongson_gsshfl");
4517 gen_reserved_instruction(ctx);
4518 break;
4519 }
4520 break;
4521 case OPC_GSSHFS:
4522 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4523 case OPC_GSSWLC1:
4524 check_cp1_enabled(ctx);
4525 t1 = tcg_temp_new();
4526 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4527 fp0 = tcg_temp_new_i32();
4528 gen_load_fpr32(ctx, fp0, rt);
4529 tcg_gen_ext_i32_tl(t1, fp0);
4530 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4531 tcg_temp_free_i32(fp0);
4532 tcg_temp_free(t1);
4533 break;
4534 case OPC_GSSWRC1:
4535 check_cp1_enabled(ctx);
4536 t1 = tcg_temp_new();
4537 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4538 fp0 = tcg_temp_new_i32();
4539 gen_load_fpr32(ctx, fp0, rt);
4540 tcg_gen_ext_i32_tl(t1, fp0);
4541 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4542 tcg_temp_free_i32(fp0);
4543 tcg_temp_free(t1);
4544 break;
4545#if defined(TARGET_MIPS64)
4546 case OPC_GSSDLC1:
4547 check_cp1_enabled(ctx);
4548 t1 = tcg_temp_new();
4549 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4550 gen_load_fpr64(ctx, t1, rt);
4551 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4552 tcg_temp_free(t1);
4553 break;
4554 case OPC_GSSDRC1:
4555 check_cp1_enabled(ctx);
4556 t1 = tcg_temp_new();
4557 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4558 gen_load_fpr64(ctx, t1, rt);
4559 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4560 tcg_temp_free(t1);
4561 break;
4562#endif
4563 default:
4564 MIPS_INVAL("loongson_gsshfs");
4565 gen_reserved_instruction(ctx);
4566 break;
4567 }
4568 break;
4569 default:
4570 MIPS_INVAL("loongson_gslsq");
4571 gen_reserved_instruction(ctx);
4572 break;
4573 }
4574 tcg_temp_free(t0);
4575}
4576
4577
4578static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4579 int rs, int rd)
4580{
4581 int offset = sextract32(ctx->opcode, 3, 8);
4582 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4583 TCGv t0, t1;
4584 TCGv_i32 fp0;
4585
4586
4587 switch (opc) {
4588 case OPC_GSLBX:
4589 case OPC_GSLHX:
4590 case OPC_GSLWX:
4591 case OPC_GSLDX:
4592
4593 if (rt == 0) {
4594 return;
4595 }
4596 break;
4597 case OPC_GSSBX:
4598 case OPC_GSSHX:
4599 case OPC_GSSWX:
4600 case OPC_GSSDX:
4601 break;
4602 case OPC_GSLWXC1:
4603#if defined(TARGET_MIPS64)
4604 case OPC_GSLDXC1:
4605#endif
4606 check_cp1_enabled(ctx);
4607
4608 if (rt == 0) {
4609 return;
4610 }
4611 break;
4612 case OPC_GSSWXC1:
4613#if defined(TARGET_MIPS64)
4614 case OPC_GSSDXC1:
4615#endif
4616 check_cp1_enabled(ctx);
4617 break;
4618 default:
4619 MIPS_INVAL("loongson_lsdc2");
4620 gen_reserved_instruction(ctx);
4621 return;
4622 break;
4623 }
4624
4625 t0 = tcg_temp_new();
4626
4627 gen_base_offset_addr(ctx, t0, rs, offset);
4628 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4629
4630 switch (opc) {
4631 case OPC_GSLBX:
4632 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4633 gen_store_gpr(t0, rt);
4634 break;
4635 case OPC_GSLHX:
4636 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4637 ctx->default_tcg_memop_mask);
4638 gen_store_gpr(t0, rt);
4639 break;
4640 case OPC_GSLWX:
4641 gen_base_offset_addr(ctx, t0, rs, offset);
4642 if (rd) {
4643 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4644 }
4645 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4646 ctx->default_tcg_memop_mask);
4647 gen_store_gpr(t0, rt);
4648 break;
4649#if defined(TARGET_MIPS64)
4650 case OPC_GSLDX:
4651 gen_base_offset_addr(ctx, t0, rs, offset);
4652 if (rd) {
4653 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4654 }
4655 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4656 ctx->default_tcg_memop_mask);
4657 gen_store_gpr(t0, rt);
4658 break;
4659#endif
4660 case OPC_GSLWXC1:
4661 gen_base_offset_addr(ctx, t0, rs, offset);
4662 if (rd) {
4663 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4664 }
4665 fp0 = tcg_temp_new_i32();
4666 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4667 ctx->default_tcg_memop_mask);
4668 gen_store_fpr32(ctx, fp0, rt);
4669 tcg_temp_free_i32(fp0);
4670 break;
4671#if defined(TARGET_MIPS64)
4672 case OPC_GSLDXC1:
4673 gen_base_offset_addr(ctx, t0, rs, offset);
4674 if (rd) {
4675 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4676 }
4677 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4678 ctx->default_tcg_memop_mask);
4679 gen_store_fpr64(ctx, t0, rt);
4680 break;
4681#endif
4682 case OPC_GSSBX:
4683 t1 = tcg_temp_new();
4684 gen_load_gpr(t1, rt);
4685 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4686 tcg_temp_free(t1);
4687 break;
4688 case OPC_GSSHX:
4689 t1 = tcg_temp_new();
4690 gen_load_gpr(t1, rt);
4691 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4692 ctx->default_tcg_memop_mask);
4693 tcg_temp_free(t1);
4694 break;
4695 case OPC_GSSWX:
4696 t1 = tcg_temp_new();
4697 gen_load_gpr(t1, rt);
4698 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4699 ctx->default_tcg_memop_mask);
4700 tcg_temp_free(t1);
4701 break;
4702#if defined(TARGET_MIPS64)
4703 case OPC_GSSDX:
4704 t1 = tcg_temp_new();
4705 gen_load_gpr(t1, rt);
4706 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4707 ctx->default_tcg_memop_mask);
4708 tcg_temp_free(t1);
4709 break;
4710#endif
4711 case OPC_GSSWXC1:
4712 fp0 = tcg_temp_new_i32();
4713 gen_load_fpr32(ctx, fp0, rt);
4714 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4715 ctx->default_tcg_memop_mask);
4716 tcg_temp_free_i32(fp0);
4717 break;
4718#if defined(TARGET_MIPS64)
4719 case OPC_GSSDXC1:
4720 t1 = tcg_temp_new();
4721 gen_load_fpr64(ctx, t1, rt);
4722 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ |
4723 ctx->default_tcg_memop_mask);
4724 tcg_temp_free(t1);
4725 break;
4726#endif
4727 default:
4728 break;
4729 }
4730
4731 tcg_temp_free(t0);
4732}
4733
4734
4735static void gen_trap(DisasContext *ctx, uint32_t opc,
4736 int rs, int rt, int16_t imm, int code)
4737{
4738 int cond;
4739 TCGv t0 = tcg_temp_new();
4740 TCGv t1 = tcg_temp_new();
4741
4742 cond = 0;
4743
4744 switch (opc) {
4745 case OPC_TEQ:
4746 case OPC_TGE:
4747 case OPC_TGEU:
4748 case OPC_TLT:
4749 case OPC_TLTU:
4750 case OPC_TNE:
4751
4752 if (rs != rt) {
4753 gen_load_gpr(t0, rs);
4754 gen_load_gpr(t1, rt);
4755 cond = 1;
4756 }
4757 break;
4758 case OPC_TEQI:
4759 case OPC_TGEI:
4760 case OPC_TGEIU:
4761 case OPC_TLTI:
4762 case OPC_TLTIU:
4763 case OPC_TNEI:
4764
4765 if (rs != 0 || imm != 0) {
4766 gen_load_gpr(t0, rs);
4767 tcg_gen_movi_tl(t1, (int32_t)imm);
4768 cond = 1;
4769 }
4770 break;
4771 }
4772 if (cond == 0) {
4773 switch (opc) {
4774 case OPC_TEQ:
4775 case OPC_TEQI:
4776 case OPC_TGE:
4777 case OPC_TGEI:
4778 case OPC_TGEU:
4779 case OPC_TGEIU:
4780
4781#ifdef CONFIG_USER_ONLY
4782
4783 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4784 offsetof(CPUMIPSState, error_code));
4785#endif
4786 generate_exception_end(ctx, EXCP_TRAP);
4787 break;
4788 case OPC_TLT:
4789 case OPC_TLTI:
4790 case OPC_TLTU:
4791 case OPC_TLTIU:
4792 case OPC_TNE:
4793 case OPC_TNEI:
4794
4795 break;
4796 }
4797 } else {
4798 TCGLabel *l1 = gen_new_label();
4799
4800 switch (opc) {
4801 case OPC_TEQ:
4802 case OPC_TEQI:
4803 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4804 break;
4805 case OPC_TGE:
4806 case OPC_TGEI:
4807 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4808 break;
4809 case OPC_TGEU:
4810 case OPC_TGEIU:
4811 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4812 break;
4813 case OPC_TLT:
4814 case OPC_TLTI:
4815 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4816 break;
4817 case OPC_TLTU:
4818 case OPC_TLTIU:
4819 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4820 break;
4821 case OPC_TNE:
4822 case OPC_TNEI:
4823 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4824 break;
4825 }
4826#ifdef CONFIG_USER_ONLY
4827
4828 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4829 offsetof(CPUMIPSState, error_code));
4830#endif
4831
4832 if (ctx->base.pc_next != ctx->saved_pc) {
4833 gen_save_pc(ctx->base.pc_next);
4834 }
4835 if (ctx->hflags != ctx->saved_hflags) {
4836 tcg_gen_movi_i32(hflags, ctx->hflags);
4837 }
4838 generate_exception(ctx, EXCP_TRAP);
4839 gen_set_label(l1);
4840 }
4841 tcg_temp_free(t0);
4842 tcg_temp_free(t1);
4843}
4844
4845static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4846{
4847 if (translator_use_goto_tb(&ctx->base, dest)) {
4848 tcg_gen_goto_tb(n);
4849 gen_save_pc(dest);
4850 tcg_gen_exit_tb(ctx->base.tb, n);
4851 } else {
4852 gen_save_pc(dest);
4853 tcg_gen_lookup_and_goto_ptr();
4854 }
4855}
4856
4857
4858static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4859 int insn_bytes,
4860 int rs, int rt, int32_t offset,
4861 int delayslot_size)
4862{
4863 target_ulong btgt = -1;
4864 int blink = 0;
4865 int bcond_compute = 0;
4866 TCGv t0 = tcg_temp_new();
4867 TCGv t1 = tcg_temp_new();
4868
4869 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4870#ifdef MIPS_DEBUG_DISAS
4871 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4872 TARGET_FMT_lx "\n", ctx->base.pc_next);
4873#endif
4874 gen_reserved_instruction(ctx);
4875 goto out;
4876 }
4877
4878
4879 switch (opc) {
4880 case OPC_BEQ:
4881 case OPC_BEQL:
4882 case OPC_BNE:
4883 case OPC_BNEL:
4884
4885 if (rs != rt) {
4886 gen_load_gpr(t0, rs);
4887 gen_load_gpr(t1, rt);
4888 bcond_compute = 1;
4889 }
4890 btgt = ctx->base.pc_next + insn_bytes + offset;
4891 break;
4892 case OPC_BGEZ:
4893 case OPC_BGEZAL:
4894 case OPC_BGEZALL:
4895 case OPC_BGEZL:
4896 case OPC_BGTZ:
4897 case OPC_BGTZL:
4898 case OPC_BLEZ:
4899 case OPC_BLEZL:
4900 case OPC_BLTZ:
4901 case OPC_BLTZAL:
4902 case OPC_BLTZALL:
4903 case OPC_BLTZL:
4904
4905 if (rs != 0) {
4906 gen_load_gpr(t0, rs);
4907 bcond_compute = 1;
4908 }
4909 btgt = ctx->base.pc_next + insn_bytes + offset;
4910 break;
4911 case OPC_BPOSGE32:
4912#if defined(TARGET_MIPS64)
4913 case OPC_BPOSGE64:
4914 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4915#else
4916 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4917#endif
4918 bcond_compute = 1;
4919 btgt = ctx->base.pc_next + insn_bytes + offset;
4920 break;
4921 case OPC_J:
4922 case OPC_JAL:
4923 case OPC_JALX:
4924
4925 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4926 (uint32_t)offset;
4927 break;
4928 case OPC_JR:
4929 case OPC_JALR:
4930
4931 if (offset != 0 && offset != 16) {
4932
4933
4934
4935
4936 MIPS_INVAL("jump hint");
4937 gen_reserved_instruction(ctx);
4938 goto out;
4939 }
4940 gen_load_gpr(btarget, rs);
4941 break;
4942 default:
4943 MIPS_INVAL("branch/jump");
4944 gen_reserved_instruction(ctx);
4945 goto out;
4946 }
4947 if (bcond_compute == 0) {
4948
4949 switch (opc) {
4950 case OPC_BEQ:
4951 case OPC_BEQL:
4952 case OPC_BGEZ:
4953 case OPC_BGEZL:
4954 case OPC_BLEZ:
4955 case OPC_BLEZL:
4956
4957 ctx->hflags |= MIPS_HFLAG_B;
4958 break;
4959 case OPC_BGEZAL:
4960 case OPC_BGEZALL:
4961
4962 blink = 31;
4963 ctx->hflags |= MIPS_HFLAG_B;
4964 break;
4965 case OPC_BNE:
4966 case OPC_BGTZ:
4967 case OPC_BLTZ:
4968
4969 goto out;
4970 case OPC_BLTZAL:
4971
4972
4973
4974
4975 blink = 31;
4976 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4977 ctx->hflags |= MIPS_HFLAG_B;
4978 break;
4979 case OPC_BLTZALL:
4980 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4981
4982 ctx->base.pc_next += 4;
4983 goto out;
4984 case OPC_BNEL:
4985 case OPC_BGTZL:
4986 case OPC_BLTZL:
4987
4988 ctx->base.pc_next += 4;
4989 goto out;
4990 case OPC_J:
4991 ctx->hflags |= MIPS_HFLAG_B;
4992 break;
4993 case OPC_JALX:
4994 ctx->hflags |= MIPS_HFLAG_BX;
4995
4996 case OPC_JAL:
4997 blink = 31;
4998 ctx->hflags |= MIPS_HFLAG_B;
4999 break;
5000 case OPC_JR:
5001 ctx->hflags |= MIPS_HFLAG_BR;
5002 break;
5003 case OPC_JALR:
5004 blink = rt;
5005 ctx->hflags |= MIPS_HFLAG_BR;
5006 break;
5007 default:
5008 MIPS_INVAL("branch/jump");
5009 gen_reserved_instruction(ctx);
5010 goto out;
5011 }
5012 } else {
5013 switch (opc) {
5014 case OPC_BEQ:
5015 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5016 goto not_likely;
5017 case OPC_BEQL:
5018 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5019 goto likely;
5020 case OPC_BNE:
5021 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5022 goto not_likely;
5023 case OPC_BNEL:
5024 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5025 goto likely;
5026 case OPC_BGEZ:
5027 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5028 goto not_likely;
5029 case OPC_BGEZL:
5030 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5031 goto likely;
5032 case OPC_BGEZAL:
5033 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5034 blink = 31;
5035 goto not_likely;
5036 case OPC_BGEZALL:
5037 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5038 blink = 31;
5039 goto likely;
5040 case OPC_BGTZ:
5041 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5042 goto not_likely;
5043 case OPC_BGTZL:
5044 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5045 goto likely;
5046 case OPC_BLEZ:
5047 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5048 goto not_likely;
5049 case OPC_BLEZL:
5050 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5051 goto likely;
5052 case OPC_BLTZ:
5053 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5054 goto not_likely;
5055 case OPC_BLTZL:
5056 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5057 goto likely;
5058 case OPC_BPOSGE32:
5059 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5060 goto not_likely;
5061#if defined(TARGET_MIPS64)
5062 case OPC_BPOSGE64:
5063 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5064 goto not_likely;
5065#endif
5066 case OPC_BLTZAL:
5067 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5068 blink = 31;
5069 not_likely:
5070 ctx->hflags |= MIPS_HFLAG_BC;
5071 break;
5072 case OPC_BLTZALL:
5073 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5074 blink = 31;
5075 likely:
5076 ctx->hflags |= MIPS_HFLAG_BL;
5077 break;
5078 default:
5079 MIPS_INVAL("conditional branch/jump");
5080 gen_reserved_instruction(ctx);
5081 goto out;
5082 }
5083 }
5084
5085 ctx->btarget = btgt;
5086
5087 switch (delayslot_size) {
5088 case 2:
5089 ctx->hflags |= MIPS_HFLAG_BDS16;
5090 break;
5091 case 4:
5092 ctx->hflags |= MIPS_HFLAG_BDS32;
5093 break;
5094 }
5095
5096 if (blink > 0) {
5097 int post_delay = insn_bytes + delayslot_size;
5098 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5099
5100 tcg_gen_movi_tl(cpu_gpr[blink],
5101 ctx->base.pc_next + post_delay + lowbit);
5102 }
5103
5104 out:
5105 if (insn_bytes == 2) {
5106 ctx->hflags |= MIPS_HFLAG_B16;
5107 }
5108 tcg_temp_free(t0);
5109 tcg_temp_free(t1);
5110}
5111
5112
5113
5114static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5115 int rs, int lsb, int msb)
5116{
5117 TCGv t0 = tcg_temp_new();
5118 TCGv t1 = tcg_temp_new();
5119
5120 gen_load_gpr(t1, rs);
5121 switch (opc) {
5122 case OPC_EXT:
5123 if (lsb + msb > 31) {
5124 goto fail;
5125 }
5126 if (msb != 31) {
5127 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5128 } else {
5129
5130
5131
5132
5133 tcg_gen_ext32s_tl(t0, t1);
5134 }
5135 break;
5136#if defined(TARGET_MIPS64)
5137 case OPC_DEXTU:
5138 lsb += 32;
5139 goto do_dext;
5140 case OPC_DEXTM:
5141 msb += 32;
5142 goto do_dext;
5143 case OPC_DEXT:
5144 do_dext:
5145 if (lsb + msb > 63) {
5146 goto fail;
5147 }
5148 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5149 break;
5150#endif
5151 case OPC_INS:
5152 if (lsb > msb) {
5153 goto fail;
5154 }
5155 gen_load_gpr(t0, rt);
5156 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5157 tcg_gen_ext32s_tl(t0, t0);
5158 break;
5159#if defined(TARGET_MIPS64)
5160 case OPC_DINSU:
5161 lsb += 32;
5162
5163 case OPC_DINSM:
5164 msb += 32;
5165
5166 case OPC_DINS:
5167 if (lsb > msb) {
5168 goto fail;
5169 }
5170 gen_load_gpr(t0, rt);
5171 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5172 break;
5173#endif
5174 default:
5175fail:
5176 MIPS_INVAL("bitops");
5177 gen_reserved_instruction(ctx);
5178 tcg_temp_free(t0);
5179 tcg_temp_free(t1);
5180 return;
5181 }
5182 gen_store_gpr(t0, rt);
5183 tcg_temp_free(t0);
5184 tcg_temp_free(t1);
5185}
5186
5187static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5188{
5189 TCGv t0;
5190
5191 if (rd == 0) {
5192
5193 return;
5194 }
5195
5196 t0 = tcg_temp_new();
5197 gen_load_gpr(t0, rt);
5198 switch (op2) {
5199 case OPC_WSBH:
5200 {
5201 TCGv t1 = tcg_temp_new();
5202 TCGv t2 = tcg_const_tl(0x00FF00FF);
5203
5204 tcg_gen_shri_tl(t1, t0, 8);
5205 tcg_gen_and_tl(t1, t1, t2);
5206 tcg_gen_and_tl(t0, t0, t2);
5207 tcg_gen_shli_tl(t0, t0, 8);
5208 tcg_gen_or_tl(t0, t0, t1);
5209 tcg_temp_free(t2);
5210 tcg_temp_free(t1);
5211 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5212 }
5213 break;
5214 case OPC_SEB:
5215 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5216 break;
5217 case OPC_SEH:
5218 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5219 break;
5220#if defined(TARGET_MIPS64)
5221 case OPC_DSBH:
5222 {
5223 TCGv t1 = tcg_temp_new();
5224 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5225
5226 tcg_gen_shri_tl(t1, t0, 8);
5227 tcg_gen_and_tl(t1, t1, t2);
5228 tcg_gen_and_tl(t0, t0, t2);
5229 tcg_gen_shli_tl(t0, t0, 8);
5230 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5231 tcg_temp_free(t2);
5232 tcg_temp_free(t1);
5233 }
5234 break;
5235 case OPC_DSHD:
5236 {
5237 TCGv t1 = tcg_temp_new();
5238 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5239
5240 tcg_gen_shri_tl(t1, t0, 16);
5241 tcg_gen_and_tl(t1, t1, t2);
5242 tcg_gen_and_tl(t0, t0, t2);
5243 tcg_gen_shli_tl(t0, t0, 16);
5244 tcg_gen_or_tl(t0, t0, t1);
5245 tcg_gen_shri_tl(t1, t0, 32);
5246 tcg_gen_shli_tl(t0, t0, 32);
5247 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5248 tcg_temp_free(t2);
5249 tcg_temp_free(t1);
5250 }
5251 break;
5252#endif
5253 default:
5254 MIPS_INVAL("bsfhl");
5255 gen_reserved_instruction(ctx);
5256 tcg_temp_free(t0);
5257 return;
5258 }
5259 tcg_temp_free(t0);
5260}
5261
5262static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5263 int rt, int bits)
5264{
5265 TCGv t0;
5266 if (rd == 0) {
5267
5268 return;
5269 }
5270 t0 = tcg_temp_new();
5271 if (bits == 0 || bits == wordsz) {
5272 if (bits == 0) {
5273 gen_load_gpr(t0, rt);
5274 } else {
5275 gen_load_gpr(t0, rs);
5276 }
5277 switch (wordsz) {
5278 case 32:
5279 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5280 break;
5281#if defined(TARGET_MIPS64)
5282 case 64:
5283 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5284 break;
5285#endif
5286 }
5287 } else {
5288 TCGv t1 = tcg_temp_new();
5289 gen_load_gpr(t0, rt);
5290 gen_load_gpr(t1, rs);
5291 switch (wordsz) {
5292 case 32:
5293 {
5294 TCGv_i64 t2 = tcg_temp_new_i64();
5295 tcg_gen_concat_tl_i64(t2, t1, t0);
5296 tcg_gen_shri_i64(t2, t2, 32 - bits);
5297 gen_move_low32(cpu_gpr[rd], t2);
5298 tcg_temp_free_i64(t2);
5299 }
5300 break;
5301#if defined(TARGET_MIPS64)
5302 case 64:
5303 tcg_gen_shli_tl(t0, t0, bits);
5304 tcg_gen_shri_tl(t1, t1, 64 - bits);
5305 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5306 break;
5307#endif
5308 }
5309 tcg_temp_free(t1);
5310 }
5311
5312 tcg_temp_free(t0);
5313}
5314
5315void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5316{
5317 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5318}
5319
5320static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5321{
5322 TCGv t0;
5323 if (rd == 0) {
5324
5325 return;
5326 }
5327 t0 = tcg_temp_new();
5328 gen_load_gpr(t0, rt);
5329 switch (opc) {
5330 case OPC_BITSWAP:
5331 gen_helper_bitswap(cpu_gpr[rd], t0);
5332 break;
5333#if defined(TARGET_MIPS64)
5334 case OPC_DBITSWAP:
5335 gen_helper_dbitswap(cpu_gpr[rd], t0);
5336 break;
5337#endif
5338 }
5339 tcg_temp_free(t0);
5340}
5341
5342#ifndef CONFIG_USER_ONLY
5343
5344static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5345{
5346 TCGv_i64 t0 = tcg_temp_new_i64();
5347 TCGv_i64 t1 = tcg_temp_new_i64();
5348
5349 tcg_gen_ext_tl_i64(t0, arg);
5350 tcg_gen_ld_i64(t1, cpu_env, off);
5351#if defined(TARGET_MIPS64)
5352 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5353#else
5354 tcg_gen_concat32_i64(t1, t1, t0);
5355#endif
5356 tcg_gen_st_i64(t1, cpu_env, off);
5357 tcg_temp_free_i64(t1);
5358 tcg_temp_free_i64(t0);
5359}
5360
5361static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5362{
5363 TCGv_i64 t0 = tcg_temp_new_i64();
5364 TCGv_i64 t1 = tcg_temp_new_i64();
5365
5366 tcg_gen_ext_tl_i64(t0, arg);
5367 tcg_gen_ld_i64(t1, cpu_env, off);
5368 tcg_gen_concat32_i64(t1, t1, t0);
5369 tcg_gen_st_i64(t1, cpu_env, off);
5370 tcg_temp_free_i64(t1);
5371 tcg_temp_free_i64(t0);
5372}
5373
5374static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5375{
5376 TCGv_i64 t0 = tcg_temp_new_i64();
5377
5378 tcg_gen_ld_i64(t0, cpu_env, off);
5379#if defined(TARGET_MIPS64)
5380 tcg_gen_shri_i64(t0, t0, 30);
5381#else
5382 tcg_gen_shri_i64(t0, t0, 32);
5383#endif
5384 gen_move_low32(arg, t0);
5385 tcg_temp_free_i64(t0);
5386}
5387
5388static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5389{
5390 TCGv_i64 t0 = tcg_temp_new_i64();
5391
5392 tcg_gen_ld_i64(t0, cpu_env, off);
5393 tcg_gen_shri_i64(t0, t0, 32 + shift);
5394 gen_move_low32(arg, t0);
5395 tcg_temp_free_i64(t0);
5396}
5397
5398static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5399{
5400 TCGv_i32 t0 = tcg_temp_new_i32();
5401
5402 tcg_gen_ld_i32(t0, cpu_env, off);
5403 tcg_gen_ext_i32_tl(arg, t0);
5404 tcg_temp_free_i32(t0);
5405}
5406
5407static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5408{
5409 tcg_gen_ld_tl(arg, cpu_env, off);
5410 tcg_gen_ext32s_tl(arg, arg);
5411}
5412
5413static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5414{
5415 TCGv_i32 t0 = tcg_temp_new_i32();
5416
5417 tcg_gen_trunc_tl_i32(t0, arg);
5418 tcg_gen_st_i32(t0, cpu_env, off);
5419 tcg_temp_free_i32(t0);
5420}
5421
5422#define CP0_CHECK(c) \
5423 do { \
5424 if (!(c)) { \
5425 goto cp0_unimplemented; \
5426 } \
5427 } while (0)
5428
5429static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5430{
5431 const char *register_name = "invalid";
5432
5433 switch (reg) {
5434 case CP0_REGISTER_02:
5435 switch (sel) {
5436 case 0:
5437 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5438 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5439 register_name = "EntryLo0";
5440 break;
5441 default:
5442 goto cp0_unimplemented;
5443 }
5444 break;
5445 case CP0_REGISTER_03:
5446 switch (sel) {
5447 case CP0_REG03__ENTRYLO1:
5448 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5449 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5450 register_name = "EntryLo1";
5451 break;
5452 default:
5453 goto cp0_unimplemented;
5454 }
5455 break;
5456 case CP0_REGISTER_09:
5457 switch (sel) {
5458 case CP0_REG09__SAAR:
5459 CP0_CHECK(ctx->saar);
5460 gen_helper_mfhc0_saar(arg, cpu_env);
5461 register_name = "SAAR";
5462 break;
5463 default:
5464 goto cp0_unimplemented;
5465 }
5466 break;
5467 case CP0_REGISTER_17:
5468 switch (sel) {
5469 case CP0_REG17__LLADDR:
5470 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5471 ctx->CP0_LLAddr_shift);
5472 register_name = "LLAddr";
5473 break;
5474 case CP0_REG17__MAAR:
5475 CP0_CHECK(ctx->mrp);
5476 gen_helper_mfhc0_maar(arg, cpu_env);
5477 register_name = "MAAR";
5478 break;
5479 default:
5480 goto cp0_unimplemented;
5481 }
5482 break;
5483 case CP0_REGISTER_19:
5484 switch (sel) {
5485 case CP0_REG19__WATCHHI0:
5486 case CP0_REG19__WATCHHI1:
5487 case CP0_REG19__WATCHHI2:
5488 case CP0_REG19__WATCHHI3:
5489 case CP0_REG19__WATCHHI4:
5490 case CP0_REG19__WATCHHI5:
5491 case CP0_REG19__WATCHHI6:
5492 case CP0_REG19__WATCHHI7:
5493
5494 CP0_CHECK(ctx->mi);
5495 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5496 register_name = "WatchHi";
5497 break;
5498 default:
5499 goto cp0_unimplemented;
5500 }
5501 break;
5502 case CP0_REGISTER_28:
5503 switch (sel) {
5504 case 0:
5505 case 2:
5506 case 4:
5507 case 6:
5508 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5509 register_name = "TagLo";
5510 break;
5511 default:
5512 goto cp0_unimplemented;
5513 }
5514 break;
5515 default:
5516 goto cp0_unimplemented;
5517 }
5518 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5519 return;
5520
5521cp0_unimplemented:
5522 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5523 register_name, reg, sel);
5524 tcg_gen_movi_tl(arg, 0);
5525}
5526
5527static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5528{
5529 const char *register_name = "invalid";
5530 uint64_t mask = ctx->PAMask >> 36;
5531
5532 switch (reg) {
5533 case CP0_REGISTER_02:
5534 switch (sel) {
5535 case 0:
5536 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5537 tcg_gen_andi_tl(arg, arg, mask);
5538 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5539 register_name = "EntryLo0";
5540 break;
5541 default:
5542 goto cp0_unimplemented;
5543 }
5544 break;
5545 case CP0_REGISTER_03:
5546 switch (sel) {
5547 case CP0_REG03__ENTRYLO1:
5548 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5549 tcg_gen_andi_tl(arg, arg, mask);
5550 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5551 register_name = "EntryLo1";
5552 break;
5553 default:
5554 goto cp0_unimplemented;
5555 }
5556 break;
5557 case CP0_REGISTER_09:
5558 switch (sel) {
5559 case CP0_REG09__SAAR:
5560 CP0_CHECK(ctx->saar);
5561 gen_helper_mthc0_saar(cpu_env, arg);
5562 register_name = "SAAR";
5563 break;
5564 default:
5565 goto cp0_unimplemented;
5566 }
5567 break;
5568 case CP0_REGISTER_17:
5569 switch (sel) {
5570 case CP0_REG17__LLADDR:
5571
5572
5573
5574
5575
5576
5577 register_name = "LLAddr";
5578 break;
5579 case CP0_REG17__MAAR:
5580 CP0_CHECK(ctx->mrp);
5581 gen_helper_mthc0_maar(cpu_env, arg);
5582 register_name = "MAAR";
5583 break;
5584 default:
5585 goto cp0_unimplemented;
5586 }
5587 break;
5588 case CP0_REGISTER_19:
5589 switch (sel) {
5590 case CP0_REG19__WATCHHI0:
5591 case CP0_REG19__WATCHHI1:
5592 case CP0_REG19__WATCHHI2:
5593 case CP0_REG19__WATCHHI3:
5594 case CP0_REG19__WATCHHI4:
5595 case CP0_REG19__WATCHHI5:
5596 case CP0_REG19__WATCHHI6:
5597 case CP0_REG19__WATCHHI7:
5598
5599 CP0_CHECK(ctx->mi);
5600 gen_helper_0e1i(mthc0_watchhi, arg, sel);
5601 register_name = "WatchHi";
5602 break;
5603 default:
5604 goto cp0_unimplemented;
5605 }
5606 break;
5607 case CP0_REGISTER_28:
5608 switch (sel) {
5609 case 0:
5610 case 2:
5611 case 4:
5612 case 6:
5613 tcg_gen_andi_tl(arg, arg, mask);
5614 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5615 register_name = "TagLo";
5616 break;
5617 default:
5618 goto cp0_unimplemented;
5619 }
5620 break;
5621 default:
5622 goto cp0_unimplemented;
5623 }
5624 trace_mips_translate_c0("mthc0", register_name, reg, sel);
5625 return;
5626
5627cp0_unimplemented:
5628 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5629 register_name, reg, sel);
5630}
5631
5632static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5633{
5634 if (ctx->insn_flags & ISA_MIPS_R6) {
5635 tcg_gen_movi_tl(arg, 0);
5636 } else {
5637 tcg_gen_movi_tl(arg, ~0);
5638 }
5639}
5640
5641static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5642{
5643 const char *register_name = "invalid";
5644
5645 if (sel != 0) {
5646 check_insn(ctx, ISA_MIPS_R1);
5647 }
5648
5649 switch (reg) {
5650 case CP0_REGISTER_00:
5651 switch (sel) {
5652 case CP0_REG00__INDEX:
5653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5654 register_name = "Index";
5655 break;
5656 case CP0_REG00__MVPCONTROL:
5657 CP0_CHECK(ctx->insn_flags & ASE_MT);
5658 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5659 register_name = "MVPControl";
5660 break;
5661 case CP0_REG00__MVPCONF0:
5662 CP0_CHECK(ctx->insn_flags & ASE_MT);
5663 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5664 register_name = "MVPConf0";
5665 break;
5666 case CP0_REG00__MVPCONF1:
5667 CP0_CHECK(ctx->insn_flags & ASE_MT);
5668 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5669 register_name = "MVPConf1";
5670 break;
5671 case CP0_REG00__VPCONTROL:
5672 CP0_CHECK(ctx->vp);
5673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5674 register_name = "VPControl";
5675 break;
5676 default:
5677 goto cp0_unimplemented;
5678 }
5679 break;
5680 case CP0_REGISTER_01:
5681 switch (sel) {
5682 case CP0_REG01__RANDOM:
5683 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5684 gen_helper_mfc0_random(arg, cpu_env);
5685 register_name = "Random";
5686 break;
5687 case CP0_REG01__VPECONTROL:
5688 CP0_CHECK(ctx->insn_flags & ASE_MT);
5689 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5690 register_name = "VPEControl";
5691 break;
5692 case CP0_REG01__VPECONF0:
5693 CP0_CHECK(ctx->insn_flags & ASE_MT);
5694 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5695 register_name = "VPEConf0";
5696 break;
5697 case CP0_REG01__VPECONF1:
5698 CP0_CHECK(ctx->insn_flags & ASE_MT);
5699 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5700 register_name = "VPEConf1";
5701 break;
5702 case CP0_REG01__YQMASK:
5703 CP0_CHECK(ctx->insn_flags & ASE_MT);
5704 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5705 register_name = "YQMask";
5706 break;
5707 case CP0_REG01__VPESCHEDULE:
5708 CP0_CHECK(ctx->insn_flags & ASE_MT);
5709 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5710 register_name = "VPESchedule";
5711 break;
5712 case CP0_REG01__VPESCHEFBACK:
5713 CP0_CHECK(ctx->insn_flags & ASE_MT);
5714 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5715 register_name = "VPEScheFBack";
5716 break;
5717 case CP0_REG01__VPEOPT:
5718 CP0_CHECK(ctx->insn_flags & ASE_MT);
5719 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5720 register_name = "VPEOpt";
5721 break;
5722 default:
5723 goto cp0_unimplemented;
5724 }
5725 break;
5726 case CP0_REGISTER_02:
5727 switch (sel) {
5728 case CP0_REG02__ENTRYLO0:
5729 {
5730 TCGv_i64 tmp = tcg_temp_new_i64();
5731 tcg_gen_ld_i64(tmp, cpu_env,
5732 offsetof(CPUMIPSState, CP0_EntryLo0));
5733#if defined(TARGET_MIPS64)
5734 if (ctx->rxi) {
5735
5736 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5737 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5738 }
5739#endif
5740 gen_move_low32(arg, tmp);
5741 tcg_temp_free_i64(tmp);
5742 }
5743 register_name = "EntryLo0";
5744 break;
5745 case CP0_REG02__TCSTATUS:
5746 CP0_CHECK(ctx->insn_flags & ASE_MT);
5747 gen_helper_mfc0_tcstatus(arg, cpu_env);
5748 register_name = "TCStatus";
5749 break;
5750 case CP0_REG02__TCBIND:
5751 CP0_CHECK(ctx->insn_flags & ASE_MT);
5752 gen_helper_mfc0_tcbind(arg, cpu_env);
5753 register_name = "TCBind";
5754 break;
5755 case CP0_REG02__TCRESTART:
5756 CP0_CHECK(ctx->insn_flags & ASE_MT);
5757 gen_helper_mfc0_tcrestart(arg, cpu_env);
5758 register_name = "TCRestart";
5759 break;
5760 case CP0_REG02__TCHALT:
5761 CP0_CHECK(ctx->insn_flags & ASE_MT);
5762 gen_helper_mfc0_tchalt(arg, cpu_env);
5763 register_name = "TCHalt";
5764 break;
5765 case CP0_REG02__TCCONTEXT:
5766 CP0_CHECK(ctx->insn_flags & ASE_MT);
5767 gen_helper_mfc0_tccontext(arg, cpu_env);
5768 register_name = "TCContext";
5769 break;
5770 case CP0_REG02__TCSCHEDULE:
5771 CP0_CHECK(ctx->insn_flags & ASE_MT);
5772 gen_helper_mfc0_tcschedule(arg, cpu_env);
5773 register_name = "TCSchedule";
5774 break;
5775 case CP0_REG02__TCSCHEFBACK:
5776 CP0_CHECK(ctx->insn_flags & ASE_MT);
5777 gen_helper_mfc0_tcschefback(arg, cpu_env);
5778 register_name = "TCScheFBack";
5779 break;
5780 default:
5781 goto cp0_unimplemented;
5782 }
5783 break;
5784 case CP0_REGISTER_03:
5785 switch (sel) {
5786 case CP0_REG03__ENTRYLO1:
5787 {
5788 TCGv_i64 tmp = tcg_temp_new_i64();
5789 tcg_gen_ld_i64(tmp, cpu_env,
5790 offsetof(CPUMIPSState, CP0_EntryLo1));
5791#if defined(TARGET_MIPS64)
5792 if (ctx->rxi) {
5793
5794 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5795 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5796 }
5797#endif
5798 gen_move_low32(arg, tmp);
5799 tcg_temp_free_i64(tmp);
5800 }
5801 register_name = "EntryLo1";
5802 break;
5803 case CP0_REG03__GLOBALNUM:
5804 CP0_CHECK(ctx->vp);
5805 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5806 register_name = "GlobalNumber";
5807 break;
5808 default:
5809 goto cp0_unimplemented;
5810 }
5811 break;
5812 case CP0_REGISTER_04:
5813 switch (sel) {
5814 case CP0_REG04__CONTEXT:
5815 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5816 tcg_gen_ext32s_tl(arg, arg);
5817 register_name = "Context";
5818 break;
5819 case CP0_REG04__CONTEXTCONFIG:
5820
5821
5822 register_name = "ContextConfig";
5823 goto cp0_unimplemented;
5824 case CP0_REG04__USERLOCAL:
5825 CP0_CHECK(ctx->ulri);
5826 tcg_gen_ld_tl(arg, cpu_env,
5827 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5828 tcg_gen_ext32s_tl(arg, arg);
5829 register_name = "UserLocal";
5830 break;
5831 case CP0_REG04__MMID:
5832 CP0_CHECK(ctx->mi);
5833 gen_helper_mtc0_memorymapid(cpu_env, arg);
5834 register_name = "MMID";
5835 break;
5836 default:
5837 goto cp0_unimplemented;
5838 }
5839 break;
5840 case CP0_REGISTER_05:
5841 switch (sel) {
5842 case CP0_REG05__PAGEMASK:
5843 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5844 register_name = "PageMask";
5845 break;
5846 case CP0_REG05__PAGEGRAIN:
5847 check_insn(ctx, ISA_MIPS_R2);
5848 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5849 register_name = "PageGrain";
5850 break;
5851 case CP0_REG05__SEGCTL0:
5852 CP0_CHECK(ctx->sc);
5853 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5854 tcg_gen_ext32s_tl(arg, arg);
5855 register_name = "SegCtl0";
5856 break;
5857 case CP0_REG05__SEGCTL1:
5858 CP0_CHECK(ctx->sc);
5859 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5860 tcg_gen_ext32s_tl(arg, arg);
5861 register_name = "SegCtl1";
5862 break;
5863 case CP0_REG05__SEGCTL2:
5864 CP0_CHECK(ctx->sc);
5865 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5866 tcg_gen_ext32s_tl(arg, arg);
5867 register_name = "SegCtl2";
5868 break;
5869 case CP0_REG05__PWBASE:
5870 check_pw(ctx);
5871 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5872 register_name = "PWBase";
5873 break;
5874 case CP0_REG05__PWFIELD:
5875 check_pw(ctx);
5876 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5877 register_name = "PWField";
5878 break;
5879 case CP0_REG05__PWSIZE:
5880 check_pw(ctx);
5881 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5882 register_name = "PWSize";
5883 break;
5884 default:
5885 goto cp0_unimplemented;
5886 }
5887 break;
5888 case CP0_REGISTER_06:
5889 switch (sel) {
5890 case CP0_REG06__WIRED:
5891 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5892 register_name = "Wired";
5893 break;
5894 case CP0_REG06__SRSCONF0:
5895 check_insn(ctx, ISA_MIPS_R2);
5896 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5897 register_name = "SRSConf0";
5898 break;
5899 case CP0_REG06__SRSCONF1:
5900 check_insn(ctx, ISA_MIPS_R2);
5901 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5902 register_name = "SRSConf1";
5903 break;
5904 case CP0_REG06__SRSCONF2:
5905 check_insn(ctx, ISA_MIPS_R2);
5906 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5907 register_name = "SRSConf2";
5908 break;
5909 case CP0_REG06__SRSCONF3:
5910 check_insn(ctx, ISA_MIPS_R2);
5911 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5912 register_name = "SRSConf3";
5913 break;
5914 case CP0_REG06__SRSCONF4:
5915 check_insn(ctx, ISA_MIPS_R2);
5916 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5917 register_name = "SRSConf4";
5918 break;
5919 case CP0_REG06__PWCTL:
5920 check_pw(ctx);
5921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5922 register_name = "PWCtl";
5923 break;
5924 default:
5925 goto cp0_unimplemented;
5926 }
5927 break;
5928 case CP0_REGISTER_07:
5929 switch (sel) {
5930 case CP0_REG07__HWRENA:
5931 check_insn(ctx, ISA_MIPS_R2);
5932 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5933 register_name = "HWREna";
5934 break;
5935 default:
5936 goto cp0_unimplemented;
5937 }
5938 break;
5939 case CP0_REGISTER_08:
5940 switch (sel) {
5941 case CP0_REG08__BADVADDR:
5942 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5943 tcg_gen_ext32s_tl(arg, arg);
5944 register_name = "BadVAddr";
5945 break;
5946 case CP0_REG08__BADINSTR:
5947 CP0_CHECK(ctx->bi);
5948 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5949 register_name = "BadInstr";
5950 break;
5951 case CP0_REG08__BADINSTRP:
5952 CP0_CHECK(ctx->bp);
5953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5954 register_name = "BadInstrP";
5955 break;
5956 case CP0_REG08__BADINSTRX:
5957 CP0_CHECK(ctx->bi);
5958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5959 tcg_gen_andi_tl(arg, arg, ~0xffff);
5960 register_name = "BadInstrX";
5961 break;
5962 default:
5963 goto cp0_unimplemented;
5964 }
5965 break;
5966 case CP0_REGISTER_09:
5967 switch (sel) {
5968 case CP0_REG09__COUNT:
5969
5970 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
5971 gen_io_start();
5972 }
5973 gen_helper_mfc0_count(arg, cpu_env);
5974
5975
5976
5977
5978
5979 gen_save_pc(ctx->base.pc_next + 4);
5980 ctx->base.is_jmp = DISAS_EXIT;
5981 register_name = "Count";
5982 break;
5983 case CP0_REG09__SAARI:
5984 CP0_CHECK(ctx->saar);
5985 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5986 register_name = "SAARI";
5987 break;
5988 case CP0_REG09__SAAR:
5989 CP0_CHECK(ctx->saar);
5990 gen_helper_mfc0_saar(arg, cpu_env);
5991 register_name = "SAAR";
5992 break;
5993 default:
5994 goto cp0_unimplemented;
5995 }
5996 break;
5997 case CP0_REGISTER_10:
5998 switch (sel) {
5999 case CP0_REG10__ENTRYHI:
6000 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6001 tcg_gen_ext32s_tl(arg, arg);
6002 register_name = "EntryHi";
6003 break;
6004 default:
6005 goto cp0_unimplemented;
6006 }
6007 break;
6008 case CP0_REGISTER_11:
6009 switch (sel) {
6010 case CP0_REG11__COMPARE:
6011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6012 register_name = "Compare";
6013 break;
6014
6015 default:
6016 goto cp0_unimplemented;
6017 }
6018 break;
6019 case CP0_REGISTER_12:
6020 switch (sel) {
6021 case CP0_REG12__STATUS:
6022 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6023 register_name = "Status";
6024 break;
6025 case CP0_REG12__INTCTL:
6026 check_insn(ctx, ISA_MIPS_R2);
6027 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6028 register_name = "IntCtl";
6029 break;
6030 case CP0_REG12__SRSCTL:
6031 check_insn(ctx, ISA_MIPS_R2);
6032 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6033 register_name = "SRSCtl";
6034 break;
6035 case CP0_REG12__SRSMAP:
6036 check_insn(ctx, ISA_MIPS_R2);
6037 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6038 register_name = "SRSMap";
6039 break;
6040 default:
6041 goto cp0_unimplemented;
6042 }
6043 break;
6044 case CP0_REGISTER_13:
6045 switch (sel) {
6046 case CP0_REG13__CAUSE:
6047 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6048 register_name = "Cause";
6049 break;
6050 default:
6051 goto cp0_unimplemented;
6052 }
6053 break;
6054 case CP0_REGISTER_14:
6055 switch (sel) {
6056 case CP0_REG14__EPC:
6057 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6058 tcg_gen_ext32s_tl(arg, arg);
6059 register_name = "EPC";
6060 break;
6061 default:
6062 goto cp0_unimplemented;
6063 }
6064 break;
6065 case CP0_REGISTER_15:
6066 switch (sel) {
6067 case CP0_REG15__PRID:
6068 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6069 register_name = "PRid";
6070 break;
6071 case CP0_REG15__EBASE:
6072 check_insn(ctx, ISA_MIPS_R2);
6073 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6074 tcg_gen_ext32s_tl(arg, arg);
6075 register_name = "EBase";
6076 break;
6077 case CP0_REG15__CMGCRBASE:
6078 check_insn(ctx, ISA_MIPS_R2);
6079 CP0_CHECK(ctx->cmgcr);
6080 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6081 tcg_gen_ext32s_tl(arg, arg);
6082 register_name = "CMGCRBase";
6083 break;
6084 default:
6085 goto cp0_unimplemented;
6086 }
6087 break;
6088 case CP0_REGISTER_16:
6089 switch (sel) {
6090 case CP0_REG16__CONFIG:
6091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6092 register_name = "Config";
6093 break;
6094 case CP0_REG16__CONFIG1:
6095 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6096 register_name = "Config1";
6097 break;
6098 case CP0_REG16__CONFIG2:
6099 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6100 register_name = "Config2";
6101 break;
6102 case CP0_REG16__CONFIG3:
6103 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6104 register_name = "Config3";
6105 break;
6106 case CP0_REG16__CONFIG4:
6107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6108 register_name = "Config4";
6109 break;
6110 case CP0_REG16__CONFIG5:
6111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6112 register_name = "Config5";
6113 break;
6114
6115 case CP0_REG16__CONFIG6:
6116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6117 register_name = "Config6";
6118 break;
6119 case CP0_REG16__CONFIG7:
6120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6121 register_name = "Config7";
6122 break;
6123 default:
6124 goto cp0_unimplemented;
6125 }
6126 break;
6127 case CP0_REGISTER_17:
6128 switch (sel) {
6129 case CP0_REG17__LLADDR:
6130 gen_helper_mfc0_lladdr(arg, cpu_env);
6131 register_name = "LLAddr";
6132 break;
6133 case CP0_REG17__MAAR:
6134 CP0_CHECK(ctx->mrp);
6135 gen_helper_mfc0_maar(arg, cpu_env);
6136 register_name = "MAAR";
6137 break;
6138 case CP0_REG17__MAARI:
6139 CP0_CHECK(ctx->mrp);
6140 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6141 register_name = "MAARI";
6142 break;
6143 default:
6144 goto cp0_unimplemented;
6145 }
6146 break;
6147 case CP0_REGISTER_18:
6148 switch (sel) {
6149 case CP0_REG18__WATCHLO0:
6150 case CP0_REG18__WATCHLO1:
6151 case CP0_REG18__WATCHLO2:
6152 case CP0_REG18__WATCHLO3:
6153 case CP0_REG18__WATCHLO4:
6154 case CP0_REG18__WATCHLO5:
6155 case CP0_REG18__WATCHLO6:
6156 case CP0_REG18__WATCHLO7:
6157 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6158 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6159 register_name = "WatchLo";
6160 break;
6161 default:
6162 goto cp0_unimplemented;
6163 }
6164 break;
6165 case CP0_REGISTER_19:
6166 switch (sel) {
6167 case CP0_REG19__WATCHHI0:
6168 case CP0_REG19__WATCHHI1:
6169 case CP0_REG19__WATCHHI2:
6170 case CP0_REG19__WATCHHI3:
6171 case CP0_REG19__WATCHHI4:
6172 case CP0_REG19__WATCHHI5:
6173 case CP0_REG19__WATCHHI6:
6174 case CP0_REG19__WATCHHI7:
6175 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6176 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6177 register_name = "WatchHi";
6178 break;
6179 default:
6180 goto cp0_unimplemented;
6181 }
6182 break;
6183 case CP0_REGISTER_20:
6184 switch (sel) {
6185 case CP0_REG20__XCONTEXT:
6186#if defined(TARGET_MIPS64)
6187 check_insn(ctx, ISA_MIPS3);
6188 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6189 tcg_gen_ext32s_tl(arg, arg);
6190 register_name = "XContext";
6191 break;
6192#endif
6193 default:
6194 goto cp0_unimplemented;
6195 }
6196 break;
6197 case CP0_REGISTER_21:
6198
6199 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6200 switch (sel) {
6201 case 0:
6202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6203 register_name = "Framemask";
6204 break;
6205 default:
6206 goto cp0_unimplemented;
6207 }
6208 break;
6209 case CP0_REGISTER_22:
6210 tcg_gen_movi_tl(arg, 0);
6211 register_name = "'Diagnostic";
6212 break;
6213 case CP0_REGISTER_23:
6214 switch (sel) {
6215 case CP0_REG23__DEBUG:
6216 gen_helper_mfc0_debug(arg, cpu_env);
6217 register_name = "Debug";
6218 break;
6219 case CP0_REG23__TRACECONTROL:
6220
6221
6222 register_name = "TraceControl";
6223 goto cp0_unimplemented;
6224 case CP0_REG23__TRACECONTROL2:
6225
6226
6227 register_name = "TraceControl2";
6228 goto cp0_unimplemented;
6229 case CP0_REG23__USERTRACEDATA1:
6230
6231
6232 register_name = "UserTraceData1";
6233 goto cp0_unimplemented;
6234 case CP0_REG23__TRACEIBPC:
6235
6236
6237 register_name = "TraceIBPC";
6238 goto cp0_unimplemented;
6239 case CP0_REG23__TRACEDBPC:
6240
6241
6242 register_name = "TraceDBPC";
6243 goto cp0_unimplemented;
6244 default:
6245 goto cp0_unimplemented;
6246 }
6247 break;
6248 case CP0_REGISTER_24:
6249 switch (sel) {
6250 case CP0_REG24__DEPC:
6251
6252 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6253 tcg_gen_ext32s_tl(arg, arg);
6254 register_name = "DEPC";
6255 break;
6256 default:
6257 goto cp0_unimplemented;
6258 }
6259 break;
6260 case CP0_REGISTER_25:
6261 switch (sel) {
6262 case CP0_REG25__PERFCTL0:
6263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6264 register_name = "Performance0";
6265 break;
6266 case CP0_REG25__PERFCNT0:
6267
6268 register_name = "Performance1";
6269 goto cp0_unimplemented;
6270 case CP0_REG25__PERFCTL1:
6271
6272 register_name = "Performance2";
6273 goto cp0_unimplemented;
6274 case CP0_REG25__PERFCNT1:
6275
6276 register_name = "Performance3";
6277 goto cp0_unimplemented;
6278 case CP0_REG25__PERFCTL2:
6279
6280 register_name = "Performance4";
6281 goto cp0_unimplemented;
6282 case CP0_REG25__PERFCNT2:
6283
6284 register_name = "Performance5";
6285 goto cp0_unimplemented;
6286 case CP0_REG25__PERFCTL3:
6287
6288 register_name = "Performance6";
6289 goto cp0_unimplemented;
6290 case CP0_REG25__PERFCNT3:
6291
6292 register_name = "Performance7";
6293 goto cp0_unimplemented;
6294 default:
6295 goto cp0_unimplemented;
6296 }
6297 break;
6298 case CP0_REGISTER_26:
6299 switch (sel) {
6300 case CP0_REG26__ERRCTL:
6301 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6302 register_name = "ErrCtl";
6303 break;
6304 default:
6305 goto cp0_unimplemented;
6306 }
6307 break;
6308 case CP0_REGISTER_27:
6309 switch (sel) {
6310 case CP0_REG27__CACHERR:
6311 tcg_gen_movi_tl(arg, 0);
6312 register_name = "CacheErr";
6313 break;
6314 default:
6315 goto cp0_unimplemented;
6316 }
6317 break;
6318 case CP0_REGISTER_28:
6319 switch (sel) {
6320 case CP0_REG28__TAGLO:
6321 case CP0_REG28__TAGLO1:
6322 case CP0_REG28__TAGLO2:
6323 case CP0_REG28__TAGLO3:
6324 {
6325 TCGv_i64 tmp = tcg_temp_new_i64();
6326 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6327 gen_move_low32(arg, tmp);
6328 tcg_temp_free_i64(tmp);
6329 }
6330 register_name = "TagLo";
6331 break;
6332 case CP0_REG28__DATALO:
6333 case CP0_REG28__DATALO1:
6334 case CP0_REG28__DATALO2:
6335 case CP0_REG28__DATALO3:
6336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6337 register_name = "DataLo";
6338 break;
6339 default:
6340 goto cp0_unimplemented;
6341 }
6342 break;
6343 case CP0_REGISTER_29:
6344 switch (sel) {
6345 case CP0_REG29__TAGHI:
6346 case CP0_REG29__TAGHI1:
6347 case CP0_REG29__TAGHI2:
6348 case CP0_REG29__TAGHI3:
6349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6350 register_name = "TagHi";
6351 break;
6352 case CP0_REG29__DATAHI:
6353 case CP0_REG29__DATAHI1:
6354 case CP0_REG29__DATAHI2:
6355 case CP0_REG29__DATAHI3:
6356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6357 register_name = "DataHi";
6358 break;
6359 default:
6360 goto cp0_unimplemented;
6361 }
6362 break;
6363 case CP0_REGISTER_30:
6364 switch (sel) {
6365 case CP0_REG30__ERROREPC:
6366 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6367 tcg_gen_ext32s_tl(arg, arg);
6368 register_name = "ErrorEPC";
6369 break;
6370 default:
6371 goto cp0_unimplemented;
6372 }
6373 break;
6374 case CP0_REGISTER_31:
6375 switch (sel) {
6376 case CP0_REG31__DESAVE:
6377
6378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6379 register_name = "DESAVE";
6380 break;
6381 case CP0_REG31__KSCRATCH1:
6382 case CP0_REG31__KSCRATCH2:
6383 case CP0_REG31__KSCRATCH3:
6384 case CP0_REG31__KSCRATCH4:
6385 case CP0_REG31__KSCRATCH5:
6386 case CP0_REG31__KSCRATCH6:
6387 CP0_CHECK(ctx->kscrexist & (1 << sel));
6388 tcg_gen_ld_tl(arg, cpu_env,
6389 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6390 tcg_gen_ext32s_tl(arg, arg);
6391 register_name = "KScratch";
6392 break;
6393 default:
6394 goto cp0_unimplemented;
6395 }
6396 break;
6397 default:
6398 goto cp0_unimplemented;
6399 }
6400 trace_mips_translate_c0("mfc0", register_name, reg, sel);
6401 return;
6402
6403cp0_unimplemented:
6404 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6405 register_name, reg, sel);
6406 gen_mfc0_unimplemented(ctx, arg);
6407}
6408
6409static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6410{
6411 const char *register_name = "invalid";
6412
6413 if (sel != 0) {
6414 check_insn(ctx, ISA_MIPS_R1);
6415 }
6416
6417 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6418 gen_io_start();
6419 }
6420
6421 switch (reg) {
6422 case CP0_REGISTER_00:
6423 switch (sel) {
6424 case CP0_REG00__INDEX:
6425 gen_helper_mtc0_index(cpu_env, arg);
6426 register_name = "Index";
6427 break;
6428 case CP0_REG00__MVPCONTROL:
6429 CP0_CHECK(ctx->insn_flags & ASE_MT);
6430 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6431 register_name = "MVPControl";
6432 break;
6433 case CP0_REG00__MVPCONF0:
6434 CP0_CHECK(ctx->insn_flags & ASE_MT);
6435
6436 register_name = "MVPConf0";
6437 break;
6438 case CP0_REG00__MVPCONF1:
6439 CP0_CHECK(ctx->insn_flags & ASE_MT);
6440
6441 register_name = "MVPConf1";
6442 break;
6443 case CP0_REG00__VPCONTROL:
6444 CP0_CHECK(ctx->vp);
6445
6446 register_name = "VPControl";
6447 break;
6448 default:
6449 goto cp0_unimplemented;
6450 }
6451 break;
6452 case CP0_REGISTER_01:
6453 switch (sel) {
6454 case CP0_REG01__RANDOM:
6455
6456 register_name = "Random";
6457 break;
6458 case CP0_REG01__VPECONTROL:
6459 CP0_CHECK(ctx->insn_flags & ASE_MT);
6460 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6461 register_name = "VPEControl";
6462 break;
6463 case CP0_REG01__VPECONF0:
6464 CP0_CHECK(ctx->insn_flags & ASE_MT);
6465 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6466 register_name = "VPEConf0";
6467 break;
6468 case CP0_REG01__VPECONF1:
6469 CP0_CHECK(ctx->insn_flags & ASE_MT);
6470 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6471 register_name = "VPEConf1";
6472 break;
6473 case CP0_REG01__YQMASK:
6474 CP0_CHECK(ctx->insn_flags & ASE_MT);
6475 gen_helper_mtc0_yqmask(cpu_env, arg);
6476 register_name = "YQMask";
6477 break;
6478 case CP0_REG01__VPESCHEDULE:
6479 CP0_CHECK(ctx->insn_flags & ASE_MT);
6480 tcg_gen_st_tl(arg, cpu_env,
6481 offsetof(CPUMIPSState, CP0_VPESchedule));
6482 register_name = "VPESchedule";
6483 break;
6484 case CP0_REG01__VPESCHEFBACK:
6485 CP0_CHECK(ctx->insn_flags & ASE_MT);
6486 tcg_gen_st_tl(arg, cpu_env,
6487 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6488 register_name = "VPEScheFBack";
6489 break;
6490 case CP0_REG01__VPEOPT:
6491 CP0_CHECK(ctx->insn_flags & ASE_MT);
6492 gen_helper_mtc0_vpeopt(cpu_env, arg);
6493 register_name = "VPEOpt";
6494 break;
6495 default:
6496 goto cp0_unimplemented;
6497 }
6498 break;
6499 case CP0_REGISTER_02:
6500 switch (sel) {
6501 case CP0_REG02__ENTRYLO0:
6502 gen_helper_mtc0_entrylo0(cpu_env, arg);
6503 register_name = "EntryLo0";
6504 break;
6505 case CP0_REG02__TCSTATUS:
6506 CP0_CHECK(ctx->insn_flags & ASE_MT);
6507 gen_helper_mtc0_tcstatus(cpu_env, arg);
6508 register_name = "TCStatus";
6509 break;
6510 case CP0_REG02__TCBIND:
6511 CP0_CHECK(ctx->insn_flags & ASE_MT);
6512 gen_helper_mtc0_tcbind(cpu_env, arg);
6513 register_name = "TCBind";
6514 break;
6515 case CP0_REG02__TCRESTART:
6516 CP0_CHECK(ctx->insn_flags & ASE_MT);
6517 gen_helper_mtc0_tcrestart(cpu_env, arg);
6518 register_name = "TCRestart";
6519 break;
6520 case CP0_REG02__TCHALT:
6521 CP0_CHECK(ctx->insn_flags & ASE_MT);
6522 gen_helper_mtc0_tchalt(cpu_env, arg);
6523 register_name = "TCHalt";
6524 break;
6525 case CP0_REG02__TCCONTEXT:
6526 CP0_CHECK(ctx->insn_flags & ASE_MT);
6527 gen_helper_mtc0_tccontext(cpu_env, arg);
6528 register_name = "TCContext";
6529 break;
6530 case CP0_REG02__TCSCHEDULE:
6531 CP0_CHECK(ctx->insn_flags & ASE_MT);
6532 gen_helper_mtc0_tcschedule(cpu_env, arg);
6533 register_name = "TCSchedule";
6534 break;
6535 case CP0_REG02__TCSCHEFBACK:
6536 CP0_CHECK(ctx->insn_flags & ASE_MT);
6537 gen_helper_mtc0_tcschefback(cpu_env, arg);
6538 register_name = "TCScheFBack";
6539 break;
6540 default:
6541 goto cp0_unimplemented;
6542 }
6543 break;
6544 case CP0_REGISTER_03:
6545 switch (sel) {
6546 case CP0_REG03__ENTRYLO1:
6547 gen_helper_mtc0_entrylo1(cpu_env, arg);
6548 register_name = "EntryLo1";
6549 break;
6550 case CP0_REG03__GLOBALNUM:
6551 CP0_CHECK(ctx->vp);
6552
6553 register_name = "GlobalNumber";
6554 break;
6555 default:
6556 goto cp0_unimplemented;
6557 }
6558 break;
6559 case CP0_REGISTER_04:
6560 switch (sel) {
6561 case CP0_REG04__CONTEXT:
6562 gen_helper_mtc0_context(cpu_env, arg);
6563 register_name = "Context";
6564 break;
6565 case CP0_REG04__CONTEXTCONFIG:
6566
6567
6568 register_name = "ContextConfig";
6569 goto cp0_unimplemented;
6570 case CP0_REG04__USERLOCAL:
6571 CP0_CHECK(ctx->ulri);
6572 tcg_gen_st_tl(arg, cpu_env,
6573 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6574 register_name = "UserLocal";
6575 break;
6576 case CP0_REG04__MMID:
6577 CP0_CHECK(ctx->mi);
6578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6579 register_name = "MMID";
6580 break;
6581 default:
6582 goto cp0_unimplemented;
6583 }
6584 break;
6585 case CP0_REGISTER_05:
6586 switch (sel) {
6587 case CP0_REG05__PAGEMASK:
6588 gen_helper_mtc0_pagemask(cpu_env, arg);
6589 register_name = "PageMask";
6590 break;
6591 case CP0_REG05__PAGEGRAIN:
6592 check_insn(ctx, ISA_MIPS_R2);
6593 gen_helper_mtc0_pagegrain(cpu_env, arg);
6594 register_name = "PageGrain";
6595 ctx->base.is_jmp = DISAS_STOP;
6596 break;
6597 case CP0_REG05__SEGCTL0:
6598 CP0_CHECK(ctx->sc);
6599 gen_helper_mtc0_segctl0(cpu_env, arg);
6600 register_name = "SegCtl0";
6601 break;
6602 case CP0_REG05__SEGCTL1:
6603 CP0_CHECK(ctx->sc);
6604 gen_helper_mtc0_segctl1(cpu_env, arg);
6605 register_name = "SegCtl1";
6606 break;
6607 case CP0_REG05__SEGCTL2:
6608 CP0_CHECK(ctx->sc);
6609 gen_helper_mtc0_segctl2(cpu_env, arg);
6610 register_name = "SegCtl2";
6611 break;
6612 case CP0_REG05__PWBASE:
6613 check_pw(ctx);
6614 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6615 register_name = "PWBase";
6616 break;
6617 case CP0_REG05__PWFIELD:
6618 check_pw(ctx);
6619 gen_helper_mtc0_pwfield(cpu_env, arg);
6620 register_name = "PWField";
6621 break;
6622 case CP0_REG05__PWSIZE:
6623 check_pw(ctx);
6624 gen_helper_mtc0_pwsize(cpu_env, arg);
6625 register_name = "PWSize";
6626 break;
6627 default:
6628 goto cp0_unimplemented;
6629 }
6630 break;
6631 case CP0_REGISTER_06:
6632 switch (sel) {
6633 case CP0_REG06__WIRED:
6634 gen_helper_mtc0_wired(cpu_env, arg);
6635 register_name = "Wired";
6636 break;
6637 case CP0_REG06__SRSCONF0:
6638 check_insn(ctx, ISA_MIPS_R2);
6639 gen_helper_mtc0_srsconf0(cpu_env, arg);
6640 register_name = "SRSConf0";
6641 break;
6642 case CP0_REG06__SRSCONF1:
6643 check_insn(ctx, ISA_MIPS_R2);
6644 gen_helper_mtc0_srsconf1(cpu_env, arg);
6645 register_name = "SRSConf1";
6646 break;
6647 case CP0_REG06__SRSCONF2:
6648 check_insn(ctx, ISA_MIPS_R2);
6649 gen_helper_mtc0_srsconf2(cpu_env, arg);
6650 register_name = "SRSConf2";
6651 break;
6652 case CP0_REG06__SRSCONF3:
6653 check_insn(ctx, ISA_MIPS_R2);
6654 gen_helper_mtc0_srsconf3(cpu_env, arg);
6655 register_name = "SRSConf3";
6656 break;
6657 case CP0_REG06__SRSCONF4:
6658 check_insn(ctx, ISA_MIPS_R2);
6659 gen_helper_mtc0_srsconf4(cpu_env, arg);
6660 register_name = "SRSConf4";
6661 break;
6662 case CP0_REG06__PWCTL:
6663 check_pw(ctx);
6664 gen_helper_mtc0_pwctl(cpu_env, arg);
6665 register_name = "PWCtl";
6666 break;
6667 default:
6668 goto cp0_unimplemented;
6669 }
6670 break;
6671 case CP0_REGISTER_07:
6672 switch (sel) {
6673 case CP0_REG07__HWRENA:
6674 check_insn(ctx, ISA_MIPS_R2);
6675 gen_helper_mtc0_hwrena(cpu_env, arg);
6676 ctx->base.is_jmp = DISAS_STOP;
6677 register_name = "HWREna";
6678 break;
6679 default:
6680 goto cp0_unimplemented;
6681 }
6682 break;
6683 case CP0_REGISTER_08:
6684 switch (sel) {
6685 case CP0_REG08__BADVADDR:
6686
6687 register_name = "BadVAddr";
6688 break;
6689 case CP0_REG08__BADINSTR:
6690
6691 register_name = "BadInstr";
6692 break;
6693 case CP0_REG08__BADINSTRP:
6694
6695 register_name = "BadInstrP";
6696 break;
6697 case CP0_REG08__BADINSTRX:
6698
6699 register_name = "BadInstrX";
6700 break;
6701 default:
6702 goto cp0_unimplemented;
6703 }
6704 break;
6705 case CP0_REGISTER_09:
6706 switch (sel) {
6707 case CP0_REG09__COUNT:
6708 gen_helper_mtc0_count(cpu_env, arg);
6709 register_name = "Count";
6710 break;
6711 case CP0_REG09__SAARI:
6712 CP0_CHECK(ctx->saar);
6713 gen_helper_mtc0_saari(cpu_env, arg);
6714 register_name = "SAARI";
6715 break;
6716 case CP0_REG09__SAAR:
6717 CP0_CHECK(ctx->saar);
6718 gen_helper_mtc0_saar(cpu_env, arg);
6719 register_name = "SAAR";
6720 break;
6721 default:
6722 goto cp0_unimplemented;
6723 }
6724 break;
6725 case CP0_REGISTER_10:
6726 switch (sel) {
6727 case CP0_REG10__ENTRYHI:
6728 gen_helper_mtc0_entryhi(cpu_env, arg);
6729 register_name = "EntryHi";
6730 break;
6731 default:
6732 goto cp0_unimplemented;
6733 }
6734 break;
6735 case CP0_REGISTER_11:
6736 switch (sel) {
6737 case CP0_REG11__COMPARE:
6738 gen_helper_mtc0_compare(cpu_env, arg);
6739 register_name = "Compare";
6740 break;
6741
6742 default:
6743 goto cp0_unimplemented;
6744 }
6745 break;
6746 case CP0_REGISTER_12:
6747 switch (sel) {
6748 case CP0_REG12__STATUS:
6749 save_cpu_state(ctx, 1);
6750 gen_helper_mtc0_status(cpu_env, arg);
6751
6752 gen_save_pc(ctx->base.pc_next + 4);
6753 ctx->base.is_jmp = DISAS_EXIT;
6754 register_name = "Status";
6755 break;
6756 case CP0_REG12__INTCTL:
6757 check_insn(ctx, ISA_MIPS_R2);
6758 gen_helper_mtc0_intctl(cpu_env, arg);
6759
6760 ctx->base.is_jmp = DISAS_STOP;
6761 register_name = "IntCtl";
6762 break;
6763 case CP0_REG12__SRSCTL:
6764 check_insn(ctx, ISA_MIPS_R2);
6765 gen_helper_mtc0_srsctl(cpu_env, arg);
6766
6767 ctx->base.is_jmp = DISAS_STOP;
6768 register_name = "SRSCtl";
6769 break;
6770 case CP0_REG12__SRSMAP:
6771 check_insn(ctx, ISA_MIPS_R2);
6772 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6773
6774 ctx->base.is_jmp = DISAS_STOP;
6775 register_name = "SRSMap";
6776 break;
6777 default:
6778 goto cp0_unimplemented;
6779 }
6780 break;
6781 case CP0_REGISTER_13:
6782 switch (sel) {
6783 case CP0_REG13__CAUSE:
6784 save_cpu_state(ctx, 1);
6785 gen_helper_mtc0_cause(cpu_env, arg);
6786
6787
6788
6789
6790
6791 gen_save_pc(ctx->base.pc_next + 4);
6792 ctx->base.is_jmp = DISAS_EXIT;
6793 register_name = "Cause";
6794 break;
6795 default:
6796 goto cp0_unimplemented;
6797 }
6798 break;
6799 case CP0_REGISTER_14:
6800 switch (sel) {
6801 case CP0_REG14__EPC:
6802 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6803 register_name = "EPC";
6804 break;
6805 default:
6806 goto cp0_unimplemented;
6807 }
6808 break;
6809 case CP0_REGISTER_15:
6810 switch (sel) {
6811 case CP0_REG15__PRID:
6812
6813 register_name = "PRid";
6814 break;
6815 case CP0_REG15__EBASE:
6816 check_insn(ctx, ISA_MIPS_R2);
6817 gen_helper_mtc0_ebase(cpu_env, arg);
6818 register_name = "EBase";
6819 break;
6820 default:
6821 goto cp0_unimplemented;
6822 }
6823 break;
6824 case CP0_REGISTER_16:
6825 switch (sel) {
6826 case CP0_REG16__CONFIG:
6827 gen_helper_mtc0_config0(cpu_env, arg);
6828 register_name = "Config";
6829
6830 ctx->base.is_jmp = DISAS_STOP;
6831 break;
6832 case CP0_REG16__CONFIG1:
6833
6834 register_name = "Config1";
6835 break;
6836 case CP0_REG16__CONFIG2:
6837 gen_helper_mtc0_config2(cpu_env, arg);
6838 register_name = "Config2";
6839
6840 ctx->base.is_jmp = DISAS_STOP;
6841 break;
6842 case CP0_REG16__CONFIG3:
6843 gen_helper_mtc0_config3(cpu_env, arg);
6844 register_name = "Config3";
6845
6846 ctx->base.is_jmp = DISAS_STOP;
6847 break;
6848 case CP0_REG16__CONFIG4:
6849 gen_helper_mtc0_config4(cpu_env, arg);
6850 register_name = "Config4";
6851 ctx->base.is_jmp = DISAS_STOP;
6852 break;
6853 case CP0_REG16__CONFIG5:
6854 gen_helper_mtc0_config5(cpu_env, arg);
6855 register_name = "Config5";
6856
6857 ctx->base.is_jmp = DISAS_STOP;
6858 break;
6859
6860 case CP0_REG16__CONFIG6:
6861
6862 register_name = "Config6";
6863 break;
6864 case CP0_REG16__CONFIG7:
6865
6866 register_name = "Config7";
6867 break;
6868 default:
6869 register_name = "Invalid config selector";
6870 goto cp0_unimplemented;
6871 }
6872 break;
6873 case CP0_REGISTER_17:
6874 switch (sel) {
6875 case CP0_REG17__LLADDR:
6876 gen_helper_mtc0_lladdr(cpu_env, arg);
6877 register_name = "LLAddr";
6878 break;
6879 case CP0_REG17__MAAR:
6880 CP0_CHECK(ctx->mrp);
6881 gen_helper_mtc0_maar(cpu_env, arg);
6882 register_name = "MAAR";
6883 break;
6884 case CP0_REG17__MAARI:
6885 CP0_CHECK(ctx->mrp);
6886 gen_helper_mtc0_maari(cpu_env, arg);
6887 register_name = "MAARI";
6888 break;
6889 default:
6890 goto cp0_unimplemented;
6891 }
6892 break;
6893 case CP0_REGISTER_18:
6894 switch (sel) {
6895 case CP0_REG18__WATCHLO0:
6896 case CP0_REG18__WATCHLO1:
6897 case CP0_REG18__WATCHLO2:
6898 case CP0_REG18__WATCHLO3:
6899 case CP0_REG18__WATCHLO4:
6900 case CP0_REG18__WATCHLO5:
6901 case CP0_REG18__WATCHLO6:
6902 case CP0_REG18__WATCHLO7:
6903 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6904 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6905 register_name = "WatchLo";
6906 break;
6907 default:
6908 goto cp0_unimplemented;
6909 }
6910 break;
6911 case CP0_REGISTER_19:
6912 switch (sel) {
6913 case CP0_REG19__WATCHHI0:
6914 case CP0_REG19__WATCHHI1:
6915 case CP0_REG19__WATCHHI2:
6916 case CP0_REG19__WATCHHI3:
6917 case CP0_REG19__WATCHHI4:
6918 case CP0_REG19__WATCHHI5:
6919 case CP0_REG19__WATCHHI6:
6920 case CP0_REG19__WATCHHI7:
6921 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6922 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6923 register_name = "WatchHi";
6924 break;
6925 default:
6926 goto cp0_unimplemented;
6927 }
6928 break;
6929 case CP0_REGISTER_20:
6930 switch (sel) {
6931 case CP0_REG20__XCONTEXT:
6932#if defined(TARGET_MIPS64)
6933 check_insn(ctx, ISA_MIPS3);
6934 gen_helper_mtc0_xcontext(cpu_env, arg);
6935 register_name = "XContext";
6936 break;
6937#endif
6938 default:
6939 goto cp0_unimplemented;
6940 }
6941 break;
6942 case CP0_REGISTER_21:
6943
6944 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6945 switch (sel) {
6946 case 0:
6947 gen_helper_mtc0_framemask(cpu_env, arg);
6948 register_name = "Framemask";
6949 break;
6950 default:
6951 goto cp0_unimplemented;
6952 }
6953 break;
6954 case CP0_REGISTER_22:
6955
6956 register_name = "Diagnostic";
6957 break;
6958 case CP0_REGISTER_23:
6959 switch (sel) {
6960 case CP0_REG23__DEBUG:
6961 gen_helper_mtc0_debug(cpu_env, arg);
6962
6963 gen_save_pc(ctx->base.pc_next + 4);
6964 ctx->base.is_jmp = DISAS_EXIT;
6965 register_name = "Debug";
6966 break;
6967 case CP0_REG23__TRACECONTROL:
6968
6969
6970 register_name = "TraceControl";
6971
6972 ctx->base.is_jmp = DISAS_STOP;
6973 goto cp0_unimplemented;
6974 case CP0_REG23__TRACECONTROL2:
6975
6976
6977 register_name = "TraceControl2";
6978
6979 ctx->base.is_jmp = DISAS_STOP;
6980 goto cp0_unimplemented;
6981 case CP0_REG23__USERTRACEDATA1:
6982
6983 ctx->base.is_jmp = DISAS_STOP;
6984
6985
6986 register_name = "UserTraceData";
6987
6988 ctx->base.is_jmp = DISAS_STOP;
6989 goto cp0_unimplemented;
6990 case CP0_REG23__TRACEIBPC:
6991
6992
6993
6994 ctx->base.is_jmp = DISAS_STOP;
6995 register_name = "TraceIBPC";
6996 goto cp0_unimplemented;
6997 case CP0_REG23__TRACEDBPC:
6998
6999
7000
7001 ctx->base.is_jmp = DISAS_STOP;
7002 register_name = "TraceDBPC";
7003 goto cp0_unimplemented;
7004 default:
7005 goto cp0_unimplemented;
7006 }
7007 break;
7008 case CP0_REGISTER_24:
7009 switch (sel) {
7010 case CP0_REG24__DEPC:
7011
7012 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7013 register_name = "DEPC";
7014 break;
7015 default:
7016 goto cp0_unimplemented;
7017 }
7018 break;
7019 case CP0_REGISTER_25:
7020 switch (sel) {
7021 case CP0_REG25__PERFCTL0:
7022 gen_helper_mtc0_performance0(cpu_env, arg);
7023 register_name = "Performance0";
7024 break;
7025 case CP0_REG25__PERFCNT0:
7026
7027 register_name = "Performance1";
7028 goto cp0_unimplemented;
7029 case CP0_REG25__PERFCTL1:
7030
7031 register_name = "Performance2";
7032 goto cp0_unimplemented;
7033 case CP0_REG25__PERFCNT1:
7034
7035 register_name = "Performance3";
7036 goto cp0_unimplemented;
7037 case CP0_REG25__PERFCTL2:
7038
7039 register_name = "Performance4";
7040 goto cp0_unimplemented;
7041 case CP0_REG25__PERFCNT2:
7042
7043 register_name = "Performance5";
7044 goto cp0_unimplemented;
7045 case CP0_REG25__PERFCTL3:
7046
7047 register_name = "Performance6";
7048 goto cp0_unimplemented;
7049 case CP0_REG25__PERFCNT3:
7050
7051 register_name = "Performance7";
7052 goto cp0_unimplemented;
7053 default:
7054 goto cp0_unimplemented;
7055 }
7056 break;
7057 case CP0_REGISTER_26:
7058 switch (sel) {
7059 case CP0_REG26__ERRCTL:
7060 gen_helper_mtc0_errctl(cpu_env, arg);
7061 ctx->base.is_jmp = DISAS_STOP;
7062 register_name = "ErrCtl";
7063 break;
7064 default:
7065 goto cp0_unimplemented;
7066 }
7067 break;
7068 case CP0_REGISTER_27:
7069 switch (sel) {
7070 case CP0_REG27__CACHERR:
7071
7072 register_name = "CacheErr";
7073 break;
7074 default:
7075 goto cp0_unimplemented;
7076 }
7077 break;
7078 case CP0_REGISTER_28:
7079 switch (sel) {
7080 case CP0_REG28__TAGLO:
7081 case CP0_REG28__TAGLO1:
7082 case CP0_REG28__TAGLO2:
7083 case CP0_REG28__TAGLO3:
7084 gen_helper_mtc0_taglo(cpu_env, arg);
7085 register_name = "TagLo";
7086 break;
7087 case CP0_REG28__DATALO:
7088 case CP0_REG28__DATALO1:
7089 case CP0_REG28__DATALO2:
7090 case CP0_REG28__DATALO3:
7091 gen_helper_mtc0_datalo(cpu_env, arg);
7092 register_name = "DataLo";
7093 break;
7094 default:
7095 goto cp0_unimplemented;
7096 }
7097 break;
7098 case CP0_REGISTER_29:
7099 switch (sel) {
7100 case CP0_REG29__TAGHI:
7101 case CP0_REG29__TAGHI1:
7102 case CP0_REG29__TAGHI2:
7103 case CP0_REG29__TAGHI3:
7104 gen_helper_mtc0_taghi(cpu_env, arg);
7105 register_name = "TagHi";
7106 break;
7107 case CP0_REG29__DATAHI:
7108 case CP0_REG29__DATAHI1:
7109 case CP0_REG29__DATAHI2:
7110 case CP0_REG29__DATAHI3:
7111 gen_helper_mtc0_datahi(cpu_env, arg);
7112 register_name = "DataHi";
7113 break;
7114 default:
7115 register_name = "invalid sel";
7116 goto cp0_unimplemented;
7117 }
7118 break;
7119 case CP0_REGISTER_30:
7120 switch (sel) {
7121 case CP0_REG30__ERROREPC:
7122 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7123 register_name = "ErrorEPC";
7124 break;
7125 default:
7126 goto cp0_unimplemented;
7127 }
7128 break;
7129 case CP0_REGISTER_31:
7130 switch (sel) {
7131 case CP0_REG31__DESAVE:
7132
7133 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7134 register_name = "DESAVE";
7135 break;
7136 case CP0_REG31__KSCRATCH1:
7137 case CP0_REG31__KSCRATCH2:
7138 case CP0_REG31__KSCRATCH3:
7139 case CP0_REG31__KSCRATCH4:
7140 case CP0_REG31__KSCRATCH5:
7141 case CP0_REG31__KSCRATCH6:
7142 CP0_CHECK(ctx->kscrexist & (1 << sel));
7143 tcg_gen_st_tl(arg, cpu_env,
7144 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7145 register_name = "KScratch";
7146 break;
7147 default:
7148 goto cp0_unimplemented;
7149 }
7150 break;
7151 default:
7152 goto cp0_unimplemented;
7153 }
7154 trace_mips_translate_c0("mtc0", register_name, reg, sel);
7155
7156
7157 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7158
7159
7160
7161
7162 gen_save_pc(ctx->base.pc_next + 4);
7163 ctx->base.is_jmp = DISAS_EXIT;
7164 }
7165 return;
7166
7167cp0_unimplemented:
7168 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7169 register_name, reg, sel);
7170}
7171
7172#if defined(TARGET_MIPS64)
7173static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7174{
7175 const char *register_name = "invalid";
7176
7177 if (sel != 0) {
7178 check_insn(ctx, ISA_MIPS_R1);
7179 }
7180
7181 switch (reg) {
7182 case CP0_REGISTER_00:
7183 switch (sel) {
7184 case CP0_REG00__INDEX:
7185 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7186 register_name = "Index";
7187 break;
7188 case CP0_REG00__MVPCONTROL:
7189 CP0_CHECK(ctx->insn_flags & ASE_MT);
7190 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7191 register_name = "MVPControl";
7192 break;
7193 case CP0_REG00__MVPCONF0:
7194 CP0_CHECK(ctx->insn_flags & ASE_MT);
7195 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7196 register_name = "MVPConf0";
7197 break;
7198 case CP0_REG00__MVPCONF1:
7199 CP0_CHECK(ctx->insn_flags & ASE_MT);
7200 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7201 register_name = "MVPConf1";
7202 break;
7203 case CP0_REG00__VPCONTROL:
7204 CP0_CHECK(ctx->vp);
7205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7206 register_name = "VPControl";
7207 break;
7208 default:
7209 goto cp0_unimplemented;
7210 }
7211 break;
7212 case CP0_REGISTER_01:
7213 switch (sel) {
7214 case CP0_REG01__RANDOM:
7215 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7216 gen_helper_mfc0_random(arg, cpu_env);
7217 register_name = "Random";
7218 break;
7219 case CP0_REG01__VPECONTROL:
7220 CP0_CHECK(ctx->insn_flags & ASE_MT);
7221 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7222 register_name = "VPEControl";
7223 break;
7224 case CP0_REG01__VPECONF0:
7225 CP0_CHECK(ctx->insn_flags & ASE_MT);
7226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7227 register_name = "VPEConf0";
7228 break;
7229 case CP0_REG01__VPECONF1:
7230 CP0_CHECK(ctx->insn_flags & ASE_MT);
7231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7232 register_name = "VPEConf1";
7233 break;
7234 case CP0_REG01__YQMASK:
7235 CP0_CHECK(ctx->insn_flags & ASE_MT);
7236 tcg_gen_ld_tl(arg, cpu_env,
7237 offsetof(CPUMIPSState, CP0_YQMask));
7238 register_name = "YQMask";
7239 break;
7240 case CP0_REG01__VPESCHEDULE:
7241 CP0_CHECK(ctx->insn_flags & ASE_MT);
7242 tcg_gen_ld_tl(arg, cpu_env,
7243 offsetof(CPUMIPSState, CP0_VPESchedule));
7244 register_name = "VPESchedule";
7245 break;
7246 case CP0_REG01__VPESCHEFBACK:
7247 CP0_CHECK(ctx->insn_flags & ASE_MT);
7248 tcg_gen_ld_tl(arg, cpu_env,
7249 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7250 register_name = "VPEScheFBack";
7251 break;
7252 case CP0_REG01__VPEOPT:
7253 CP0_CHECK(ctx->insn_flags & ASE_MT);
7254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7255 register_name = "VPEOpt";
7256 break;
7257 default:
7258 goto cp0_unimplemented;
7259 }
7260 break;
7261 case CP0_REGISTER_02:
7262 switch (sel) {
7263 case CP0_REG02__ENTRYLO0:
7264 tcg_gen_ld_tl(arg, cpu_env,
7265 offsetof(CPUMIPSState, CP0_EntryLo0));
7266 register_name = "EntryLo0";
7267 break;
7268 case CP0_REG02__TCSTATUS:
7269 CP0_CHECK(ctx->insn_flags & ASE_MT);
7270 gen_helper_mfc0_tcstatus(arg, cpu_env);
7271 register_name = "TCStatus";
7272 break;
7273 case CP0_REG02__TCBIND:
7274 CP0_CHECK(ctx->insn_flags & ASE_MT);
7275 gen_helper_mfc0_tcbind(arg, cpu_env);
7276 register_name = "TCBind";
7277 break;
7278 case CP0_REG02__TCRESTART:
7279 CP0_CHECK(ctx->insn_flags & ASE_MT);
7280 gen_helper_dmfc0_tcrestart(arg, cpu_env);
7281 register_name = "TCRestart";
7282 break;
7283 case CP0_REG02__TCHALT:
7284 CP0_CHECK(ctx->insn_flags & ASE_MT);
7285 gen_helper_dmfc0_tchalt(arg, cpu_env);
7286 register_name = "TCHalt";
7287 break;
7288 case CP0_REG02__TCCONTEXT:
7289 CP0_CHECK(ctx->insn_flags & ASE_MT);
7290 gen_helper_dmfc0_tccontext(arg, cpu_env);
7291 register_name = "TCContext";
7292 break;
7293 case CP0_REG02__TCSCHEDULE:
7294 CP0_CHECK(ctx->insn_flags & ASE_MT);
7295 gen_helper_dmfc0_tcschedule(arg, cpu_env);
7296 register_name = "TCSchedule";
7297 break;
7298 case CP0_REG02__TCSCHEFBACK:
7299 CP0_CHECK(ctx->insn_flags & ASE_MT);
7300 gen_helper_dmfc0_tcschefback(arg, cpu_env);
7301 register_name = "TCScheFBack";
7302 break;
7303 default:
7304 goto cp0_unimplemented;
7305 }
7306 break;
7307 case CP0_REGISTER_03:
7308 switch (sel) {
7309 case CP0_REG03__ENTRYLO1:
7310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7311 register_name = "EntryLo1";
7312 break;
7313 case CP0_REG03__GLOBALNUM:
7314 CP0_CHECK(ctx->vp);
7315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7316 register_name = "GlobalNumber";
7317 break;
7318 default:
7319 goto cp0_unimplemented;
7320 }
7321 break;
7322 case CP0_REGISTER_04:
7323 switch (sel) {
7324 case CP0_REG04__CONTEXT:
7325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7326 register_name = "Context";
7327 break;
7328 case CP0_REG04__CONTEXTCONFIG:
7329
7330
7331 register_name = "ContextConfig";
7332 goto cp0_unimplemented;
7333 case CP0_REG04__USERLOCAL:
7334 CP0_CHECK(ctx->ulri);
7335 tcg_gen_ld_tl(arg, cpu_env,
7336 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7337 register_name = "UserLocal";
7338 break;
7339 case CP0_REG04__MMID:
7340 CP0_CHECK(ctx->mi);
7341 gen_helper_mtc0_memorymapid(cpu_env, arg);
7342 register_name = "MMID";
7343 break;
7344 default:
7345 goto cp0_unimplemented;
7346 }
7347 break;
7348 case CP0_REGISTER_05:
7349 switch (sel) {
7350 case CP0_REG05__PAGEMASK:
7351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7352 register_name = "PageMask";
7353 break;
7354 case CP0_REG05__PAGEGRAIN:
7355 check_insn(ctx, ISA_MIPS_R2);
7356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7357 register_name = "PageGrain";
7358 break;
7359 case CP0_REG05__SEGCTL0:
7360 CP0_CHECK(ctx->sc);
7361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7362 register_name = "SegCtl0";
7363 break;
7364 case CP0_REG05__SEGCTL1:
7365 CP0_CHECK(ctx->sc);
7366 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7367 register_name = "SegCtl1";
7368 break;
7369 case CP0_REG05__SEGCTL2:
7370 CP0_CHECK(ctx->sc);
7371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7372 register_name = "SegCtl2";
7373 break;
7374 case CP0_REG05__PWBASE:
7375 check_pw(ctx);
7376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7377 register_name = "PWBase";
7378 break;
7379 case CP0_REG05__PWFIELD:
7380 check_pw(ctx);
7381 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7382 register_name = "PWField";
7383 break;
7384 case CP0_REG05__PWSIZE:
7385 check_pw(ctx);
7386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7387 register_name = "PWSize";
7388 break;
7389 default:
7390 goto cp0_unimplemented;
7391 }
7392 break;
7393 case CP0_REGISTER_06:
7394 switch (sel) {
7395 case CP0_REG06__WIRED:
7396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7397 register_name = "Wired";
7398 break;
7399 case CP0_REG06__SRSCONF0:
7400 check_insn(ctx, ISA_MIPS_R2);
7401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7402 register_name = "SRSConf0";
7403 break;
7404 case CP0_REG06__SRSCONF1:
7405 check_insn(ctx, ISA_MIPS_R2);
7406 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7407 register_name = "SRSConf1";
7408 break;
7409 case CP0_REG06__SRSCONF2:
7410 check_insn(ctx, ISA_MIPS_R2);
7411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7412 register_name = "SRSConf2";
7413 break;
7414 case CP0_REG06__SRSCONF3:
7415 check_insn(ctx, ISA_MIPS_R2);
7416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7417 register_name = "SRSConf3";
7418 break;
7419 case CP0_REG06__SRSCONF4:
7420 check_insn(ctx, ISA_MIPS_R2);
7421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7422 register_name = "SRSConf4";
7423 break;
7424 case CP0_REG06__PWCTL:
7425 check_pw(ctx);
7426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7427 register_name = "PWCtl";
7428 break;
7429 default:
7430 goto cp0_unimplemented;
7431 }
7432 break;
7433 case CP0_REGISTER_07:
7434 switch (sel) {
7435 case CP0_REG07__HWRENA:
7436 check_insn(ctx, ISA_MIPS_R2);
7437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7438 register_name = "HWREna";
7439 break;
7440 default:
7441 goto cp0_unimplemented;
7442 }
7443 break;
7444 case CP0_REGISTER_08:
7445 switch (sel) {
7446 case CP0_REG08__BADVADDR:
7447 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7448 register_name = "BadVAddr";
7449 break;
7450 case CP0_REG08__BADINSTR:
7451 CP0_CHECK(ctx->bi);
7452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7453 register_name = "BadInstr";
7454 break;
7455 case CP0_REG08__BADINSTRP:
7456 CP0_CHECK(ctx->bp);
7457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7458 register_name = "BadInstrP";
7459 break;
7460 case CP0_REG08__BADINSTRX:
7461 CP0_CHECK(ctx->bi);
7462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7463 tcg_gen_andi_tl(arg, arg, ~0xffff);
7464 register_name = "BadInstrX";
7465 break;
7466 default:
7467 goto cp0_unimplemented;
7468 }
7469 break;
7470 case CP0_REGISTER_09:
7471 switch (sel) {
7472 case CP0_REG09__COUNT:
7473
7474 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7475 gen_io_start();
7476 }
7477 gen_helper_mfc0_count(arg, cpu_env);
7478
7479
7480
7481
7482
7483 gen_save_pc(ctx->base.pc_next + 4);
7484 ctx->base.is_jmp = DISAS_EXIT;
7485 register_name = "Count";
7486 break;
7487 case CP0_REG09__SAARI:
7488 CP0_CHECK(ctx->saar);
7489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7490 register_name = "SAARI";
7491 break;
7492 case CP0_REG09__SAAR:
7493 CP0_CHECK(ctx->saar);
7494 gen_helper_dmfc0_saar(arg, cpu_env);
7495 register_name = "SAAR";
7496 break;
7497 default:
7498 goto cp0_unimplemented;
7499 }
7500 break;
7501 case CP0_REGISTER_10:
7502 switch (sel) {
7503 case CP0_REG10__ENTRYHI:
7504 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7505 register_name = "EntryHi";
7506 break;
7507 default:
7508 goto cp0_unimplemented;
7509 }
7510 break;
7511 case CP0_REGISTER_11:
7512 switch (sel) {
7513 case CP0_REG11__COMPARE:
7514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7515 register_name = "Compare";
7516 break;
7517
7518 default:
7519 goto cp0_unimplemented;
7520 }
7521 break;
7522 case CP0_REGISTER_12:
7523 switch (sel) {
7524 case CP0_REG12__STATUS:
7525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7526 register_name = "Status";
7527 break;
7528 case CP0_REG12__INTCTL:
7529 check_insn(ctx, ISA_MIPS_R2);
7530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7531 register_name = "IntCtl";
7532 break;
7533 case CP0_REG12__SRSCTL:
7534 check_insn(ctx, ISA_MIPS_R2);
7535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7536 register_name = "SRSCtl";
7537 break;
7538 case CP0_REG12__SRSMAP:
7539 check_insn(ctx, ISA_MIPS_R2);
7540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7541 register_name = "SRSMap";
7542 break;
7543 default:
7544 goto cp0_unimplemented;
7545 }
7546 break;
7547 case CP0_REGISTER_13:
7548 switch (sel) {
7549 case CP0_REG13__CAUSE:
7550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7551 register_name = "Cause";
7552 break;
7553 default:
7554 goto cp0_unimplemented;
7555 }
7556 break;
7557 case CP0_REGISTER_14:
7558 switch (sel) {
7559 case CP0_REG14__EPC:
7560 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7561 register_name = "EPC";
7562 break;
7563 default:
7564 goto cp0_unimplemented;
7565 }
7566 break;
7567 case CP0_REGISTER_15:
7568 switch (sel) {
7569 case CP0_REG15__PRID:
7570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7571 register_name = "PRid";
7572 break;
7573 case CP0_REG15__EBASE:
7574 check_insn(ctx, ISA_MIPS_R2);
7575 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7576 register_name = "EBase";
7577 break;
7578 case CP0_REG15__CMGCRBASE:
7579 check_insn(ctx, ISA_MIPS_R2);
7580 CP0_CHECK(ctx->cmgcr);
7581 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7582 register_name = "CMGCRBase";
7583 break;
7584 default:
7585 goto cp0_unimplemented;
7586 }
7587 break;
7588 case CP0_REGISTER_16:
7589 switch (sel) {
7590 case CP0_REG16__CONFIG:
7591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7592 register_name = "Config";
7593 break;
7594 case CP0_REG16__CONFIG1:
7595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7596 register_name = "Config1";
7597 break;
7598 case CP0_REG16__CONFIG2:
7599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7600 register_name = "Config2";
7601 break;
7602 case CP0_REG16__CONFIG3:
7603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7604 register_name = "Config3";
7605 break;
7606 case CP0_REG16__CONFIG4:
7607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7608 register_name = "Config4";
7609 break;
7610 case CP0_REG16__CONFIG5:
7611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7612 register_name = "Config5";
7613 break;
7614
7615 case CP0_REG16__CONFIG6:
7616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7617 register_name = "Config6";
7618 break;
7619 case CP0_REG16__CONFIG7:
7620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7621 register_name = "Config7";
7622 break;
7623 default:
7624 goto cp0_unimplemented;
7625 }
7626 break;
7627 case CP0_REGISTER_17:
7628 switch (sel) {
7629 case CP0_REG17__LLADDR:
7630 gen_helper_dmfc0_lladdr(arg, cpu_env);
7631 register_name = "LLAddr";
7632 break;
7633 case CP0_REG17__MAAR:
7634 CP0_CHECK(ctx->mrp);
7635 gen_helper_dmfc0_maar(arg, cpu_env);
7636 register_name = "MAAR";
7637 break;
7638 case CP0_REG17__MAARI:
7639 CP0_CHECK(ctx->mrp);
7640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7641 register_name = "MAARI";
7642 break;
7643 default:
7644 goto cp0_unimplemented;
7645 }
7646 break;
7647 case CP0_REGISTER_18:
7648 switch (sel) {
7649 case CP0_REG18__WATCHLO0:
7650 case CP0_REG18__WATCHLO1:
7651 case CP0_REG18__WATCHLO2:
7652 case CP0_REG18__WATCHLO3:
7653 case CP0_REG18__WATCHLO4:
7654 case CP0_REG18__WATCHLO5:
7655 case CP0_REG18__WATCHLO6:
7656 case CP0_REG18__WATCHLO7:
7657 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7658 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7659 register_name = "WatchLo";
7660 break;
7661 default:
7662 goto cp0_unimplemented;
7663 }
7664 break;
7665 case CP0_REGISTER_19:
7666 switch (sel) {
7667 case CP0_REG19__WATCHHI0:
7668 case CP0_REG19__WATCHHI1:
7669 case CP0_REG19__WATCHHI2:
7670 case CP0_REG19__WATCHHI3:
7671 case CP0_REG19__WATCHHI4:
7672 case CP0_REG19__WATCHHI5:
7673 case CP0_REG19__WATCHHI6:
7674 case CP0_REG19__WATCHHI7:
7675 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7676 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7677 register_name = "WatchHi";
7678 break;
7679 default:
7680 goto cp0_unimplemented;
7681 }
7682 break;
7683 case CP0_REGISTER_20:
7684 switch (sel) {
7685 case CP0_REG20__XCONTEXT:
7686 check_insn(ctx, ISA_MIPS3);
7687 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7688 register_name = "XContext";
7689 break;
7690 default:
7691 goto cp0_unimplemented;
7692 }
7693 break;
7694 case CP0_REGISTER_21:
7695
7696 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7697 switch (sel) {
7698 case 0:
7699 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7700 register_name = "Framemask";
7701 break;
7702 default:
7703 goto cp0_unimplemented;
7704 }
7705 break;
7706 case CP0_REGISTER_22:
7707 tcg_gen_movi_tl(arg, 0);
7708 register_name = "'Diagnostic";
7709 break;
7710 case CP0_REGISTER_23:
7711 switch (sel) {
7712 case CP0_REG23__DEBUG:
7713 gen_helper_mfc0_debug(arg, cpu_env);
7714 register_name = "Debug";
7715 break;
7716 case CP0_REG23__TRACECONTROL:
7717
7718
7719 register_name = "TraceControl";
7720 goto cp0_unimplemented;
7721 case CP0_REG23__TRACECONTROL2:
7722
7723
7724 register_name = "TraceControl2";
7725 goto cp0_unimplemented;
7726 case CP0_REG23__USERTRACEDATA1:
7727
7728
7729 register_name = "UserTraceData1";
7730 goto cp0_unimplemented;
7731 case CP0_REG23__TRACEIBPC:
7732
7733
7734 register_name = "TraceIBPC";
7735 goto cp0_unimplemented;
7736 case CP0_REG23__TRACEDBPC:
7737
7738
7739 register_name = "TraceDBPC";
7740 goto cp0_unimplemented;
7741 default:
7742 goto cp0_unimplemented;
7743 }
7744 break;
7745 case CP0_REGISTER_24:
7746 switch (sel) {
7747 case CP0_REG24__DEPC:
7748
7749 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7750 register_name = "DEPC";
7751 break;
7752 default:
7753 goto cp0_unimplemented;
7754 }
7755 break;
7756 case CP0_REGISTER_25:
7757 switch (sel) {
7758 case CP0_REG25__PERFCTL0:
7759 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7760 register_name = "Performance0";
7761 break;
7762 case CP0_REG25__PERFCNT0:
7763
7764 register_name = "Performance1";
7765 goto cp0_unimplemented;
7766 case CP0_REG25__PERFCTL1:
7767
7768 register_name = "Performance2";
7769 goto cp0_unimplemented;
7770 case CP0_REG25__PERFCNT1:
7771
7772 register_name = "Performance3";
7773 goto cp0_unimplemented;
7774 case CP0_REG25__PERFCTL2:
7775
7776 register_name = "Performance4";
7777 goto cp0_unimplemented;
7778 case CP0_REG25__PERFCNT2:
7779
7780 register_name = "Performance5";
7781 goto cp0_unimplemented;
7782 case CP0_REG25__PERFCTL3:
7783
7784 register_name = "Performance6";
7785 goto cp0_unimplemented;
7786 case CP0_REG25__PERFCNT3:
7787
7788 register_name = "Performance7";
7789 goto cp0_unimplemented;
7790 default:
7791 goto cp0_unimplemented;
7792 }
7793 break;
7794 case CP0_REGISTER_26:
7795 switch (sel) {
7796 case CP0_REG26__ERRCTL:
7797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7798 register_name = "ErrCtl";
7799 break;
7800 default:
7801 goto cp0_unimplemented;
7802 }
7803 break;
7804 case CP0_REGISTER_27:
7805 switch (sel) {
7806
7807 case CP0_REG27__CACHERR:
7808 tcg_gen_movi_tl(arg, 0);
7809 register_name = "CacheErr";
7810 break;
7811 default:
7812 goto cp0_unimplemented;
7813 }
7814 break;
7815 case CP0_REGISTER_28:
7816 switch (sel) {
7817 case CP0_REG28__TAGLO:
7818 case CP0_REG28__TAGLO1:
7819 case CP0_REG28__TAGLO2:
7820 case CP0_REG28__TAGLO3:
7821 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7822 register_name = "TagLo";
7823 break;
7824 case CP0_REG28__DATALO:
7825 case CP0_REG28__DATALO1:
7826 case CP0_REG28__DATALO2:
7827 case CP0_REG28__DATALO3:
7828 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7829 register_name = "DataLo";
7830 break;
7831 default:
7832 goto cp0_unimplemented;
7833 }
7834 break;
7835 case CP0_REGISTER_29:
7836 switch (sel) {
7837 case CP0_REG29__TAGHI:
7838 case CP0_REG29__TAGHI1:
7839 case CP0_REG29__TAGHI2:
7840 case CP0_REG29__TAGHI3:
7841 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7842 register_name = "TagHi";
7843 break;
7844 case CP0_REG29__DATAHI:
7845 case CP0_REG29__DATAHI1:
7846 case CP0_REG29__DATAHI2:
7847 case CP0_REG29__DATAHI3:
7848 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7849 register_name = "DataHi";
7850 break;
7851 default:
7852 goto cp0_unimplemented;
7853 }
7854 break;
7855 case CP0_REGISTER_30:
7856 switch (sel) {
7857 case CP0_REG30__ERROREPC:
7858 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7859 register_name = "ErrorEPC";
7860 break;
7861 default:
7862 goto cp0_unimplemented;
7863 }
7864 break;
7865 case CP0_REGISTER_31:
7866 switch (sel) {
7867 case CP0_REG31__DESAVE:
7868
7869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7870 register_name = "DESAVE";
7871 break;
7872 case CP0_REG31__KSCRATCH1:
7873 case CP0_REG31__KSCRATCH2:
7874 case CP0_REG31__KSCRATCH3:
7875 case CP0_REG31__KSCRATCH4:
7876 case CP0_REG31__KSCRATCH5:
7877 case CP0_REG31__KSCRATCH6:
7878 CP0_CHECK(ctx->kscrexist & (1 << sel));
7879 tcg_gen_ld_tl(arg, cpu_env,
7880 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7881 register_name = "KScratch";
7882 break;
7883 default:
7884 goto cp0_unimplemented;
7885 }
7886 break;
7887 default:
7888 goto cp0_unimplemented;
7889 }
7890 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7891 return;
7892
7893cp0_unimplemented:
7894 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7895 register_name, reg, sel);
7896 gen_mfc0_unimplemented(ctx, arg);
7897}
7898
7899static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7900{
7901 const char *register_name = "invalid";
7902
7903 if (sel != 0) {
7904 check_insn(ctx, ISA_MIPS_R1);
7905 }
7906
7907 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7908 gen_io_start();
7909 }
7910
7911 switch (reg) {
7912 case CP0_REGISTER_00:
7913 switch (sel) {
7914 case CP0_REG00__INDEX:
7915 gen_helper_mtc0_index(cpu_env, arg);
7916 register_name = "Index";
7917 break;
7918 case CP0_REG00__MVPCONTROL:
7919 CP0_CHECK(ctx->insn_flags & ASE_MT);
7920 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7921 register_name = "MVPControl";
7922 break;
7923 case CP0_REG00__MVPCONF0:
7924 CP0_CHECK(ctx->insn_flags & ASE_MT);
7925
7926 register_name = "MVPConf0";
7927 break;
7928 case CP0_REG00__MVPCONF1:
7929 CP0_CHECK(ctx->insn_flags & ASE_MT);
7930
7931 register_name = "MVPConf1";
7932 break;
7933 case CP0_REG00__VPCONTROL:
7934 CP0_CHECK(ctx->vp);
7935
7936 register_name = "VPControl";
7937 break;
7938 default:
7939 goto cp0_unimplemented;
7940 }
7941 break;
7942 case CP0_REGISTER_01:
7943 switch (sel) {
7944 case CP0_REG01__RANDOM:
7945
7946 register_name = "Random";
7947 break;
7948 case CP0_REG01__VPECONTROL:
7949 CP0_CHECK(ctx->insn_flags & ASE_MT);
7950 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7951 register_name = "VPEControl";
7952 break;
7953 case CP0_REG01__VPECONF0:
7954 CP0_CHECK(ctx->insn_flags & ASE_MT);
7955 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7956 register_name = "VPEConf0";
7957 break;
7958 case CP0_REG01__VPECONF1:
7959 CP0_CHECK(ctx->insn_flags & ASE_MT);
7960 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7961 register_name = "VPEConf1";
7962 break;
7963 case CP0_REG01__YQMASK:
7964 CP0_CHECK(ctx->insn_flags & ASE_MT);
7965 gen_helper_mtc0_yqmask(cpu_env, arg);
7966 register_name = "YQMask";
7967 break;
7968 case CP0_REG01__VPESCHEDULE:
7969 CP0_CHECK(ctx->insn_flags & ASE_MT);
7970 tcg_gen_st_tl(arg, cpu_env,
7971 offsetof(CPUMIPSState, CP0_VPESchedule));
7972 register_name = "VPESchedule";
7973 break;
7974 case CP0_REG01__VPESCHEFBACK:
7975 CP0_CHECK(ctx->insn_flags & ASE_MT);
7976 tcg_gen_st_tl(arg, cpu_env,
7977 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7978 register_name = "VPEScheFBack";
7979 break;
7980 case CP0_REG01__VPEOPT:
7981 CP0_CHECK(ctx->insn_flags & ASE_MT);
7982 gen_helper_mtc0_vpeopt(cpu_env, arg);
7983 register_name = "VPEOpt";
7984 break;
7985 default:
7986 goto cp0_unimplemented;
7987 }
7988 break;
7989 case CP0_REGISTER_02:
7990 switch (sel) {
7991 case CP0_REG02__ENTRYLO0:
7992 gen_helper_dmtc0_entrylo0(cpu_env, arg);
7993 register_name = "EntryLo0";
7994 break;
7995 case CP0_REG02__TCSTATUS:
7996 CP0_CHECK(ctx->insn_flags & ASE_MT);
7997 gen_helper_mtc0_tcstatus(cpu_env, arg);
7998 register_name = "TCStatus";
7999 break;
8000 case CP0_REG02__TCBIND:
8001 CP0_CHECK(ctx->insn_flags & ASE_MT);
8002 gen_helper_mtc0_tcbind(cpu_env, arg);
8003 register_name = "TCBind";
8004 break;
8005 case CP0_REG02__TCRESTART:
8006 CP0_CHECK(ctx->insn_flags & ASE_MT);
8007 gen_helper_mtc0_tcrestart(cpu_env, arg);
8008 register_name = "TCRestart";
8009 break;
8010 case CP0_REG02__TCHALT:
8011 CP0_CHECK(ctx->insn_flags & ASE_MT);
8012 gen_helper_mtc0_tchalt(cpu_env, arg);
8013 register_name = "TCHalt";
8014 break;
8015 case CP0_REG02__TCCONTEXT:
8016 CP0_CHECK(ctx->insn_flags & ASE_MT);
8017 gen_helper_mtc0_tccontext(cpu_env, arg);
8018 register_name = "TCContext";
8019 break;
8020 case CP0_REG02__TCSCHEDULE:
8021 CP0_CHECK(ctx->insn_flags & ASE_MT);
8022 gen_helper_mtc0_tcschedule(cpu_env, arg);
8023 register_name = "TCSchedule";
8024 break;
8025 case CP0_REG02__TCSCHEFBACK:
8026 CP0_CHECK(ctx->insn_flags & ASE_MT);
8027 gen_helper_mtc0_tcschefback(cpu_env, arg);
8028 register_name = "TCScheFBack";
8029 break;
8030 default:
8031 goto cp0_unimplemented;
8032 }
8033 break;
8034 case CP0_REGISTER_03:
8035 switch (sel) {
8036 case CP0_REG03__ENTRYLO1:
8037 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8038 register_name = "EntryLo1";
8039 break;
8040 case CP0_REG03__GLOBALNUM:
8041 CP0_CHECK(ctx->vp);
8042
8043 register_name = "GlobalNumber";
8044 break;
8045 default:
8046 goto cp0_unimplemented;
8047 }
8048 break;
8049 case CP0_REGISTER_04:
8050 switch (sel) {
8051 case CP0_REG04__CONTEXT:
8052 gen_helper_mtc0_context(cpu_env, arg);
8053 register_name = "Context";
8054 break;
8055 case CP0_REG04__CONTEXTCONFIG:
8056
8057
8058 register_name = "ContextConfig";
8059 goto cp0_unimplemented;
8060 case CP0_REG04__USERLOCAL:
8061 CP0_CHECK(ctx->ulri);
8062 tcg_gen_st_tl(arg, cpu_env,
8063 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8064 register_name = "UserLocal";
8065 break;
8066 case CP0_REG04__MMID:
8067 CP0_CHECK(ctx->mi);
8068 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8069 register_name = "MMID";
8070 break;
8071 default:
8072 goto cp0_unimplemented;
8073 }
8074 break;
8075 case CP0_REGISTER_05:
8076 switch (sel) {
8077 case CP0_REG05__PAGEMASK:
8078 gen_helper_mtc0_pagemask(cpu_env, arg);
8079 register_name = "PageMask";
8080 break;
8081 case CP0_REG05__PAGEGRAIN:
8082 check_insn(ctx, ISA_MIPS_R2);
8083 gen_helper_mtc0_pagegrain(cpu_env, arg);
8084 register_name = "PageGrain";
8085 break;
8086 case CP0_REG05__SEGCTL0:
8087 CP0_CHECK(ctx->sc);
8088 gen_helper_mtc0_segctl0(cpu_env, arg);
8089 register_name = "SegCtl0";
8090 break;
8091 case CP0_REG05__SEGCTL1:
8092 CP0_CHECK(ctx->sc);
8093 gen_helper_mtc0_segctl1(cpu_env, arg);
8094 register_name = "SegCtl1";
8095 break;
8096 case CP0_REG05__SEGCTL2:
8097 CP0_CHECK(ctx->sc);
8098 gen_helper_mtc0_segctl2(cpu_env, arg);
8099 register_name = "SegCtl2";
8100 break;
8101 case CP0_REG05__PWBASE:
8102 check_pw(ctx);
8103 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8104 register_name = "PWBase";
8105 break;
8106 case CP0_REG05__PWFIELD:
8107 check_pw(ctx);
8108 gen_helper_mtc0_pwfield(cpu_env, arg);
8109 register_name = "PWField";
8110 break;
8111 case CP0_REG05__PWSIZE:
8112 check_pw(ctx);
8113 gen_helper_mtc0_pwsize(cpu_env, arg);
8114 register_name = "PWSize";
8115 break;
8116 default:
8117 goto cp0_unimplemented;
8118 }
8119 break;
8120 case CP0_REGISTER_06:
8121 switch (sel) {
8122 case CP0_REG06__WIRED:
8123 gen_helper_mtc0_wired(cpu_env, arg);
8124 register_name = "Wired";
8125 break;
8126 case CP0_REG06__SRSCONF0:
8127 check_insn(ctx, ISA_MIPS_R2);
8128 gen_helper_mtc0_srsconf0(cpu_env, arg);
8129 register_name = "SRSConf0";
8130 break;
8131 case CP0_REG06__SRSCONF1:
8132 check_insn(ctx, ISA_MIPS_R2);
8133 gen_helper_mtc0_srsconf1(cpu_env, arg);
8134 register_name = "SRSConf1";
8135 break;
8136 case CP0_REG06__SRSCONF2:
8137 check_insn(ctx, ISA_MIPS_R2);
8138 gen_helper_mtc0_srsconf2(cpu_env, arg);
8139 register_name = "SRSConf2";
8140 break;
8141 case CP0_REG06__SRSCONF3:
8142 check_insn(ctx, ISA_MIPS_R2);
8143 gen_helper_mtc0_srsconf3(cpu_env, arg);
8144 register_name = "SRSConf3";
8145 break;
8146 case CP0_REG06__SRSCONF4:
8147 check_insn(ctx, ISA_MIPS_R2);
8148 gen_helper_mtc0_srsconf4(cpu_env, arg);
8149 register_name = "SRSConf4";
8150 break;
8151 case CP0_REG06__PWCTL:
8152 check_pw(ctx);
8153 gen_helper_mtc0_pwctl(cpu_env, arg);
8154 register_name = "PWCtl";
8155 break;
8156 default:
8157 goto cp0_unimplemented;
8158 }
8159 break;
8160 case CP0_REGISTER_07:
8161 switch (sel) {
8162 case CP0_REG07__HWRENA:
8163 check_insn(ctx, ISA_MIPS_R2);
8164 gen_helper_mtc0_hwrena(cpu_env, arg);
8165 ctx->base.is_jmp = DISAS_STOP;
8166 register_name = "HWREna";
8167 break;
8168 default:
8169 goto cp0_unimplemented;
8170 }
8171 break;
8172 case CP0_REGISTER_08:
8173 switch (sel) {
8174 case CP0_REG08__BADVADDR:
8175
8176 register_name = "BadVAddr";
8177 break;
8178 case CP0_REG08__BADINSTR:
8179
8180 register_name = "BadInstr";
8181 break;
8182 case CP0_REG08__BADINSTRP:
8183
8184 register_name = "BadInstrP";
8185 break;
8186 case CP0_REG08__BADINSTRX:
8187
8188 register_name = "BadInstrX";
8189 break;
8190 default:
8191 goto cp0_unimplemented;
8192 }
8193 break;
8194 case CP0_REGISTER_09:
8195 switch (sel) {
8196 case CP0_REG09__COUNT:
8197 gen_helper_mtc0_count(cpu_env, arg);
8198 register_name = "Count";
8199 break;
8200 case CP0_REG09__SAARI:
8201 CP0_CHECK(ctx->saar);
8202 gen_helper_mtc0_saari(cpu_env, arg);
8203 register_name = "SAARI";
8204 break;
8205 case CP0_REG09__SAAR:
8206 CP0_CHECK(ctx->saar);
8207 gen_helper_mtc0_saar(cpu_env, arg);
8208 register_name = "SAAR";
8209 break;
8210 default:
8211 goto cp0_unimplemented;
8212 }
8213
8214 ctx->base.is_jmp = DISAS_STOP;
8215 break;
8216 case CP0_REGISTER_10:
8217 switch (sel) {
8218 case CP0_REG10__ENTRYHI:
8219 gen_helper_mtc0_entryhi(cpu_env, arg);
8220 register_name = "EntryHi";
8221 break;
8222 default:
8223 goto cp0_unimplemented;
8224 }
8225 break;
8226 case CP0_REGISTER_11:
8227 switch (sel) {
8228 case CP0_REG11__COMPARE:
8229 gen_helper_mtc0_compare(cpu_env, arg);
8230 register_name = "Compare";
8231 break;
8232
8233 default:
8234 goto cp0_unimplemented;
8235 }
8236
8237 ctx->base.is_jmp = DISAS_STOP;
8238 break;
8239 case CP0_REGISTER_12:
8240 switch (sel) {
8241 case CP0_REG12__STATUS:
8242 save_cpu_state(ctx, 1);
8243 gen_helper_mtc0_status(cpu_env, arg);
8244
8245 gen_save_pc(ctx->base.pc_next + 4);
8246 ctx->base.is_jmp = DISAS_EXIT;
8247 register_name = "Status";
8248 break;
8249 case CP0_REG12__INTCTL:
8250 check_insn(ctx, ISA_MIPS_R2);
8251 gen_helper_mtc0_intctl(cpu_env, arg);
8252
8253 ctx->base.is_jmp = DISAS_STOP;
8254 register_name = "IntCtl";
8255 break;
8256 case CP0_REG12__SRSCTL:
8257 check_insn(ctx, ISA_MIPS_R2);
8258 gen_helper_mtc0_srsctl(cpu_env, arg);
8259
8260 ctx->base.is_jmp = DISAS_STOP;
8261 register_name = "SRSCtl";
8262 break;
8263 case CP0_REG12__SRSMAP:
8264 check_insn(ctx, ISA_MIPS_R2);
8265 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8266
8267 ctx->base.is_jmp = DISAS_STOP;
8268 register_name = "SRSMap";
8269 break;
8270 default:
8271 goto cp0_unimplemented;
8272 }
8273 break;
8274 case CP0_REGISTER_13:
8275 switch (sel) {
8276 case CP0_REG13__CAUSE:
8277 save_cpu_state(ctx, 1);
8278 gen_helper_mtc0_cause(cpu_env, arg);
8279
8280
8281
8282
8283
8284 gen_save_pc(ctx->base.pc_next + 4);
8285 ctx->base.is_jmp = DISAS_EXIT;
8286 register_name = "Cause";
8287 break;
8288 default:
8289 goto cp0_unimplemented;
8290 }
8291 break;
8292 case CP0_REGISTER_14:
8293 switch (sel) {
8294 case CP0_REG14__EPC:
8295 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8296 register_name = "EPC";
8297 break;
8298 default:
8299 goto cp0_unimplemented;
8300 }
8301 break;
8302 case CP0_REGISTER_15:
8303 switch (sel) {
8304 case CP0_REG15__PRID:
8305
8306 register_name = "PRid";
8307 break;
8308 case CP0_REG15__EBASE:
8309 check_insn(ctx, ISA_MIPS_R2);
8310 gen_helper_mtc0_ebase(cpu_env, arg);
8311 register_name = "EBase";
8312 break;
8313 default:
8314 goto cp0_unimplemented;
8315 }
8316 break;
8317 case CP0_REGISTER_16:
8318 switch (sel) {
8319 case CP0_REG16__CONFIG:
8320 gen_helper_mtc0_config0(cpu_env, arg);
8321 register_name = "Config";
8322
8323 ctx->base.is_jmp = DISAS_STOP;
8324 break;
8325 case CP0_REG16__CONFIG1:
8326
8327 register_name = "Config1";
8328 break;
8329 case CP0_REG16__CONFIG2:
8330 gen_helper_mtc0_config2(cpu_env, arg);
8331 register_name = "Config2";
8332
8333 ctx->base.is_jmp = DISAS_STOP;
8334 break;
8335 case CP0_REG16__CONFIG3:
8336 gen_helper_mtc0_config3(cpu_env, arg);
8337 register_name = "Config3";
8338
8339 ctx->base.is_jmp = DISAS_STOP;
8340 break;
8341 case CP0_REG16__CONFIG4:
8342
8343 register_name = "Config4";
8344 break;
8345 case CP0_REG16__CONFIG5:
8346 gen_helper_mtc0_config5(cpu_env, arg);
8347 register_name = "Config5";
8348
8349 ctx->base.is_jmp = DISAS_STOP;
8350 break;
8351
8352 default:
8353 register_name = "Invalid config selector";
8354 goto cp0_unimplemented;
8355 }
8356 break;
8357 case CP0_REGISTER_17:
8358 switch (sel) {
8359 case CP0_REG17__LLADDR:
8360 gen_helper_mtc0_lladdr(cpu_env, arg);
8361 register_name = "LLAddr";
8362 break;
8363 case CP0_REG17__MAAR:
8364 CP0_CHECK(ctx->mrp);
8365 gen_helper_mtc0_maar(cpu_env, arg);
8366 register_name = "MAAR";
8367 break;
8368 case CP0_REG17__MAARI:
8369 CP0_CHECK(ctx->mrp);
8370 gen_helper_mtc0_maari(cpu_env, arg);
8371 register_name = "MAARI";
8372 break;
8373 default:
8374 goto cp0_unimplemented;
8375 }
8376 break;
8377 case CP0_REGISTER_18:
8378 switch (sel) {
8379 case CP0_REG18__WATCHLO0:
8380 case CP0_REG18__WATCHLO1:
8381 case CP0_REG18__WATCHLO2:
8382 case CP0_REG18__WATCHLO3:
8383 case CP0_REG18__WATCHLO4:
8384 case CP0_REG18__WATCHLO5:
8385 case CP0_REG18__WATCHLO6:
8386 case CP0_REG18__WATCHLO7:
8387 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8388 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8389 register_name = "WatchLo";
8390 break;
8391 default:
8392 goto cp0_unimplemented;
8393 }
8394 break;
8395 case CP0_REGISTER_19:
8396 switch (sel) {
8397 case CP0_REG19__WATCHHI0:
8398 case CP0_REG19__WATCHHI1:
8399 case CP0_REG19__WATCHHI2:
8400 case CP0_REG19__WATCHHI3:
8401 case CP0_REG19__WATCHHI4:
8402 case CP0_REG19__WATCHHI5:
8403 case CP0_REG19__WATCHHI6:
8404 case CP0_REG19__WATCHHI7:
8405 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8406 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8407 register_name = "WatchHi";
8408 break;
8409 default:
8410 goto cp0_unimplemented;
8411 }
8412 break;
8413 case CP0_REGISTER_20:
8414 switch (sel) {
8415 case CP0_REG20__XCONTEXT:
8416 check_insn(ctx, ISA_MIPS3);
8417 gen_helper_mtc0_xcontext(cpu_env, arg);
8418 register_name = "XContext";
8419 break;
8420 default:
8421 goto cp0_unimplemented;
8422 }
8423 break;
8424 case CP0_REGISTER_21:
8425
8426 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8427 switch (sel) {
8428 case 0:
8429 gen_helper_mtc0_framemask(cpu_env, arg);
8430 register_name = "Framemask";
8431 break;
8432 default:
8433 goto cp0_unimplemented;
8434 }
8435 break;
8436 case CP0_REGISTER_22:
8437
8438 register_name = "Diagnostic";
8439 break;
8440 case CP0_REGISTER_23:
8441 switch (sel) {
8442 case CP0_REG23__DEBUG:
8443 gen_helper_mtc0_debug(cpu_env, arg);
8444
8445 gen_save_pc(ctx->base.pc_next + 4);
8446 ctx->base.is_jmp = DISAS_EXIT;
8447 register_name = "Debug";
8448 break;
8449 case CP0_REG23__TRACECONTROL:
8450
8451
8452
8453 ctx->base.is_jmp = DISAS_STOP;
8454 register_name = "TraceControl";
8455 goto cp0_unimplemented;
8456 case CP0_REG23__TRACECONTROL2:
8457
8458
8459
8460 ctx->base.is_jmp = DISAS_STOP;
8461 register_name = "TraceControl2";
8462 goto cp0_unimplemented;
8463 case CP0_REG23__USERTRACEDATA1:
8464
8465
8466
8467 ctx->base.is_jmp = DISAS_STOP;
8468 register_name = "UserTraceData1";
8469 goto cp0_unimplemented;
8470 case CP0_REG23__TRACEIBPC:
8471
8472
8473
8474 ctx->base.is_jmp = DISAS_STOP;
8475 register_name = "TraceIBPC";
8476 goto cp0_unimplemented;
8477 case CP0_REG23__TRACEDBPC:
8478
8479
8480
8481 ctx->base.is_jmp = DISAS_STOP;
8482 register_name = "TraceDBPC";
8483 goto cp0_unimplemented;
8484 default:
8485 goto cp0_unimplemented;
8486 }
8487 break;
8488 case CP0_REGISTER_24:
8489 switch (sel) {
8490 case CP0_REG24__DEPC:
8491
8492 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8493 register_name = "DEPC";
8494 break;
8495 default:
8496 goto cp0_unimplemented;
8497 }
8498 break;
8499 case CP0_REGISTER_25:
8500 switch (sel) {
8501 case CP0_REG25__PERFCTL0:
8502 gen_helper_mtc0_performance0(cpu_env, arg);
8503 register_name = "Performance0";
8504 break;
8505 case CP0_REG25__PERFCNT0:
8506
8507 register_name = "Performance1";
8508 goto cp0_unimplemented;
8509 case CP0_REG25__PERFCTL1:
8510
8511 register_name = "Performance2";
8512 goto cp0_unimplemented;
8513 case CP0_REG25__PERFCNT1:
8514
8515 register_name = "Performance3";
8516 goto cp0_unimplemented;
8517 case CP0_REG25__PERFCTL2:
8518
8519 register_name = "Performance4";
8520 goto cp0_unimplemented;
8521 case CP0_REG25__PERFCNT2:
8522
8523 register_name = "Performance5";
8524 goto cp0_unimplemented;
8525 case CP0_REG25__PERFCTL3:
8526
8527 register_name = "Performance6";
8528 goto cp0_unimplemented;
8529 case CP0_REG25__PERFCNT3:
8530
8531 register_name = "Performance7";
8532 goto cp0_unimplemented;
8533 default:
8534 goto cp0_unimplemented;
8535 }
8536 break;
8537 case CP0_REGISTER_26:
8538 switch (sel) {
8539 case CP0_REG26__ERRCTL:
8540 gen_helper_mtc0_errctl(cpu_env, arg);
8541 ctx->base.is_jmp = DISAS_STOP;
8542 register_name = "ErrCtl";
8543 break;
8544 default:
8545 goto cp0_unimplemented;
8546 }
8547 break;
8548 case CP0_REGISTER_27:
8549 switch (sel) {
8550 case CP0_REG27__CACHERR:
8551
8552 register_name = "CacheErr";
8553 break;
8554 default:
8555 goto cp0_unimplemented;
8556 }
8557 break;
8558 case CP0_REGISTER_28:
8559 switch (sel) {
8560 case CP0_REG28__TAGLO:
8561 case CP0_REG28__TAGLO1:
8562 case CP0_REG28__TAGLO2:
8563 case CP0_REG28__TAGLO3:
8564 gen_helper_mtc0_taglo(cpu_env, arg);
8565 register_name = "TagLo";
8566 break;
8567 case CP0_REG28__DATALO:
8568 case CP0_REG28__DATALO1:
8569 case CP0_REG28__DATALO2:
8570 case CP0_REG28__DATALO3:
8571 gen_helper_mtc0_datalo(cpu_env, arg);
8572 register_name = "DataLo";
8573 break;
8574 default:
8575 goto cp0_unimplemented;
8576 }
8577 break;
8578 case CP0_REGISTER_29:
8579 switch (sel) {
8580 case CP0_REG29__TAGHI:
8581 case CP0_REG29__TAGHI1:
8582 case CP0_REG29__TAGHI2:
8583 case CP0_REG29__TAGHI3:
8584 gen_helper_mtc0_taghi(cpu_env, arg);
8585 register_name = "TagHi";
8586 break;
8587 case CP0_REG29__DATAHI:
8588 case CP0_REG29__DATAHI1:
8589 case CP0_REG29__DATAHI2:
8590 case CP0_REG29__DATAHI3:
8591 gen_helper_mtc0_datahi(cpu_env, arg);
8592 register_name = "DataHi";
8593 break;
8594 default:
8595 register_name = "invalid sel";
8596 goto cp0_unimplemented;
8597 }
8598 break;
8599 case CP0_REGISTER_30:
8600 switch (sel) {
8601 case CP0_REG30__ERROREPC:
8602 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8603 register_name = "ErrorEPC";
8604 break;
8605 default:
8606 goto cp0_unimplemented;
8607 }
8608 break;
8609 case CP0_REGISTER_31:
8610 switch (sel) {
8611 case CP0_REG31__DESAVE:
8612
8613 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8614 register_name = "DESAVE";
8615 break;
8616 case CP0_REG31__KSCRATCH1:
8617 case CP0_REG31__KSCRATCH2:
8618 case CP0_REG31__KSCRATCH3:
8619 case CP0_REG31__KSCRATCH4:
8620 case CP0_REG31__KSCRATCH5:
8621 case CP0_REG31__KSCRATCH6:
8622 CP0_CHECK(ctx->kscrexist & (1 << sel));
8623 tcg_gen_st_tl(arg, cpu_env,
8624 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8625 register_name = "KScratch";
8626 break;
8627 default:
8628 goto cp0_unimplemented;
8629 }
8630 break;
8631 default:
8632 goto cp0_unimplemented;
8633 }
8634 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8635
8636
8637 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8638
8639
8640
8641
8642 gen_save_pc(ctx->base.pc_next + 4);
8643 ctx->base.is_jmp = DISAS_EXIT;
8644 }
8645 return;
8646
8647cp0_unimplemented:
8648 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8649 register_name, reg, sel);
8650}
8651#endif
8652
8653static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8654 int u, int sel, int h)
8655{
8656 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8657 TCGv t0 = tcg_temp_local_new();
8658
8659 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8660 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8661 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8662 tcg_gen_movi_tl(t0, -1);
8663 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8664 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8665 tcg_gen_movi_tl(t0, -1);
8666 } else if (u == 0) {
8667 switch (rt) {
8668 case 1:
8669 switch (sel) {
8670 case 1:
8671 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8672 break;
8673 case 2:
8674 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8675 break;
8676 default:
8677 goto die;
8678 break;
8679 }
8680 break;
8681 case 2:
8682 switch (sel) {
8683 case 1:
8684 gen_helper_mftc0_tcstatus(t0, cpu_env);
8685 break;
8686 case 2:
8687 gen_helper_mftc0_tcbind(t0, cpu_env);
8688 break;
8689 case 3:
8690 gen_helper_mftc0_tcrestart(t0, cpu_env);
8691 break;
8692 case 4:
8693 gen_helper_mftc0_tchalt(t0, cpu_env);
8694 break;
8695 case 5:
8696 gen_helper_mftc0_tccontext(t0, cpu_env);
8697 break;
8698 case 6:
8699 gen_helper_mftc0_tcschedule(t0, cpu_env);
8700 break;
8701 case 7:
8702 gen_helper_mftc0_tcschefback(t0, cpu_env);
8703 break;
8704 default:
8705 gen_mfc0(ctx, t0, rt, sel);
8706 break;
8707 }
8708 break;
8709 case 10:
8710 switch (sel) {
8711 case 0:
8712 gen_helper_mftc0_entryhi(t0, cpu_env);
8713 break;
8714 default:
8715 gen_mfc0(ctx, t0, rt, sel);
8716 break;
8717 }
8718 break;
8719 case 12:
8720 switch (sel) {
8721 case 0:
8722 gen_helper_mftc0_status(t0, cpu_env);
8723 break;
8724 default:
8725 gen_mfc0(ctx, t0, rt, sel);
8726 break;
8727 }
8728 break;
8729 case 13:
8730 switch (sel) {
8731 case 0:
8732 gen_helper_mftc0_cause(t0, cpu_env);
8733 break;
8734 default:
8735 goto die;
8736 break;
8737 }
8738 break;
8739 case 14:
8740 switch (sel) {
8741 case 0:
8742 gen_helper_mftc0_epc(t0, cpu_env);
8743 break;
8744 default:
8745 goto die;
8746 break;
8747 }
8748 break;
8749 case 15:
8750 switch (sel) {
8751 case 1:
8752 gen_helper_mftc0_ebase(t0, cpu_env);
8753 break;
8754 default:
8755 goto die;
8756 break;
8757 }
8758 break;
8759 case 16:
8760 switch (sel) {
8761 case 0:
8762 case 1:
8763 case 2:
8764 case 3:
8765 case 4:
8766 case 5:
8767 case 6:
8768 case 7:
8769 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8770 break;
8771 default:
8772 goto die;
8773 break;
8774 }
8775 break;
8776 case 23:
8777 switch (sel) {
8778 case 0:
8779 gen_helper_mftc0_debug(t0, cpu_env);
8780 break;
8781 default:
8782 gen_mfc0(ctx, t0, rt, sel);
8783 break;
8784 }
8785 break;
8786 default:
8787 gen_mfc0(ctx, t0, rt, sel);
8788 }
8789 } else {
8790 switch (sel) {
8791
8792 case 0:
8793 gen_helper_1e0i(mftgpr, t0, rt);
8794 break;
8795
8796 case 1:
8797 switch (rt) {
8798 case 0:
8799 gen_helper_1e0i(mftlo, t0, 0);
8800 break;
8801 case 1:
8802 gen_helper_1e0i(mfthi, t0, 0);
8803 break;
8804 case 2:
8805 gen_helper_1e0i(mftacx, t0, 0);
8806 break;
8807 case 4:
8808 gen_helper_1e0i(mftlo, t0, 1);
8809 break;
8810 case 5:
8811 gen_helper_1e0i(mfthi, t0, 1);
8812 break;
8813 case 6:
8814 gen_helper_1e0i(mftacx, t0, 1);
8815 break;
8816 case 8:
8817 gen_helper_1e0i(mftlo, t0, 2);
8818 break;
8819 case 9:
8820 gen_helper_1e0i(mfthi, t0, 2);
8821 break;
8822 case 10:
8823 gen_helper_1e0i(mftacx, t0, 2);
8824 break;
8825 case 12:
8826 gen_helper_1e0i(mftlo, t0, 3);
8827 break;
8828 case 13:
8829 gen_helper_1e0i(mfthi, t0, 3);
8830 break;
8831 case 14:
8832 gen_helper_1e0i(mftacx, t0, 3);
8833 break;
8834 case 16:
8835 gen_helper_mftdsp(t0, cpu_env);
8836 break;
8837 default:
8838 goto die;
8839 }
8840 break;
8841
8842 case 2:
8843
8844 if (h == 0) {
8845 TCGv_i32 fp0 = tcg_temp_new_i32();
8846
8847 gen_load_fpr32(ctx, fp0, rt);
8848 tcg_gen_ext_i32_tl(t0, fp0);
8849 tcg_temp_free_i32(fp0);
8850 } else {
8851 TCGv_i32 fp0 = tcg_temp_new_i32();
8852
8853 gen_load_fpr32h(ctx, fp0, rt);
8854 tcg_gen_ext_i32_tl(t0, fp0);
8855 tcg_temp_free_i32(fp0);
8856 }
8857 break;
8858 case 3:
8859
8860 gen_helper_1e0i(cfc1, t0, rt);
8861 break;
8862
8863 case 4:
8864 case 5:
8865
8866 default:
8867 goto die;
8868 }
8869 }
8870 trace_mips_translate_tr("mftr", rt, u, sel, h);
8871 gen_store_gpr(t0, rd);
8872 tcg_temp_free(t0);
8873 return;
8874
8875die:
8876 tcg_temp_free(t0);
8877 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8878 gen_reserved_instruction(ctx);
8879}
8880
8881static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8882 int u, int sel, int h)
8883{
8884 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8885 TCGv t0 = tcg_temp_local_new();
8886
8887 gen_load_gpr(t0, rt);
8888 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8889 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8890 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8891
8892 ;
8893 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8894 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8895
8896 ;
8897 } else if (u == 0) {
8898 switch (rd) {
8899 case 1:
8900 switch (sel) {
8901 case 1:
8902 gen_helper_mttc0_vpecontrol(cpu_env, t0);
8903 break;
8904 case 2:
8905 gen_helper_mttc0_vpeconf0(cpu_env, t0);
8906 break;
8907 default:
8908 goto die;
8909 break;
8910 }
8911 break;
8912 case 2:
8913 switch (sel) {
8914 case 1:
8915 gen_helper_mttc0_tcstatus(cpu_env, t0);
8916 break;
8917 case 2:
8918 gen_helper_mttc0_tcbind(cpu_env, t0);
8919 break;
8920 case 3:
8921 gen_helper_mttc0_tcrestart(cpu_env, t0);
8922 break;
8923 case 4:
8924 gen_helper_mttc0_tchalt(cpu_env, t0);
8925 break;
8926 case 5:
8927 gen_helper_mttc0_tccontext(cpu_env, t0);
8928 break;
8929 case 6:
8930 gen_helper_mttc0_tcschedule(cpu_env, t0);
8931 break;
8932 case 7:
8933 gen_helper_mttc0_tcschefback(cpu_env, t0);
8934 break;
8935 default:
8936 gen_mtc0(ctx, t0, rd, sel);
8937 break;
8938 }
8939 break;
8940 case 10:
8941 switch (sel) {
8942 case 0:
8943 gen_helper_mttc0_entryhi(cpu_env, t0);
8944 break;
8945 default:
8946 gen_mtc0(ctx, t0, rd, sel);
8947 break;
8948 }
8949 break;
8950 case 12:
8951 switch (sel) {
8952 case 0:
8953 gen_helper_mttc0_status(cpu_env, t0);
8954 break;
8955 default:
8956 gen_mtc0(ctx, t0, rd, sel);
8957 break;
8958 }
8959 break;
8960 case 13:
8961 switch (sel) {
8962 case 0:
8963 gen_helper_mttc0_cause(cpu_env, t0);
8964 break;
8965 default:
8966 goto die;
8967 break;
8968 }
8969 break;
8970 case 15:
8971 switch (sel) {
8972 case 1:
8973 gen_helper_mttc0_ebase(cpu_env, t0);
8974 break;
8975 default:
8976 goto die;
8977 break;
8978 }
8979 break;
8980 case 23:
8981 switch (sel) {
8982 case 0:
8983 gen_helper_mttc0_debug(cpu_env, t0);
8984 break;
8985 default:
8986 gen_mtc0(ctx, t0, rd, sel);
8987 break;
8988 }
8989 break;
8990 default:
8991 gen_mtc0(ctx, t0, rd, sel);
8992 }
8993 } else {
8994 switch (sel) {
8995
8996 case 0:
8997 gen_helper_0e1i(mttgpr, t0, rd);
8998 break;
8999
9000 case 1:
9001 switch (rd) {
9002 case 0:
9003 gen_helper_0e1i(mttlo, t0, 0);
9004 break;
9005 case 1:
9006 gen_helper_0e1i(mtthi, t0, 0);
9007 break;
9008 case 2:
9009 gen_helper_0e1i(mttacx, t0, 0);
9010 break;
9011 case 4:
9012 gen_helper_0e1i(mttlo, t0, 1);
9013 break;
9014 case 5:
9015 gen_helper_0e1i(mtthi, t0, 1);
9016 break;
9017 case 6:
9018 gen_helper_0e1i(mttacx, t0, 1);
9019 break;
9020 case 8:
9021 gen_helper_0e1i(mttlo, t0, 2);
9022 break;
9023 case 9:
9024 gen_helper_0e1i(mtthi, t0, 2);
9025 break;
9026 case 10:
9027 gen_helper_0e1i(mttacx, t0, 2);
9028 break;
9029 case 12:
9030 gen_helper_0e1i(mttlo, t0, 3);
9031 break;
9032 case 13:
9033 gen_helper_0e1i(mtthi, t0, 3);
9034 break;
9035 case 14:
9036 gen_helper_0e1i(mttacx, t0, 3);
9037 break;
9038 case 16:
9039 gen_helper_mttdsp(cpu_env, t0);
9040 break;
9041 default:
9042 goto die;
9043 }
9044 break;
9045
9046 case 2:
9047
9048 if (h == 0) {
9049 TCGv_i32 fp0 = tcg_temp_new_i32();
9050
9051 tcg_gen_trunc_tl_i32(fp0, t0);
9052 gen_store_fpr32(ctx, fp0, rd);
9053 tcg_temp_free_i32(fp0);
9054 } else {
9055 TCGv_i32 fp0 = tcg_temp_new_i32();
9056
9057 tcg_gen_trunc_tl_i32(fp0, t0);
9058 gen_store_fpr32h(ctx, fp0, rd);
9059 tcg_temp_free_i32(fp0);
9060 }
9061 break;
9062 case 3:
9063
9064 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
9065
9066 ctx->base.is_jmp = DISAS_STOP;
9067 break;
9068
9069 case 4:
9070 case 5:
9071
9072 default:
9073 goto die;
9074 }
9075 }
9076 trace_mips_translate_tr("mttr", rd, u, sel, h);
9077 tcg_temp_free(t0);
9078 return;
9079
9080die:
9081 tcg_temp_free(t0);
9082 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9083 gen_reserved_instruction(ctx);
9084}
9085
9086static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9087 int rt, int rd)
9088{
9089 const char *opn = "ldst";
9090
9091 check_cp0_enabled(ctx);
9092 switch (opc) {
9093 case OPC_MFC0:
9094 if (rt == 0) {
9095
9096 return;
9097 }
9098 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9099 opn = "mfc0";
9100 break;
9101 case OPC_MTC0:
9102 {
9103 TCGv t0 = tcg_temp_new();
9104
9105 gen_load_gpr(t0, rt);
9106 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9107 tcg_temp_free(t0);
9108 }
9109 opn = "mtc0";
9110 break;
9111#if defined(TARGET_MIPS64)
9112 case OPC_DMFC0:
9113 check_insn(ctx, ISA_MIPS3);
9114 if (rt == 0) {
9115
9116 return;
9117 }
9118 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9119 opn = "dmfc0";
9120 break;
9121 case OPC_DMTC0:
9122 check_insn(ctx, ISA_MIPS3);
9123 {
9124 TCGv t0 = tcg_temp_new();
9125
9126 gen_load_gpr(t0, rt);
9127 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9128 tcg_temp_free(t0);
9129 }
9130 opn = "dmtc0";
9131 break;
9132#endif
9133 case OPC_MFHC0:
9134 check_mvh(ctx);
9135 if (rt == 0) {
9136
9137 return;
9138 }
9139 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9140 opn = "mfhc0";
9141 break;
9142 case OPC_MTHC0:
9143 check_mvh(ctx);
9144 {
9145 TCGv t0 = tcg_temp_new();
9146 gen_load_gpr(t0, rt);
9147 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9148 tcg_temp_free(t0);
9149 }
9150 opn = "mthc0";
9151 break;
9152 case OPC_MFTR:
9153 check_cp0_enabled(ctx);
9154 if (rd == 0) {
9155
9156 return;
9157 }
9158 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9159 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9160 opn = "mftr";
9161 break;
9162 case OPC_MTTR:
9163 check_cp0_enabled(ctx);
9164 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9165 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9166 opn = "mttr";
9167 break;
9168 case OPC_TLBWI:
9169 opn = "tlbwi";
9170 if (!env->tlb->helper_tlbwi) {
9171 goto die;
9172 }
9173 gen_helper_tlbwi(cpu_env);
9174 break;
9175 case OPC_TLBINV:
9176 opn = "tlbinv";
9177 if (ctx->ie >= 2) {
9178 if (!env->tlb->helper_tlbinv) {
9179 goto die;
9180 }
9181 gen_helper_tlbinv(cpu_env);
9182 }
9183 break;
9184 case OPC_TLBINVF:
9185 opn = "tlbinvf";
9186 if (ctx->ie >= 2) {
9187 if (!env->tlb->helper_tlbinvf) {
9188 goto die;
9189 }
9190 gen_helper_tlbinvf(cpu_env);
9191 }
9192 break;
9193 case OPC_TLBWR:
9194 opn = "tlbwr";
9195 if (!env->tlb->helper_tlbwr) {
9196 goto die;
9197 }
9198 gen_helper_tlbwr(cpu_env);
9199 break;
9200 case OPC_TLBP:
9201 opn = "tlbp";
9202 if (!env->tlb->helper_tlbp) {
9203 goto die;
9204 }
9205 gen_helper_tlbp(cpu_env);
9206 break;
9207 case OPC_TLBR:
9208 opn = "tlbr";
9209 if (!env->tlb->helper_tlbr) {
9210 goto die;
9211 }
9212 gen_helper_tlbr(cpu_env);
9213 break;
9214 case OPC_ERET:
9215 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9216 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9217 goto die;
9218 } else {
9219 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9220 if (ctx->opcode & (1 << bit_shift)) {
9221
9222 opn = "eretnc";
9223 check_insn(ctx, ISA_MIPS_R5);
9224 gen_helper_eretnc(cpu_env);
9225 } else {
9226
9227 opn = "eret";
9228 check_insn(ctx, ISA_MIPS2);
9229 gen_helper_eret(cpu_env);
9230 }
9231 ctx->base.is_jmp = DISAS_EXIT;
9232 }
9233 break;
9234 case OPC_DERET:
9235 opn = "deret";
9236 check_insn(ctx, ISA_MIPS_R1);
9237 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9238 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9239 goto die;
9240 }
9241 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9242 MIPS_INVAL(opn);
9243 gen_reserved_instruction(ctx);
9244 } else {
9245 gen_helper_deret(cpu_env);
9246 ctx->base.is_jmp = DISAS_EXIT;
9247 }
9248 break;
9249 case OPC_WAIT:
9250 opn = "wait";
9251 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9252 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9253 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9254 goto die;
9255 }
9256
9257 ctx->base.pc_next += 4;
9258 save_cpu_state(ctx, 1);
9259 ctx->base.pc_next -= 4;
9260 gen_helper_wait(cpu_env);
9261 ctx->base.is_jmp = DISAS_NORETURN;
9262 break;
9263 default:
9264 die:
9265 MIPS_INVAL(opn);
9266 gen_reserved_instruction(ctx);
9267 return;
9268 }
9269 (void)opn;
9270}
9271#endif
9272
9273
9274static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9275 int32_t cc, int32_t offset)
9276{
9277 target_ulong btarget;
9278 TCGv_i32 t0 = tcg_temp_new_i32();
9279
9280 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9281 gen_reserved_instruction(ctx);
9282 goto out;
9283 }
9284
9285 if (cc != 0) {
9286 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9287 }
9288
9289 btarget = ctx->base.pc_next + 4 + offset;
9290
9291 switch (op) {
9292 case OPC_BC1F:
9293 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9294 tcg_gen_not_i32(t0, t0);
9295 tcg_gen_andi_i32(t0, t0, 1);
9296 tcg_gen_extu_i32_tl(bcond, t0);
9297 goto not_likely;
9298 case OPC_BC1FL:
9299 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9300 tcg_gen_not_i32(t0, t0);
9301 tcg_gen_andi_i32(t0, t0, 1);
9302 tcg_gen_extu_i32_tl(bcond, t0);
9303 goto likely;
9304 case OPC_BC1T:
9305 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9306 tcg_gen_andi_i32(t0, t0, 1);
9307 tcg_gen_extu_i32_tl(bcond, t0);
9308 goto not_likely;
9309 case OPC_BC1TL:
9310 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9311 tcg_gen_andi_i32(t0, t0, 1);
9312 tcg_gen_extu_i32_tl(bcond, t0);
9313 likely:
9314 ctx->hflags |= MIPS_HFLAG_BL;
9315 break;
9316 case OPC_BC1FANY2:
9317 {
9318 TCGv_i32 t1 = tcg_temp_new_i32();
9319 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9320 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9321 tcg_gen_nand_i32(t0, t0, t1);
9322 tcg_temp_free_i32(t1);
9323 tcg_gen_andi_i32(t0, t0, 1);
9324 tcg_gen_extu_i32_tl(bcond, t0);
9325 }
9326 goto not_likely;
9327 case OPC_BC1TANY2:
9328 {
9329 TCGv_i32 t1 = tcg_temp_new_i32();
9330 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9331 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9332 tcg_gen_or_i32(t0, t0, t1);
9333 tcg_temp_free_i32(t1);
9334 tcg_gen_andi_i32(t0, t0, 1);
9335 tcg_gen_extu_i32_tl(bcond, t0);
9336 }
9337 goto not_likely;
9338 case OPC_BC1FANY4:
9339 {
9340 TCGv_i32 t1 = tcg_temp_new_i32();
9341 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9342 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9343 tcg_gen_and_i32(t0, t0, t1);
9344 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9345 tcg_gen_and_i32(t0, t0, t1);
9346 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9347 tcg_gen_nand_i32(t0, t0, t1);
9348 tcg_temp_free_i32(t1);
9349 tcg_gen_andi_i32(t0, t0, 1);
9350 tcg_gen_extu_i32_tl(bcond, t0);
9351 }
9352 goto not_likely;
9353 case OPC_BC1TANY4:
9354 {
9355 TCGv_i32 t1 = tcg_temp_new_i32();
9356 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9357 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9358 tcg_gen_or_i32(t0, t0, t1);
9359 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9360 tcg_gen_or_i32(t0, t0, t1);
9361 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9362 tcg_gen_or_i32(t0, t0, t1);
9363 tcg_temp_free_i32(t1);
9364 tcg_gen_andi_i32(t0, t0, 1);
9365 tcg_gen_extu_i32_tl(bcond, t0);
9366 }
9367 not_likely:
9368 ctx->hflags |= MIPS_HFLAG_BC;
9369 break;
9370 default:
9371 MIPS_INVAL("cp1 cond branch");
9372 gen_reserved_instruction(ctx);
9373 goto out;
9374 }
9375 ctx->btarget = btarget;
9376 ctx->hflags |= MIPS_HFLAG_BDS32;
9377 out:
9378 tcg_temp_free_i32(t0);
9379}
9380
9381
9382static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9383 int32_t ft, int32_t offset,
9384 int delayslot_size)
9385{
9386 target_ulong btarget;
9387 TCGv_i64 t0 = tcg_temp_new_i64();
9388
9389 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9390#ifdef MIPS_DEBUG_DISAS
9391 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9392 "\n", ctx->base.pc_next);
9393#endif
9394 gen_reserved_instruction(ctx);
9395 goto out;
9396 }
9397
9398 gen_load_fpr64(ctx, t0, ft);
9399 tcg_gen_andi_i64(t0, t0, 1);
9400
9401 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9402
9403 switch (op) {
9404 case OPC_BC1EQZ:
9405 tcg_gen_xori_i64(t0, t0, 1);
9406 ctx->hflags |= MIPS_HFLAG_BC;
9407 break;
9408 case OPC_BC1NEZ:
9409
9410 ctx->hflags |= MIPS_HFLAG_BC;
9411 break;
9412 default:
9413 MIPS_INVAL("cp1 cond branch");
9414 gen_reserved_instruction(ctx);
9415 goto out;
9416 }
9417
9418 tcg_gen_trunc_i64_tl(bcond, t0);
9419
9420 ctx->btarget = btarget;
9421
9422 switch (delayslot_size) {
9423 case 2:
9424 ctx->hflags |= MIPS_HFLAG_BDS16;
9425 break;
9426 case 4:
9427 ctx->hflags |= MIPS_HFLAG_BDS32;
9428 break;
9429 }
9430
9431out:
9432 tcg_temp_free_i64(t0);
9433}
9434
9435
9436
9437#define FOP(func, fmt) (((fmt) << 21) | (func))
9438
9439enum fopcode {
9440 OPC_ADD_S = FOP(0, FMT_S),
9441 OPC_SUB_S = FOP(1, FMT_S),
9442 OPC_MUL_S = FOP(2, FMT_S),
9443 OPC_DIV_S = FOP(3, FMT_S),
9444 OPC_SQRT_S = FOP(4, FMT_S),
9445 OPC_ABS_S = FOP(5, FMT_S),
9446 OPC_MOV_S = FOP(6, FMT_S),
9447 OPC_NEG_S = FOP(7, FMT_S),
9448 OPC_ROUND_L_S = FOP(8, FMT_S),
9449 OPC_TRUNC_L_S = FOP(9, FMT_S),
9450 OPC_CEIL_L_S = FOP(10, FMT_S),
9451 OPC_FLOOR_L_S = FOP(11, FMT_S),
9452 OPC_ROUND_W_S = FOP(12, FMT_S),
9453 OPC_TRUNC_W_S = FOP(13, FMT_S),
9454 OPC_CEIL_W_S = FOP(14, FMT_S),
9455 OPC_FLOOR_W_S = FOP(15, FMT_S),
9456 OPC_SEL_S = FOP(16, FMT_S),
9457 OPC_MOVCF_S = FOP(17, FMT_S),
9458 OPC_MOVZ_S = FOP(18, FMT_S),
9459 OPC_MOVN_S = FOP(19, FMT_S),
9460 OPC_SELEQZ_S = FOP(20, FMT_S),
9461 OPC_RECIP_S = FOP(21, FMT_S),
9462 OPC_RSQRT_S = FOP(22, FMT_S),
9463 OPC_SELNEZ_S = FOP(23, FMT_S),
9464 OPC_MADDF_S = FOP(24, FMT_S),
9465 OPC_MSUBF_S = FOP(25, FMT_S),
9466 OPC_RINT_S = FOP(26, FMT_S),
9467 OPC_CLASS_S = FOP(27, FMT_S),
9468 OPC_MIN_S = FOP(28, FMT_S),
9469 OPC_RECIP2_S = FOP(28, FMT_S),
9470 OPC_MINA_S = FOP(29, FMT_S),
9471 OPC_RECIP1_S = FOP(29, FMT_S),
9472 OPC_MAX_S = FOP(30, FMT_S),
9473 OPC_RSQRT1_S = FOP(30, FMT_S),
9474 OPC_MAXA_S = FOP(31, FMT_S),
9475 OPC_RSQRT2_S = FOP(31, FMT_S),
9476 OPC_CVT_D_S = FOP(33, FMT_S),
9477 OPC_CVT_W_S = FOP(36, FMT_S),
9478 OPC_CVT_L_S = FOP(37, FMT_S),
9479 OPC_CVT_PS_S = FOP(38, FMT_S),
9480 OPC_CMP_F_S = FOP(48, FMT_S),
9481 OPC_CMP_UN_S = FOP(49, FMT_S),
9482 OPC_CMP_EQ_S = FOP(50, FMT_S),
9483 OPC_CMP_UEQ_S = FOP(51, FMT_S),
9484 OPC_CMP_OLT_S = FOP(52, FMT_S),
9485 OPC_CMP_ULT_S = FOP(53, FMT_S),
9486 OPC_CMP_OLE_S = FOP(54, FMT_S),
9487 OPC_CMP_ULE_S = FOP(55, FMT_S),
9488 OPC_CMP_SF_S = FOP(56, FMT_S),
9489 OPC_CMP_NGLE_S = FOP(57, FMT_S),
9490 OPC_CMP_SEQ_S = FOP(58, FMT_S),
9491 OPC_CMP_NGL_S = FOP(59, FMT_S),
9492 OPC_CMP_LT_S = FOP(60, FMT_S),
9493 OPC_CMP_NGE_S = FOP(61, FMT_S),
9494 OPC_CMP_LE_S = FOP(62, FMT_S),
9495 OPC_CMP_NGT_S = FOP(63, FMT_S),
9496
9497 OPC_ADD_D = FOP(0, FMT_D),
9498 OPC_SUB_D = FOP(1, FMT_D),
9499 OPC_MUL_D = FOP(2, FMT_D),
9500 OPC_DIV_D = FOP(3, FMT_D),
9501 OPC_SQRT_D = FOP(4, FMT_D),
9502 OPC_ABS_D = FOP(5, FMT_D),
9503 OPC_MOV_D = FOP(6, FMT_D),
9504 OPC_NEG_D = FOP(7, FMT_D),
9505 OPC_ROUND_L_D = FOP(8, FMT_D),
9506 OPC_TRUNC_L_D = FOP(9, FMT_D),
9507 OPC_CEIL_L_D = FOP(10, FMT_D),
9508 OPC_FLOOR_L_D = FOP(11, FMT_D),
9509 OPC_ROUND_W_D = FOP(12, FMT_D),
9510 OPC_TRUNC_W_D = FOP(13, FMT_D),
9511 OPC_CEIL_W_D = FOP(14, FMT_D),
9512 OPC_FLOOR_W_D = FOP(15, FMT_D),
9513 OPC_SEL_D = FOP(16, FMT_D),
9514 OPC_MOVCF_D = FOP(17, FMT_D),
9515 OPC_MOVZ_D = FOP(18, FMT_D),
9516 OPC_MOVN_D = FOP(19, FMT_D),
9517 OPC_SELEQZ_D = FOP(20, FMT_D),
9518 OPC_RECIP_D = FOP(21, FMT_D),
9519 OPC_RSQRT_D = FOP(22, FMT_D),
9520 OPC_SELNEZ_D = FOP(23, FMT_D),
9521 OPC_MADDF_D = FOP(24, FMT_D),
9522 OPC_MSUBF_D = FOP(25, FMT_D),
9523 OPC_RINT_D = FOP(26, FMT_D),
9524 OPC_CLASS_D = FOP(27, FMT_D),
9525 OPC_MIN_D = FOP(28, FMT_D),
9526 OPC_RECIP2_D = FOP(28, FMT_D),
9527 OPC_MINA_D = FOP(29, FMT_D),
9528 OPC_RECIP1_D = FOP(29, FMT_D),
9529 OPC_MAX_D = FOP(30, FMT_D),
9530 OPC_RSQRT1_D = FOP(30, FMT_D),
9531 OPC_MAXA_D = FOP(31, FMT_D),
9532 OPC_RSQRT2_D = FOP(31, FMT_D),
9533 OPC_CVT_S_D = FOP(32, FMT_D),
9534 OPC_CVT_W_D = FOP(36, FMT_D),
9535 OPC_CVT_L_D = FOP(37, FMT_D),
9536 OPC_CMP_F_D = FOP(48, FMT_D),
9537 OPC_CMP_UN_D = FOP(49, FMT_D),
9538 OPC_CMP_EQ_D = FOP(50, FMT_D),
9539 OPC_CMP_UEQ_D = FOP(51, FMT_D),
9540 OPC_CMP_OLT_D = FOP(52, FMT_D),
9541 OPC_CMP_ULT_D = FOP(53, FMT_D),
9542 OPC_CMP_OLE_D = FOP(54, FMT_D),
9543 OPC_CMP_ULE_D = FOP(55, FMT_D),
9544 OPC_CMP_SF_D = FOP(56, FMT_D),
9545 OPC_CMP_NGLE_D = FOP(57, FMT_D),
9546 OPC_CMP_SEQ_D = FOP(58, FMT_D),
9547 OPC_CMP_NGL_D = FOP(59, FMT_D),
9548 OPC_CMP_LT_D = FOP(60, FMT_D),
9549 OPC_CMP_NGE_D = FOP(61, FMT_D),
9550 OPC_CMP_LE_D = FOP(62, FMT_D),
9551 OPC_CMP_NGT_D = FOP(63, FMT_D),
9552
9553 OPC_CVT_S_W = FOP(32, FMT_W),
9554 OPC_CVT_D_W = FOP(33, FMT_W),
9555 OPC_CVT_S_L = FOP(32, FMT_L),
9556 OPC_CVT_D_L = FOP(33, FMT_L),
9557 OPC_CVT_PS_PW = FOP(38, FMT_W),
9558
9559 OPC_ADD_PS = FOP(0, FMT_PS),
9560 OPC_SUB_PS = FOP(1, FMT_PS),
9561 OPC_MUL_PS = FOP(2, FMT_PS),
9562 OPC_DIV_PS = FOP(3, FMT_PS),
9563 OPC_ABS_PS = FOP(5, FMT_PS),
9564 OPC_MOV_PS = FOP(6, FMT_PS),
9565 OPC_NEG_PS = FOP(7, FMT_PS),
9566 OPC_MOVCF_PS = FOP(17, FMT_PS),
9567 OPC_MOVZ_PS = FOP(18, FMT_PS),
9568 OPC_MOVN_PS = FOP(19, FMT_PS),
9569 OPC_ADDR_PS = FOP(24, FMT_PS),
9570 OPC_MULR_PS = FOP(26, FMT_PS),
9571 OPC_RECIP2_PS = FOP(28, FMT_PS),
9572 OPC_RECIP1_PS = FOP(29, FMT_PS),
9573 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9574 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9575
9576 OPC_CVT_S_PU = FOP(32, FMT_PS),
9577 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9578 OPC_CVT_S_PL = FOP(40, FMT_PS),
9579 OPC_PLL_PS = FOP(44, FMT_PS),
9580 OPC_PLU_PS = FOP(45, FMT_PS),
9581 OPC_PUL_PS = FOP(46, FMT_PS),
9582 OPC_PUU_PS = FOP(47, FMT_PS),
9583 OPC_CMP_F_PS = FOP(48, FMT_PS),
9584 OPC_CMP_UN_PS = FOP(49, FMT_PS),
9585 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9586 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9587 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9588 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9589 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9590 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9591 OPC_CMP_SF_PS = FOP(56, FMT_PS),
9592 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9593 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9594 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9595 OPC_CMP_LT_PS = FOP(60, FMT_PS),
9596 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9597 OPC_CMP_LE_PS = FOP(62, FMT_PS),
9598 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9599};
9600
9601enum r6_f_cmp_op {
9602 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9603 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9604 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9605 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9606 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9607 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9608 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9609 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9610 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9611 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9612 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9613 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9614 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9615 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9616 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9617 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9618 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9619 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9620 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9621 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9622 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9623 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9624
9625 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9626 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9627 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9628 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9629 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9630 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9631 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9632 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9633 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9634 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9635 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9636 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9637 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9638 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9639 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9640 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9641 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9642 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9643 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9644 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9645 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9646 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9647};
9648
9649static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9650{
9651 TCGv t0 = tcg_temp_new();
9652
9653 switch (opc) {
9654 case OPC_MFC1:
9655 {
9656 TCGv_i32 fp0 = tcg_temp_new_i32();
9657
9658 gen_load_fpr32(ctx, fp0, fs);
9659 tcg_gen_ext_i32_tl(t0, fp0);
9660 tcg_temp_free_i32(fp0);
9661 }
9662 gen_store_gpr(t0, rt);
9663 break;
9664 case OPC_MTC1:
9665 gen_load_gpr(t0, rt);
9666 {
9667 TCGv_i32 fp0 = tcg_temp_new_i32();
9668
9669 tcg_gen_trunc_tl_i32(fp0, t0);
9670 gen_store_fpr32(ctx, fp0, fs);
9671 tcg_temp_free_i32(fp0);
9672 }
9673 break;
9674 case OPC_CFC1:
9675 gen_helper_1e0i(cfc1, t0, fs);
9676 gen_store_gpr(t0, rt);
9677 break;
9678 case OPC_CTC1:
9679 gen_load_gpr(t0, rt);
9680 save_cpu_state(ctx, 0);
9681 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9682
9683 ctx->base.is_jmp = DISAS_STOP;
9684 break;
9685#if defined(TARGET_MIPS64)
9686 case OPC_DMFC1:
9687 gen_load_fpr64(ctx, t0, fs);
9688 gen_store_gpr(t0, rt);
9689 break;
9690 case OPC_DMTC1:
9691 gen_load_gpr(t0, rt);
9692 gen_store_fpr64(ctx, t0, fs);
9693 break;
9694#endif
9695 case OPC_MFHC1:
9696 {
9697 TCGv_i32 fp0 = tcg_temp_new_i32();
9698
9699 gen_load_fpr32h(ctx, fp0, fs);
9700 tcg_gen_ext_i32_tl(t0, fp0);
9701 tcg_temp_free_i32(fp0);
9702 }
9703 gen_store_gpr(t0, rt);
9704 break;
9705 case OPC_MTHC1:
9706 gen_load_gpr(t0, rt);
9707 {
9708 TCGv_i32 fp0 = tcg_temp_new_i32();
9709
9710 tcg_gen_trunc_tl_i32(fp0, t0);
9711 gen_store_fpr32h(ctx, fp0, fs);
9712 tcg_temp_free_i32(fp0);
9713 }
9714 break;
9715 default:
9716 MIPS_INVAL("cp1 move");
9717 gen_reserved_instruction(ctx);
9718 goto out;
9719 }
9720
9721 out:
9722 tcg_temp_free(t0);
9723}
9724
9725static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9726{
9727 TCGLabel *l1;
9728 TCGCond cond;
9729 TCGv_i32 t0;
9730
9731 if (rd == 0) {
9732
9733 return;
9734 }
9735
9736 if (tf) {
9737 cond = TCG_COND_EQ;
9738 } else {
9739 cond = TCG_COND_NE;
9740 }
9741
9742 l1 = gen_new_label();
9743 t0 = tcg_temp_new_i32();
9744 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9745 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9746 tcg_temp_free_i32(t0);
9747 gen_load_gpr(cpu_gpr[rd], rs);
9748 gen_set_label(l1);
9749}
9750
9751static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9752 int tf)
9753{
9754 int cond;
9755 TCGv_i32 t0 = tcg_temp_new_i32();
9756 TCGLabel *l1 = gen_new_label();
9757
9758 if (tf) {
9759 cond = TCG_COND_EQ;
9760 } else {
9761 cond = TCG_COND_NE;
9762 }
9763
9764 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9765 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9766 gen_load_fpr32(ctx, t0, fs);
9767 gen_store_fpr32(ctx, t0, fd);
9768 gen_set_label(l1);
9769 tcg_temp_free_i32(t0);
9770}
9771
9772static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9773 int tf)
9774{
9775 int cond;
9776 TCGv_i32 t0 = tcg_temp_new_i32();
9777 TCGv_i64 fp0;
9778 TCGLabel *l1 = gen_new_label();
9779
9780 if (tf) {
9781 cond = TCG_COND_EQ;
9782 } else {
9783 cond = TCG_COND_NE;
9784 }
9785
9786 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9787 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9788 tcg_temp_free_i32(t0);
9789 fp0 = tcg_temp_new_i64();
9790 gen_load_fpr64(ctx, fp0, fs);
9791 gen_store_fpr64(ctx, fp0, fd);
9792 tcg_temp_free_i64(fp0);
9793 gen_set_label(l1);
9794}
9795
9796static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9797 int cc, int tf)
9798{
9799 int cond;
9800 TCGv_i32 t0 = tcg_temp_new_i32();
9801 TCGLabel *l1 = gen_new_label();
9802 TCGLabel *l2 = gen_new_label();
9803
9804 if (tf) {
9805 cond = TCG_COND_EQ;
9806 } else {
9807 cond = TCG_COND_NE;
9808 }
9809
9810 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9811 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9812 gen_load_fpr32(ctx, t0, fs);
9813 gen_store_fpr32(ctx, t0, fd);
9814 gen_set_label(l1);
9815
9816 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9817 tcg_gen_brcondi_i32(cond, t0, 0, l2);
9818 gen_load_fpr32h(ctx, t0, fs);
9819 gen_store_fpr32h(ctx, t0, fd);
9820 tcg_temp_free_i32(t0);
9821 gen_set_label(l2);
9822}
9823
9824static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9825 int fs)
9826{
9827 TCGv_i32 t1 = tcg_const_i32(0);
9828 TCGv_i32 fp0 = tcg_temp_new_i32();
9829 TCGv_i32 fp1 = tcg_temp_new_i32();
9830 TCGv_i32 fp2 = tcg_temp_new_i32();
9831 gen_load_fpr32(ctx, fp0, fd);
9832 gen_load_fpr32(ctx, fp1, ft);
9833 gen_load_fpr32(ctx, fp2, fs);
9834
9835 switch (op1) {
9836 case OPC_SEL_S:
9837 tcg_gen_andi_i32(fp0, fp0, 1);
9838 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9839 break;
9840 case OPC_SELEQZ_S:
9841 tcg_gen_andi_i32(fp1, fp1, 1);
9842 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9843 break;
9844 case OPC_SELNEZ_S:
9845 tcg_gen_andi_i32(fp1, fp1, 1);
9846 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9847 break;
9848 default:
9849 MIPS_INVAL("gen_sel_s");
9850 gen_reserved_instruction(ctx);
9851 break;
9852 }
9853
9854 gen_store_fpr32(ctx, fp0, fd);
9855 tcg_temp_free_i32(fp2);
9856 tcg_temp_free_i32(fp1);
9857 tcg_temp_free_i32(fp0);
9858 tcg_temp_free_i32(t1);
9859}
9860
9861static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9862 int fs)
9863{
9864 TCGv_i64 t1 = tcg_const_i64(0);
9865 TCGv_i64 fp0 = tcg_temp_new_i64();
9866 TCGv_i64 fp1 = tcg_temp_new_i64();
9867 TCGv_i64 fp2 = tcg_temp_new_i64();
9868 gen_load_fpr64(ctx, fp0, fd);
9869 gen_load_fpr64(ctx, fp1, ft);
9870 gen_load_fpr64(ctx, fp2, fs);
9871
9872 switch (op1) {
9873 case OPC_SEL_D:
9874 tcg_gen_andi_i64(fp0, fp0, 1);
9875 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9876 break;
9877 case OPC_SELEQZ_D:
9878 tcg_gen_andi_i64(fp1, fp1, 1);
9879 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9880 break;
9881 case OPC_SELNEZ_D:
9882 tcg_gen_andi_i64(fp1, fp1, 1);
9883 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9884 break;
9885 default:
9886 MIPS_INVAL("gen_sel_d");
9887 gen_reserved_instruction(ctx);
9888 break;
9889 }
9890
9891 gen_store_fpr64(ctx, fp0, fd);
9892 tcg_temp_free_i64(fp2);
9893 tcg_temp_free_i64(fp1);
9894 tcg_temp_free_i64(fp0);
9895 tcg_temp_free_i64(t1);
9896}
9897
9898static void gen_farith(DisasContext *ctx, enum fopcode op1,
9899 int ft, int fs, int fd, int cc)
9900{
9901 uint32_t func = ctx->opcode & 0x3f;
9902 switch (op1) {
9903 case OPC_ADD_S:
9904 {
9905 TCGv_i32 fp0 = tcg_temp_new_i32();
9906 TCGv_i32 fp1 = tcg_temp_new_i32();
9907
9908 gen_load_fpr32(ctx, fp0, fs);
9909 gen_load_fpr32(ctx, fp1, ft);
9910 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9911 tcg_temp_free_i32(fp1);
9912 gen_store_fpr32(ctx, fp0, fd);
9913 tcg_temp_free_i32(fp0);
9914 }
9915 break;
9916 case OPC_SUB_S:
9917 {
9918 TCGv_i32 fp0 = tcg_temp_new_i32();
9919 TCGv_i32 fp1 = tcg_temp_new_i32();
9920
9921 gen_load_fpr32(ctx, fp0, fs);
9922 gen_load_fpr32(ctx, fp1, ft);
9923 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9924 tcg_temp_free_i32(fp1);
9925 gen_store_fpr32(ctx, fp0, fd);
9926 tcg_temp_free_i32(fp0);
9927 }
9928 break;
9929 case OPC_MUL_S:
9930 {
9931 TCGv_i32 fp0 = tcg_temp_new_i32();
9932 TCGv_i32 fp1 = tcg_temp_new_i32();
9933
9934 gen_load_fpr32(ctx, fp0, fs);
9935 gen_load_fpr32(ctx, fp1, ft);
9936 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9937 tcg_temp_free_i32(fp1);
9938 gen_store_fpr32(ctx, fp0, fd);
9939 tcg_temp_free_i32(fp0);
9940 }
9941 break;
9942 case OPC_DIV_S:
9943 {
9944 TCGv_i32 fp0 = tcg_temp_new_i32();
9945 TCGv_i32 fp1 = tcg_temp_new_i32();
9946
9947 gen_load_fpr32(ctx, fp0, fs);
9948 gen_load_fpr32(ctx, fp1, ft);
9949 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9950 tcg_temp_free_i32(fp1);
9951 gen_store_fpr32(ctx, fp0, fd);
9952 tcg_temp_free_i32(fp0);
9953 }
9954 break;
9955 case OPC_SQRT_S:
9956 {
9957 TCGv_i32 fp0 = tcg_temp_new_i32();
9958
9959 gen_load_fpr32(ctx, fp0, fs);
9960 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9961 gen_store_fpr32(ctx, fp0, fd);
9962 tcg_temp_free_i32(fp0);
9963 }
9964 break;
9965 case OPC_ABS_S:
9966 {
9967 TCGv_i32 fp0 = tcg_temp_new_i32();
9968
9969 gen_load_fpr32(ctx, fp0, fs);
9970 if (ctx->abs2008) {
9971 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9972 } else {
9973 gen_helper_float_abs_s(fp0, fp0);
9974 }
9975 gen_store_fpr32(ctx, fp0, fd);
9976 tcg_temp_free_i32(fp0);
9977 }
9978 break;
9979 case OPC_MOV_S:
9980 {
9981 TCGv_i32 fp0 = tcg_temp_new_i32();
9982
9983 gen_load_fpr32(ctx, fp0, fs);
9984 gen_store_fpr32(ctx, fp0, fd);
9985 tcg_temp_free_i32(fp0);
9986 }
9987 break;
9988 case OPC_NEG_S:
9989 {
9990 TCGv_i32 fp0 = tcg_temp_new_i32();
9991
9992 gen_load_fpr32(ctx, fp0, fs);
9993 if (ctx->abs2008) {
9994 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9995 } else {
9996 gen_helper_float_chs_s(fp0, fp0);
9997 }
9998 gen_store_fpr32(ctx, fp0, fd);
9999 tcg_temp_free_i32(fp0);
10000 }
10001 break;
10002 case OPC_ROUND_L_S:
10003 check_cp1_64bitmode(ctx);
10004 {
10005 TCGv_i32 fp32 = tcg_temp_new_i32();
10006 TCGv_i64 fp64 = tcg_temp_new_i64();
10007
10008 gen_load_fpr32(ctx, fp32, fs);
10009 if (ctx->nan2008) {
10010 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10011 } else {
10012 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10013 }
10014 tcg_temp_free_i32(fp32);
10015 gen_store_fpr64(ctx, fp64, fd);
10016 tcg_temp_free_i64(fp64);
10017 }
10018 break;
10019 case OPC_TRUNC_L_S:
10020 check_cp1_64bitmode(ctx);
10021 {
10022 TCGv_i32 fp32 = tcg_temp_new_i32();
10023 TCGv_i64 fp64 = tcg_temp_new_i64();
10024
10025 gen_load_fpr32(ctx, fp32, fs);
10026 if (ctx->nan2008) {
10027 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10028 } else {
10029 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10030 }
10031 tcg_temp_free_i32(fp32);
10032 gen_store_fpr64(ctx, fp64, fd);
10033 tcg_temp_free_i64(fp64);
10034 }
10035 break;
10036 case OPC_CEIL_L_S:
10037 check_cp1_64bitmode(ctx);
10038 {
10039 TCGv_i32 fp32 = tcg_temp_new_i32();
10040 TCGv_i64 fp64 = tcg_temp_new_i64();
10041
10042 gen_load_fpr32(ctx, fp32, fs);
10043 if (ctx->nan2008) {
10044 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10045 } else {
10046 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10047 }
10048 tcg_temp_free_i32(fp32);
10049 gen_store_fpr64(ctx, fp64, fd);
10050 tcg_temp_free_i64(fp64);
10051 }
10052 break;
10053 case OPC_FLOOR_L_S:
10054 check_cp1_64bitmode(ctx);
10055 {
10056 TCGv_i32 fp32 = tcg_temp_new_i32();
10057 TCGv_i64 fp64 = tcg_temp_new_i64();
10058
10059 gen_load_fpr32(ctx, fp32, fs);
10060 if (ctx->nan2008) {
10061 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10062 } else {
10063 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10064 }
10065 tcg_temp_free_i32(fp32);
10066 gen_store_fpr64(ctx, fp64, fd);
10067 tcg_temp_free_i64(fp64);
10068 }
10069 break;
10070 case OPC_ROUND_W_S:
10071 {
10072 TCGv_i32 fp0 = tcg_temp_new_i32();
10073
10074 gen_load_fpr32(ctx, fp0, fs);
10075 if (ctx->nan2008) {
10076 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10077 } else {
10078 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10079 }
10080 gen_store_fpr32(ctx, fp0, fd);
10081 tcg_temp_free_i32(fp0);
10082 }
10083 break;
10084 case OPC_TRUNC_W_S:
10085 {
10086 TCGv_i32 fp0 = tcg_temp_new_i32();
10087
10088 gen_load_fpr32(ctx, fp0, fs);
10089 if (ctx->nan2008) {
10090 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10091 } else {
10092 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10093 }
10094 gen_store_fpr32(ctx, fp0, fd);
10095 tcg_temp_free_i32(fp0);
10096 }
10097 break;
10098 case OPC_CEIL_W_S:
10099 {
10100 TCGv_i32 fp0 = tcg_temp_new_i32();
10101
10102 gen_load_fpr32(ctx, fp0, fs);
10103 if (ctx->nan2008) {
10104 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10105 } else {
10106 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10107 }
10108 gen_store_fpr32(ctx, fp0, fd);
10109 tcg_temp_free_i32(fp0);
10110 }
10111 break;
10112 case OPC_FLOOR_W_S:
10113 {
10114 TCGv_i32 fp0 = tcg_temp_new_i32();
10115
10116 gen_load_fpr32(ctx, fp0, fs);
10117 if (ctx->nan2008) {
10118 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10119 } else {
10120 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10121 }
10122 gen_store_fpr32(ctx, fp0, fd);
10123 tcg_temp_free_i32(fp0);
10124 }
10125 break;
10126 case OPC_SEL_S:
10127 check_insn(ctx, ISA_MIPS_R6);
10128 gen_sel_s(ctx, op1, fd, ft, fs);
10129 break;
10130 case OPC_SELEQZ_S:
10131 check_insn(ctx, ISA_MIPS_R6);
10132 gen_sel_s(ctx, op1, fd, ft, fs);
10133 break;
10134 case OPC_SELNEZ_S:
10135 check_insn(ctx, ISA_MIPS_R6);
10136 gen_sel_s(ctx, op1, fd, ft, fs);
10137 break;
10138 case OPC_MOVCF_S:
10139 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10140 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10141 break;
10142 case OPC_MOVZ_S:
10143 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10144 {
10145 TCGLabel *l1 = gen_new_label();
10146 TCGv_i32 fp0;
10147
10148 if (ft != 0) {
10149 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10150 }
10151 fp0 = tcg_temp_new_i32();
10152 gen_load_fpr32(ctx, fp0, fs);
10153 gen_store_fpr32(ctx, fp0, fd);
10154 tcg_temp_free_i32(fp0);
10155 gen_set_label(l1);
10156 }
10157 break;
10158 case OPC_MOVN_S:
10159 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10160 {
10161 TCGLabel *l1 = gen_new_label();
10162 TCGv_i32 fp0;
10163
10164 if (ft != 0) {
10165 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10166 fp0 = tcg_temp_new_i32();
10167 gen_load_fpr32(ctx, fp0, fs);
10168 gen_store_fpr32(ctx, fp0, fd);
10169 tcg_temp_free_i32(fp0);
10170 gen_set_label(l1);
10171 }
10172 }
10173 break;
10174 case OPC_RECIP_S:
10175 {
10176 TCGv_i32 fp0 = tcg_temp_new_i32();
10177
10178 gen_load_fpr32(ctx, fp0, fs);
10179 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10180 gen_store_fpr32(ctx, fp0, fd);
10181 tcg_temp_free_i32(fp0);
10182 }
10183 break;
10184 case OPC_RSQRT_S:
10185 {
10186 TCGv_i32 fp0 = tcg_temp_new_i32();
10187
10188 gen_load_fpr32(ctx, fp0, fs);
10189 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10190 gen_store_fpr32(ctx, fp0, fd);
10191 tcg_temp_free_i32(fp0);
10192 }
10193 break;
10194 case OPC_MADDF_S:
10195 check_insn(ctx, ISA_MIPS_R6);
10196 {
10197 TCGv_i32 fp0 = tcg_temp_new_i32();
10198 TCGv_i32 fp1 = tcg_temp_new_i32();
10199 TCGv_i32 fp2 = tcg_temp_new_i32();
10200 gen_load_fpr32(ctx, fp0, fs);
10201 gen_load_fpr32(ctx, fp1, ft);
10202 gen_load_fpr32(ctx, fp2, fd);
10203 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10204 gen_store_fpr32(ctx, fp2, fd);
10205 tcg_temp_free_i32(fp2);
10206 tcg_temp_free_i32(fp1);
10207 tcg_temp_free_i32(fp0);
10208 }
10209 break;
10210 case OPC_MSUBF_S:
10211 check_insn(ctx, ISA_MIPS_R6);
10212 {
10213 TCGv_i32 fp0 = tcg_temp_new_i32();
10214 TCGv_i32 fp1 = tcg_temp_new_i32();
10215 TCGv_i32 fp2 = tcg_temp_new_i32();
10216 gen_load_fpr32(ctx, fp0, fs);
10217 gen_load_fpr32(ctx, fp1, ft);
10218 gen_load_fpr32(ctx, fp2, fd);
10219 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10220 gen_store_fpr32(ctx, fp2, fd);
10221 tcg_temp_free_i32(fp2);
10222 tcg_temp_free_i32(fp1);
10223 tcg_temp_free_i32(fp0);
10224 }
10225 break;
10226 case OPC_RINT_S:
10227 check_insn(ctx, ISA_MIPS_R6);
10228 {
10229 TCGv_i32 fp0 = tcg_temp_new_i32();
10230 gen_load_fpr32(ctx, fp0, fs);
10231 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10232 gen_store_fpr32(ctx, fp0, fd);
10233 tcg_temp_free_i32(fp0);
10234 }
10235 break;
10236 case OPC_CLASS_S:
10237 check_insn(ctx, ISA_MIPS_R6);
10238 {
10239 TCGv_i32 fp0 = tcg_temp_new_i32();
10240 gen_load_fpr32(ctx, fp0, fs);
10241 gen_helper_float_class_s(fp0, cpu_env, fp0);
10242 gen_store_fpr32(ctx, fp0, fd);
10243 tcg_temp_free_i32(fp0);
10244 }
10245 break;
10246 case OPC_MIN_S:
10247 if (ctx->insn_flags & ISA_MIPS_R6) {
10248
10249 TCGv_i32 fp0 = tcg_temp_new_i32();
10250 TCGv_i32 fp1 = tcg_temp_new_i32();
10251 TCGv_i32 fp2 = tcg_temp_new_i32();
10252 gen_load_fpr32(ctx, fp0, fs);
10253 gen_load_fpr32(ctx, fp1, ft);
10254 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10255 gen_store_fpr32(ctx, fp2, fd);
10256 tcg_temp_free_i32(fp2);
10257 tcg_temp_free_i32(fp1);
10258 tcg_temp_free_i32(fp0);
10259 } else {
10260
10261 check_cp1_64bitmode(ctx);
10262 {
10263 TCGv_i32 fp0 = tcg_temp_new_i32();
10264 TCGv_i32 fp1 = tcg_temp_new_i32();
10265
10266 gen_load_fpr32(ctx, fp0, fs);
10267 gen_load_fpr32(ctx, fp1, ft);
10268 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10269 tcg_temp_free_i32(fp1);
10270 gen_store_fpr32(ctx, fp0, fd);
10271 tcg_temp_free_i32(fp0);
10272 }
10273 }
10274 break;
10275 case OPC_MINA_S:
10276 if (ctx->insn_flags & ISA_MIPS_R6) {
10277
10278 TCGv_i32 fp0 = tcg_temp_new_i32();
10279 TCGv_i32 fp1 = tcg_temp_new_i32();
10280 TCGv_i32 fp2 = tcg_temp_new_i32();
10281 gen_load_fpr32(ctx, fp0, fs);
10282 gen_load_fpr32(ctx, fp1, ft);
10283 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10284 gen_store_fpr32(ctx, fp2, fd);
10285 tcg_temp_free_i32(fp2);
10286 tcg_temp_free_i32(fp1);
10287 tcg_temp_free_i32(fp0);
10288 } else {
10289
10290 check_cp1_64bitmode(ctx);
10291 {
10292 TCGv_i32 fp0 = tcg_temp_new_i32();
10293
10294 gen_load_fpr32(ctx, fp0, fs);
10295 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10296 gen_store_fpr32(ctx, fp0, fd);
10297 tcg_temp_free_i32(fp0);
10298 }
10299 }
10300 break;
10301 case OPC_MAX_S:
10302 if (ctx->insn_flags & ISA_MIPS_R6) {
10303
10304 TCGv_i32 fp0 = tcg_temp_new_i32();
10305 TCGv_i32 fp1 = tcg_temp_new_i32();
10306 gen_load_fpr32(ctx, fp0, fs);
10307 gen_load_fpr32(ctx, fp1, ft);
10308 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10309 gen_store_fpr32(ctx, fp1, fd);
10310 tcg_temp_free_i32(fp1);
10311 tcg_temp_free_i32(fp0);
10312 } else {
10313
10314 check_cp1_64bitmode(ctx);
10315 {
10316 TCGv_i32 fp0 = tcg_temp_new_i32();
10317
10318 gen_load_fpr32(ctx, fp0, fs);
10319 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10320 gen_store_fpr32(ctx, fp0, fd);
10321 tcg_temp_free_i32(fp0);
10322 }
10323 }
10324 break;
10325 case OPC_MAXA_S:
10326 if (ctx->insn_flags & ISA_MIPS_R6) {
10327
10328 TCGv_i32 fp0 = tcg_temp_new_i32();
10329 TCGv_i32 fp1 = tcg_temp_new_i32();
10330 gen_load_fpr32(ctx, fp0, fs);
10331 gen_load_fpr32(ctx, fp1, ft);
10332 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10333 gen_store_fpr32(ctx, fp1, fd);
10334 tcg_temp_free_i32(fp1);
10335 tcg_temp_free_i32(fp0);
10336 } else {
10337
10338 check_cp1_64bitmode(ctx);
10339 {
10340 TCGv_i32 fp0 = tcg_temp_new_i32();
10341 TCGv_i32 fp1 = tcg_temp_new_i32();
10342
10343 gen_load_fpr32(ctx, fp0, fs);
10344 gen_load_fpr32(ctx, fp1, ft);
10345 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10346 tcg_temp_free_i32(fp1);
10347 gen_store_fpr32(ctx, fp0, fd);
10348 tcg_temp_free_i32(fp0);
10349 }
10350 }
10351 break;
10352 case OPC_CVT_D_S:
10353 check_cp1_registers(ctx, fd);
10354 {
10355 TCGv_i32 fp32 = tcg_temp_new_i32();
10356 TCGv_i64 fp64 = tcg_temp_new_i64();
10357
10358 gen_load_fpr32(ctx, fp32, fs);
10359 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10360 tcg_temp_free_i32(fp32);
10361 gen_store_fpr64(ctx, fp64, fd);
10362 tcg_temp_free_i64(fp64);
10363 }
10364 break;
10365 case OPC_CVT_W_S:
10366 {
10367 TCGv_i32 fp0 = tcg_temp_new_i32();
10368
10369 gen_load_fpr32(ctx, fp0, fs);
10370 if (ctx->nan2008) {
10371 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10372 } else {
10373 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10374 }
10375 gen_store_fpr32(ctx, fp0, fd);
10376 tcg_temp_free_i32(fp0);
10377 }
10378 break;
10379 case OPC_CVT_L_S:
10380 check_cp1_64bitmode(ctx);
10381 {
10382 TCGv_i32 fp32 = tcg_temp_new_i32();
10383 TCGv_i64 fp64 = tcg_temp_new_i64();
10384
10385 gen_load_fpr32(ctx, fp32, fs);
10386 if (ctx->nan2008) {
10387 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10388 } else {
10389 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10390 }
10391 tcg_temp_free_i32(fp32);
10392 gen_store_fpr64(ctx, fp64, fd);
10393 tcg_temp_free_i64(fp64);
10394 }
10395 break;
10396 case OPC_CVT_PS_S:
10397 check_ps(ctx);
10398 {
10399 TCGv_i64 fp64 = tcg_temp_new_i64();
10400 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10401 TCGv_i32 fp32_1 = tcg_temp_new_i32();
10402
10403 gen_load_fpr32(ctx, fp32_0, fs);
10404 gen_load_fpr32(ctx, fp32_1, ft);
10405 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10406 tcg_temp_free_i32(fp32_1);
10407 tcg_temp_free_i32(fp32_0);
10408 gen_store_fpr64(ctx, fp64, fd);
10409 tcg_temp_free_i64(fp64);
10410 }
10411 break;
10412 case OPC_CMP_F_S:
10413 case OPC_CMP_UN_S:
10414 case OPC_CMP_EQ_S:
10415 case OPC_CMP_UEQ_S:
10416 case OPC_CMP_OLT_S:
10417 case OPC_CMP_ULT_S:
10418 case OPC_CMP_OLE_S:
10419 case OPC_CMP_ULE_S:
10420 case OPC_CMP_SF_S:
10421 case OPC_CMP_NGLE_S:
10422 case OPC_CMP_SEQ_S:
10423 case OPC_CMP_NGL_S:
10424 case OPC_CMP_LT_S:
10425 case OPC_CMP_NGE_S:
10426 case OPC_CMP_LE_S:
10427 case OPC_CMP_NGT_S:
10428 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10429 if (ctx->opcode & (1 << 6)) {
10430 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10431 } else {
10432 gen_cmp_s(ctx, func - 48, ft, fs, cc);
10433 }
10434 break;
10435 case OPC_ADD_D:
10436 check_cp1_registers(ctx, fs | ft | fd);
10437 {
10438 TCGv_i64 fp0 = tcg_temp_new_i64();
10439 TCGv_i64 fp1 = tcg_temp_new_i64();
10440
10441 gen_load_fpr64(ctx, fp0, fs);
10442 gen_load_fpr64(ctx, fp1, ft);
10443 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10444 tcg_temp_free_i64(fp1);
10445 gen_store_fpr64(ctx, fp0, fd);
10446 tcg_temp_free_i64(fp0);
10447 }
10448 break;
10449 case OPC_SUB_D:
10450 check_cp1_registers(ctx, fs | ft | fd);
10451 {
10452 TCGv_i64 fp0 = tcg_temp_new_i64();
10453 TCGv_i64 fp1 = tcg_temp_new_i64();
10454
10455 gen_load_fpr64(ctx, fp0, fs);
10456 gen_load_fpr64(ctx, fp1, ft);
10457 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10458 tcg_temp_free_i64(fp1);
10459 gen_store_fpr64(ctx, fp0, fd);
10460 tcg_temp_free_i64(fp0);
10461 }
10462 break;
10463 case OPC_MUL_D:
10464 check_cp1_registers(ctx, fs | ft | fd);
10465 {
10466 TCGv_i64 fp0 = tcg_temp_new_i64();
10467 TCGv_i64 fp1 = tcg_temp_new_i64();
10468
10469 gen_load_fpr64(ctx, fp0, fs);
10470 gen_load_fpr64(ctx, fp1, ft);
10471 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10472 tcg_temp_free_i64(fp1);
10473 gen_store_fpr64(ctx, fp0, fd);
10474 tcg_temp_free_i64(fp0);
10475 }
10476 break;
10477 case OPC_DIV_D:
10478 check_cp1_registers(ctx, fs | ft | fd);
10479 {
10480 TCGv_i64 fp0 = tcg_temp_new_i64();
10481 TCGv_i64 fp1 = tcg_temp_new_i64();
10482
10483 gen_load_fpr64(ctx, fp0, fs);
10484 gen_load_fpr64(ctx, fp1, ft);
10485 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10486 tcg_temp_free_i64(fp1);
10487 gen_store_fpr64(ctx, fp0, fd);
10488 tcg_temp_free_i64(fp0);
10489 }
10490 break;
10491 case OPC_SQRT_D:
10492 check_cp1_registers(ctx, fs | fd);
10493 {
10494 TCGv_i64 fp0 = tcg_temp_new_i64();
10495
10496 gen_load_fpr64(ctx, fp0, fs);
10497 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10498 gen_store_fpr64(ctx, fp0, fd);
10499 tcg_temp_free_i64(fp0);
10500 }
10501 break;
10502 case OPC_ABS_D:
10503 check_cp1_registers(ctx, fs | fd);
10504 {
10505 TCGv_i64 fp0 = tcg_temp_new_i64();
10506
10507 gen_load_fpr64(ctx, fp0, fs);
10508 if (ctx->abs2008) {
10509 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10510 } else {
10511 gen_helper_float_abs_d(fp0, fp0);
10512 }
10513 gen_store_fpr64(ctx, fp0, fd);
10514 tcg_temp_free_i64(fp0);
10515 }
10516 break;
10517 case OPC_MOV_D:
10518 check_cp1_registers(ctx, fs | fd);
10519 {
10520 TCGv_i64 fp0 = tcg_temp_new_i64();
10521
10522 gen_load_fpr64(ctx, fp0, fs);
10523 gen_store_fpr64(ctx, fp0, fd);
10524 tcg_temp_free_i64(fp0);
10525 }
10526 break;
10527 case OPC_NEG_D:
10528 check_cp1_registers(ctx, fs | fd);
10529 {
10530 TCGv_i64 fp0 = tcg_temp_new_i64();
10531
10532 gen_load_fpr64(ctx, fp0, fs);
10533 if (ctx->abs2008) {
10534 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10535 } else {
10536 gen_helper_float_chs_d(fp0, fp0);
10537 }
10538 gen_store_fpr64(ctx, fp0, fd);
10539 tcg_temp_free_i64(fp0);
10540 }
10541 break;
10542 case OPC_ROUND_L_D:
10543 check_cp1_64bitmode(ctx);
10544 {
10545 TCGv_i64 fp0 = tcg_temp_new_i64();
10546
10547 gen_load_fpr64(ctx, fp0, fs);
10548 if (ctx->nan2008) {
10549 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10550 } else {
10551 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10552 }
10553 gen_store_fpr64(ctx, fp0, fd);
10554 tcg_temp_free_i64(fp0);
10555 }
10556 break;
10557 case OPC_TRUNC_L_D:
10558 check_cp1_64bitmode(ctx);
10559 {
10560 TCGv_i64 fp0 = tcg_temp_new_i64();
10561
10562 gen_load_fpr64(ctx, fp0, fs);
10563 if (ctx->nan2008) {
10564 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10565 } else {
10566 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10567 }
10568 gen_store_fpr64(ctx, fp0, fd);
10569 tcg_temp_free_i64(fp0);
10570 }
10571 break;
10572 case OPC_CEIL_L_D:
10573 check_cp1_64bitmode(ctx);
10574 {
10575 TCGv_i64 fp0 = tcg_temp_new_i64();
10576
10577 gen_load_fpr64(ctx, fp0, fs);
10578 if (ctx->nan2008) {
10579 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10580 } else {
10581 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10582 }
10583 gen_store_fpr64(ctx, fp0, fd);
10584 tcg_temp_free_i64(fp0);
10585 }
10586 break;
10587 case OPC_FLOOR_L_D:
10588 check_cp1_64bitmode(ctx);
10589 {
10590 TCGv_i64 fp0 = tcg_temp_new_i64();
10591
10592 gen_load_fpr64(ctx, fp0, fs);
10593 if (ctx->nan2008) {
10594 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10595 } else {
10596 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10597 }
10598 gen_store_fpr64(ctx, fp0, fd);
10599 tcg_temp_free_i64(fp0);
10600 }
10601 break;
10602 case OPC_ROUND_W_D:
10603 check_cp1_registers(ctx, fs);
10604 {
10605 TCGv_i32 fp32 = tcg_temp_new_i32();
10606 TCGv_i64 fp64 = tcg_temp_new_i64();
10607
10608 gen_load_fpr64(ctx, fp64, fs);
10609 if (ctx->nan2008) {
10610 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10611 } else {
10612 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10613 }
10614 tcg_temp_free_i64(fp64);
10615 gen_store_fpr32(ctx, fp32, fd);
10616 tcg_temp_free_i32(fp32);
10617 }
10618 break;
10619 case OPC_TRUNC_W_D:
10620 check_cp1_registers(ctx, fs);
10621 {
10622 TCGv_i32 fp32 = tcg_temp_new_i32();
10623 TCGv_i64 fp64 = tcg_temp_new_i64();
10624
10625 gen_load_fpr64(ctx, fp64, fs);
10626 if (ctx->nan2008) {
10627 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10628 } else {
10629 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10630 }
10631 tcg_temp_free_i64(fp64);
10632 gen_store_fpr32(ctx, fp32, fd);
10633 tcg_temp_free_i32(fp32);
10634 }
10635 break;
10636 case OPC_CEIL_W_D:
10637 check_cp1_registers(ctx, fs);
10638 {
10639 TCGv_i32 fp32 = tcg_temp_new_i32();
10640 TCGv_i64 fp64 = tcg_temp_new_i64();
10641
10642 gen_load_fpr64(ctx, fp64, fs);
10643 if (ctx->nan2008) {
10644 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10645 } else {
10646 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10647 }
10648 tcg_temp_free_i64(fp64);
10649 gen_store_fpr32(ctx, fp32, fd);
10650 tcg_temp_free_i32(fp32);
10651 }
10652 break;
10653 case OPC_FLOOR_W_D:
10654 check_cp1_registers(ctx, fs);
10655 {
10656 TCGv_i32 fp32 = tcg_temp_new_i32();
10657 TCGv_i64 fp64 = tcg_temp_new_i64();
10658
10659 gen_load_fpr64(ctx, fp64, fs);
10660 if (ctx->nan2008) {
10661 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10662 } else {
10663 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10664 }
10665 tcg_temp_free_i64(fp64);
10666 gen_store_fpr32(ctx, fp32, fd);
10667 tcg_temp_free_i32(fp32);
10668 }
10669 break;
10670 case OPC_SEL_D:
10671 check_insn(ctx, ISA_MIPS_R6);
10672 gen_sel_d(ctx, op1, fd, ft, fs);
10673 break;
10674 case OPC_SELEQZ_D:
10675 check_insn(ctx, ISA_MIPS_R6);
10676 gen_sel_d(ctx, op1, fd, ft, fs);
10677 break;
10678 case OPC_SELNEZ_D:
10679 check_insn(ctx, ISA_MIPS_R6);
10680 gen_sel_d(ctx, op1, fd, ft, fs);
10681 break;
10682 case OPC_MOVCF_D:
10683 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10684 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10685 break;
10686 case OPC_MOVZ_D:
10687 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10688 {
10689 TCGLabel *l1 = gen_new_label();
10690 TCGv_i64 fp0;
10691
10692 if (ft != 0) {
10693 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10694 }
10695 fp0 = tcg_temp_new_i64();
10696 gen_load_fpr64(ctx, fp0, fs);
10697 gen_store_fpr64(ctx, fp0, fd);
10698 tcg_temp_free_i64(fp0);
10699 gen_set_label(l1);
10700 }
10701 break;
10702 case OPC_MOVN_D:
10703 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10704 {
10705 TCGLabel *l1 = gen_new_label();
10706 TCGv_i64 fp0;
10707
10708 if (ft != 0) {
10709 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10710 fp0 = tcg_temp_new_i64();
10711 gen_load_fpr64(ctx, fp0, fs);
10712 gen_store_fpr64(ctx, fp0, fd);
10713 tcg_temp_free_i64(fp0);
10714 gen_set_label(l1);
10715 }
10716 }
10717 break;
10718 case OPC_RECIP_D:
10719 check_cp1_registers(ctx, fs | fd);
10720 {
10721 TCGv_i64 fp0 = tcg_temp_new_i64();
10722
10723 gen_load_fpr64(ctx, fp0, fs);
10724 gen_helper_float_recip_d(fp0, cpu_env, fp0);
10725 gen_store_fpr64(ctx, fp0, fd);
10726 tcg_temp_free_i64(fp0);
10727 }
10728 break;
10729 case OPC_RSQRT_D:
10730 check_cp1_registers(ctx, fs | fd);
10731 {
10732 TCGv_i64 fp0 = tcg_temp_new_i64();
10733
10734 gen_load_fpr64(ctx, fp0, fs);
10735 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10736 gen_store_fpr64(ctx, fp0, fd);
10737 tcg_temp_free_i64(fp0);
10738 }
10739 break;
10740 case OPC_MADDF_D:
10741 check_insn(ctx, ISA_MIPS_R6);
10742 {
10743 TCGv_i64 fp0 = tcg_temp_new_i64();
10744 TCGv_i64 fp1 = tcg_temp_new_i64();
10745 TCGv_i64 fp2 = tcg_temp_new_i64();
10746 gen_load_fpr64(ctx, fp0, fs);
10747 gen_load_fpr64(ctx, fp1, ft);
10748 gen_load_fpr64(ctx, fp2, fd);
10749 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10750 gen_store_fpr64(ctx, fp2, fd);
10751 tcg_temp_free_i64(fp2);
10752 tcg_temp_free_i64(fp1);
10753 tcg_temp_free_i64(fp0);
10754 }
10755 break;
10756 case OPC_MSUBF_D:
10757 check_insn(ctx, ISA_MIPS_R6);
10758 {
10759 TCGv_i64 fp0 = tcg_temp_new_i64();
10760 TCGv_i64 fp1 = tcg_temp_new_i64();
10761 TCGv_i64 fp2 = tcg_temp_new_i64();
10762 gen_load_fpr64(ctx, fp0, fs);
10763 gen_load_fpr64(ctx, fp1, ft);
10764 gen_load_fpr64(ctx, fp2, fd);
10765 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10766 gen_store_fpr64(ctx, fp2, fd);
10767 tcg_temp_free_i64(fp2);
10768 tcg_temp_free_i64(fp1);
10769 tcg_temp_free_i64(fp0);
10770 }
10771 break;
10772 case OPC_RINT_D:
10773 check_insn(ctx, ISA_MIPS_R6);
10774 {
10775 TCGv_i64 fp0 = tcg_temp_new_i64();
10776 gen_load_fpr64(ctx, fp0, fs);
10777 gen_helper_float_rint_d(fp0, cpu_env, fp0);
10778 gen_store_fpr64(ctx, fp0, fd);
10779 tcg_temp_free_i64(fp0);
10780 }
10781 break;
10782 case OPC_CLASS_D:
10783 check_insn(ctx, ISA_MIPS_R6);
10784 {
10785 TCGv_i64 fp0 = tcg_temp_new_i64();
10786 gen_load_fpr64(ctx, fp0, fs);
10787 gen_helper_float_class_d(fp0, cpu_env, fp0);
10788 gen_store_fpr64(ctx, fp0, fd);
10789 tcg_temp_free_i64(fp0);
10790 }
10791 break;
10792 case OPC_MIN_D:
10793 if (ctx->insn_flags & ISA_MIPS_R6) {
10794
10795 TCGv_i64 fp0 = tcg_temp_new_i64();
10796 TCGv_i64 fp1 = tcg_temp_new_i64();
10797 gen_load_fpr64(ctx, fp0, fs);
10798 gen_load_fpr64(ctx, fp1, ft);
10799 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10800 gen_store_fpr64(ctx, fp1, fd);
10801 tcg_temp_free_i64(fp1);
10802 tcg_temp_free_i64(fp0);
10803 } else {
10804
10805 check_cp1_64bitmode(ctx);
10806 {
10807 TCGv_i64 fp0 = tcg_temp_new_i64();
10808 TCGv_i64 fp1 = tcg_temp_new_i64();
10809
10810 gen_load_fpr64(ctx, fp0, fs);
10811 gen_load_fpr64(ctx, fp1, ft);
10812 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10813 tcg_temp_free_i64(fp1);
10814 gen_store_fpr64(ctx, fp0, fd);
10815 tcg_temp_free_i64(fp0);
10816 }
10817 }
10818 break;
10819 case OPC_MINA_D:
10820 if (ctx->insn_flags & ISA_MIPS_R6) {
10821
10822 TCGv_i64 fp0 = tcg_temp_new_i64();
10823 TCGv_i64 fp1 = tcg_temp_new_i64();
10824 gen_load_fpr64(ctx, fp0, fs);
10825 gen_load_fpr64(ctx, fp1, ft);
10826 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10827 gen_store_fpr64(ctx, fp1, fd);
10828 tcg_temp_free_i64(fp1);
10829 tcg_temp_free_i64(fp0);
10830 } else {
10831
10832 check_cp1_64bitmode(ctx);
10833 {
10834 TCGv_i64 fp0 = tcg_temp_new_i64();
10835
10836 gen_load_fpr64(ctx, fp0, fs);
10837 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10838 gen_store_fpr64(ctx, fp0, fd);
10839 tcg_temp_free_i64(fp0);
10840 }
10841 }
10842 break;
10843 case OPC_MAX_D:
10844 if (ctx->insn_flags & ISA_MIPS_R6) {
10845
10846 TCGv_i64 fp0 = tcg_temp_new_i64();
10847 TCGv_i64 fp1 = tcg_temp_new_i64();
10848 gen_load_fpr64(ctx, fp0, fs);
10849 gen_load_fpr64(ctx, fp1, ft);
10850 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10851 gen_store_fpr64(ctx, fp1, fd);
10852 tcg_temp_free_i64(fp1);
10853 tcg_temp_free_i64(fp0);
10854 } else {
10855
10856 check_cp1_64bitmode(ctx);
10857 {
10858 TCGv_i64 fp0 = tcg_temp_new_i64();
10859
10860 gen_load_fpr64(ctx, fp0, fs);
10861 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10862 gen_store_fpr64(ctx, fp0, fd);
10863 tcg_temp_free_i64(fp0);
10864 }
10865 }
10866 break;
10867 case OPC_MAXA_D:
10868 if (ctx->insn_flags & ISA_MIPS_R6) {
10869
10870 TCGv_i64 fp0 = tcg_temp_new_i64();
10871 TCGv_i64 fp1 = tcg_temp_new_i64();
10872 gen_load_fpr64(ctx, fp0, fs);
10873 gen_load_fpr64(ctx, fp1, ft);
10874 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10875 gen_store_fpr64(ctx, fp1, fd);
10876 tcg_temp_free_i64(fp1);
10877 tcg_temp_free_i64(fp0);
10878 } else {
10879
10880 check_cp1_64bitmode(ctx);
10881 {
10882 TCGv_i64 fp0 = tcg_temp_new_i64();
10883 TCGv_i64 fp1 = tcg_temp_new_i64();
10884
10885 gen_load_fpr64(ctx, fp0, fs);
10886 gen_load_fpr64(ctx, fp1, ft);
10887 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10888 tcg_temp_free_i64(fp1);
10889 gen_store_fpr64(ctx, fp0, fd);
10890 tcg_temp_free_i64(fp0);
10891 }
10892 }
10893 break;
10894 case OPC_CMP_F_D:
10895 case OPC_CMP_UN_D:
10896 case OPC_CMP_EQ_D:
10897 case OPC_CMP_UEQ_D:
10898 case OPC_CMP_OLT_D:
10899 case OPC_CMP_ULT_D:
10900 case OPC_CMP_OLE_D:
10901 case OPC_CMP_ULE_D:
10902 case OPC_CMP_SF_D:
10903 case OPC_CMP_NGLE_D:
10904 case OPC_CMP_SEQ_D:
10905 case OPC_CMP_NGL_D:
10906 case OPC_CMP_LT_D:
10907 case OPC_CMP_NGE_D:
10908 case OPC_CMP_LE_D:
10909 case OPC_CMP_NGT_D:
10910 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10911 if (ctx->opcode & (1 << 6)) {
10912 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10913 } else {
10914 gen_cmp_d(ctx, func - 48, ft, fs, cc);
10915 }
10916 break;
10917 case OPC_CVT_S_D:
10918 check_cp1_registers(ctx, fs);
10919 {
10920 TCGv_i32 fp32 = tcg_temp_new_i32();
10921 TCGv_i64 fp64 = tcg_temp_new_i64();
10922
10923 gen_load_fpr64(ctx, fp64, fs);
10924 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10925 tcg_temp_free_i64(fp64);
10926 gen_store_fpr32(ctx, fp32, fd);
10927 tcg_temp_free_i32(fp32);
10928 }
10929 break;
10930 case OPC_CVT_W_D:
10931 check_cp1_registers(ctx, fs);
10932 {
10933 TCGv_i32 fp32 = tcg_temp_new_i32();
10934 TCGv_i64 fp64 = tcg_temp_new_i64();
10935
10936 gen_load_fpr64(ctx, fp64, fs);
10937 if (ctx->nan2008) {
10938 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10939 } else {
10940 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10941 }
10942 tcg_temp_free_i64(fp64);
10943 gen_store_fpr32(ctx, fp32, fd);
10944 tcg_temp_free_i32(fp32);
10945 }
10946 break;
10947 case OPC_CVT_L_D:
10948 check_cp1_64bitmode(ctx);
10949 {
10950 TCGv_i64 fp0 = tcg_temp_new_i64();
10951
10952 gen_load_fpr64(ctx, fp0, fs);
10953 if (ctx->nan2008) {
10954 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10955 } else {
10956 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10957 }
10958 gen_store_fpr64(ctx, fp0, fd);
10959 tcg_temp_free_i64(fp0);
10960 }
10961 break;
10962 case OPC_CVT_S_W:
10963 {
10964 TCGv_i32 fp0 = tcg_temp_new_i32();
10965
10966 gen_load_fpr32(ctx, fp0, fs);
10967 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10968 gen_store_fpr32(ctx, fp0, fd);
10969 tcg_temp_free_i32(fp0);
10970 }
10971 break;
10972 case OPC_CVT_D_W:
10973 check_cp1_registers(ctx, fd);
10974 {
10975 TCGv_i32 fp32 = tcg_temp_new_i32();
10976 TCGv_i64 fp64 = tcg_temp_new_i64();
10977
10978 gen_load_fpr32(ctx, fp32, fs);
10979 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10980 tcg_temp_free_i32(fp32);
10981 gen_store_fpr64(ctx, fp64, fd);
10982 tcg_temp_free_i64(fp64);
10983 }
10984 break;
10985 case OPC_CVT_S_L:
10986 check_cp1_64bitmode(ctx);
10987 {
10988 TCGv_i32 fp32 = tcg_temp_new_i32();
10989 TCGv_i64 fp64 = tcg_temp_new_i64();
10990
10991 gen_load_fpr64(ctx, fp64, fs);
10992 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10993 tcg_temp_free_i64(fp64);
10994 gen_store_fpr32(ctx, fp32, fd);
10995 tcg_temp_free_i32(fp32);
10996 }
10997 break;
10998 case OPC_CVT_D_L:
10999 check_cp1_64bitmode(ctx);
11000 {
11001 TCGv_i64 fp0 = tcg_temp_new_i64();
11002
11003 gen_load_fpr64(ctx, fp0, fs);
11004 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11005 gen_store_fpr64(ctx, fp0, fd);
11006 tcg_temp_free_i64(fp0);
11007 }
11008 break;
11009 case OPC_CVT_PS_PW:
11010 check_ps(ctx);
11011 {
11012 TCGv_i64 fp0 = tcg_temp_new_i64();
11013
11014 gen_load_fpr64(ctx, fp0, fs);
11015 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11016 gen_store_fpr64(ctx, fp0, fd);
11017 tcg_temp_free_i64(fp0);
11018 }
11019 break;
11020 case OPC_ADD_PS:
11021 check_ps(ctx);
11022 {
11023 TCGv_i64 fp0 = tcg_temp_new_i64();
11024 TCGv_i64 fp1 = tcg_temp_new_i64();
11025
11026 gen_load_fpr64(ctx, fp0, fs);
11027 gen_load_fpr64(ctx, fp1, ft);
11028 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11029 tcg_temp_free_i64(fp1);
11030 gen_store_fpr64(ctx, fp0, fd);
11031 tcg_temp_free_i64(fp0);
11032 }
11033 break;
11034 case OPC_SUB_PS:
11035 check_ps(ctx);
11036 {
11037 TCGv_i64 fp0 = tcg_temp_new_i64();
11038 TCGv_i64 fp1 = tcg_temp_new_i64();
11039
11040 gen_load_fpr64(ctx, fp0, fs);
11041 gen_load_fpr64(ctx, fp1, ft);
11042 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11043 tcg_temp_free_i64(fp1);
11044 gen_store_fpr64(ctx, fp0, fd);
11045 tcg_temp_free_i64(fp0);
11046 }
11047 break;
11048 case OPC_MUL_PS:
11049 check_ps(ctx);
11050 {
11051 TCGv_i64 fp0 = tcg_temp_new_i64();
11052 TCGv_i64 fp1 = tcg_temp_new_i64();
11053
11054 gen_load_fpr64(ctx, fp0, fs);
11055 gen_load_fpr64(ctx, fp1, ft);
11056 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11057 tcg_temp_free_i64(fp1);
11058 gen_store_fpr64(ctx, fp0, fd);
11059 tcg_temp_free_i64(fp0);
11060 }
11061 break;
11062 case OPC_ABS_PS:
11063 check_ps(ctx);
11064 {
11065 TCGv_i64 fp0 = tcg_temp_new_i64();
11066
11067 gen_load_fpr64(ctx, fp0, fs);
11068 gen_helper_float_abs_ps(fp0, fp0);
11069 gen_store_fpr64(ctx, fp0, fd);
11070 tcg_temp_free_i64(fp0);
11071 }
11072 break;
11073 case OPC_MOV_PS:
11074 check_ps(ctx);
11075 {
11076 TCGv_i64 fp0 = tcg_temp_new_i64();
11077
11078 gen_load_fpr64(ctx, fp0, fs);
11079 gen_store_fpr64(ctx, fp0, fd);
11080 tcg_temp_free_i64(fp0);
11081 }
11082 break;
11083 case OPC_NEG_PS:
11084 check_ps(ctx);
11085 {
11086 TCGv_i64 fp0 = tcg_temp_new_i64();
11087
11088 gen_load_fpr64(ctx, fp0, fs);
11089 gen_helper_float_chs_ps(fp0, fp0);
11090 gen_store_fpr64(ctx, fp0, fd);
11091 tcg_temp_free_i64(fp0);
11092 }
11093 break;
11094 case OPC_MOVCF_PS:
11095 check_ps(ctx);
11096 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11097 break;
11098 case OPC_MOVZ_PS:
11099 check_ps(ctx);
11100 {
11101 TCGLabel *l1 = gen_new_label();
11102 TCGv_i64 fp0;
11103
11104 if (ft != 0) {
11105 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11106 }
11107 fp0 = tcg_temp_new_i64();
11108 gen_load_fpr64(ctx, fp0, fs);
11109 gen_store_fpr64(ctx, fp0, fd);
11110 tcg_temp_free_i64(fp0);
11111 gen_set_label(l1);
11112 }
11113 break;
11114 case OPC_MOVN_PS:
11115 check_ps(ctx);
11116 {
11117 TCGLabel *l1 = gen_new_label();
11118 TCGv_i64 fp0;
11119
11120 if (ft != 0) {
11121 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11122 fp0 = tcg_temp_new_i64();
11123 gen_load_fpr64(ctx, fp0, fs);
11124 gen_store_fpr64(ctx, fp0, fd);
11125 tcg_temp_free_i64(fp0);
11126 gen_set_label(l1);
11127 }
11128 }
11129 break;
11130 case OPC_ADDR_PS:
11131 check_ps(ctx);
11132 {
11133 TCGv_i64 fp0 = tcg_temp_new_i64();
11134 TCGv_i64 fp1 = tcg_temp_new_i64();
11135
11136 gen_load_fpr64(ctx, fp0, ft);
11137 gen_load_fpr64(ctx, fp1, fs);
11138 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11139 tcg_temp_free_i64(fp1);
11140 gen_store_fpr64(ctx, fp0, fd);
11141 tcg_temp_free_i64(fp0);
11142 }
11143 break;
11144 case OPC_MULR_PS:
11145 check_ps(ctx);
11146 {
11147 TCGv_i64 fp0 = tcg_temp_new_i64();
11148 TCGv_i64 fp1 = tcg_temp_new_i64();
11149
11150 gen_load_fpr64(ctx, fp0, ft);
11151 gen_load_fpr64(ctx, fp1, fs);
11152 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11153 tcg_temp_free_i64(fp1);
11154 gen_store_fpr64(ctx, fp0, fd);
11155 tcg_temp_free_i64(fp0);
11156 }
11157 break;
11158 case OPC_RECIP2_PS:
11159 check_ps(ctx);
11160 {
11161 TCGv_i64 fp0 = tcg_temp_new_i64();
11162 TCGv_i64 fp1 = tcg_temp_new_i64();
11163
11164 gen_load_fpr64(ctx, fp0, fs);
11165 gen_load_fpr64(ctx, fp1, ft);
11166 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11167 tcg_temp_free_i64(fp1);
11168 gen_store_fpr64(ctx, fp0, fd);
11169 tcg_temp_free_i64(fp0);
11170 }
11171 break;
11172 case OPC_RECIP1_PS:
11173 check_ps(ctx);
11174 {
11175 TCGv_i64 fp0 = tcg_temp_new_i64();
11176
11177 gen_load_fpr64(ctx, fp0, fs);
11178 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11179 gen_store_fpr64(ctx, fp0, fd);
11180 tcg_temp_free_i64(fp0);
11181 }
11182 break;
11183 case OPC_RSQRT1_PS:
11184 check_ps(ctx);
11185 {
11186 TCGv_i64 fp0 = tcg_temp_new_i64();
11187
11188 gen_load_fpr64(ctx, fp0, fs);
11189 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11190 gen_store_fpr64(ctx, fp0, fd);
11191 tcg_temp_free_i64(fp0);
11192 }
11193 break;
11194 case OPC_RSQRT2_PS:
11195 check_ps(ctx);
11196 {
11197 TCGv_i64 fp0 = tcg_temp_new_i64();
11198 TCGv_i64 fp1 = tcg_temp_new_i64();
11199
11200 gen_load_fpr64(ctx, fp0, fs);
11201 gen_load_fpr64(ctx, fp1, ft);
11202 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11203 tcg_temp_free_i64(fp1);
11204 gen_store_fpr64(ctx, fp0, fd);
11205 tcg_temp_free_i64(fp0);
11206 }
11207 break;
11208 case OPC_CVT_S_PU:
11209 check_cp1_64bitmode(ctx);
11210 {
11211 TCGv_i32 fp0 = tcg_temp_new_i32();
11212
11213 gen_load_fpr32h(ctx, fp0, fs);
11214 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11215 gen_store_fpr32(ctx, fp0, fd);
11216 tcg_temp_free_i32(fp0);
11217 }
11218 break;
11219 case OPC_CVT_PW_PS:
11220 check_ps(ctx);
11221 {
11222 TCGv_i64 fp0 = tcg_temp_new_i64();
11223
11224 gen_load_fpr64(ctx, fp0, fs);
11225 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11226 gen_store_fpr64(ctx, fp0, fd);
11227 tcg_temp_free_i64(fp0);
11228 }
11229 break;
11230 case OPC_CVT_S_PL:
11231 check_cp1_64bitmode(ctx);
11232 {
11233 TCGv_i32 fp0 = tcg_temp_new_i32();
11234
11235 gen_load_fpr32(ctx, fp0, fs);
11236 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11237 gen_store_fpr32(ctx, fp0, fd);
11238 tcg_temp_free_i32(fp0);
11239 }
11240 break;
11241 case OPC_PLL_PS:
11242 check_ps(ctx);
11243 {
11244 TCGv_i32 fp0 = tcg_temp_new_i32();
11245 TCGv_i32 fp1 = tcg_temp_new_i32();
11246
11247 gen_load_fpr32(ctx, fp0, fs);
11248 gen_load_fpr32(ctx, fp1, ft);
11249 gen_store_fpr32h(ctx, fp0, fd);
11250 gen_store_fpr32(ctx, fp1, fd);
11251 tcg_temp_free_i32(fp0);
11252 tcg_temp_free_i32(fp1);
11253 }
11254 break;
11255 case OPC_PLU_PS:
11256 check_ps(ctx);
11257 {
11258 TCGv_i32 fp0 = tcg_temp_new_i32();
11259 TCGv_i32 fp1 = tcg_temp_new_i32();
11260
11261 gen_load_fpr32(ctx, fp0, fs);
11262 gen_load_fpr32h(ctx, fp1, ft);
11263 gen_store_fpr32(ctx, fp1, fd);
11264 gen_store_fpr32h(ctx, fp0, fd);
11265 tcg_temp_free_i32(fp0);
11266 tcg_temp_free_i32(fp1);
11267 }
11268 break;
11269 case OPC_PUL_PS:
11270 check_ps(ctx);
11271 {
11272 TCGv_i32 fp0 = tcg_temp_new_i32();
11273 TCGv_i32 fp1 = tcg_temp_new_i32();
11274
11275 gen_load_fpr32h(ctx, fp0, fs);
11276 gen_load_fpr32(ctx, fp1, ft);
11277 gen_store_fpr32(ctx, fp1, fd);
11278 gen_store_fpr32h(ctx, fp0, fd);
11279 tcg_temp_free_i32(fp0);
11280 tcg_temp_free_i32(fp1);
11281 }
11282 break;
11283 case OPC_PUU_PS:
11284 check_ps(ctx);
11285 {
11286 TCGv_i32 fp0 = tcg_temp_new_i32();
11287 TCGv_i32 fp1 = tcg_temp_new_i32();
11288
11289 gen_load_fpr32h(ctx, fp0, fs);
11290 gen_load_fpr32h(ctx, fp1, ft);
11291 gen_store_fpr32(ctx, fp1, fd);
11292 gen_store_fpr32h(ctx, fp0, fd);
11293 tcg_temp_free_i32(fp0);
11294 tcg_temp_free_i32(fp1);
11295 }
11296 break;
11297 case OPC_CMP_F_PS:
11298 case OPC_CMP_UN_PS:
11299 case OPC_CMP_EQ_PS:
11300 case OPC_CMP_UEQ_PS:
11301 case OPC_CMP_OLT_PS:
11302 case OPC_CMP_ULT_PS:
11303 case OPC_CMP_OLE_PS:
11304 case OPC_CMP_ULE_PS:
11305 case OPC_CMP_SF_PS:
11306 case OPC_CMP_NGLE_PS:
11307 case OPC_CMP_SEQ_PS:
11308 case OPC_CMP_NGL_PS:
11309 case OPC_CMP_LT_PS:
11310 case OPC_CMP_NGE_PS:
11311 case OPC_CMP_LE_PS:
11312 case OPC_CMP_NGT_PS:
11313 if (ctx->opcode & (1 << 6)) {
11314 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11315 } else {
11316 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11317 }
11318 break;
11319 default:
11320 MIPS_INVAL("farith");
11321 gen_reserved_instruction(ctx);
11322 return;
11323 }
11324}
11325
11326
11327static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11328 int fd, int fs, int base, int index)
11329{
11330 TCGv t0 = tcg_temp_new();
11331
11332 if (base == 0) {
11333 gen_load_gpr(t0, index);
11334 } else if (index == 0) {
11335 gen_load_gpr(t0, base);
11336 } else {
11337 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11338 }
11339
11340
11341
11342
11343 switch (opc) {
11344 case OPC_LWXC1:
11345 check_cop1x(ctx);
11346 {
11347 TCGv_i32 fp0 = tcg_temp_new_i32();
11348
11349 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11350 tcg_gen_trunc_tl_i32(fp0, t0);
11351 gen_store_fpr32(ctx, fp0, fd);
11352 tcg_temp_free_i32(fp0);
11353 }
11354 break;
11355 case OPC_LDXC1:
11356 check_cop1x(ctx);
11357 check_cp1_registers(ctx, fd);
11358 {
11359 TCGv_i64 fp0 = tcg_temp_new_i64();
11360 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11361 gen_store_fpr64(ctx, fp0, fd);
11362 tcg_temp_free_i64(fp0);
11363 }
11364 break;
11365 case OPC_LUXC1:
11366 check_cp1_64bitmode(ctx);
11367 tcg_gen_andi_tl(t0, t0, ~0x7);
11368 {
11369 TCGv_i64 fp0 = tcg_temp_new_i64();
11370
11371 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11372 gen_store_fpr64(ctx, fp0, fd);
11373 tcg_temp_free_i64(fp0);
11374 }
11375 break;
11376 case OPC_SWXC1:
11377 check_cop1x(ctx);
11378 {
11379 TCGv_i32 fp0 = tcg_temp_new_i32();
11380 gen_load_fpr32(ctx, fp0, fs);
11381 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11382 tcg_temp_free_i32(fp0);
11383 }
11384 break;
11385 case OPC_SDXC1:
11386 check_cop1x(ctx);
11387 check_cp1_registers(ctx, fs);
11388 {
11389 TCGv_i64 fp0 = tcg_temp_new_i64();
11390 gen_load_fpr64(ctx, fp0, fs);
11391 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11392 tcg_temp_free_i64(fp0);
11393 }
11394 break;
11395 case OPC_SUXC1:
11396 check_cp1_64bitmode(ctx);
11397 tcg_gen_andi_tl(t0, t0, ~0x7);
11398 {
11399 TCGv_i64 fp0 = tcg_temp_new_i64();
11400 gen_load_fpr64(ctx, fp0, fs);
11401 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11402 tcg_temp_free_i64(fp0);
11403 }
11404 break;
11405 }
11406 tcg_temp_free(t0);
11407}
11408
11409static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11410 int fd, int fr, int fs, int ft)
11411{
11412 switch (opc) {
11413 case OPC_ALNV_PS:
11414 check_ps(ctx);
11415 {
11416 TCGv t0 = tcg_temp_local_new();
11417 TCGv_i32 fp = tcg_temp_new_i32();
11418 TCGv_i32 fph = tcg_temp_new_i32();
11419 TCGLabel *l1 = gen_new_label();
11420 TCGLabel *l2 = gen_new_label();
11421
11422 gen_load_gpr(t0, fr);
11423 tcg_gen_andi_tl(t0, t0, 0x7);
11424
11425 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11426 gen_load_fpr32(ctx, fp, fs);
11427 gen_load_fpr32h(ctx, fph, fs);
11428 gen_store_fpr32(ctx, fp, fd);
11429 gen_store_fpr32h(ctx, fph, fd);
11430 tcg_gen_br(l2);
11431 gen_set_label(l1);
11432 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11433 tcg_temp_free(t0);
11434 if (cpu_is_bigendian(ctx)) {
11435 gen_load_fpr32(ctx, fp, fs);
11436 gen_load_fpr32h(ctx, fph, ft);
11437 gen_store_fpr32h(ctx, fp, fd);
11438 gen_store_fpr32(ctx, fph, fd);
11439 } else {
11440 gen_load_fpr32h(ctx, fph, fs);
11441 gen_load_fpr32(ctx, fp, ft);
11442 gen_store_fpr32(ctx, fph, fd);
11443 gen_store_fpr32h(ctx, fp, fd);
11444 }
11445 gen_set_label(l2);
11446 tcg_temp_free_i32(fp);
11447 tcg_temp_free_i32(fph);
11448 }
11449 break;
11450 case OPC_MADD_S:
11451 check_cop1x(ctx);
11452 {
11453 TCGv_i32 fp0 = tcg_temp_new_i32();
11454 TCGv_i32 fp1 = tcg_temp_new_i32();
11455 TCGv_i32 fp2 = tcg_temp_new_i32();
11456
11457 gen_load_fpr32(ctx, fp0, fs);
11458 gen_load_fpr32(ctx, fp1, ft);
11459 gen_load_fpr32(ctx, fp2, fr);
11460 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11461 tcg_temp_free_i32(fp0);
11462 tcg_temp_free_i32(fp1);
11463 gen_store_fpr32(ctx, fp2, fd);
11464 tcg_temp_free_i32(fp2);
11465 }
11466 break;
11467 case OPC_MADD_D:
11468 check_cop1x(ctx);
11469 check_cp1_registers(ctx, fd | fs | ft | fr);
11470 {
11471 TCGv_i64 fp0 = tcg_temp_new_i64();
11472 TCGv_i64 fp1 = tcg_temp_new_i64();
11473 TCGv_i64 fp2 = tcg_temp_new_i64();
11474
11475 gen_load_fpr64(ctx, fp0, fs);
11476 gen_load_fpr64(ctx, fp1, ft);
11477 gen_load_fpr64(ctx, fp2, fr);
11478 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11479 tcg_temp_free_i64(fp0);
11480 tcg_temp_free_i64(fp1);
11481 gen_store_fpr64(ctx, fp2, fd);
11482 tcg_temp_free_i64(fp2);
11483 }
11484 break;
11485 case OPC_MADD_PS:
11486 check_ps(ctx);
11487 {
11488 TCGv_i64 fp0 = tcg_temp_new_i64();
11489 TCGv_i64 fp1 = tcg_temp_new_i64();
11490 TCGv_i64 fp2 = tcg_temp_new_i64();
11491
11492 gen_load_fpr64(ctx, fp0, fs);
11493 gen_load_fpr64(ctx, fp1, ft);
11494 gen_load_fpr64(ctx, fp2, fr);
11495 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11496 tcg_temp_free_i64(fp0);
11497 tcg_temp_free_i64(fp1);
11498 gen_store_fpr64(ctx, fp2, fd);
11499 tcg_temp_free_i64(fp2);
11500 }
11501 break;
11502 case OPC_MSUB_S:
11503 check_cop1x(ctx);
11504 {
11505 TCGv_i32 fp0 = tcg_temp_new_i32();
11506 TCGv_i32 fp1 = tcg_temp_new_i32();
11507 TCGv_i32 fp2 = tcg_temp_new_i32();
11508
11509 gen_load_fpr32(ctx, fp0, fs);
11510 gen_load_fpr32(ctx, fp1, ft);
11511 gen_load_fpr32(ctx, fp2, fr);
11512 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11513 tcg_temp_free_i32(fp0);
11514 tcg_temp_free_i32(fp1);
11515 gen_store_fpr32(ctx, fp2, fd);
11516 tcg_temp_free_i32(fp2);
11517 }
11518 break;
11519 case OPC_MSUB_D:
11520 check_cop1x(ctx);
11521 check_cp1_registers(ctx, fd | fs | ft | fr);
11522 {
11523 TCGv_i64 fp0 = tcg_temp_new_i64();
11524 TCGv_i64 fp1 = tcg_temp_new_i64();
11525 TCGv_i64 fp2 = tcg_temp_new_i64();
11526
11527 gen_load_fpr64(ctx, fp0, fs);
11528 gen_load_fpr64(ctx, fp1, ft);
11529 gen_load_fpr64(ctx, fp2, fr);
11530 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11531 tcg_temp_free_i64(fp0);
11532 tcg_temp_free_i64(fp1);
11533 gen_store_fpr64(ctx, fp2, fd);
11534 tcg_temp_free_i64(fp2);
11535 }
11536 break;
11537 case OPC_MSUB_PS:
11538 check_ps(ctx);
11539 {
11540 TCGv_i64 fp0 = tcg_temp_new_i64();
11541 TCGv_i64 fp1 = tcg_temp_new_i64();
11542 TCGv_i64 fp2 = tcg_temp_new_i64();
11543
11544 gen_load_fpr64(ctx, fp0, fs);
11545 gen_load_fpr64(ctx, fp1, ft);
11546 gen_load_fpr64(ctx, fp2, fr);
11547 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11548 tcg_temp_free_i64(fp0);
11549 tcg_temp_free_i64(fp1);
11550 gen_store_fpr64(ctx, fp2, fd);
11551 tcg_temp_free_i64(fp2);
11552 }
11553 break;
11554 case OPC_NMADD_S:
11555 check_cop1x(ctx);
11556 {
11557 TCGv_i32 fp0 = tcg_temp_new_i32();
11558 TCGv_i32 fp1 = tcg_temp_new_i32();
11559 TCGv_i32 fp2 = tcg_temp_new_i32();
11560
11561 gen_load_fpr32(ctx, fp0, fs);
11562 gen_load_fpr32(ctx, fp1, ft);
11563 gen_load_fpr32(ctx, fp2, fr);
11564 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11565 tcg_temp_free_i32(fp0);
11566 tcg_temp_free_i32(fp1);
11567 gen_store_fpr32(ctx, fp2, fd);
11568 tcg_temp_free_i32(fp2);
11569 }
11570 break;
11571 case OPC_NMADD_D:
11572 check_cop1x(ctx);
11573 check_cp1_registers(ctx, fd | fs | ft | fr);
11574 {
11575 TCGv_i64 fp0 = tcg_temp_new_i64();
11576 TCGv_i64 fp1 = tcg_temp_new_i64();
11577 TCGv_i64 fp2 = tcg_temp_new_i64();
11578
11579 gen_load_fpr64(ctx, fp0, fs);
11580 gen_load_fpr64(ctx, fp1, ft);
11581 gen_load_fpr64(ctx, fp2, fr);
11582 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11583 tcg_temp_free_i64(fp0);
11584 tcg_temp_free_i64(fp1);
11585 gen_store_fpr64(ctx, fp2, fd);
11586 tcg_temp_free_i64(fp2);
11587 }
11588 break;
11589 case OPC_NMADD_PS:
11590 check_ps(ctx);
11591 {
11592 TCGv_i64 fp0 = tcg_temp_new_i64();
11593 TCGv_i64 fp1 = tcg_temp_new_i64();
11594 TCGv_i64 fp2 = tcg_temp_new_i64();
11595
11596 gen_load_fpr64(ctx, fp0, fs);
11597 gen_load_fpr64(ctx, fp1, ft);
11598 gen_load_fpr64(ctx, fp2, fr);
11599 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11600 tcg_temp_free_i64(fp0);
11601 tcg_temp_free_i64(fp1);
11602 gen_store_fpr64(ctx, fp2, fd);
11603 tcg_temp_free_i64(fp2);
11604 }
11605 break;
11606 case OPC_NMSUB_S:
11607 check_cop1x(ctx);
11608 {
11609 TCGv_i32 fp0 = tcg_temp_new_i32();
11610 TCGv_i32 fp1 = tcg_temp_new_i32();
11611 TCGv_i32 fp2 = tcg_temp_new_i32();
11612
11613 gen_load_fpr32(ctx, fp0, fs);
11614 gen_load_fpr32(ctx, fp1, ft);
11615 gen_load_fpr32(ctx, fp2, fr);
11616 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11617 tcg_temp_free_i32(fp0);
11618 tcg_temp_free_i32(fp1);
11619 gen_store_fpr32(ctx, fp2, fd);
11620 tcg_temp_free_i32(fp2);
11621 }
11622 break;
11623 case OPC_NMSUB_D:
11624 check_cop1x(ctx);
11625 check_cp1_registers(ctx, fd | fs | ft | fr);
11626 {
11627 TCGv_i64 fp0 = tcg_temp_new_i64();
11628 TCGv_i64 fp1 = tcg_temp_new_i64();
11629 TCGv_i64 fp2 = tcg_temp_new_i64();
11630
11631 gen_load_fpr64(ctx, fp0, fs);
11632 gen_load_fpr64(ctx, fp1, ft);
11633 gen_load_fpr64(ctx, fp2, fr);
11634 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11635 tcg_temp_free_i64(fp0);
11636 tcg_temp_free_i64(fp1);
11637 gen_store_fpr64(ctx, fp2, fd);
11638 tcg_temp_free_i64(fp2);
11639 }
11640 break;
11641 case OPC_NMSUB_PS:
11642 check_ps(ctx);
11643 {
11644 TCGv_i64 fp0 = tcg_temp_new_i64();
11645 TCGv_i64 fp1 = tcg_temp_new_i64();
11646 TCGv_i64 fp2 = tcg_temp_new_i64();
11647
11648 gen_load_fpr64(ctx, fp0, fs);
11649 gen_load_fpr64(ctx, fp1, ft);
11650 gen_load_fpr64(ctx, fp2, fr);
11651 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11652 tcg_temp_free_i64(fp0);
11653 tcg_temp_free_i64(fp1);
11654 gen_store_fpr64(ctx, fp2, fd);
11655 tcg_temp_free_i64(fp2);
11656 }
11657 break;
11658 default:
11659 MIPS_INVAL("flt3_arith");
11660 gen_reserved_instruction(ctx);
11661 return;
11662 }
11663}
11664
11665void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11666{
11667 TCGv t0;
11668
11669#if !defined(CONFIG_USER_ONLY)
11670
11671
11672
11673
11674 check_insn(ctx, ISA_MIPS_R2);
11675#endif
11676 t0 = tcg_temp_new();
11677
11678 switch (rd) {
11679 case 0:
11680 gen_helper_rdhwr_cpunum(t0, cpu_env);
11681 gen_store_gpr(t0, rt);
11682 break;
11683 case 1:
11684 gen_helper_rdhwr_synci_step(t0, cpu_env);
11685 gen_store_gpr(t0, rt);
11686 break;
11687 case 2:
11688 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11689 gen_io_start();
11690 }
11691 gen_helper_rdhwr_cc(t0, cpu_env);
11692 gen_store_gpr(t0, rt);
11693
11694
11695
11696
11697
11698 gen_save_pc(ctx->base.pc_next + 4);
11699 ctx->base.is_jmp = DISAS_EXIT;
11700 break;
11701 case 3:
11702 gen_helper_rdhwr_ccres(t0, cpu_env);
11703 gen_store_gpr(t0, rt);
11704 break;
11705 case 4:
11706 check_insn(ctx, ISA_MIPS_R6);
11707 if (sel != 0) {
11708
11709
11710
11711
11712 generate_exception(ctx, EXCP_RI);
11713 }
11714 gen_helper_rdhwr_performance(t0, cpu_env);
11715 gen_store_gpr(t0, rt);
11716 break;
11717 case 5:
11718 check_insn(ctx, ISA_MIPS_R6);
11719 gen_helper_rdhwr_xnp(t0, cpu_env);
11720 gen_store_gpr(t0, rt);
11721 break;
11722 case 29:
11723#if defined(CONFIG_USER_ONLY)
11724 tcg_gen_ld_tl(t0, cpu_env,
11725 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11726 gen_store_gpr(t0, rt);
11727 break;
11728#else
11729 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11730 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11731 tcg_gen_ld_tl(t0, cpu_env,
11732 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11733 gen_store_gpr(t0, rt);
11734 } else {
11735 gen_reserved_instruction(ctx);
11736 }
11737 break;
11738#endif
11739 default:
11740 MIPS_INVAL("rdhwr");
11741 gen_reserved_instruction(ctx);
11742 break;
11743 }
11744 tcg_temp_free(t0);
11745}
11746
11747static inline void clear_branch_hflags(DisasContext *ctx)
11748{
11749 ctx->hflags &= ~MIPS_HFLAG_BMASK;
11750 if (ctx->base.is_jmp == DISAS_NEXT) {
11751 save_cpu_state(ctx, 0);
11752 } else {
11753
11754
11755
11756
11757 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11758 }
11759}
11760
11761static void gen_branch(DisasContext *ctx, int insn_bytes)
11762{
11763 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11764 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11765
11766 clear_branch_hflags(ctx);
11767 ctx->base.is_jmp = DISAS_NORETURN;
11768
11769 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11770 case MIPS_HFLAG_FBNSLOT:
11771 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11772 break;
11773 case MIPS_HFLAG_B:
11774
11775 if (proc_hflags & MIPS_HFLAG_BX) {
11776 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11777 }
11778 gen_goto_tb(ctx, 0, ctx->btarget);
11779 break;
11780 case MIPS_HFLAG_BL:
11781
11782 gen_goto_tb(ctx, 0, ctx->btarget);
11783 break;
11784 case MIPS_HFLAG_BC:
11785
11786 {
11787 TCGLabel *l1 = gen_new_label();
11788
11789 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11790 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11791 gen_set_label(l1);
11792 gen_goto_tb(ctx, 0, ctx->btarget);
11793 }
11794 break;
11795 case MIPS_HFLAG_BR:
11796
11797 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11798 TCGv t0 = tcg_temp_new();
11799 TCGv_i32 t1 = tcg_temp_new_i32();
11800
11801 tcg_gen_andi_tl(t0, btarget, 0x1);
11802 tcg_gen_trunc_tl_i32(t1, t0);
11803 tcg_temp_free(t0);
11804 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11805 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11806 tcg_gen_or_i32(hflags, hflags, t1);
11807 tcg_temp_free_i32(t1);
11808
11809 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11810 } else {
11811 tcg_gen_mov_tl(cpu_PC, btarget);
11812 }
11813 tcg_gen_lookup_and_goto_ptr();
11814 break;
11815 default:
11816 LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11817 gen_reserved_instruction(ctx);
11818 }
11819 }
11820}
11821
11822
11823static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11824 int rs, int rt, int32_t offset)
11825{
11826 int bcond_compute = 0;
11827 TCGv t0 = tcg_temp_new();
11828 TCGv t1 = tcg_temp_new();
11829 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11830
11831 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11832#ifdef MIPS_DEBUG_DISAS
11833 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11834 "\n", ctx->base.pc_next);
11835#endif
11836 gen_reserved_instruction(ctx);
11837 goto out;
11838 }
11839
11840
11841 switch (opc) {
11842
11843 case OPC_BOVC:
11844 case OPC_BNVC:
11845 gen_load_gpr(t0, rs);
11846 gen_load_gpr(t1, rt);
11847 bcond_compute = 1;
11848 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11849 if (rs <= rt && rs == 0) {
11850
11851 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11852 }
11853 break;
11854 case OPC_BLEZC:
11855 case OPC_BGTZC:
11856 gen_load_gpr(t0, rs);
11857 gen_load_gpr(t1, rt);
11858 bcond_compute = 1;
11859 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11860 break;
11861 case OPC_BLEZALC:
11862 case OPC_BGTZALC:
11863 if (rs == 0 || rs == rt) {
11864
11865
11866 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11867 }
11868 gen_load_gpr(t0, rs);
11869 gen_load_gpr(t1, rt);
11870 bcond_compute = 1;
11871 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11872 break;
11873 case OPC_BC:
11874 case OPC_BALC:
11875 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11876 break;
11877 case OPC_BEQZC:
11878 case OPC_BNEZC:
11879 if (rs != 0) {
11880
11881 gen_load_gpr(t0, rs);
11882 bcond_compute = 1;
11883 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11884 } else {
11885
11886 TCGv tbase = tcg_temp_new();
11887 TCGv toffset = tcg_constant_tl(offset);
11888
11889 gen_load_gpr(tbase, rt);
11890 gen_op_addr_add(ctx, btarget, tbase, toffset);
11891 tcg_temp_free(tbase);
11892 }
11893 break;
11894 default:
11895 MIPS_INVAL("Compact branch/jump");
11896 gen_reserved_instruction(ctx);
11897 goto out;
11898 }
11899
11900 if (bcond_compute == 0) {
11901
11902 switch (opc) {
11903 case OPC_JIALC:
11904 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11905
11906 case OPC_JIC:
11907 ctx->hflags |= MIPS_HFLAG_BR;
11908 break;
11909 case OPC_BALC:
11910 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11911
11912 case OPC_BC:
11913 ctx->hflags |= MIPS_HFLAG_B;
11914 break;
11915 default:
11916 MIPS_INVAL("Compact branch/jump");
11917 gen_reserved_instruction(ctx);
11918 goto out;
11919 }
11920
11921
11922 gen_branch(ctx, 4);
11923 } else {
11924
11925 TCGLabel *fs = gen_new_label();
11926 save_cpu_state(ctx, 0);
11927
11928 switch (opc) {
11929 case OPC_BLEZALC:
11930 if (rs == 0 && rt != 0) {
11931
11932 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11933 } else if (rs != 0 && rt != 0 && rs == rt) {
11934
11935 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11936 } else {
11937
11938 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11939 }
11940 break;
11941 case OPC_BGTZALC:
11942 if (rs == 0 && rt != 0) {
11943
11944 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11945 } else if (rs != 0 && rt != 0 && rs == rt) {
11946
11947 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11948 } else {
11949
11950 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11951 }
11952 break;
11953 case OPC_BLEZC:
11954 if (rs == 0 && rt != 0) {
11955
11956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11957 } else if (rs != 0 && rt != 0 && rs == rt) {
11958
11959 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11960 } else {
11961
11962 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11963 }
11964 break;
11965 case OPC_BGTZC:
11966 if (rs == 0 && rt != 0) {
11967
11968 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11969 } else if (rs != 0 && rt != 0 && rs == rt) {
11970
11971 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11972 } else {
11973
11974 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11975 }
11976 break;
11977 case OPC_BOVC:
11978 case OPC_BNVC:
11979 if (rs >= rt) {
11980
11981 TCGv t2 = tcg_temp_new();
11982 TCGv t3 = tcg_temp_new();
11983 TCGv t4 = tcg_temp_new();
11984 TCGv input_overflow = tcg_temp_new();
11985
11986 gen_load_gpr(t0, rs);
11987 gen_load_gpr(t1, rt);
11988 tcg_gen_ext32s_tl(t2, t0);
11989 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11990 tcg_gen_ext32s_tl(t3, t1);
11991 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11992 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11993
11994 tcg_gen_add_tl(t4, t2, t3);
11995 tcg_gen_ext32s_tl(t4, t4);
11996 tcg_gen_xor_tl(t2, t2, t3);
11997 tcg_gen_xor_tl(t3, t4, t3);
11998 tcg_gen_andc_tl(t2, t3, t2);
11999 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12000 tcg_gen_or_tl(t4, t4, input_overflow);
12001 if (opc == OPC_BOVC) {
12002
12003 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12004 } else {
12005
12006 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12007 }
12008 tcg_temp_free(input_overflow);
12009 tcg_temp_free(t4);
12010 tcg_temp_free(t3);
12011 tcg_temp_free(t2);
12012 } else if (rs < rt && rs == 0) {
12013
12014 if (opc == OPC_BEQZALC) {
12015
12016 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12017 } else {
12018
12019 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12020 }
12021 } else {
12022
12023 if (opc == OPC_BEQC) {
12024
12025 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12026 } else {
12027
12028 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12029 }
12030 }
12031 break;
12032 case OPC_BEQZC:
12033 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12034 break;
12035 case OPC_BNEZC:
12036 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12037 break;
12038 default:
12039 MIPS_INVAL("Compact conditional branch/jump");
12040 gen_reserved_instruction(ctx);
12041 goto out;
12042 }
12043
12044
12045 gen_goto_tb(ctx, 1, ctx->btarget);
12046 gen_set_label(fs);
12047
12048 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12049 }
12050
12051out:
12052 tcg_temp_free(t0);
12053 tcg_temp_free(t1);
12054}
12055
12056void gen_addiupc(DisasContext *ctx, int rx, int imm,
12057 int is_64_bit, int extended)
12058{
12059 TCGv t0;
12060
12061 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12062 gen_reserved_instruction(ctx);
12063 return;
12064 }
12065
12066 t0 = tcg_temp_new();
12067
12068 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12069 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12070 if (!is_64_bit) {
12071 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12072 }
12073
12074 tcg_temp_free(t0);
12075}
12076
12077static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12078 int16_t offset)
12079{
12080 TCGv_i32 t0 = tcg_const_i32(op);
12081 TCGv t1 = tcg_temp_new();
12082 gen_base_offset_addr(ctx, t1, base, offset);
12083 gen_helper_cache(cpu_env, t1, t0);
12084 tcg_temp_free(t1);
12085 tcg_temp_free_i32(t0);
12086}
12087
12088static inline bool is_uhi(int sdbbp_code)
12089{
12090#ifdef CONFIG_USER_ONLY
12091 return false;
12092#else
12093 return semihosting_enabled() && sdbbp_code == 1;
12094#endif
12095}
12096
12097#ifdef CONFIG_USER_ONLY
12098
12099static inline void gen_helper_do_semihosting(void *env)
12100{
12101 g_assert_not_reached();
12102}
12103#endif
12104
12105void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
12106{
12107 TCGv t0 = tcg_temp_new();
12108 TCGv t1 = tcg_temp_new();
12109
12110 gen_load_gpr(t0, base);
12111
12112 if (index != 0) {
12113 gen_load_gpr(t1, index);
12114 tcg_gen_shli_tl(t1, t1, 2);
12115 gen_op_addr_add(ctx, t0, t1, t0);
12116 }
12117
12118 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12119 gen_store_gpr(t1, rd);
12120
12121 tcg_temp_free(t0);
12122 tcg_temp_free(t1);
12123}
12124
12125static void gen_sync(int stype)
12126{
12127 TCGBar tcg_mo = TCG_BAR_SC;
12128
12129 switch (stype) {
12130 case 0x4:
12131 tcg_mo |= TCG_MO_ST_ST;
12132 break;
12133 case 0x10:
12134 tcg_mo |= TCG_MO_ALL;
12135 break;
12136 case 0x11:
12137 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12138 break;
12139 case 0x12:
12140 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12141 break;
12142 case 0x13:
12143 tcg_mo |= TCG_MO_LD_LD;
12144 break;
12145 default:
12146 tcg_mo |= TCG_MO_ALL;
12147 break;
12148 }
12149
12150 tcg_gen_mb(tcg_mo);
12151}
12152
12153
12154
12155
12156#include "mips16e_translate.c.inc"
12157
12158
12159
12160
12161
12162
12163
12164enum {
12165 FMT_SD_S = 0,
12166 FMT_SD_D = 1,
12167
12168 FMT_SDPS_S = 0,
12169 FMT_SDPS_D = 1,
12170 FMT_SDPS_PS = 2,
12171
12172 FMT_SWL_S = 0,
12173 FMT_SWL_W = 1,
12174 FMT_SWL_L = 2,
12175
12176 FMT_DWL_D = 0,
12177 FMT_DWL_W = 1,
12178 FMT_DWL_L = 2
12179};
12180
12181#include "micromips_translate.c.inc"
12182
12183#include "nanomips_translate.c.inc"
12184
12185
12186static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12187 int rd, int base, int offset)
12188{
12189 TCGv t0;
12190
12191 check_dsp(ctx);
12192 t0 = tcg_temp_new();
12193
12194 if (base == 0) {
12195 gen_load_gpr(t0, offset);
12196 } else if (offset == 0) {
12197 gen_load_gpr(t0, base);
12198 } else {
12199 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12200 }
12201
12202 switch (opc) {
12203 case OPC_LBUX:
12204 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12205 gen_store_gpr(t0, rd);
12206 break;
12207 case OPC_LHX:
12208 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12209 gen_store_gpr(t0, rd);
12210 break;
12211 case OPC_LWX:
12212 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12213 gen_store_gpr(t0, rd);
12214 break;
12215#if defined(TARGET_MIPS64)
12216 case OPC_LDX:
12217 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
12218 gen_store_gpr(t0, rd);
12219 break;
12220#endif
12221 }
12222 tcg_temp_free(t0);
12223}
12224
12225static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12226 int ret, int v1, int v2)
12227{
12228 TCGv v1_t;
12229 TCGv v2_t;
12230
12231 if (ret == 0) {
12232
12233 return;
12234 }
12235
12236 v1_t = tcg_temp_new();
12237 v2_t = tcg_temp_new();
12238
12239 gen_load_gpr(v1_t, v1);
12240 gen_load_gpr(v2_t, v2);
12241
12242 switch (op1) {
12243
12244 case OPC_MULT_G_2E:
12245 check_dsp_r2(ctx);
12246 switch (op2) {
12247 case OPC_ADDUH_QB:
12248 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12249 break;
12250 case OPC_ADDUH_R_QB:
12251 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12252 break;
12253 case OPC_ADDQH_PH:
12254 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12255 break;
12256 case OPC_ADDQH_R_PH:
12257 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12258 break;
12259 case OPC_ADDQH_W:
12260 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12261 break;
12262 case OPC_ADDQH_R_W:
12263 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12264 break;
12265 case OPC_SUBUH_QB:
12266 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12267 break;
12268 case OPC_SUBUH_R_QB:
12269 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12270 break;
12271 case OPC_SUBQH_PH:
12272 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12273 break;
12274 case OPC_SUBQH_R_PH:
12275 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12276 break;
12277 case OPC_SUBQH_W:
12278 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12279 break;
12280 case OPC_SUBQH_R_W:
12281 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12282 break;
12283 }
12284 break;
12285 case OPC_ABSQ_S_PH_DSP:
12286 switch (op2) {
12287 case OPC_ABSQ_S_QB:
12288 check_dsp_r2(ctx);
12289 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12290 break;
12291 case OPC_ABSQ_S_PH:
12292 check_dsp(ctx);
12293 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12294 break;
12295 case OPC_ABSQ_S_W:
12296 check_dsp(ctx);
12297 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12298 break;
12299 case OPC_PRECEQ_W_PHL:
12300 check_dsp(ctx);
12301 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12302 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12303 break;
12304 case OPC_PRECEQ_W_PHR:
12305 check_dsp(ctx);
12306 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12307 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12308 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12309 break;
12310 case OPC_PRECEQU_PH_QBL:
12311 check_dsp(ctx);
12312 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12313 break;
12314 case OPC_PRECEQU_PH_QBR:
12315 check_dsp(ctx);
12316 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12317 break;
12318 case OPC_PRECEQU_PH_QBLA:
12319 check_dsp(ctx);
12320 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12321 break;
12322 case OPC_PRECEQU_PH_QBRA:
12323 check_dsp(ctx);
12324 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12325 break;
12326 case OPC_PRECEU_PH_QBL:
12327 check_dsp(ctx);
12328 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12329 break;
12330 case OPC_PRECEU_PH_QBR:
12331 check_dsp(ctx);
12332 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12333 break;
12334 case OPC_PRECEU_PH_QBLA:
12335 check_dsp(ctx);
12336 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12337 break;
12338 case OPC_PRECEU_PH_QBRA:
12339 check_dsp(ctx);
12340 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12341 break;
12342 }
12343 break;
12344 case OPC_ADDU_QB_DSP:
12345 switch (op2) {
12346 case OPC_ADDQ_PH:
12347 check_dsp(ctx);
12348 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12349 break;
12350 case OPC_ADDQ_S_PH:
12351 check_dsp(ctx);
12352 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12353 break;
12354 case OPC_ADDQ_S_W:
12355 check_dsp(ctx);
12356 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12357 break;
12358 case OPC_ADDU_QB:
12359 check_dsp(ctx);
12360 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12361 break;
12362 case OPC_ADDU_S_QB:
12363 check_dsp(ctx);
12364 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12365 break;
12366 case OPC_ADDU_PH:
12367 check_dsp_r2(ctx);
12368 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12369 break;
12370 case OPC_ADDU_S_PH:
12371 check_dsp_r2(ctx);
12372 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12373 break;
12374 case OPC_SUBQ_PH:
12375 check_dsp(ctx);
12376 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12377 break;
12378 case OPC_SUBQ_S_PH:
12379 check_dsp(ctx);
12380 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12381 break;
12382 case OPC_SUBQ_S_W:
12383 check_dsp(ctx);
12384 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12385 break;
12386 case OPC_SUBU_QB:
12387 check_dsp(ctx);
12388 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12389 break;
12390 case OPC_SUBU_S_QB:
12391 check_dsp(ctx);
12392 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12393 break;
12394 case OPC_SUBU_PH:
12395 check_dsp_r2(ctx);
12396 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12397 break;
12398 case OPC_SUBU_S_PH:
12399 check_dsp_r2(ctx);
12400 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12401 break;
12402 case OPC_ADDSC:
12403 check_dsp(ctx);
12404 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12405 break;
12406 case OPC_ADDWC:
12407 check_dsp(ctx);
12408 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12409 break;
12410 case OPC_MODSUB:
12411 check_dsp(ctx);
12412 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12413 break;
12414 case OPC_RADDU_W_QB:
12415 check_dsp(ctx);
12416 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12417 break;
12418 }
12419 break;
12420 case OPC_CMPU_EQ_QB_DSP:
12421 switch (op2) {
12422 case OPC_PRECR_QB_PH:
12423 check_dsp_r2(ctx);
12424 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12425 break;
12426 case OPC_PRECRQ_QB_PH:
12427 check_dsp(ctx);
12428 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12429 break;
12430 case OPC_PRECR_SRA_PH_W:
12431 check_dsp_r2(ctx);
12432 {
12433 TCGv_i32 sa_t = tcg_const_i32(v2);
12434 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12435 cpu_gpr[ret]);
12436 tcg_temp_free_i32(sa_t);
12437 break;
12438 }
12439 case OPC_PRECR_SRA_R_PH_W:
12440 check_dsp_r2(ctx);
12441 {
12442 TCGv_i32 sa_t = tcg_const_i32(v2);
12443 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12444 cpu_gpr[ret]);
12445 tcg_temp_free_i32(sa_t);
12446 break;
12447 }
12448 case OPC_PRECRQ_PH_W:
12449 check_dsp(ctx);
12450 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12451 break;
12452 case OPC_PRECRQ_RS_PH_W:
12453 check_dsp(ctx);
12454 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12455 break;
12456 case OPC_PRECRQU_S_QB_PH:
12457 check_dsp(ctx);
12458 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12459 break;
12460 }
12461 break;
12462#ifdef TARGET_MIPS64
12463 case OPC_ABSQ_S_QH_DSP:
12464 switch (op2) {
12465 case OPC_PRECEQ_L_PWL:
12466 check_dsp(ctx);
12467 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12468 break;
12469 case OPC_PRECEQ_L_PWR:
12470 check_dsp(ctx);
12471 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12472 break;
12473 case OPC_PRECEQ_PW_QHL:
12474 check_dsp(ctx);
12475 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12476 break;
12477 case OPC_PRECEQ_PW_QHR:
12478 check_dsp(ctx);
12479 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12480 break;
12481 case OPC_PRECEQ_PW_QHLA:
12482 check_dsp(ctx);
12483 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12484 break;
12485 case OPC_PRECEQ_PW_QHRA:
12486 check_dsp(ctx);
12487 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12488 break;
12489 case OPC_PRECEQU_QH_OBL:
12490 check_dsp(ctx);
12491 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12492 break;
12493 case OPC_PRECEQU_QH_OBR:
12494 check_dsp(ctx);
12495 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12496 break;
12497 case OPC_PRECEQU_QH_OBLA:
12498 check_dsp(ctx);
12499 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12500 break;
12501 case OPC_PRECEQU_QH_OBRA:
12502 check_dsp(ctx);
12503 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12504 break;
12505 case OPC_PRECEU_QH_OBL:
12506 check_dsp(ctx);
12507 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12508 break;
12509 case OPC_PRECEU_QH_OBR:
12510 check_dsp(ctx);
12511 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12512 break;
12513 case OPC_PRECEU_QH_OBLA:
12514 check_dsp(ctx);
12515 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12516 break;
12517 case OPC_PRECEU_QH_OBRA:
12518 check_dsp(ctx);
12519 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12520 break;
12521 case OPC_ABSQ_S_OB:
12522 check_dsp_r2(ctx);
12523 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12524 break;
12525 case OPC_ABSQ_S_PW:
12526 check_dsp(ctx);
12527 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12528 break;
12529 case OPC_ABSQ_S_QH:
12530 check_dsp(ctx);
12531 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12532 break;
12533 }
12534 break;
12535 case OPC_ADDU_OB_DSP:
12536 switch (op2) {
12537 case OPC_RADDU_L_OB:
12538 check_dsp(ctx);
12539 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12540 break;
12541 case OPC_SUBQ_PW:
12542 check_dsp(ctx);
12543 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12544 break;
12545 case OPC_SUBQ_S_PW:
12546 check_dsp(ctx);
12547 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12548 break;
12549 case OPC_SUBQ_QH:
12550 check_dsp(ctx);
12551 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12552 break;
12553 case OPC_SUBQ_S_QH:
12554 check_dsp(ctx);
12555 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12556 break;
12557 case OPC_SUBU_OB:
12558 check_dsp(ctx);
12559 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12560 break;
12561 case OPC_SUBU_S_OB:
12562 check_dsp(ctx);
12563 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12564 break;
12565 case OPC_SUBU_QH:
12566 check_dsp_r2(ctx);
12567 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12568 break;
12569 case OPC_SUBU_S_QH:
12570 check_dsp_r2(ctx);
12571 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12572 break;
12573 case OPC_SUBUH_OB:
12574 check_dsp_r2(ctx);
12575 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12576 break;
12577 case OPC_SUBUH_R_OB:
12578 check_dsp_r2(ctx);
12579 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12580 break;
12581 case OPC_ADDQ_PW:
12582 check_dsp(ctx);
12583 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12584 break;
12585 case OPC_ADDQ_S_PW:
12586 check_dsp(ctx);
12587 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12588 break;
12589 case OPC_ADDQ_QH:
12590 check_dsp(ctx);
12591 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12592 break;
12593 case OPC_ADDQ_S_QH:
12594 check_dsp(ctx);
12595 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12596 break;
12597 case OPC_ADDU_OB:
12598 check_dsp(ctx);
12599 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12600 break;
12601 case OPC_ADDU_S_OB:
12602 check_dsp(ctx);
12603 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12604 break;
12605 case OPC_ADDU_QH:
12606 check_dsp_r2(ctx);
12607 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12608 break;
12609 case OPC_ADDU_S_QH:
12610 check_dsp_r2(ctx);
12611 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12612 break;
12613 case OPC_ADDUH_OB:
12614 check_dsp_r2(ctx);
12615 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12616 break;
12617 case OPC_ADDUH_R_OB:
12618 check_dsp_r2(ctx);
12619 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12620 break;
12621 }
12622 break;
12623 case OPC_CMPU_EQ_OB_DSP:
12624 switch (op2) {
12625 case OPC_PRECR_OB_QH:
12626 check_dsp_r2(ctx);
12627 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12628 break;
12629 case OPC_PRECR_SRA_QH_PW:
12630 check_dsp_r2(ctx);
12631 {
12632 TCGv_i32 ret_t = tcg_const_i32(ret);
12633 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12634 tcg_temp_free_i32(ret_t);
12635 break;
12636 }
12637 case OPC_PRECR_SRA_R_QH_PW:
12638 check_dsp_r2(ctx);
12639 {
12640 TCGv_i32 sa_v = tcg_const_i32(ret);
12641 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12642 tcg_temp_free_i32(sa_v);
12643 break;
12644 }
12645 case OPC_PRECRQ_OB_QH:
12646 check_dsp(ctx);
12647 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12648 break;
12649 case OPC_PRECRQ_PW_L:
12650 check_dsp(ctx);
12651 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12652 break;
12653 case OPC_PRECRQ_QH_PW:
12654 check_dsp(ctx);
12655 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12656 break;
12657 case OPC_PRECRQ_RS_QH_PW:
12658 check_dsp(ctx);
12659 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12660 break;
12661 case OPC_PRECRQU_S_OB_QH:
12662 check_dsp(ctx);
12663 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12664 break;
12665 }
12666 break;
12667#endif
12668 }
12669
12670 tcg_temp_free(v1_t);
12671 tcg_temp_free(v2_t);
12672}
12673
12674static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12675 int ret, int v1, int v2)
12676{
12677 uint32_t op2;
12678 TCGv t0;
12679 TCGv v1_t;
12680 TCGv v2_t;
12681
12682 if (ret == 0) {
12683
12684 return;
12685 }
12686
12687 t0 = tcg_temp_new();
12688 v1_t = tcg_temp_new();
12689 v2_t = tcg_temp_new();
12690
12691 tcg_gen_movi_tl(t0, v1);
12692 gen_load_gpr(v1_t, v1);
12693 gen_load_gpr(v2_t, v2);
12694
12695 switch (opc) {
12696 case OPC_SHLL_QB_DSP:
12697 {
12698 op2 = MASK_SHLL_QB(ctx->opcode);
12699 switch (op2) {
12700 case OPC_SHLL_QB:
12701 check_dsp(ctx);
12702 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12703 break;
12704 case OPC_SHLLV_QB:
12705 check_dsp(ctx);
12706 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12707 break;
12708 case OPC_SHLL_PH:
12709 check_dsp(ctx);
12710 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12711 break;
12712 case OPC_SHLLV_PH:
12713 check_dsp(ctx);
12714 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12715 break;
12716 case OPC_SHLL_S_PH:
12717 check_dsp(ctx);
12718 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12719 break;
12720 case OPC_SHLLV_S_PH:
12721 check_dsp(ctx);
12722 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12723 break;
12724 case OPC_SHLL_S_W:
12725 check_dsp(ctx);
12726 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12727 break;
12728 case OPC_SHLLV_S_W:
12729 check_dsp(ctx);
12730 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12731 break;
12732 case OPC_SHRL_QB:
12733 check_dsp(ctx);
12734 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12735 break;
12736 case OPC_SHRLV_QB:
12737 check_dsp(ctx);
12738 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12739 break;
12740 case OPC_SHRL_PH:
12741 check_dsp_r2(ctx);
12742 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12743 break;
12744 case OPC_SHRLV_PH:
12745 check_dsp_r2(ctx);
12746 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12747 break;
12748 case OPC_SHRA_QB:
12749 check_dsp_r2(ctx);
12750 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12751 break;
12752 case OPC_SHRA_R_QB:
12753 check_dsp_r2(ctx);
12754 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12755 break;
12756 case OPC_SHRAV_QB:
12757 check_dsp_r2(ctx);
12758 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12759 break;
12760 case OPC_SHRAV_R_QB:
12761 check_dsp_r2(ctx);
12762 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12763 break;
12764 case OPC_SHRA_PH:
12765 check_dsp(ctx);
12766 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12767 break;
12768 case OPC_SHRA_R_PH:
12769 check_dsp(ctx);
12770 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12771 break;
12772 case OPC_SHRAV_PH:
12773 check_dsp(ctx);
12774 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12775 break;
12776 case OPC_SHRAV_R_PH:
12777 check_dsp(ctx);
12778 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12779 break;
12780 case OPC_SHRA_R_W:
12781 check_dsp(ctx);
12782 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12783 break;
12784 case OPC_SHRAV_R_W:
12785 check_dsp(ctx);
12786 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12787 break;
12788 default:
12789 MIPS_INVAL("MASK SHLL.QB");
12790 gen_reserved_instruction(ctx);
12791 break;
12792 }
12793 break;
12794 }
12795#ifdef TARGET_MIPS64
12796 case OPC_SHLL_OB_DSP:
12797 op2 = MASK_SHLL_OB(ctx->opcode);
12798 switch (op2) {
12799 case OPC_SHLL_PW:
12800 check_dsp(ctx);
12801 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12802 break;
12803 case OPC_SHLLV_PW:
12804 check_dsp(ctx);
12805 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12806 break;
12807 case OPC_SHLL_S_PW:
12808 check_dsp(ctx);
12809 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12810 break;
12811 case OPC_SHLLV_S_PW:
12812 check_dsp(ctx);
12813 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12814 break;
12815 case OPC_SHLL_OB:
12816 check_dsp(ctx);
12817 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12818 break;
12819 case OPC_SHLLV_OB:
12820 check_dsp(ctx);
12821 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12822 break;
12823 case OPC_SHLL_QH:
12824 check_dsp(ctx);
12825 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12826 break;
12827 case OPC_SHLLV_QH:
12828 check_dsp(ctx);
12829 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12830 break;
12831 case OPC_SHLL_S_QH:
12832 check_dsp(ctx);
12833 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12834 break;
12835 case OPC_SHLLV_S_QH:
12836 check_dsp(ctx);
12837 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12838 break;
12839 case OPC_SHRA_OB:
12840 check_dsp_r2(ctx);
12841 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12842 break;
12843 case OPC_SHRAV_OB:
12844 check_dsp_r2(ctx);
12845 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12846 break;
12847 case OPC_SHRA_R_OB:
12848 check_dsp_r2(ctx);
12849 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12850 break;
12851 case OPC_SHRAV_R_OB:
12852 check_dsp_r2(ctx);
12853 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12854 break;
12855 case OPC_SHRA_PW:
12856 check_dsp(ctx);
12857 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12858 break;
12859 case OPC_SHRAV_PW:
12860 check_dsp(ctx);
12861 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12862 break;
12863 case OPC_SHRA_R_PW:
12864 check_dsp(ctx);
12865 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12866 break;
12867 case OPC_SHRAV_R_PW:
12868 check_dsp(ctx);
12869 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12870 break;
12871 case OPC_SHRA_QH:
12872 check_dsp(ctx);
12873 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12874 break;
12875 case OPC_SHRAV_QH:
12876 check_dsp(ctx);
12877 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12878 break;
12879 case OPC_SHRA_R_QH:
12880 check_dsp(ctx);
12881 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12882 break;
12883 case OPC_SHRAV_R_QH:
12884 check_dsp(ctx);
12885 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12886 break;
12887 case OPC_SHRL_OB:
12888 check_dsp(ctx);
12889 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12890 break;
12891 case OPC_SHRLV_OB:
12892 check_dsp(ctx);
12893 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12894 break;
12895 case OPC_SHRL_QH:
12896 check_dsp_r2(ctx);
12897 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12898 break;
12899 case OPC_SHRLV_QH:
12900 check_dsp_r2(ctx);
12901 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12902 break;
12903 default:
12904 MIPS_INVAL("MASK SHLL.OB");
12905 gen_reserved_instruction(ctx);
12906 break;
12907 }
12908 break;
12909#endif
12910 }
12911
12912 tcg_temp_free(t0);
12913 tcg_temp_free(v1_t);
12914 tcg_temp_free(v2_t);
12915}
12916
12917static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12918 int ret, int v1, int v2, int check_ret)
12919{
12920 TCGv_i32 t0;
12921 TCGv v1_t;
12922 TCGv v2_t;
12923
12924 if ((ret == 0) && (check_ret == 1)) {
12925
12926 return;
12927 }
12928
12929 t0 = tcg_temp_new_i32();
12930 v1_t = tcg_temp_new();
12931 v2_t = tcg_temp_new();
12932
12933 tcg_gen_movi_i32(t0, ret);
12934 gen_load_gpr(v1_t, v1);
12935 gen_load_gpr(v2_t, v2);
12936
12937 switch (op1) {
12938
12939
12940
12941
12942 case OPC_MULT_G_2E:
12943 check_dsp_r2(ctx);
12944 switch (op2) {
12945 case OPC_MUL_PH:
12946 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 break;
12948 case OPC_MUL_S_PH:
12949 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12950 break;
12951 case OPC_MULQ_S_W:
12952 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12953 break;
12954 case OPC_MULQ_RS_W:
12955 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12956 break;
12957 }
12958 break;
12959 case OPC_DPA_W_PH_DSP:
12960 switch (op2) {
12961 case OPC_DPAU_H_QBL:
12962 check_dsp(ctx);
12963 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12964 break;
12965 case OPC_DPAU_H_QBR:
12966 check_dsp(ctx);
12967 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12968 break;
12969 case OPC_DPSU_H_QBL:
12970 check_dsp(ctx);
12971 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12972 break;
12973 case OPC_DPSU_H_QBR:
12974 check_dsp(ctx);
12975 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12976 break;
12977 case OPC_DPA_W_PH:
12978 check_dsp_r2(ctx);
12979 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12980 break;
12981 case OPC_DPAX_W_PH:
12982 check_dsp_r2(ctx);
12983 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12984 break;
12985 case OPC_DPAQ_S_W_PH:
12986 check_dsp(ctx);
12987 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12988 break;
12989 case OPC_DPAQX_S_W_PH:
12990 check_dsp_r2(ctx);
12991 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12992 break;
12993 case OPC_DPAQX_SA_W_PH:
12994 check_dsp_r2(ctx);
12995 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12996 break;
12997 case OPC_DPS_W_PH:
12998 check_dsp_r2(ctx);
12999 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13000 break;
13001 case OPC_DPSX_W_PH:
13002 check_dsp_r2(ctx);
13003 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13004 break;
13005 case OPC_DPSQ_S_W_PH:
13006 check_dsp(ctx);
13007 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13008 break;
13009 case OPC_DPSQX_S_W_PH:
13010 check_dsp_r2(ctx);
13011 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13012 break;
13013 case OPC_DPSQX_SA_W_PH:
13014 check_dsp_r2(ctx);
13015 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13016 break;
13017 case OPC_MULSAQ_S_W_PH:
13018 check_dsp(ctx);
13019 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13020 break;
13021 case OPC_DPAQ_SA_L_W:
13022 check_dsp(ctx);
13023 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13024 break;
13025 case OPC_DPSQ_SA_L_W:
13026 check_dsp(ctx);
13027 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13028 break;
13029 case OPC_MAQ_S_W_PHL:
13030 check_dsp(ctx);
13031 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13032 break;
13033 case OPC_MAQ_S_W_PHR:
13034 check_dsp(ctx);
13035 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13036 break;
13037 case OPC_MAQ_SA_W_PHL:
13038 check_dsp(ctx);
13039 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13040 break;
13041 case OPC_MAQ_SA_W_PHR:
13042 check_dsp(ctx);
13043 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_MULSA_W_PH:
13046 check_dsp_r2(ctx);
13047 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13048 break;
13049 }
13050 break;
13051#ifdef TARGET_MIPS64
13052 case OPC_DPAQ_W_QH_DSP:
13053 {
13054 int ac = ret & 0x03;
13055 tcg_gen_movi_i32(t0, ac);
13056
13057 switch (op2) {
13058 case OPC_DMADD:
13059 check_dsp(ctx);
13060 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13061 break;
13062 case OPC_DMADDU:
13063 check_dsp(ctx);
13064 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13065 break;
13066 case OPC_DMSUB:
13067 check_dsp(ctx);
13068 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13069 break;
13070 case OPC_DMSUBU:
13071 check_dsp(ctx);
13072 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13073 break;
13074 case OPC_DPA_W_QH:
13075 check_dsp_r2(ctx);
13076 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13077 break;
13078 case OPC_DPAQ_S_W_QH:
13079 check_dsp(ctx);
13080 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13081 break;
13082 case OPC_DPAQ_SA_L_PW:
13083 check_dsp(ctx);
13084 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13085 break;
13086 case OPC_DPAU_H_OBL:
13087 check_dsp(ctx);
13088 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13089 break;
13090 case OPC_DPAU_H_OBR:
13091 check_dsp(ctx);
13092 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13093 break;
13094 case OPC_DPS_W_QH:
13095 check_dsp_r2(ctx);
13096 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13097 break;
13098 case OPC_DPSQ_S_W_QH:
13099 check_dsp(ctx);
13100 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13101 break;
13102 case OPC_DPSQ_SA_L_PW:
13103 check_dsp(ctx);
13104 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13105 break;
13106 case OPC_DPSU_H_OBL:
13107 check_dsp(ctx);
13108 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13109 break;
13110 case OPC_DPSU_H_OBR:
13111 check_dsp(ctx);
13112 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13113 break;
13114 case OPC_MAQ_S_L_PWL:
13115 check_dsp(ctx);
13116 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13117 break;
13118 case OPC_MAQ_S_L_PWR:
13119 check_dsp(ctx);
13120 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13121 break;
13122 case OPC_MAQ_S_W_QHLL:
13123 check_dsp(ctx);
13124 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13125 break;
13126 case OPC_MAQ_SA_W_QHLL:
13127 check_dsp(ctx);
13128 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13129 break;
13130 case OPC_MAQ_S_W_QHLR:
13131 check_dsp(ctx);
13132 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13133 break;
13134 case OPC_MAQ_SA_W_QHLR:
13135 check_dsp(ctx);
13136 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13137 break;
13138 case OPC_MAQ_S_W_QHRL:
13139 check_dsp(ctx);
13140 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13141 break;
13142 case OPC_MAQ_SA_W_QHRL:
13143 check_dsp(ctx);
13144 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13145 break;
13146 case OPC_MAQ_S_W_QHRR:
13147 check_dsp(ctx);
13148 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13149 break;
13150 case OPC_MAQ_SA_W_QHRR:
13151 check_dsp(ctx);
13152 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13153 break;
13154 case OPC_MULSAQ_S_L_PW:
13155 check_dsp(ctx);
13156 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13157 break;
13158 case OPC_MULSAQ_S_W_QH:
13159 check_dsp(ctx);
13160 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13161 break;
13162 }
13163 }
13164 break;
13165#endif
13166 case OPC_ADDU_QB_DSP:
13167 switch (op2) {
13168 case OPC_MULEU_S_PH_QBL:
13169 check_dsp(ctx);
13170 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13171 break;
13172 case OPC_MULEU_S_PH_QBR:
13173 check_dsp(ctx);
13174 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13175 break;
13176 case OPC_MULQ_RS_PH:
13177 check_dsp(ctx);
13178 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13179 break;
13180 case OPC_MULEQ_S_W_PHL:
13181 check_dsp(ctx);
13182 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13183 break;
13184 case OPC_MULEQ_S_W_PHR:
13185 check_dsp(ctx);
13186 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13187 break;
13188 case OPC_MULQ_S_PH:
13189 check_dsp_r2(ctx);
13190 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13191 break;
13192 }
13193 break;
13194#ifdef TARGET_MIPS64
13195 case OPC_ADDU_OB_DSP:
13196 switch (op2) {
13197 case OPC_MULEQ_S_PW_QHL:
13198 check_dsp(ctx);
13199 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13200 break;
13201 case OPC_MULEQ_S_PW_QHR:
13202 check_dsp(ctx);
13203 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13204 break;
13205 case OPC_MULEU_S_QH_OBL:
13206 check_dsp(ctx);
13207 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13208 break;
13209 case OPC_MULEU_S_QH_OBR:
13210 check_dsp(ctx);
13211 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212 break;
13213 case OPC_MULQ_RS_QH:
13214 check_dsp(ctx);
13215 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13216 break;
13217 }
13218 break;
13219#endif
13220 }
13221
13222 tcg_temp_free_i32(t0);
13223 tcg_temp_free(v1_t);
13224 tcg_temp_free(v2_t);
13225}
13226
13227static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13228 int ret, int val)
13229{
13230 int16_t imm;
13231 TCGv t0;
13232 TCGv val_t;
13233
13234 if (ret == 0) {
13235
13236 return;
13237 }
13238
13239 t0 = tcg_temp_new();
13240 val_t = tcg_temp_new();
13241 gen_load_gpr(val_t, val);
13242
13243 switch (op1) {
13244 case OPC_ABSQ_S_PH_DSP:
13245 switch (op2) {
13246 case OPC_BITREV:
13247 check_dsp(ctx);
13248 gen_helper_bitrev(cpu_gpr[ret], val_t);
13249 break;
13250 case OPC_REPL_QB:
13251 check_dsp(ctx);
13252 {
13253 target_long result;
13254 imm = (ctx->opcode >> 16) & 0xFF;
13255 result = (uint32_t)imm << 24 |
13256 (uint32_t)imm << 16 |
13257 (uint32_t)imm << 8 |
13258 (uint32_t)imm;
13259 result = (int32_t)result;
13260 tcg_gen_movi_tl(cpu_gpr[ret], result);
13261 }
13262 break;
13263 case OPC_REPLV_QB:
13264 check_dsp(ctx);
13265 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13266 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13267 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13268 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13269 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13270 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13271 break;
13272 case OPC_REPL_PH:
13273 check_dsp(ctx);
13274 {
13275 imm = (ctx->opcode >> 16) & 0x03FF;
13276 imm = (int16_t)(imm << 6) >> 6;
13277 tcg_gen_movi_tl(cpu_gpr[ret], \
13278 (target_long)((int32_t)imm << 16 | \
13279 (uint16_t)imm));
13280 }
13281 break;
13282 case OPC_REPLV_PH:
13283 check_dsp(ctx);
13284 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13285 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13286 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13287 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13288 break;
13289 }
13290 break;
13291#ifdef TARGET_MIPS64
13292 case OPC_ABSQ_S_QH_DSP:
13293 switch (op2) {
13294 case OPC_REPL_OB:
13295 check_dsp(ctx);
13296 {
13297 target_long temp;
13298
13299 imm = (ctx->opcode >> 16) & 0xFF;
13300 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13301 temp = (temp << 16) | temp;
13302 temp = (temp << 32) | temp;
13303 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13304 break;
13305 }
13306 case OPC_REPL_PW:
13307 check_dsp(ctx);
13308 {
13309 target_long temp;
13310
13311 imm = (ctx->opcode >> 16) & 0x03FF;
13312 imm = (int16_t)(imm << 6) >> 6;
13313 temp = ((target_long)imm << 32) \
13314 | ((target_long)imm & 0xFFFFFFFF);
13315 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13316 break;
13317 }
13318 case OPC_REPL_QH:
13319 check_dsp(ctx);
13320 {
13321 target_long temp;
13322
13323 imm = (ctx->opcode >> 16) & 0x03FF;
13324 imm = (int16_t)(imm << 6) >> 6;
13325
13326 temp = ((uint64_t)(uint16_t)imm << 48) |
13327 ((uint64_t)(uint16_t)imm << 32) |
13328 ((uint64_t)(uint16_t)imm << 16) |
13329 (uint64_t)(uint16_t)imm;
13330 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13331 break;
13332 }
13333 case OPC_REPLV_OB:
13334 check_dsp(ctx);
13335 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13336 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13337 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13338 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13339 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13340 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13341 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13342 break;
13343 case OPC_REPLV_PW:
13344 check_dsp(ctx);
13345 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13346 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13347 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13348 break;
13349 case OPC_REPLV_QH:
13350 check_dsp(ctx);
13351 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13352 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13353 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13354 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13355 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13356 break;
13357 }
13358 break;
13359#endif
13360 }
13361 tcg_temp_free(t0);
13362 tcg_temp_free(val_t);
13363}
13364
13365static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13366 uint32_t op1, uint32_t op2,
13367 int ret, int v1, int v2, int check_ret)
13368{
13369 TCGv t1;
13370 TCGv v1_t;
13371 TCGv v2_t;
13372
13373 if ((ret == 0) && (check_ret == 1)) {
13374
13375 return;
13376 }
13377
13378 t1 = tcg_temp_new();
13379 v1_t = tcg_temp_new();
13380 v2_t = tcg_temp_new();
13381
13382 gen_load_gpr(v1_t, v1);
13383 gen_load_gpr(v2_t, v2);
13384
13385 switch (op1) {
13386 case OPC_CMPU_EQ_QB_DSP:
13387 switch (op2) {
13388 case OPC_CMPU_EQ_QB:
13389 check_dsp(ctx);
13390 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13391 break;
13392 case OPC_CMPU_LT_QB:
13393 check_dsp(ctx);
13394 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13395 break;
13396 case OPC_CMPU_LE_QB:
13397 check_dsp(ctx);
13398 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13399 break;
13400 case OPC_CMPGU_EQ_QB:
13401 check_dsp(ctx);
13402 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13403 break;
13404 case OPC_CMPGU_LT_QB:
13405 check_dsp(ctx);
13406 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13407 break;
13408 case OPC_CMPGU_LE_QB:
13409 check_dsp(ctx);
13410 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13411 break;
13412 case OPC_CMPGDU_EQ_QB:
13413 check_dsp_r2(ctx);
13414 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13415 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13416 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13417 tcg_gen_shli_tl(t1, t1, 24);
13418 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13419 break;
13420 case OPC_CMPGDU_LT_QB:
13421 check_dsp_r2(ctx);
13422 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13423 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13424 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13425 tcg_gen_shli_tl(t1, t1, 24);
13426 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13427 break;
13428 case OPC_CMPGDU_LE_QB:
13429 check_dsp_r2(ctx);
13430 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13431 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13432 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13433 tcg_gen_shli_tl(t1, t1, 24);
13434 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13435 break;
13436 case OPC_CMP_EQ_PH:
13437 check_dsp(ctx);
13438 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13439 break;
13440 case OPC_CMP_LT_PH:
13441 check_dsp(ctx);
13442 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13443 break;
13444 case OPC_CMP_LE_PH:
13445 check_dsp(ctx);
13446 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13447 break;
13448 case OPC_PICK_QB:
13449 check_dsp(ctx);
13450 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13451 break;
13452 case OPC_PICK_PH:
13453 check_dsp(ctx);
13454 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13455 break;
13456 case OPC_PACKRL_PH:
13457 check_dsp(ctx);
13458 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13459 break;
13460 }
13461 break;
13462#ifdef TARGET_MIPS64
13463 case OPC_CMPU_EQ_OB_DSP:
13464 switch (op2) {
13465 case OPC_CMP_EQ_PW:
13466 check_dsp(ctx);
13467 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_CMP_LT_PW:
13470 check_dsp(ctx);
13471 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_CMP_LE_PW:
13474 check_dsp(ctx);
13475 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_CMP_EQ_QH:
13478 check_dsp(ctx);
13479 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_CMP_LT_QH:
13482 check_dsp(ctx);
13483 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_CMP_LE_QH:
13486 check_dsp(ctx);
13487 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_CMPGDU_EQ_OB:
13490 check_dsp_r2(ctx);
13491 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_CMPGDU_LT_OB:
13494 check_dsp_r2(ctx);
13495 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_CMPGDU_LE_OB:
13498 check_dsp_r2(ctx);
13499 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_CMPGU_EQ_OB:
13502 check_dsp(ctx);
13503 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13504 break;
13505 case OPC_CMPGU_LT_OB:
13506 check_dsp(ctx);
13507 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13508 break;
13509 case OPC_CMPGU_LE_OB:
13510 check_dsp(ctx);
13511 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13512 break;
13513 case OPC_CMPU_EQ_OB:
13514 check_dsp(ctx);
13515 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13516 break;
13517 case OPC_CMPU_LT_OB:
13518 check_dsp(ctx);
13519 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13520 break;
13521 case OPC_CMPU_LE_OB:
13522 check_dsp(ctx);
13523 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13524 break;
13525 case OPC_PACKRL_PW:
13526 check_dsp(ctx);
13527 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13528 break;
13529 case OPC_PICK_OB:
13530 check_dsp(ctx);
13531 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13532 break;
13533 case OPC_PICK_PW:
13534 check_dsp(ctx);
13535 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13536 break;
13537 case OPC_PICK_QH:
13538 check_dsp(ctx);
13539 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13540 break;
13541 }
13542 break;
13543#endif
13544 }
13545
13546 tcg_temp_free(t1);
13547 tcg_temp_free(v1_t);
13548 tcg_temp_free(v2_t);
13549}
13550
13551static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13552 uint32_t op1, int rt, int rs, int sa)
13553{
13554 TCGv t0;
13555
13556 check_dsp_r2(ctx);
13557
13558 if (rt == 0) {
13559
13560 return;
13561 }
13562
13563 t0 = tcg_temp_new();
13564 gen_load_gpr(t0, rs);
13565
13566 switch (op1) {
13567 case OPC_APPEND_DSP:
13568 switch (MASK_APPEND(ctx->opcode)) {
13569 case OPC_APPEND:
13570 if (sa != 0) {
13571 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13572 }
13573 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13574 break;
13575 case OPC_PREPEND:
13576 if (sa != 0) {
13577 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13578 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13579 tcg_gen_shli_tl(t0, t0, 32 - sa);
13580 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13581 }
13582 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13583 break;
13584 case OPC_BALIGN:
13585 sa &= 3;
13586 if (sa != 0 && sa != 2) {
13587 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13588 tcg_gen_ext32u_tl(t0, t0);
13589 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13590 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13591 }
13592 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13593 break;
13594 default:
13595 MIPS_INVAL("MASK APPEND");
13596 gen_reserved_instruction(ctx);
13597 break;
13598 }
13599 break;
13600#ifdef TARGET_MIPS64
13601 case OPC_DAPPEND_DSP:
13602 switch (MASK_DAPPEND(ctx->opcode)) {
13603 case OPC_DAPPEND:
13604 if (sa != 0) {
13605 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13606 }
13607 break;
13608 case OPC_PREPENDD:
13609 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13610 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13611 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13612 break;
13613 case OPC_PREPENDW:
13614 if (sa != 0) {
13615 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13616 tcg_gen_shli_tl(t0, t0, 64 - sa);
13617 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13618 }
13619 break;
13620 case OPC_DBALIGN:
13621 sa &= 7;
13622 if (sa != 0 && sa != 2 && sa != 4) {
13623 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13624 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13625 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13626 }
13627 break;
13628 default:
13629 MIPS_INVAL("MASK DAPPEND");
13630 gen_reserved_instruction(ctx);
13631 break;
13632 }
13633 break;
13634#endif
13635 }
13636 tcg_temp_free(t0);
13637}
13638
13639static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13640 int ret, int v1, int v2, int check_ret)
13641
13642{
13643 TCGv t0;
13644 TCGv t1;
13645 TCGv v1_t;
13646 int16_t imm;
13647
13648 if ((ret == 0) && (check_ret == 1)) {
13649
13650 return;
13651 }
13652
13653 t0 = tcg_temp_new();
13654 t1 = tcg_temp_new();
13655 v1_t = tcg_temp_new();
13656
13657 gen_load_gpr(v1_t, v1);
13658
13659 switch (op1) {
13660 case OPC_EXTR_W_DSP:
13661 check_dsp(ctx);
13662 switch (op2) {
13663 case OPC_EXTR_W:
13664 tcg_gen_movi_tl(t0, v2);
13665 tcg_gen_movi_tl(t1, v1);
13666 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13667 break;
13668 case OPC_EXTR_R_W:
13669 tcg_gen_movi_tl(t0, v2);
13670 tcg_gen_movi_tl(t1, v1);
13671 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13672 break;
13673 case OPC_EXTR_RS_W:
13674 tcg_gen_movi_tl(t0, v2);
13675 tcg_gen_movi_tl(t1, v1);
13676 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13677 break;
13678 case OPC_EXTR_S_H:
13679 tcg_gen_movi_tl(t0, v2);
13680 tcg_gen_movi_tl(t1, v1);
13681 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13682 break;
13683 case OPC_EXTRV_S_H:
13684 tcg_gen_movi_tl(t0, v2);
13685 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13686 break;
13687 case OPC_EXTRV_W:
13688 tcg_gen_movi_tl(t0, v2);
13689 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13690 break;
13691 case OPC_EXTRV_R_W:
13692 tcg_gen_movi_tl(t0, v2);
13693 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13694 break;
13695 case OPC_EXTRV_RS_W:
13696 tcg_gen_movi_tl(t0, v2);
13697 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13698 break;
13699 case OPC_EXTP:
13700 tcg_gen_movi_tl(t0, v2);
13701 tcg_gen_movi_tl(t1, v1);
13702 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13703 break;
13704 case OPC_EXTPV:
13705 tcg_gen_movi_tl(t0, v2);
13706 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13707 break;
13708 case OPC_EXTPDP:
13709 tcg_gen_movi_tl(t0, v2);
13710 tcg_gen_movi_tl(t1, v1);
13711 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13712 break;
13713 case OPC_EXTPDPV:
13714 tcg_gen_movi_tl(t0, v2);
13715 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13716 break;
13717 case OPC_SHILO:
13718 imm = (ctx->opcode >> 20) & 0x3F;
13719 tcg_gen_movi_tl(t0, ret);
13720 tcg_gen_movi_tl(t1, imm);
13721 gen_helper_shilo(t0, t1, cpu_env);
13722 break;
13723 case OPC_SHILOV:
13724 tcg_gen_movi_tl(t0, ret);
13725 gen_helper_shilo(t0, v1_t, cpu_env);
13726 break;
13727 case OPC_MTHLIP:
13728 tcg_gen_movi_tl(t0, ret);
13729 gen_helper_mthlip(t0, v1_t, cpu_env);
13730 break;
13731 case OPC_WRDSP:
13732 imm = (ctx->opcode >> 11) & 0x3FF;
13733 tcg_gen_movi_tl(t0, imm);
13734 gen_helper_wrdsp(v1_t, t0, cpu_env);
13735 break;
13736 case OPC_RDDSP:
13737 imm = (ctx->opcode >> 16) & 0x03FF;
13738 tcg_gen_movi_tl(t0, imm);
13739 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13740 break;
13741 }
13742 break;
13743#ifdef TARGET_MIPS64
13744 case OPC_DEXTR_W_DSP:
13745 check_dsp(ctx);
13746 switch (op2) {
13747 case OPC_DMTHLIP:
13748 tcg_gen_movi_tl(t0, ret);
13749 gen_helper_dmthlip(v1_t, t0, cpu_env);
13750 break;
13751 case OPC_DSHILO:
13752 {
13753 int shift = (ctx->opcode >> 19) & 0x7F;
13754 int ac = (ctx->opcode >> 11) & 0x03;
13755 tcg_gen_movi_tl(t0, shift);
13756 tcg_gen_movi_tl(t1, ac);
13757 gen_helper_dshilo(t0, t1, cpu_env);
13758 break;
13759 }
13760 case OPC_DSHILOV:
13761 {
13762 int ac = (ctx->opcode >> 11) & 0x03;
13763 tcg_gen_movi_tl(t0, ac);
13764 gen_helper_dshilo(v1_t, t0, cpu_env);
13765 break;
13766 }
13767 case OPC_DEXTP:
13768 tcg_gen_movi_tl(t0, v2);
13769 tcg_gen_movi_tl(t1, v1);
13770
13771 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13772 break;
13773 case OPC_DEXTPV:
13774 tcg_gen_movi_tl(t0, v2);
13775 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13776 break;
13777 case OPC_DEXTPDP:
13778 tcg_gen_movi_tl(t0, v2);
13779 tcg_gen_movi_tl(t1, v1);
13780 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13781 break;
13782 case OPC_DEXTPDPV:
13783 tcg_gen_movi_tl(t0, v2);
13784 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13785 break;
13786 case OPC_DEXTR_L:
13787 tcg_gen_movi_tl(t0, v2);
13788 tcg_gen_movi_tl(t1, v1);
13789 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13790 break;
13791 case OPC_DEXTR_R_L:
13792 tcg_gen_movi_tl(t0, v2);
13793 tcg_gen_movi_tl(t1, v1);
13794 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13795 break;
13796 case OPC_DEXTR_RS_L:
13797 tcg_gen_movi_tl(t0, v2);
13798 tcg_gen_movi_tl(t1, v1);
13799 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13800 break;
13801 case OPC_DEXTR_W:
13802 tcg_gen_movi_tl(t0, v2);
13803 tcg_gen_movi_tl(t1, v1);
13804 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13805 break;
13806 case OPC_DEXTR_R_W:
13807 tcg_gen_movi_tl(t0, v2);
13808 tcg_gen_movi_tl(t1, v1);
13809 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13810 break;
13811 case OPC_DEXTR_RS_W:
13812 tcg_gen_movi_tl(t0, v2);
13813 tcg_gen_movi_tl(t1, v1);
13814 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13815 break;
13816 case OPC_DEXTR_S_H:
13817 tcg_gen_movi_tl(t0, v2);
13818 tcg_gen_movi_tl(t1, v1);
13819 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13820 break;
13821 case OPC_DEXTRV_S_H:
13822 tcg_gen_movi_tl(t0, v2);
13823 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13824 break;
13825 case OPC_DEXTRV_L:
13826 tcg_gen_movi_tl(t0, v2);
13827 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13828 break;
13829 case OPC_DEXTRV_R_L:
13830 tcg_gen_movi_tl(t0, v2);
13831 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13832 break;
13833 case OPC_DEXTRV_RS_L:
13834 tcg_gen_movi_tl(t0, v2);
13835 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13836 break;
13837 case OPC_DEXTRV_W:
13838 tcg_gen_movi_tl(t0, v2);
13839 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13840 break;
13841 case OPC_DEXTRV_R_W:
13842 tcg_gen_movi_tl(t0, v2);
13843 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13844 break;
13845 case OPC_DEXTRV_RS_W:
13846 tcg_gen_movi_tl(t0, v2);
13847 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13848 break;
13849 }
13850 break;
13851#endif
13852 }
13853
13854 tcg_temp_free(t0);
13855 tcg_temp_free(t1);
13856 tcg_temp_free(v1_t);
13857}
13858
13859
13860
13861static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13862{
13863 int rs, rt, rd, sa;
13864 uint32_t op1, op2;
13865
13866 rs = (ctx->opcode >> 21) & 0x1f;
13867 rt = (ctx->opcode >> 16) & 0x1f;
13868 rd = (ctx->opcode >> 11) & 0x1f;
13869 sa = (ctx->opcode >> 6) & 0x1f;
13870
13871 op1 = MASK_SPECIAL(ctx->opcode);
13872 switch (op1) {
13873 case OPC_MULT:
13874 case OPC_MULTU:
13875 case OPC_DIV:
13876 case OPC_DIVU:
13877 op2 = MASK_R6_MULDIV(ctx->opcode);
13878 switch (op2) {
13879 case R6_OPC_MUL:
13880 case R6_OPC_MUH:
13881 case R6_OPC_MULU:
13882 case R6_OPC_MUHU:
13883 case R6_OPC_DIV:
13884 case R6_OPC_MOD:
13885 case R6_OPC_DIVU:
13886 case R6_OPC_MODU:
13887 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13888 break;
13889 default:
13890 MIPS_INVAL("special_r6 muldiv");
13891 gen_reserved_instruction(ctx);
13892 break;
13893 }
13894 break;
13895 case OPC_SELEQZ:
13896 case OPC_SELNEZ:
13897 gen_cond_move(ctx, op1, rd, rs, rt);
13898 break;
13899 case R6_OPC_CLO:
13900 case R6_OPC_CLZ:
13901 if (rt == 0 && sa == 1) {
13902
13903
13904
13905
13906 gen_cl(ctx, op1, rd, rs);
13907 } else {
13908 gen_reserved_instruction(ctx);
13909 }
13910 break;
13911 case R6_OPC_SDBBP:
13912 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
13913 gen_helper_do_semihosting(cpu_env);
13914 } else {
13915 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13916 gen_reserved_instruction(ctx);
13917 } else {
13918 generate_exception_end(ctx, EXCP_DBp);
13919 }
13920 }
13921 break;
13922#if defined(TARGET_MIPS64)
13923 case R6_OPC_DCLO:
13924 case R6_OPC_DCLZ:
13925 if (rt == 0 && sa == 1) {
13926
13927
13928
13929
13930 check_mips_64(ctx);
13931 gen_cl(ctx, op1, rd, rs);
13932 } else {
13933 gen_reserved_instruction(ctx);
13934 }
13935 break;
13936 case OPC_DMULT:
13937 case OPC_DMULTU:
13938 case OPC_DDIV:
13939 case OPC_DDIVU:
13940
13941 op2 = MASK_R6_MULDIV(ctx->opcode);
13942 switch (op2) {
13943 case R6_OPC_DMUL:
13944 case R6_OPC_DMUH:
13945 case R6_OPC_DMULU:
13946 case R6_OPC_DMUHU:
13947 case R6_OPC_DDIV:
13948 case R6_OPC_DMOD:
13949 case R6_OPC_DDIVU:
13950 case R6_OPC_DMODU:
13951 check_mips_64(ctx);
13952 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13953 break;
13954 default:
13955 MIPS_INVAL("special_r6 muldiv");
13956 gen_reserved_instruction(ctx);
13957 break;
13958 }
13959 break;
13960#endif
13961 default:
13962 MIPS_INVAL("special_r6");
13963 gen_reserved_instruction(ctx);
13964 break;
13965 }
13966}
13967
13968static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13969{
13970 int rs = extract32(ctx->opcode, 21, 5);
13971 int rt = extract32(ctx->opcode, 16, 5);
13972 int rd = extract32(ctx->opcode, 11, 5);
13973 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13974
13975 switch (op1) {
13976 case OPC_MOVN:
13977 case OPC_MOVZ:
13978 gen_cond_move(ctx, op1, rd, rs, rt);
13979 break;
13980 case OPC_MFHI:
13981 case OPC_MFLO:
13982 gen_HILO(ctx, op1, 0, rd);
13983 break;
13984 case OPC_MTHI:
13985 case OPC_MTLO:
13986 gen_HILO(ctx, op1, 0, rs);
13987 break;
13988 case OPC_MULT:
13989 case OPC_MULTU:
13990 gen_mul_txx9(ctx, op1, rd, rs, rt);
13991 break;
13992 case OPC_DIV:
13993 case OPC_DIVU:
13994 gen_muldiv(ctx, op1, 0, rs, rt);
13995 break;
13996#if defined(TARGET_MIPS64)
13997 case OPC_DMULT:
13998 case OPC_DMULTU:
13999 case OPC_DDIV:
14000 case OPC_DDIVU:
14001 check_insn_opc_user_only(ctx, INSN_R5900);
14002 gen_muldiv(ctx, op1, 0, rs, rt);
14003 break;
14004#endif
14005 case OPC_JR:
14006 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14007 break;
14008 default:
14009 MIPS_INVAL("special_tx79");
14010 gen_reserved_instruction(ctx);
14011 break;
14012 }
14013}
14014
14015static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14016{
14017 int rs, rt, rd;
14018 uint32_t op1;
14019
14020 rs = (ctx->opcode >> 21) & 0x1f;
14021 rt = (ctx->opcode >> 16) & 0x1f;
14022 rd = (ctx->opcode >> 11) & 0x1f;
14023
14024 op1 = MASK_SPECIAL(ctx->opcode);
14025 switch (op1) {
14026 case OPC_MOVN:
14027 case OPC_MOVZ:
14028 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
14029 INSN_LOONGSON2E | INSN_LOONGSON2F);
14030 gen_cond_move(ctx, op1, rd, rs, rt);
14031 break;
14032 case OPC_MFHI:
14033 case OPC_MFLO:
14034 gen_HILO(ctx, op1, rs & 3, rd);
14035 break;
14036 case OPC_MTHI:
14037 case OPC_MTLO:
14038 gen_HILO(ctx, op1, rd & 3, rs);
14039 break;
14040 case OPC_MOVCI:
14041 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
14042 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14043 check_cp1_enabled(ctx);
14044 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14045 (ctx->opcode >> 16) & 1);
14046 } else {
14047 generate_exception_err(ctx, EXCP_CpU, 1);
14048 }
14049 break;
14050 case OPC_MULT:
14051 case OPC_MULTU:
14052 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14053 break;
14054 case OPC_DIV:
14055 case OPC_DIVU:
14056 gen_muldiv(ctx, op1, 0, rs, rt);
14057 break;
14058#if defined(TARGET_MIPS64)
14059 case OPC_DMULT:
14060 case OPC_DMULTU:
14061 case OPC_DDIV:
14062 case OPC_DDIVU:
14063 check_insn(ctx, ISA_MIPS3);
14064 check_mips_64(ctx);
14065 gen_muldiv(ctx, op1, 0, rs, rt);
14066 break;
14067#endif
14068 case OPC_JR:
14069 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14070 break;
14071 case OPC_SPIM:
14072#ifdef MIPS_STRICT_STANDARD
14073 MIPS_INVAL("SPIM");
14074 gen_reserved_instruction(ctx);
14075#else
14076
14077 MIPS_INVAL("spim (unofficial)");
14078 gen_reserved_instruction(ctx);
14079#endif
14080 break;
14081 default:
14082 MIPS_INVAL("special_legacy");
14083 gen_reserved_instruction(ctx);
14084 break;
14085 }
14086}
14087
14088static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
14089{
14090 int rs, rt, rd, sa;
14091 uint32_t op1;
14092
14093 rs = (ctx->opcode >> 21) & 0x1f;
14094 rt = (ctx->opcode >> 16) & 0x1f;
14095 rd = (ctx->opcode >> 11) & 0x1f;
14096 sa = (ctx->opcode >> 6) & 0x1f;
14097
14098 op1 = MASK_SPECIAL(ctx->opcode);
14099 switch (op1) {
14100 case OPC_SLL:
14101 if (sa == 5 && rd == 0 &&
14102 rs == 0 && rt == 0) {
14103 if ((ctx->insn_flags & ISA_MIPS_R6) &&
14104 (ctx->hflags & MIPS_HFLAG_BMASK)) {
14105 gen_reserved_instruction(ctx);
14106 break;
14107 }
14108 }
14109
14110 case OPC_SRA:
14111 gen_shift_imm(ctx, op1, rd, rt, sa);
14112 break;
14113 case OPC_SRL:
14114 switch ((ctx->opcode >> 21) & 0x1f) {
14115 case 1:
14116
14117 if (ctx->insn_flags & ISA_MIPS_R2) {
14118 op1 = OPC_ROTR;
14119 }
14120
14121 case 0:
14122 gen_shift_imm(ctx, op1, rd, rt, sa);
14123 break;
14124 default:
14125 gen_reserved_instruction(ctx);
14126 break;
14127 }
14128 break;
14129 case OPC_ADD:
14130 case OPC_ADDU:
14131 case OPC_SUB:
14132 case OPC_SUBU:
14133 gen_arith(ctx, op1, rd, rs, rt);
14134 break;
14135 case OPC_SLLV:
14136 case OPC_SRAV:
14137 gen_shift(ctx, op1, rd, rs, rt);
14138 break;
14139 case OPC_SRLV:
14140 switch ((ctx->opcode >> 6) & 0x1f) {
14141 case 1:
14142
14143 if (ctx->insn_flags & ISA_MIPS_R2) {
14144 op1 = OPC_ROTRV;
14145 }
14146
14147 case 0:
14148 gen_shift(ctx, op1, rd, rs, rt);
14149 break;
14150 default:
14151 gen_reserved_instruction(ctx);
14152 break;
14153 }
14154 break;
14155 case OPC_SLT:
14156 case OPC_SLTU:
14157 gen_slt(ctx, op1, rd, rs, rt);
14158 break;
14159 case OPC_AND:
14160 case OPC_OR:
14161 case OPC_NOR:
14162 case OPC_XOR:
14163 gen_logic(ctx, op1, rd, rs, rt);
14164 break;
14165 case OPC_JALR:
14166 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14167 break;
14168 case OPC_TGE:
14169 case OPC_TGEU:
14170 case OPC_TLT:
14171 case OPC_TLTU:
14172 case OPC_TEQ:
14173 case OPC_TNE:
14174 check_insn(ctx, ISA_MIPS2);
14175 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
14176 break;
14177 case OPC_PMON:
14178
14179#ifdef MIPS_STRICT_STANDARD
14180 MIPS_INVAL("PMON / selsl");
14181 gen_reserved_instruction(ctx);
14182#else
14183 gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
14184#endif
14185 break;
14186 case OPC_SYSCALL:
14187 generate_exception_end(ctx, EXCP_SYSCALL);
14188 break;
14189 case OPC_BREAK:
14190 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
14191 break;
14192 case OPC_SYNC:
14193 check_insn(ctx, ISA_MIPS2);
14194 gen_sync(extract32(ctx->opcode, 6, 5));
14195 break;
14196
14197#if defined(TARGET_MIPS64)
14198
14199 case OPC_DSLL:
14200 case OPC_DSRA:
14201 case OPC_DSLL32:
14202 case OPC_DSRA32:
14203 check_insn(ctx, ISA_MIPS3);
14204 check_mips_64(ctx);
14205 gen_shift_imm(ctx, op1, rd, rt, sa);
14206 break;
14207 case OPC_DSRL:
14208 switch ((ctx->opcode >> 21) & 0x1f) {
14209 case 1:
14210
14211 if (ctx->insn_flags & ISA_MIPS_R2) {
14212 op1 = OPC_DROTR;
14213 }
14214
14215 case 0:
14216 check_insn(ctx, ISA_MIPS3);
14217 check_mips_64(ctx);
14218 gen_shift_imm(ctx, op1, rd, rt, sa);
14219 break;
14220 default:
14221 gen_reserved_instruction(ctx);
14222 break;
14223 }
14224 break;
14225 case OPC_DSRL32:
14226 switch ((ctx->opcode >> 21) & 0x1f) {
14227 case 1:
14228
14229 if (ctx->insn_flags & ISA_MIPS_R2) {
14230 op1 = OPC_DROTR32;
14231 }
14232
14233 case 0:
14234 check_insn(ctx, ISA_MIPS3);
14235 check_mips_64(ctx);
14236 gen_shift_imm(ctx, op1, rd, rt, sa);
14237 break;
14238 default:
14239 gen_reserved_instruction(ctx);
14240 break;
14241 }
14242 break;
14243 case OPC_DADD:
14244 case OPC_DADDU:
14245 case OPC_DSUB:
14246 case OPC_DSUBU:
14247 check_insn(ctx, ISA_MIPS3);
14248 check_mips_64(ctx);
14249 gen_arith(ctx, op1, rd, rs, rt);
14250 break;
14251 case OPC_DSLLV:
14252 case OPC_DSRAV:
14253 check_insn(ctx, ISA_MIPS3);
14254 check_mips_64(ctx);
14255 gen_shift(ctx, op1, rd, rs, rt);
14256 break;
14257 case OPC_DSRLV:
14258 switch ((ctx->opcode >> 6) & 0x1f) {
14259 case 1:
14260
14261 if (ctx->insn_flags & ISA_MIPS_R2) {
14262 op1 = OPC_DROTRV;
14263 }
14264
14265 case 0:
14266 check_insn(ctx, ISA_MIPS3);
14267 check_mips_64(ctx);
14268 gen_shift(ctx, op1, rd, rs, rt);
14269 break;
14270 default:
14271 gen_reserved_instruction(ctx);
14272 break;
14273 }
14274 break;
14275#endif
14276 default:
14277 if (ctx->insn_flags & ISA_MIPS_R6) {
14278 decode_opc_special_r6(env, ctx);
14279 } else if (ctx->insn_flags & INSN_R5900) {
14280 decode_opc_special_tx79(env, ctx);
14281 } else {
14282 decode_opc_special_legacy(env, ctx);
14283 }
14284 }
14285}
14286
14287
14288static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
14289{
14290 int rs, rt, rd;
14291 uint32_t op1;
14292
14293 rs = (ctx->opcode >> 21) & 0x1f;
14294 rt = (ctx->opcode >> 16) & 0x1f;
14295 rd = (ctx->opcode >> 11) & 0x1f;
14296
14297 op1 = MASK_SPECIAL2(ctx->opcode);
14298 switch (op1) {
14299 case OPC_MADD:
14300 case OPC_MADDU:
14301 case OPC_MSUB:
14302 case OPC_MSUBU:
14303 check_insn(ctx, ISA_MIPS_R1);
14304 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14305 break;
14306 case OPC_MUL:
14307 gen_arith(ctx, op1, rd, rs, rt);
14308 break;
14309 case OPC_DIV_G_2F:
14310 case OPC_DIVU_G_2F:
14311 case OPC_MULT_G_2F:
14312 case OPC_MULTU_G_2F:
14313 case OPC_MOD_G_2F:
14314 case OPC_MODU_G_2F:
14315 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14316 gen_loongson_integer(ctx, op1, rd, rs, rt);
14317 break;
14318 case OPC_CLO:
14319 case OPC_CLZ:
14320 check_insn(ctx, ISA_MIPS_R1);
14321 gen_cl(ctx, op1, rd, rs);
14322 break;
14323 case OPC_SDBBP:
14324 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14325 gen_helper_do_semihosting(cpu_env);
14326 } else {
14327
14328
14329
14330
14331 check_insn(ctx, ISA_MIPS_R1);
14332 generate_exception_end(ctx, EXCP_DBp);
14333 }
14334 break;
14335#if defined(TARGET_MIPS64)
14336 case OPC_DCLO:
14337 case OPC_DCLZ:
14338 check_insn(ctx, ISA_MIPS_R1);
14339 check_mips_64(ctx);
14340 gen_cl(ctx, op1, rd, rs);
14341 break;
14342 case OPC_DMULT_G_2F:
14343 case OPC_DMULTU_G_2F:
14344 case OPC_DDIV_G_2F:
14345 case OPC_DDIVU_G_2F:
14346 case OPC_DMOD_G_2F:
14347 case OPC_DMODU_G_2F:
14348 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14349 gen_loongson_integer(ctx, op1, rd, rs, rt);
14350 break;
14351#endif
14352 default:
14353 MIPS_INVAL("special2_legacy");
14354 gen_reserved_instruction(ctx);
14355 break;
14356 }
14357}
14358
14359static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14360{
14361 int rs, rt, rd, sa;
14362 uint32_t op1, op2;
14363 int16_t imm;
14364
14365 rs = (ctx->opcode >> 21) & 0x1f;
14366 rt = (ctx->opcode >> 16) & 0x1f;
14367 rd = (ctx->opcode >> 11) & 0x1f;
14368 sa = (ctx->opcode >> 6) & 0x1f;
14369 imm = (int16_t)ctx->opcode >> 7;
14370
14371 op1 = MASK_SPECIAL3(ctx->opcode);
14372 switch (op1) {
14373 case R6_OPC_PREF:
14374 if (rt >= 24) {
14375
14376 gen_reserved_instruction(ctx);
14377 }
14378
14379 break;
14380 case R6_OPC_CACHE:
14381 check_cp0_enabled(ctx);
14382 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14383 gen_cache_operation(ctx, rt, rs, imm);
14384 }
14385 break;
14386 case R6_OPC_SC:
14387 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14388 break;
14389 case R6_OPC_LL:
14390 gen_ld(ctx, op1, rt, rs, imm);
14391 break;
14392 case OPC_BSHFL:
14393 {
14394 if (rd == 0) {
14395
14396 break;
14397 }
14398 op2 = MASK_BSHFL(ctx->opcode);
14399 switch (op2) {
14400 case OPC_ALIGN:
14401 case OPC_ALIGN_1:
14402 case OPC_ALIGN_2:
14403 case OPC_ALIGN_3:
14404 gen_align(ctx, 32, rd, rs, rt, sa & 3);
14405 break;
14406 case OPC_BITSWAP:
14407 gen_bitswap(ctx, op2, rd, rt);
14408 break;
14409 }
14410 }
14411 break;
14412#ifndef CONFIG_USER_ONLY
14413 case OPC_GINV:
14414 if (unlikely(ctx->gi <= 1)) {
14415 gen_reserved_instruction(ctx);
14416 }
14417 check_cp0_enabled(ctx);
14418 switch ((ctx->opcode >> 6) & 3) {
14419 case 0:
14420
14421 break;
14422 case 2:
14423 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14424 break;
14425 default:
14426 gen_reserved_instruction(ctx);
14427 break;
14428 }
14429 break;
14430#endif
14431#if defined(TARGET_MIPS64)
14432 case R6_OPC_SCD:
14433 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
14434 break;
14435 case R6_OPC_LLD:
14436 gen_ld(ctx, op1, rt, rs, imm);
14437 break;
14438 case OPC_DBSHFL:
14439 check_mips_64(ctx);
14440 {
14441 if (rd == 0) {
14442
14443 break;
14444 }
14445 op2 = MASK_DBSHFL(ctx->opcode);
14446 switch (op2) {
14447 case OPC_DALIGN:
14448 case OPC_DALIGN_1:
14449 case OPC_DALIGN_2:
14450 case OPC_DALIGN_3:
14451 case OPC_DALIGN_4:
14452 case OPC_DALIGN_5:
14453 case OPC_DALIGN_6:
14454 case OPC_DALIGN_7:
14455 gen_align(ctx, 64, rd, rs, rt, sa & 7);
14456 break;
14457 case OPC_DBITSWAP:
14458 gen_bitswap(ctx, op2, rd, rt);
14459 break;
14460 }
14461
14462 }
14463 break;
14464#endif
14465 default:
14466 MIPS_INVAL("special3_r6");
14467 gen_reserved_instruction(ctx);
14468 break;
14469 }
14470}
14471
14472static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14473{
14474 int rs, rt, rd;
14475 uint32_t op1, op2;
14476
14477 rs = (ctx->opcode >> 21) & 0x1f;
14478 rt = (ctx->opcode >> 16) & 0x1f;
14479 rd = (ctx->opcode >> 11) & 0x1f;
14480
14481 op1 = MASK_SPECIAL3(ctx->opcode);
14482 switch (op1) {
14483 case OPC_DIV_G_2E:
14484 case OPC_DIVU_G_2E:
14485 case OPC_MOD_G_2E:
14486 case OPC_MODU_G_2E:
14487 case OPC_MULT_G_2E:
14488 case OPC_MULTU_G_2E:
14489
14490
14491
14492
14493 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
14494 op2 = MASK_ADDUH_QB(ctx->opcode);
14495 switch (op2) {
14496 case OPC_ADDUH_QB:
14497 case OPC_ADDUH_R_QB:
14498 case OPC_ADDQH_PH:
14499 case OPC_ADDQH_R_PH:
14500 case OPC_ADDQH_W:
14501 case OPC_ADDQH_R_W:
14502 case OPC_SUBUH_QB:
14503 case OPC_SUBUH_R_QB:
14504 case OPC_SUBQH_PH:
14505 case OPC_SUBQH_R_PH:
14506 case OPC_SUBQH_W:
14507 case OPC_SUBQH_R_W:
14508 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14509 break;
14510 case OPC_MUL_PH:
14511 case OPC_MUL_S_PH:
14512 case OPC_MULQ_S_W:
14513 case OPC_MULQ_RS_W:
14514 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14515 break;
14516 default:
14517 MIPS_INVAL("MASK ADDUH.QB");
14518 gen_reserved_instruction(ctx);
14519 break;
14520 }
14521 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14522 gen_loongson_integer(ctx, op1, rd, rs, rt);
14523 } else {
14524 gen_reserved_instruction(ctx);
14525 }
14526 break;
14527 case OPC_LX_DSP:
14528 op2 = MASK_LX(ctx->opcode);
14529 switch (op2) {
14530#if defined(TARGET_MIPS64)
14531 case OPC_LDX:
14532#endif
14533 case OPC_LBUX:
14534 case OPC_LHX:
14535 case OPC_LWX:
14536 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14537 break;
14538 default:
14539 MIPS_INVAL("MASK LX");
14540 gen_reserved_instruction(ctx);
14541 break;
14542 }
14543 break;
14544 case OPC_ABSQ_S_PH_DSP:
14545 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14546 switch (op2) {
14547 case OPC_ABSQ_S_QB:
14548 case OPC_ABSQ_S_PH:
14549 case OPC_ABSQ_S_W:
14550 case OPC_PRECEQ_W_PHL:
14551 case OPC_PRECEQ_W_PHR:
14552 case OPC_PRECEQU_PH_QBL:
14553 case OPC_PRECEQU_PH_QBR:
14554 case OPC_PRECEQU_PH_QBLA:
14555 case OPC_PRECEQU_PH_QBRA:
14556 case OPC_PRECEU_PH_QBL:
14557 case OPC_PRECEU_PH_QBR:
14558 case OPC_PRECEU_PH_QBLA:
14559 case OPC_PRECEU_PH_QBRA:
14560 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14561 break;
14562 case OPC_BITREV:
14563 case OPC_REPL_QB:
14564 case OPC_REPLV_QB:
14565 case OPC_REPL_PH:
14566 case OPC_REPLV_PH:
14567 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14568 break;
14569 default:
14570 MIPS_INVAL("MASK ABSQ_S.PH");
14571 gen_reserved_instruction(ctx);
14572 break;
14573 }
14574 break;
14575 case OPC_ADDU_QB_DSP:
14576 op2 = MASK_ADDU_QB(ctx->opcode);
14577 switch (op2) {
14578 case OPC_ADDQ_PH:
14579 case OPC_ADDQ_S_PH:
14580 case OPC_ADDQ_S_W:
14581 case OPC_ADDU_QB:
14582 case OPC_ADDU_S_QB:
14583 case OPC_ADDU_PH:
14584 case OPC_ADDU_S_PH:
14585 case OPC_SUBQ_PH:
14586 case OPC_SUBQ_S_PH:
14587 case OPC_SUBQ_S_W:
14588 case OPC_SUBU_QB:
14589 case OPC_SUBU_S_QB:
14590 case OPC_SUBU_PH:
14591 case OPC_SUBU_S_PH:
14592 case OPC_ADDSC:
14593 case OPC_ADDWC:
14594 case OPC_MODSUB:
14595 case OPC_RADDU_W_QB:
14596 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14597 break;
14598 case OPC_MULEU_S_PH_QBL:
14599 case OPC_MULEU_S_PH_QBR:
14600 case OPC_MULQ_RS_PH:
14601 case OPC_MULEQ_S_W_PHL:
14602 case OPC_MULEQ_S_W_PHR:
14603 case OPC_MULQ_S_PH:
14604 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14605 break;
14606 default:
14607 MIPS_INVAL("MASK ADDU.QB");
14608 gen_reserved_instruction(ctx);
14609 break;
14610
14611 }
14612 break;
14613 case OPC_CMPU_EQ_QB_DSP:
14614 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14615 switch (op2) {
14616 case OPC_PRECR_SRA_PH_W:
14617 case OPC_PRECR_SRA_R_PH_W:
14618 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14619 break;
14620 case OPC_PRECR_QB_PH:
14621 case OPC_PRECRQ_QB_PH:
14622 case OPC_PRECRQ_PH_W:
14623 case OPC_PRECRQ_RS_PH_W:
14624 case OPC_PRECRQU_S_QB_PH:
14625 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14626 break;
14627 case OPC_CMPU_EQ_QB:
14628 case OPC_CMPU_LT_QB:
14629 case OPC_CMPU_LE_QB:
14630 case OPC_CMP_EQ_PH:
14631 case OPC_CMP_LT_PH:
14632 case OPC_CMP_LE_PH:
14633 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14634 break;
14635 case OPC_CMPGU_EQ_QB:
14636 case OPC_CMPGU_LT_QB:
14637 case OPC_CMPGU_LE_QB:
14638 case OPC_CMPGDU_EQ_QB:
14639 case OPC_CMPGDU_LT_QB:
14640 case OPC_CMPGDU_LE_QB:
14641 case OPC_PICK_QB:
14642 case OPC_PICK_PH:
14643 case OPC_PACKRL_PH:
14644 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14645 break;
14646 default:
14647 MIPS_INVAL("MASK CMPU.EQ.QB");
14648 gen_reserved_instruction(ctx);
14649 break;
14650 }
14651 break;
14652 case OPC_SHLL_QB_DSP:
14653 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14654 break;
14655 case OPC_DPA_W_PH_DSP:
14656 op2 = MASK_DPA_W_PH(ctx->opcode);
14657 switch (op2) {
14658 case OPC_DPAU_H_QBL:
14659 case OPC_DPAU_H_QBR:
14660 case OPC_DPSU_H_QBL:
14661 case OPC_DPSU_H_QBR:
14662 case OPC_DPA_W_PH:
14663 case OPC_DPAX_W_PH:
14664 case OPC_DPAQ_S_W_PH:
14665 case OPC_DPAQX_S_W_PH:
14666 case OPC_DPAQX_SA_W_PH:
14667 case OPC_DPS_W_PH:
14668 case OPC_DPSX_W_PH:
14669 case OPC_DPSQ_S_W_PH:
14670 case OPC_DPSQX_S_W_PH:
14671 case OPC_DPSQX_SA_W_PH:
14672 case OPC_MULSAQ_S_W_PH:
14673 case OPC_DPAQ_SA_L_W:
14674 case OPC_DPSQ_SA_L_W:
14675 case OPC_MAQ_S_W_PHL:
14676 case OPC_MAQ_S_W_PHR:
14677 case OPC_MAQ_SA_W_PHL:
14678 case OPC_MAQ_SA_W_PHR:
14679 case OPC_MULSA_W_PH:
14680 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14681 break;
14682 default:
14683 MIPS_INVAL("MASK DPAW.PH");
14684 gen_reserved_instruction(ctx);
14685 break;
14686 }
14687 break;
14688 case OPC_INSV_DSP:
14689 op2 = MASK_INSV(ctx->opcode);
14690 switch (op2) {
14691 case OPC_INSV:
14692 check_dsp(ctx);
14693 {
14694 TCGv t0, t1;
14695
14696 if (rt == 0) {
14697 break;
14698 }
14699
14700 t0 = tcg_temp_new();
14701 t1 = tcg_temp_new();
14702
14703 gen_load_gpr(t0, rt);
14704 gen_load_gpr(t1, rs);
14705
14706 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14707
14708 tcg_temp_free(t0);
14709 tcg_temp_free(t1);
14710 break;
14711 }
14712 default:
14713 MIPS_INVAL("MASK INSV");
14714 gen_reserved_instruction(ctx);
14715 break;
14716 }
14717 break;
14718 case OPC_APPEND_DSP:
14719 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14720 break;
14721 case OPC_EXTR_W_DSP:
14722 op2 = MASK_EXTR_W(ctx->opcode);
14723 switch (op2) {
14724 case OPC_EXTR_W:
14725 case OPC_EXTR_R_W:
14726 case OPC_EXTR_RS_W:
14727 case OPC_EXTR_S_H:
14728 case OPC_EXTRV_S_H:
14729 case OPC_EXTRV_W:
14730 case OPC_EXTRV_R_W:
14731 case OPC_EXTRV_RS_W:
14732 case OPC_EXTP:
14733 case OPC_EXTPV:
14734 case OPC_EXTPDP:
14735 case OPC_EXTPDPV:
14736 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14737 break;
14738 case OPC_RDDSP:
14739 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14740 break;
14741 case OPC_SHILO:
14742 case OPC_SHILOV:
14743 case OPC_MTHLIP:
14744 case OPC_WRDSP:
14745 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14746 break;
14747 default:
14748 MIPS_INVAL("MASK EXTR.W");
14749 gen_reserved_instruction(ctx);
14750 break;
14751 }
14752 break;
14753#if defined(TARGET_MIPS64)
14754 case OPC_DDIV_G_2E:
14755 case OPC_DDIVU_G_2E:
14756 case OPC_DMULT_G_2E:
14757 case OPC_DMULTU_G_2E:
14758 case OPC_DMOD_G_2E:
14759 case OPC_DMODU_G_2E:
14760 check_insn(ctx, INSN_LOONGSON2E);
14761 gen_loongson_integer(ctx, op1, rd, rs, rt);
14762 break;
14763 case OPC_ABSQ_S_QH_DSP:
14764 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14765 switch (op2) {
14766 case OPC_PRECEQ_L_PWL:
14767 case OPC_PRECEQ_L_PWR:
14768 case OPC_PRECEQ_PW_QHL:
14769 case OPC_PRECEQ_PW_QHR:
14770 case OPC_PRECEQ_PW_QHLA:
14771 case OPC_PRECEQ_PW_QHRA:
14772 case OPC_PRECEQU_QH_OBL:
14773 case OPC_PRECEQU_QH_OBR:
14774 case OPC_PRECEQU_QH_OBLA:
14775 case OPC_PRECEQU_QH_OBRA:
14776 case OPC_PRECEU_QH_OBL:
14777 case OPC_PRECEU_QH_OBR:
14778 case OPC_PRECEU_QH_OBLA:
14779 case OPC_PRECEU_QH_OBRA:
14780 case OPC_ABSQ_S_OB:
14781 case OPC_ABSQ_S_PW:
14782 case OPC_ABSQ_S_QH:
14783 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14784 break;
14785 case OPC_REPL_OB:
14786 case OPC_REPL_PW:
14787 case OPC_REPL_QH:
14788 case OPC_REPLV_OB:
14789 case OPC_REPLV_PW:
14790 case OPC_REPLV_QH:
14791 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14792 break;
14793 default:
14794 MIPS_INVAL("MASK ABSQ_S.QH");
14795 gen_reserved_instruction(ctx);
14796 break;
14797 }
14798 break;
14799 case OPC_ADDU_OB_DSP:
14800 op2 = MASK_ADDU_OB(ctx->opcode);
14801 switch (op2) {
14802 case OPC_RADDU_L_OB:
14803 case OPC_SUBQ_PW:
14804 case OPC_SUBQ_S_PW:
14805 case OPC_SUBQ_QH:
14806 case OPC_SUBQ_S_QH:
14807 case OPC_SUBU_OB:
14808 case OPC_SUBU_S_OB:
14809 case OPC_SUBU_QH:
14810 case OPC_SUBU_S_QH:
14811 case OPC_SUBUH_OB:
14812 case OPC_SUBUH_R_OB:
14813 case OPC_ADDQ_PW:
14814 case OPC_ADDQ_S_PW:
14815 case OPC_ADDQ_QH:
14816 case OPC_ADDQ_S_QH:
14817 case OPC_ADDU_OB:
14818 case OPC_ADDU_S_OB:
14819 case OPC_ADDU_QH:
14820 case OPC_ADDU_S_QH:
14821 case OPC_ADDUH_OB:
14822 case OPC_ADDUH_R_OB:
14823 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14824 break;
14825 case OPC_MULEQ_S_PW_QHL:
14826 case OPC_MULEQ_S_PW_QHR:
14827 case OPC_MULEU_S_QH_OBL:
14828 case OPC_MULEU_S_QH_OBR:
14829 case OPC_MULQ_RS_QH:
14830 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14831 break;
14832 default:
14833 MIPS_INVAL("MASK ADDU.OB");
14834 gen_reserved_instruction(ctx);
14835 break;
14836 }
14837 break;
14838 case OPC_CMPU_EQ_OB_DSP:
14839 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14840 switch (op2) {
14841 case OPC_PRECR_SRA_QH_PW:
14842 case OPC_PRECR_SRA_R_QH_PW:
14843
14844 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14845 break;
14846 case OPC_PRECR_OB_QH:
14847 case OPC_PRECRQ_OB_QH:
14848 case OPC_PRECRQ_PW_L:
14849 case OPC_PRECRQ_QH_PW:
14850 case OPC_PRECRQ_RS_QH_PW:
14851 case OPC_PRECRQU_S_OB_QH:
14852 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14853 break;
14854 case OPC_CMPU_EQ_OB:
14855 case OPC_CMPU_LT_OB:
14856 case OPC_CMPU_LE_OB:
14857 case OPC_CMP_EQ_QH:
14858 case OPC_CMP_LT_QH:
14859 case OPC_CMP_LE_QH:
14860 case OPC_CMP_EQ_PW:
14861 case OPC_CMP_LT_PW:
14862 case OPC_CMP_LE_PW:
14863 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14864 break;
14865 case OPC_CMPGDU_EQ_OB:
14866 case OPC_CMPGDU_LT_OB:
14867 case OPC_CMPGDU_LE_OB:
14868 case OPC_CMPGU_EQ_OB:
14869 case OPC_CMPGU_LT_OB:
14870 case OPC_CMPGU_LE_OB:
14871 case OPC_PACKRL_PW:
14872 case OPC_PICK_OB:
14873 case OPC_PICK_PW:
14874 case OPC_PICK_QH:
14875 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14876 break;
14877 default:
14878 MIPS_INVAL("MASK CMPU_EQ.OB");
14879 gen_reserved_instruction(ctx);
14880 break;
14881 }
14882 break;
14883 case OPC_DAPPEND_DSP:
14884 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14885 break;
14886 case OPC_DEXTR_W_DSP:
14887 op2 = MASK_DEXTR_W(ctx->opcode);
14888 switch (op2) {
14889 case OPC_DEXTP:
14890 case OPC_DEXTPDP:
14891 case OPC_DEXTPDPV:
14892 case OPC_DEXTPV:
14893 case OPC_DEXTR_L:
14894 case OPC_DEXTR_R_L:
14895 case OPC_DEXTR_RS_L:
14896 case OPC_DEXTR_W:
14897 case OPC_DEXTR_R_W:
14898 case OPC_DEXTR_RS_W:
14899 case OPC_DEXTR_S_H:
14900 case OPC_DEXTRV_L:
14901 case OPC_DEXTRV_R_L:
14902 case OPC_DEXTRV_RS_L:
14903 case OPC_DEXTRV_S_H:
14904 case OPC_DEXTRV_W:
14905 case OPC_DEXTRV_R_W:
14906 case OPC_DEXTRV_RS_W:
14907 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14908 break;
14909 case OPC_DMTHLIP:
14910 case OPC_DSHILO:
14911 case OPC_DSHILOV:
14912 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14913 break;
14914 default:
14915 MIPS_INVAL("MASK EXTR.W");
14916 gen_reserved_instruction(ctx);
14917 break;
14918 }
14919 break;
14920 case OPC_DPAQ_W_QH_DSP:
14921 op2 = MASK_DPAQ_W_QH(ctx->opcode);
14922 switch (op2) {
14923 case OPC_DPAU_H_OBL:
14924 case OPC_DPAU_H_OBR:
14925 case OPC_DPSU_H_OBL:
14926 case OPC_DPSU_H_OBR:
14927 case OPC_DPA_W_QH:
14928 case OPC_DPAQ_S_W_QH:
14929 case OPC_DPS_W_QH:
14930 case OPC_DPSQ_S_W_QH:
14931 case OPC_MULSAQ_S_W_QH:
14932 case OPC_DPAQ_SA_L_PW:
14933 case OPC_DPSQ_SA_L_PW:
14934 case OPC_MULSAQ_S_L_PW:
14935 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14936 break;
14937 case OPC_MAQ_S_W_QHLL:
14938 case OPC_MAQ_S_W_QHLR:
14939 case OPC_MAQ_S_W_QHRL:
14940 case OPC_MAQ_S_W_QHRR:
14941 case OPC_MAQ_SA_W_QHLL:
14942 case OPC_MAQ_SA_W_QHLR:
14943 case OPC_MAQ_SA_W_QHRL:
14944 case OPC_MAQ_SA_W_QHRR:
14945 case OPC_MAQ_S_L_PWL:
14946 case OPC_MAQ_S_L_PWR:
14947 case OPC_DMADD:
14948 case OPC_DMADDU:
14949 case OPC_DMSUB:
14950 case OPC_DMSUBU:
14951 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14952 break;
14953 default:
14954 MIPS_INVAL("MASK DPAQ.W.QH");
14955 gen_reserved_instruction(ctx);
14956 break;
14957 }
14958 break;
14959 case OPC_DINSV_DSP:
14960 op2 = MASK_INSV(ctx->opcode);
14961 switch (op2) {
14962 case OPC_DINSV:
14963 {
14964 TCGv t0, t1;
14965
14966 check_dsp(ctx);
14967
14968 if (rt == 0) {
14969 break;
14970 }
14971
14972 t0 = tcg_temp_new();
14973 t1 = tcg_temp_new();
14974
14975 gen_load_gpr(t0, rt);
14976 gen_load_gpr(t1, rs);
14977
14978 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14979
14980 tcg_temp_free(t0);
14981 tcg_temp_free(t1);
14982 break;
14983 }
14984 default:
14985 MIPS_INVAL("MASK DINSV");
14986 gen_reserved_instruction(ctx);
14987 break;
14988 }
14989 break;
14990 case OPC_SHLL_OB_DSP:
14991 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14992 break;
14993#endif
14994 default:
14995 MIPS_INVAL("special3_legacy");
14996 gen_reserved_instruction(ctx);
14997 break;
14998 }
14999}
15000
15001
15002#if defined(TARGET_MIPS64)
15003
15004static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
15005{
15006 uint32_t opc = MASK_MMI(ctx->opcode);
15007 int rs = extract32(ctx->opcode, 21, 5);
15008 int rt = extract32(ctx->opcode, 16, 5);
15009 int rd = extract32(ctx->opcode, 11, 5);
15010
15011 switch (opc) {
15012 case MMI_OPC_MULT1:
15013 case MMI_OPC_MULTU1:
15014 case MMI_OPC_MADD:
15015 case MMI_OPC_MADDU:
15016 case MMI_OPC_MADD1:
15017 case MMI_OPC_MADDU1:
15018 gen_mul_txx9(ctx, opc, rd, rs, rt);
15019 break;
15020 case MMI_OPC_DIV1:
15021 case MMI_OPC_DIVU1:
15022 gen_div1_tx79(ctx, opc, rs, rt);
15023 break;
15024 default:
15025 MIPS_INVAL("TX79 MMI class");
15026 gen_reserved_instruction(ctx);
15027 break;
15028 }
15029}
15030
15031static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
15032{
15033 gen_reserved_instruction(ctx);
15034}
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
15058{
15059 int base = extract32(ctx->opcode, 21, 5);
15060 int rt = extract32(ctx->opcode, 16, 5);
15061 int offset = extract32(ctx->opcode, 0, 16);
15062
15063#ifdef CONFIG_USER_ONLY
15064 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15065 uint32_t op2 = extract32(ctx->opcode, 6, 5);
15066
15067 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15068 int rd = extract32(ctx->opcode, 11, 5);
15069
15070 gen_rdhwr(ctx, rt, rd, 0);
15071 return;
15072 }
15073#endif
15074
15075 gen_mmi_sq(ctx, base, rt, offset);
15076}
15077
15078#endif
15079
15080static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15081{
15082 int rs, rt, rd, sa;
15083 uint32_t op1, op2;
15084 int16_t imm;
15085
15086 rs = (ctx->opcode >> 21) & 0x1f;
15087 rt = (ctx->opcode >> 16) & 0x1f;
15088 rd = (ctx->opcode >> 11) & 0x1f;
15089 sa = (ctx->opcode >> 6) & 0x1f;
15090 imm = sextract32(ctx->opcode, 7, 9);
15091
15092 op1 = MASK_SPECIAL3(ctx->opcode);
15093
15094
15095
15096
15097
15098
15099 if (ctx->eva) {
15100 switch (op1) {
15101 case OPC_LWLE:
15102 case OPC_LWRE:
15103 case OPC_LBUE:
15104 case OPC_LHUE:
15105 case OPC_LBE:
15106 case OPC_LHE:
15107 case OPC_LLE:
15108 case OPC_LWE:
15109 check_cp0_enabled(ctx);
15110 gen_ld(ctx, op1, rt, rs, imm);
15111 return;
15112 case OPC_SWLE:
15113 case OPC_SWRE:
15114 case OPC_SBE:
15115 case OPC_SHE:
15116 case OPC_SWE:
15117 check_cp0_enabled(ctx);
15118 gen_st(ctx, op1, rt, rs, imm);
15119 return;
15120 case OPC_SCE:
15121 check_cp0_enabled(ctx);
15122 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
15123 return;
15124 case OPC_CACHEE:
15125 check_eva(ctx);
15126 check_cp0_enabled(ctx);
15127 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15128 gen_cache_operation(ctx, rt, rs, imm);
15129 }
15130 return;
15131 case OPC_PREFE:
15132 check_cp0_enabled(ctx);
15133
15134 return;
15135 }
15136 }
15137
15138 switch (op1) {
15139 case OPC_EXT:
15140 case OPC_INS:
15141 check_insn(ctx, ISA_MIPS_R2);
15142 gen_bitops(ctx, op1, rt, rs, sa, rd);
15143 break;
15144 case OPC_BSHFL:
15145 op2 = MASK_BSHFL(ctx->opcode);
15146 switch (op2) {
15147 case OPC_ALIGN:
15148 case OPC_ALIGN_1:
15149 case OPC_ALIGN_2:
15150 case OPC_ALIGN_3:
15151 case OPC_BITSWAP:
15152 check_insn(ctx, ISA_MIPS_R6);
15153 decode_opc_special3_r6(env, ctx);
15154 break;
15155 default:
15156 check_insn(ctx, ISA_MIPS_R2);
15157 gen_bshfl(ctx, op2, rt, rd);
15158 break;
15159 }
15160 break;
15161#if defined(TARGET_MIPS64)
15162 case OPC_DEXTM:
15163 case OPC_DEXTU:
15164 case OPC_DEXT:
15165 case OPC_DINSM:
15166 case OPC_DINSU:
15167 case OPC_DINS:
15168 check_insn(ctx, ISA_MIPS_R2);
15169 check_mips_64(ctx);
15170 gen_bitops(ctx, op1, rt, rs, sa, rd);
15171 break;
15172 case OPC_DBSHFL:
15173 op2 = MASK_DBSHFL(ctx->opcode);
15174 switch (op2) {
15175 case OPC_DALIGN:
15176 case OPC_DALIGN_1:
15177 case OPC_DALIGN_2:
15178 case OPC_DALIGN_3:
15179 case OPC_DALIGN_4:
15180 case OPC_DALIGN_5:
15181 case OPC_DALIGN_6:
15182 case OPC_DALIGN_7:
15183 case OPC_DBITSWAP:
15184 check_insn(ctx, ISA_MIPS_R6);
15185 decode_opc_special3_r6(env, ctx);
15186 break;
15187 default:
15188 check_insn(ctx, ISA_MIPS_R2);
15189 check_mips_64(ctx);
15190 op2 = MASK_DBSHFL(ctx->opcode);
15191 gen_bshfl(ctx, op2, rt, rd);
15192 break;
15193 }
15194 break;
15195#endif
15196 case OPC_RDHWR:
15197 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
15198 break;
15199 case OPC_FORK:
15200 check_mt(ctx);
15201 {
15202 TCGv t0 = tcg_temp_new();
15203 TCGv t1 = tcg_temp_new();
15204
15205 gen_load_gpr(t0, rt);
15206 gen_load_gpr(t1, rs);
15207 gen_helper_fork(t0, t1);
15208 tcg_temp_free(t0);
15209 tcg_temp_free(t1);
15210 }
15211 break;
15212 case OPC_YIELD:
15213 check_mt(ctx);
15214 {
15215 TCGv t0 = tcg_temp_new();
15216
15217 gen_load_gpr(t0, rs);
15218 gen_helper_yield(t0, cpu_env, t0);
15219 gen_store_gpr(t0, rd);
15220 tcg_temp_free(t0);
15221 }
15222 break;
15223 default:
15224 if (ctx->insn_flags & ISA_MIPS_R6) {
15225 decode_opc_special3_r6(env, ctx);
15226 } else {
15227 decode_opc_special3_legacy(env, ctx);
15228 }
15229 }
15230}
15231
15232static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
15233{
15234 int32_t offset;
15235 int rs, rt, rd, sa;
15236 uint32_t op, op1;
15237 int16_t imm;
15238
15239 op = MASK_OP_MAJOR(ctx->opcode);
15240 rs = (ctx->opcode >> 21) & 0x1f;
15241 rt = (ctx->opcode >> 16) & 0x1f;
15242 rd = (ctx->opcode >> 11) & 0x1f;
15243 sa = (ctx->opcode >> 6) & 0x1f;
15244 imm = (int16_t)ctx->opcode;
15245 switch (op) {
15246 case OPC_SPECIAL:
15247 decode_opc_special(env, ctx);
15248 break;
15249 case OPC_SPECIAL2:
15250#if defined(TARGET_MIPS64)
15251 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15252 decode_mmi(env, ctx);
15253 break;
15254 }
15255#endif
15256 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
15257 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15258 gen_arith(ctx, OPC_MUL, rd, rs, rt);
15259 } else {
15260 decode_ase_mxu(ctx, ctx->opcode);
15261 }
15262 break;
15263 }
15264 decode_opc_special2_legacy(env, ctx);
15265 break;
15266 case OPC_SPECIAL3:
15267#if defined(TARGET_MIPS64)
15268 if (ctx->insn_flags & INSN_R5900) {
15269 decode_mmi_sq(env, ctx);
15270 } else {
15271 decode_opc_special3(env, ctx);
15272 }
15273#else
15274 decode_opc_special3(env, ctx);
15275#endif
15276 break;
15277 case OPC_REGIMM:
15278 op1 = MASK_REGIMM(ctx->opcode);
15279 switch (op1) {
15280 case OPC_BLTZL:
15281 case OPC_BGEZL:
15282 case OPC_BLTZALL:
15283 case OPC_BGEZALL:
15284 check_insn(ctx, ISA_MIPS2);
15285 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15286
15287 case OPC_BLTZ:
15288 case OPC_BGEZ:
15289 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15290 break;
15291 case OPC_BLTZAL:
15292 case OPC_BGEZAL:
15293 if (ctx->insn_flags & ISA_MIPS_R6) {
15294 if (rs == 0) {
15295
15296 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15297 } else {
15298 gen_reserved_instruction(ctx);
15299 }
15300 } else {
15301 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15302 }
15303 break;
15304 case OPC_TGEI:
15305 case OPC_TGEIU:
15306 case OPC_TLTI:
15307 case OPC_TLTIU:
15308 case OPC_TEQI:
15309 case OPC_TNEI:
15310 check_insn(ctx, ISA_MIPS2);
15311 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15312 gen_trap(ctx, op1, rs, -1, imm, 0);
15313 break;
15314 case OPC_SIGRIE:
15315 check_insn(ctx, ISA_MIPS_R6);
15316 gen_reserved_instruction(ctx);
15317 break;
15318 case OPC_SYNCI:
15319 check_insn(ctx, ISA_MIPS_R2);
15320
15321
15322
15323
15324 ctx->base.is_jmp = DISAS_STOP;
15325 break;
15326 case OPC_BPOSGE32:
15327#if defined(TARGET_MIPS64)
15328 case OPC_BPOSGE64:
15329#endif
15330 check_dsp(ctx);
15331 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
15332 break;
15333#if defined(TARGET_MIPS64)
15334 case OPC_DAHI:
15335 check_insn(ctx, ISA_MIPS_R6);
15336 check_mips_64(ctx);
15337 if (rs != 0) {
15338 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15339 }
15340 break;
15341 case OPC_DATI:
15342 check_insn(ctx, ISA_MIPS_R6);
15343 check_mips_64(ctx);
15344 if (rs != 0) {
15345 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15346 }
15347 break;
15348#endif
15349 default:
15350 MIPS_INVAL("regimm");
15351 gen_reserved_instruction(ctx);
15352 break;
15353 }
15354 break;
15355 case OPC_CP0:
15356 check_cp0_enabled(ctx);
15357 op1 = MASK_CP0(ctx->opcode);
15358 switch (op1) {
15359 case OPC_MFC0:
15360 case OPC_MTC0:
15361 case OPC_MFTR:
15362 case OPC_MTTR:
15363 case OPC_MFHC0:
15364 case OPC_MTHC0:
15365#if defined(TARGET_MIPS64)
15366 case OPC_DMFC0:
15367 case OPC_DMTC0:
15368#endif
15369#ifndef CONFIG_USER_ONLY
15370 gen_cp0(env, ctx, op1, rt, rd);
15371#endif
15372 break;
15373 case OPC_C0:
15374 case OPC_C0_1:
15375 case OPC_C0_2:
15376 case OPC_C0_3:
15377 case OPC_C0_4:
15378 case OPC_C0_5:
15379 case OPC_C0_6:
15380 case OPC_C0_7:
15381 case OPC_C0_8:
15382 case OPC_C0_9:
15383 case OPC_C0_A:
15384 case OPC_C0_B:
15385 case OPC_C0_C:
15386 case OPC_C0_D:
15387 case OPC_C0_E:
15388 case OPC_C0_F:
15389#ifndef CONFIG_USER_ONLY
15390 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15391#endif
15392 break;
15393 case OPC_MFMC0:
15394#ifndef CONFIG_USER_ONLY
15395 {
15396 uint32_t op2;
15397 TCGv t0 = tcg_temp_new();
15398
15399 op2 = MASK_MFMC0(ctx->opcode);
15400 switch (op2) {
15401 case OPC_DMT:
15402 check_cp0_mt(ctx);
15403 gen_helper_dmt(t0);
15404 gen_store_gpr(t0, rt);
15405 break;
15406 case OPC_EMT:
15407 check_cp0_mt(ctx);
15408 gen_helper_emt(t0);
15409 gen_store_gpr(t0, rt);
15410 break;
15411 case OPC_DVPE:
15412 check_cp0_mt(ctx);
15413 gen_helper_dvpe(t0, cpu_env);
15414 gen_store_gpr(t0, rt);
15415 break;
15416 case OPC_EVPE:
15417 check_cp0_mt(ctx);
15418 gen_helper_evpe(t0, cpu_env);
15419 gen_store_gpr(t0, rt);
15420 break;
15421 case OPC_DVP:
15422 check_insn(ctx, ISA_MIPS_R6);
15423 if (ctx->vp) {
15424 gen_helper_dvp(t0, cpu_env);
15425 gen_store_gpr(t0, rt);
15426 }
15427 break;
15428 case OPC_EVP:
15429 check_insn(ctx, ISA_MIPS_R6);
15430 if (ctx->vp) {
15431 gen_helper_evp(t0, cpu_env);
15432 gen_store_gpr(t0, rt);
15433 }
15434 break;
15435 case OPC_DI:
15436 check_insn(ctx, ISA_MIPS_R2);
15437 save_cpu_state(ctx, 1);
15438 gen_helper_di(t0, cpu_env);
15439 gen_store_gpr(t0, rt);
15440
15441
15442
15443
15444 ctx->base.is_jmp = DISAS_STOP;
15445 break;
15446 case OPC_EI:
15447 check_insn(ctx, ISA_MIPS_R2);
15448 save_cpu_state(ctx, 1);
15449 gen_helper_ei(t0, cpu_env);
15450 gen_store_gpr(t0, rt);
15451
15452
15453
15454
15455 gen_save_pc(ctx->base.pc_next + 4);
15456 ctx->base.is_jmp = DISAS_EXIT;
15457 break;
15458 default:
15459 MIPS_INVAL("mfmc0");
15460 gen_reserved_instruction(ctx);
15461 break;
15462 }
15463 tcg_temp_free(t0);
15464 }
15465#endif
15466 break;
15467 case OPC_RDPGPR:
15468 check_insn(ctx, ISA_MIPS_R2);
15469 gen_load_srsgpr(rt, rd);
15470 break;
15471 case OPC_WRPGPR:
15472 check_insn(ctx, ISA_MIPS_R2);
15473 gen_store_srsgpr(rt, rd);
15474 break;
15475 default:
15476 MIPS_INVAL("cp0");
15477 gen_reserved_instruction(ctx);
15478 break;
15479 }
15480 break;
15481 case OPC_BOVC:
15482 if (ctx->insn_flags & ISA_MIPS_R6) {
15483
15484 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15485 } else {
15486
15487
15488 gen_arith_imm(ctx, op, rt, rs, imm);
15489 }
15490 break;
15491 case OPC_ADDIU:
15492 gen_arith_imm(ctx, op, rt, rs, imm);
15493 break;
15494 case OPC_SLTI:
15495 case OPC_SLTIU:
15496 gen_slt_imm(ctx, op, rt, rs, imm);
15497 break;
15498 case OPC_ANDI:
15499 case OPC_LUI:
15500 case OPC_ORI:
15501 case OPC_XORI:
15502 gen_logic_imm(ctx, op, rt, rs, imm);
15503 break;
15504 case OPC_J:
15505 case OPC_JAL:
15506 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15507 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15508 break;
15509
15510 case OPC_BLEZC:
15511 if (ctx->insn_flags & ISA_MIPS_R6) {
15512 if (rt == 0) {
15513 gen_reserved_instruction(ctx);
15514 break;
15515 }
15516
15517 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15518 } else {
15519
15520 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15521 }
15522 break;
15523 case OPC_BGTZC:
15524 if (ctx->insn_flags & ISA_MIPS_R6) {
15525 if (rt == 0) {
15526 gen_reserved_instruction(ctx);
15527 break;
15528 }
15529
15530 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15531 } else {
15532
15533 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15534 }
15535 break;
15536 case OPC_BLEZALC:
15537 if (rt == 0) {
15538
15539 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15540 } else {
15541 check_insn(ctx, ISA_MIPS_R6);
15542
15543 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15544 }
15545 break;
15546 case OPC_BGTZALC:
15547 if (rt == 0) {
15548
15549 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15550 } else {
15551 check_insn(ctx, ISA_MIPS_R6);
15552
15553 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15554 }
15555 break;
15556 case OPC_BEQL:
15557 case OPC_BNEL:
15558 check_insn(ctx, ISA_MIPS2);
15559 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15560
15561 case OPC_BEQ:
15562 case OPC_BNE:
15563 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15564 break;
15565 case OPC_LL:
15566 check_insn(ctx, ISA_MIPS2);
15567 if (ctx->insn_flags & INSN_R5900) {
15568 check_insn_opc_user_only(ctx, INSN_R5900);
15569 }
15570
15571 case OPC_LWL:
15572 case OPC_LWR:
15573 case OPC_LB:
15574 case OPC_LH:
15575 case OPC_LW:
15576 case OPC_LWPC:
15577 case OPC_LBU:
15578 case OPC_LHU:
15579 gen_ld(ctx, op, rt, rs, imm);
15580 break;
15581 case OPC_SWL:
15582 case OPC_SWR:
15583 case OPC_SB:
15584 case OPC_SH:
15585 case OPC_SW:
15586 gen_st(ctx, op, rt, rs, imm);
15587 break;
15588 case OPC_SC:
15589 check_insn(ctx, ISA_MIPS2);
15590 if (ctx->insn_flags & INSN_R5900) {
15591 check_insn_opc_user_only(ctx, INSN_R5900);
15592 }
15593 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15594 break;
15595 case OPC_CACHE:
15596 check_cp0_enabled(ctx);
15597 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
15598 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15599 gen_cache_operation(ctx, rt, rs, imm);
15600 }
15601
15602 break;
15603 case OPC_PREF:
15604 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15605
15606 break;
15607
15608
15609 case OPC_LWC1:
15610 case OPC_LDC1:
15611 case OPC_SWC1:
15612 case OPC_SDC1:
15613 gen_cop1_ldst(ctx, op, rt, rs, imm);
15614 break;
15615
15616 case OPC_CP1:
15617 op1 = MASK_CP1(ctx->opcode);
15618
15619 switch (op1) {
15620 case OPC_MFHC1:
15621 case OPC_MTHC1:
15622 check_cp1_enabled(ctx);
15623 check_insn(ctx, ISA_MIPS_R2);
15624
15625 case OPC_MFC1:
15626 case OPC_CFC1:
15627 case OPC_MTC1:
15628 case OPC_CTC1:
15629 check_cp1_enabled(ctx);
15630 gen_cp1(ctx, op1, rt, rd);
15631 break;
15632#if defined(TARGET_MIPS64)
15633 case OPC_DMFC1:
15634 case OPC_DMTC1:
15635 check_cp1_enabled(ctx);
15636 check_insn(ctx, ISA_MIPS3);
15637 check_mips_64(ctx);
15638 gen_cp1(ctx, op1, rt, rd);
15639 break;
15640#endif
15641 case OPC_BC1EQZ:
15642 check_cp1_enabled(ctx);
15643 if (ctx->insn_flags & ISA_MIPS_R6) {
15644
15645 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15646 rt, imm << 2, 4);
15647 } else {
15648
15649 check_cop1x(ctx);
15650 check_insn(ctx, ASE_MIPS3D);
15651 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15652 (rt >> 2) & 0x7, imm << 2);
15653 }
15654 break;
15655 case OPC_BC1NEZ:
15656 check_cp1_enabled(ctx);
15657 check_insn(ctx, ISA_MIPS_R6);
15658 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15659 rt, imm << 2, 4);
15660 break;
15661 case OPC_BC1ANY4:
15662 check_cp1_enabled(ctx);
15663 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15664 check_cop1x(ctx);
15665 check_insn(ctx, ASE_MIPS3D);
15666
15667 case OPC_BC1:
15668 check_cp1_enabled(ctx);
15669 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15670 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15671 (rt >> 2) & 0x7, imm << 2);
15672 break;
15673 case OPC_PS_FMT:
15674 check_ps(ctx);
15675
15676 case OPC_S_FMT:
15677 case OPC_D_FMT:
15678 check_cp1_enabled(ctx);
15679 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15680 (imm >> 8) & 0x7);
15681 break;
15682 case OPC_W_FMT:
15683 case OPC_L_FMT:
15684 {
15685 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15686 check_cp1_enabled(ctx);
15687 if (ctx->insn_flags & ISA_MIPS_R6) {
15688 switch (r6_op) {
15689 case R6_OPC_CMP_AF_S:
15690 case R6_OPC_CMP_UN_S:
15691 case R6_OPC_CMP_EQ_S:
15692 case R6_OPC_CMP_UEQ_S:
15693 case R6_OPC_CMP_LT_S:
15694 case R6_OPC_CMP_ULT_S:
15695 case R6_OPC_CMP_LE_S:
15696 case R6_OPC_CMP_ULE_S:
15697 case R6_OPC_CMP_SAF_S:
15698 case R6_OPC_CMP_SUN_S:
15699 case R6_OPC_CMP_SEQ_S:
15700 case R6_OPC_CMP_SEUQ_S:
15701 case R6_OPC_CMP_SLT_S:
15702 case R6_OPC_CMP_SULT_S:
15703 case R6_OPC_CMP_SLE_S:
15704 case R6_OPC_CMP_SULE_S:
15705 case R6_OPC_CMP_OR_S:
15706 case R6_OPC_CMP_UNE_S:
15707 case R6_OPC_CMP_NE_S:
15708 case R6_OPC_CMP_SOR_S:
15709 case R6_OPC_CMP_SUNE_S:
15710 case R6_OPC_CMP_SNE_S:
15711 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15712 break;
15713 case R6_OPC_CMP_AF_D:
15714 case R6_OPC_CMP_UN_D:
15715 case R6_OPC_CMP_EQ_D:
15716 case R6_OPC_CMP_UEQ_D:
15717 case R6_OPC_CMP_LT_D:
15718 case R6_OPC_CMP_ULT_D:
15719 case R6_OPC_CMP_LE_D:
15720 case R6_OPC_CMP_ULE_D:
15721 case R6_OPC_CMP_SAF_D:
15722 case R6_OPC_CMP_SUN_D:
15723 case R6_OPC_CMP_SEQ_D:
15724 case R6_OPC_CMP_SEUQ_D:
15725 case R6_OPC_CMP_SLT_D:
15726 case R6_OPC_CMP_SULT_D:
15727 case R6_OPC_CMP_SLE_D:
15728 case R6_OPC_CMP_SULE_D:
15729 case R6_OPC_CMP_OR_D:
15730 case R6_OPC_CMP_UNE_D:
15731 case R6_OPC_CMP_NE_D:
15732 case R6_OPC_CMP_SOR_D:
15733 case R6_OPC_CMP_SUNE_D:
15734 case R6_OPC_CMP_SNE_D:
15735 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15736 break;
15737 default:
15738 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15739 rt, rd, sa, (imm >> 8) & 0x7);
15740
15741 break;
15742 }
15743 } else {
15744 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15745 (imm >> 8) & 0x7);
15746 }
15747 break;
15748 }
15749 default:
15750 MIPS_INVAL("cp1");
15751 gen_reserved_instruction(ctx);
15752 break;
15753 }
15754 break;
15755
15756
15757 case OPC_BC:
15758 case OPC_BALC:
15759 if (ctx->insn_flags & ISA_MIPS_R6) {
15760
15761 gen_compute_compact_branch(ctx, op, 0, 0,
15762 sextract32(ctx->opcode << 2, 0, 28));
15763 } else if (ctx->insn_flags & ASE_LEXT) {
15764 gen_loongson_lswc2(ctx, rt, rs, rd);
15765 } else {
15766
15767
15768 generate_exception_err(ctx, EXCP_CpU, 2);
15769 }
15770 break;
15771 case OPC_BEQZC:
15772 case OPC_BNEZC:
15773 if (ctx->insn_flags & ISA_MIPS_R6) {
15774 if (rs != 0) {
15775
15776 gen_compute_compact_branch(ctx, op, rs, 0,
15777 sextract32(ctx->opcode << 2, 0, 23));
15778 } else {
15779
15780 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15781 }
15782 } else if (ctx->insn_flags & ASE_LEXT) {
15783 gen_loongson_lsdc2(ctx, rt, rs, rd);
15784 } else {
15785
15786
15787 generate_exception_err(ctx, EXCP_CpU, 2);
15788 }
15789 break;
15790 case OPC_CP2:
15791 check_insn(ctx, ASE_LMMI);
15792
15793 gen_loongson_multimedia(ctx, sa, rd, rt);
15794 break;
15795
15796 case OPC_CP3:
15797 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15798 check_cp1_enabled(ctx);
15799 op1 = MASK_CP3(ctx->opcode);
15800 switch (op1) {
15801 case OPC_LUXC1:
15802 case OPC_SUXC1:
15803 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15804
15805 case OPC_LWXC1:
15806 case OPC_LDXC1:
15807 case OPC_SWXC1:
15808 case OPC_SDXC1:
15809 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15810 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15811 break;
15812 case OPC_PREFX:
15813 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15814
15815 break;
15816 case OPC_ALNV_PS:
15817 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15818
15819 case OPC_MADD_S:
15820 case OPC_MADD_D:
15821 case OPC_MADD_PS:
15822 case OPC_MSUB_S:
15823 case OPC_MSUB_D:
15824 case OPC_MSUB_PS:
15825 case OPC_NMADD_S:
15826 case OPC_NMADD_D:
15827 case OPC_NMADD_PS:
15828 case OPC_NMSUB_S:
15829 case OPC_NMSUB_D:
15830 case OPC_NMSUB_PS:
15831 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15832 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15833 break;
15834 default:
15835 MIPS_INVAL("cp3");
15836 gen_reserved_instruction(ctx);
15837 break;
15838 }
15839 } else {
15840 generate_exception_err(ctx, EXCP_CpU, 1);
15841 }
15842 break;
15843
15844#if defined(TARGET_MIPS64)
15845
15846 case OPC_LLD:
15847 if (ctx->insn_flags & INSN_R5900) {
15848 check_insn_opc_user_only(ctx, INSN_R5900);
15849 }
15850
15851 case OPC_LDL:
15852 case OPC_LDR:
15853 case OPC_LWU:
15854 case OPC_LD:
15855 check_insn(ctx, ISA_MIPS3);
15856 check_mips_64(ctx);
15857 gen_ld(ctx, op, rt, rs, imm);
15858 break;
15859 case OPC_SDL:
15860 case OPC_SDR:
15861 case OPC_SD:
15862 check_insn(ctx, ISA_MIPS3);
15863 check_mips_64(ctx);
15864 gen_st(ctx, op, rt, rs, imm);
15865 break;
15866 case OPC_SCD:
15867 check_insn(ctx, ISA_MIPS3);
15868 if (ctx->insn_flags & INSN_R5900) {
15869 check_insn_opc_user_only(ctx, INSN_R5900);
15870 }
15871 check_mips_64(ctx);
15872 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
15873 break;
15874 case OPC_BNVC:
15875 if (ctx->insn_flags & ISA_MIPS_R6) {
15876
15877 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15878 } else {
15879
15880 check_insn(ctx, ISA_MIPS3);
15881 check_mips_64(ctx);
15882 gen_arith_imm(ctx, op, rt, rs, imm);
15883 }
15884 break;
15885 case OPC_DADDIU:
15886 check_insn(ctx, ISA_MIPS3);
15887 check_mips_64(ctx);
15888 gen_arith_imm(ctx, op, rt, rs, imm);
15889 break;
15890#else
15891 case OPC_BNVC:
15892 if (ctx->insn_flags & ISA_MIPS_R6) {
15893 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15894 } else {
15895 MIPS_INVAL("major opcode");
15896 gen_reserved_instruction(ctx);
15897 }
15898 break;
15899#endif
15900 case OPC_DAUI:
15901 if (ctx->insn_flags & ISA_MIPS_R6) {
15902#if defined(TARGET_MIPS64)
15903
15904 check_mips_64(ctx);
15905 if (rs == 0) {
15906 generate_exception(ctx, EXCP_RI);
15907 } else if (rt != 0) {
15908 TCGv t0 = tcg_temp_new();
15909 gen_load_gpr(t0, rs);
15910 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15911 tcg_temp_free(t0);
15912 }
15913#else
15914 gen_reserved_instruction(ctx);
15915 MIPS_INVAL("major opcode");
15916#endif
15917 } else {
15918
15919 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15920 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15921 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15922 }
15923 break;
15924 case OPC_MDMX:
15925
15926 break;
15927 case OPC_PCREL:
15928 check_insn(ctx, ISA_MIPS_R6);
15929 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15930 break;
15931 default:
15932 MIPS_INVAL("major opcode");
15933 return false;
15934 }
15935 return true;
15936}
15937
15938static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15939{
15940
15941 if (ctx->base.pc_next & 0x3) {
15942 env->CP0_BadVAddr = ctx->base.pc_next;
15943 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15944 return;
15945 }
15946
15947
15948 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15949 TCGLabel *l1 = gen_new_label();
15950
15951 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15952 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15953 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15954 gen_set_label(l1);
15955 }
15956
15957
15958
15959
15960 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15961 return;
15962 }
15963 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15964 return;
15965 }
15966
15967
15968 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15969 return;
15970 }
15971
15972
15973 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15974 return;
15975 }
15976
15977 if (decode_opc_legacy(env, ctx)) {
15978 return;
15979 }
15980
15981 gen_reserved_instruction(ctx);
15982}
15983
15984static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15985{
15986 DisasContext *ctx = container_of(dcbase, DisasContext, base);
15987 CPUMIPSState *env = cs->env_ptr;
15988
15989 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15990 ctx->saved_pc = -1;
15991 ctx->insn_flags = env->insn_flags;
15992 ctx->CP0_Config0 = env->CP0_Config0;
15993 ctx->CP0_Config1 = env->CP0_Config1;
15994 ctx->CP0_Config2 = env->CP0_Config2;
15995 ctx->CP0_Config3 = env->CP0_Config3;
15996 ctx->CP0_Config5 = env->CP0_Config5;
15997 ctx->btarget = 0;
15998 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15999 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
16000 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
16001 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
16002 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
16003 ctx->PAMask = env->PAMask;
16004 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
16005 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
16006 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
16007 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
16008 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
16009
16010 ctx->hflags = (uint32_t)ctx->base.tb->flags;
16011 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
16012 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
16013 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
16014 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
16015 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
16016 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
16017 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
16018 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
16019 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
16020 restore_cpu_state(env, ctx);
16021#ifdef CONFIG_USER_ONLY
16022 ctx->mem_idx = MIPS_HFLAG_UM;
16023#else
16024 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
16025#endif
16026 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
16027 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
16028
16029
16030
16031
16032
16033
16034
16035 if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
16036 ctx->base.max_insns = 2;
16037 }
16038
16039 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16040 ctx->hflags);
16041}
16042
16043static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16044{
16045}
16046
16047static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16048{
16049 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16050
16051 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16052 ctx->btarget);
16053}
16054
16055static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16056{
16057 CPUMIPSState *env = cs->env_ptr;
16058 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16059 int insn_bytes;
16060 int is_slot;
16061
16062 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
16063 if (ctx->insn_flags & ISA_NANOMIPS32) {
16064 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16065 insn_bytes = decode_isa_nanomips(env, ctx);
16066 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
16067 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
16068 insn_bytes = 4;
16069 decode_opc(env, ctx);
16070 } else if (ctx->insn_flags & ASE_MICROMIPS) {
16071 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16072 insn_bytes = decode_isa_micromips(env, ctx);
16073 } else if (ctx->insn_flags & ASE_MIPS16) {
16074 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16075 insn_bytes = decode_ase_mips16e(env, ctx);
16076 } else {
16077 gen_reserved_instruction(ctx);
16078 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16079 return;
16080 }
16081
16082 if (ctx->hflags & MIPS_HFLAG_BMASK) {
16083 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16084 MIPS_HFLAG_FBNSLOT))) {
16085
16086
16087
16088
16089 is_slot = 1;
16090 }
16091 if ((ctx->hflags & MIPS_HFLAG_M16) &&
16092 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
16093
16094
16095
16096
16097 is_slot = 1;
16098 }
16099 }
16100 if (is_slot) {
16101 gen_branch(ctx, insn_bytes);
16102 }
16103 ctx->base.pc_next += insn_bytes;
16104
16105 if (ctx->base.is_jmp != DISAS_NEXT) {
16106 return;
16107 }
16108
16109
16110
16111
16112
16113
16114 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
16115 && !ctx->base.singlestep_enabled) {
16116 ctx->base.is_jmp = DISAS_TOO_MANY;
16117 }
16118}
16119
16120static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16121{
16122 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16123
16124 switch (ctx->base.is_jmp) {
16125 case DISAS_STOP:
16126 gen_save_pc(ctx->base.pc_next);
16127 tcg_gen_lookup_and_goto_ptr();
16128 break;
16129 case DISAS_NEXT:
16130 case DISAS_TOO_MANY:
16131 save_cpu_state(ctx, 0);
16132 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16133 break;
16134 case DISAS_EXIT:
16135 tcg_gen_exit_tb(NULL, 0);
16136 break;
16137 case DISAS_NORETURN:
16138 break;
16139 default:
16140 g_assert_not_reached();
16141 }
16142}
16143
16144static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
16145{
16146 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
16147 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
16148}
16149
16150static const TranslatorOps mips_tr_ops = {
16151 .init_disas_context = mips_tr_init_disas_context,
16152 .tb_start = mips_tr_tb_start,
16153 .insn_start = mips_tr_insn_start,
16154 .translate_insn = mips_tr_translate_insn,
16155 .tb_stop = mips_tr_tb_stop,
16156 .disas_log = mips_tr_disas_log,
16157};
16158
16159void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
16160{
16161 DisasContext ctx;
16162
16163 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
16164}
16165
16166void mips_tcg_init(void)
16167{
16168 int i;
16169
16170 cpu_gpr[0] = NULL;
16171 for (i = 1; i < 32; i++)
16172 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16173 offsetof(CPUMIPSState,
16174 active_tc.gpr[i]),
16175 regnames[i]);
16176#if defined(TARGET_MIPS64)
16177 cpu_gpr_hi[0] = NULL;
16178
16179 for (unsigned i = 1; i < 32; i++) {
16180 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16181
16182 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16183 offsetof(CPUMIPSState,
16184 active_tc.gpr_hi[i]),
16185 rname);
16186 }
16187#endif
16188 for (i = 0; i < 32; i++) {
16189 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
16190
16191 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16192 }
16193 msa_translate_init();
16194 cpu_PC = tcg_global_mem_new(cpu_env,
16195 offsetof(CPUMIPSState, active_tc.PC), "PC");
16196 for (i = 0; i < MIPS_DSP_ACC; i++) {
16197 cpu_HI[i] = tcg_global_mem_new(cpu_env,
16198 offsetof(CPUMIPSState, active_tc.HI[i]),
16199 regnames_HI[i]);
16200 cpu_LO[i] = tcg_global_mem_new(cpu_env,
16201 offsetof(CPUMIPSState, active_tc.LO[i]),
16202 regnames_LO[i]);
16203 }
16204 cpu_dspctrl = tcg_global_mem_new(cpu_env,
16205 offsetof(CPUMIPSState,
16206 active_tc.DSPControl),
16207 "DSPControl");
16208 bcond = tcg_global_mem_new(cpu_env,
16209 offsetof(CPUMIPSState, bcond), "bcond");
16210 btarget = tcg_global_mem_new(cpu_env,
16211 offsetof(CPUMIPSState, btarget), "btarget");
16212 hflags = tcg_global_mem_new_i32(cpu_env,
16213 offsetof(CPUMIPSState, hflags), "hflags");
16214
16215 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
16216 offsetof(CPUMIPSState, active_fpu.fcr0),
16217 "fcr0");
16218 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
16219 offsetof(CPUMIPSState, active_fpu.fcr31),
16220 "fcr31");
16221 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16222 "lladdr");
16223 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16224 "llval");
16225
16226 if (TARGET_LONG_BITS == 32) {
16227 mxu_translate_init();
16228 }
16229}
16230
16231void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16232 target_ulong *data)
16233{
16234 env->active_tc.PC = data[0];
16235 env->hflags &= ~MIPS_HFLAG_BMASK;
16236 env->hflags |= data[1];
16237 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16238 case MIPS_HFLAG_BR:
16239 break;
16240 case MIPS_HFLAG_BC:
16241 case MIPS_HFLAG_BL:
16242 case MIPS_HFLAG_B:
16243 env->btarget = data[2];
16244 break;
16245 }
16246}
16247