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