1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "cpu.h"
27#include "internal.h"
28#include "tcg/tcg-op.h"
29#include "exec/translator.h"
30#include "exec/helper-proto.h"
31#include "exec/helper-gen.h"
32#include "semihosting/semihost.h"
33
34#include "trace.h"
35#include "exec/translator.h"
36#include "exec/log.h"
37#include "qemu/qemu-print.h"
38#include "fpu_helper.h"
39#include "translate.h"
40
41
42
43
44
45
46#define STUB_HELPER(NAME, ...) \
47 static inline void gen_helper_##NAME(__VA_ARGS__) \
48 { g_assert_not_reached(); }
49
50#ifdef CONFIG_USER_ONLY
51STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
52#endif
53
54enum {
55
56 OPC_SPECIAL = (0x00 << 26),
57 OPC_REGIMM = (0x01 << 26),
58 OPC_CP0 = (0x10 << 26),
59 OPC_CP2 = (0x12 << 26),
60 OPC_CP3 = (0x13 << 26),
61 OPC_SPECIAL2 = (0x1C << 26),
62 OPC_SPECIAL3 = (0x1F << 26),
63
64 OPC_ADDI = (0x08 << 26),
65 OPC_ADDIU = (0x09 << 26),
66 OPC_SLTI = (0x0A << 26),
67 OPC_SLTIU = (0x0B << 26),
68
69 OPC_ANDI = (0x0C << 26),
70 OPC_ORI = (0x0D << 26),
71 OPC_XORI = (0x0E << 26),
72 OPC_LUI = (0x0F << 26),
73
74 OPC_DADDI = (0x18 << 26),
75 OPC_DADDIU = (0x19 << 26),
76
77 OPC_J = (0x02 << 26),
78 OPC_JAL = (0x03 << 26),
79 OPC_BEQ = (0x04 << 26),
80 OPC_BEQL = (0x14 << 26),
81 OPC_BNE = (0x05 << 26),
82 OPC_BNEL = (0x15 << 26),
83 OPC_BLEZ = (0x06 << 26),
84 OPC_BLEZL = (0x16 << 26),
85 OPC_BGTZ = (0x07 << 26),
86 OPC_BGTZL = (0x17 << 26),
87 OPC_JALX = (0x1D << 26),
88 OPC_DAUI = (0x1D << 26),
89
90 OPC_LDL = (0x1A << 26),
91 OPC_LDR = (0x1B << 26),
92 OPC_LB = (0x20 << 26),
93 OPC_LH = (0x21 << 26),
94 OPC_LWL = (0x22 << 26),
95 OPC_LW = (0x23 << 26),
96 OPC_LWPC = OPC_LW | 0x5,
97 OPC_LBU = (0x24 << 26),
98 OPC_LHU = (0x25 << 26),
99 OPC_LWR = (0x26 << 26),
100 OPC_LWU = (0x27 << 26),
101 OPC_SB = (0x28 << 26),
102 OPC_SH = (0x29 << 26),
103 OPC_SWL = (0x2A << 26),
104 OPC_SW = (0x2B << 26),
105 OPC_SDL = (0x2C << 26),
106 OPC_SDR = (0x2D << 26),
107 OPC_SWR = (0x2E << 26),
108 OPC_LL = (0x30 << 26),
109 OPC_LLD = (0x34 << 26),
110 OPC_LD = (0x37 << 26),
111 OPC_LDPC = OPC_LD | 0x5,
112 OPC_SC = (0x38 << 26),
113 OPC_SCD = (0x3C << 26),
114 OPC_SD = (0x3F << 26),
115
116 OPC_LWC1 = (0x31 << 26),
117 OPC_LWC2 = (0x32 << 26),
118 OPC_LDC1 = (0x35 << 26),
119 OPC_LDC2 = (0x36 << 26),
120 OPC_SWC1 = (0x39 << 26),
121 OPC_SWC2 = (0x3A << 26),
122 OPC_SDC1 = (0x3D << 26),
123 OPC_SDC2 = (0x3E << 26),
124
125 OPC_BLEZALC = (0x06 << 26),
126 OPC_BGEZALC = (0x06 << 26),
127 OPC_BGEUC = (0x06 << 26),
128 OPC_BGTZALC = (0x07 << 26),
129 OPC_BLTZALC = (0x07 << 26),
130 OPC_BLTUC = (0x07 << 26),
131 OPC_BOVC = (0x08 << 26),
132 OPC_BEQZALC = (0x08 << 26),
133 OPC_BEQC = (0x08 << 26),
134 OPC_BLEZC = (0x16 << 26),
135 OPC_BGEZC = (0x16 << 26),
136 OPC_BGEC = (0x16 << 26),
137 OPC_BGTZC = (0x17 << 26),
138 OPC_BLTZC = (0x17 << 26),
139 OPC_BLTC = (0x17 << 26),
140 OPC_BNVC = (0x18 << 26),
141 OPC_BNEZALC = (0x18 << 26),
142 OPC_BNEC = (0x18 << 26),
143 OPC_BC = (0x32 << 26),
144 OPC_BEQZC = (0x36 << 26),
145 OPC_JIC = (0x36 << 26),
146 OPC_BALC = (0x3A << 26),
147 OPC_BNEZC = (0x3E << 26),
148 OPC_JIALC = (0x3E << 26),
149
150 OPC_MDMX = (0x1E << 26),
151
152 OPC_CACHE = (0x2F << 26),
153 OPC_PREF = (0x33 << 26),
154
155 OPC_PCREL = (0x3B << 26),
156};
157
158
159#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
160#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
161enum {
162
163 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
164 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
165 OPC_LWUPC = OPC_PCREL | (2 << 19),
166
167
168 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
169 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
170
171
172 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
173};
174
175
176#define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
177
178enum {
179
180 OPC_SLL = 0x00 | OPC_SPECIAL,
181
182
183
184 OPC_SRL = 0x02 | OPC_SPECIAL,
185 OPC_ROTR = OPC_SRL | (1 << 21),
186 OPC_SRA = 0x03 | OPC_SPECIAL,
187 OPC_SLLV = 0x04 | OPC_SPECIAL,
188 OPC_SRLV = 0x06 | OPC_SPECIAL,
189 OPC_ROTRV = OPC_SRLV | (1 << 6),
190 OPC_SRAV = 0x07 | OPC_SPECIAL,
191 OPC_DSLLV = 0x14 | OPC_SPECIAL,
192 OPC_DSRLV = 0x16 | OPC_SPECIAL,
193 OPC_DROTRV = OPC_DSRLV | (1 << 6),
194 OPC_DSRAV = 0x17 | OPC_SPECIAL,
195 OPC_DSLL = 0x38 | OPC_SPECIAL,
196 OPC_DSRL = 0x3A | OPC_SPECIAL,
197 OPC_DROTR = OPC_DSRL | (1 << 21),
198 OPC_DSRA = 0x3B | OPC_SPECIAL,
199 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
200 OPC_DSRL32 = 0x3E | OPC_SPECIAL,
201 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
202 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
203
204 OPC_MULT = 0x18 | OPC_SPECIAL,
205 OPC_MULTU = 0x19 | OPC_SPECIAL,
206 OPC_DIV = 0x1A | OPC_SPECIAL,
207 OPC_DIVU = 0x1B | OPC_SPECIAL,
208 OPC_DMULT = 0x1C | OPC_SPECIAL,
209 OPC_DMULTU = 0x1D | OPC_SPECIAL,
210 OPC_DDIV = 0x1E | OPC_SPECIAL,
211 OPC_DDIVU = 0x1F | OPC_SPECIAL,
212
213
214 OPC_ADD = 0x20 | OPC_SPECIAL,
215 OPC_ADDU = 0x21 | OPC_SPECIAL,
216 OPC_SUB = 0x22 | OPC_SPECIAL,
217 OPC_SUBU = 0x23 | OPC_SPECIAL,
218 OPC_AND = 0x24 | OPC_SPECIAL,
219 OPC_OR = 0x25 | OPC_SPECIAL,
220 OPC_XOR = 0x26 | OPC_SPECIAL,
221 OPC_NOR = 0x27 | OPC_SPECIAL,
222 OPC_SLT = 0x2A | OPC_SPECIAL,
223 OPC_SLTU = 0x2B | OPC_SPECIAL,
224 OPC_DADD = 0x2C | OPC_SPECIAL,
225 OPC_DADDU = 0x2D | OPC_SPECIAL,
226 OPC_DSUB = 0x2E | OPC_SPECIAL,
227 OPC_DSUBU = 0x2F | OPC_SPECIAL,
228
229 OPC_JR = 0x08 | OPC_SPECIAL,
230 OPC_JALR = 0x09 | OPC_SPECIAL,
231
232 OPC_TGE = 0x30 | OPC_SPECIAL,
233 OPC_TGEU = 0x31 | OPC_SPECIAL,
234 OPC_TLT = 0x32 | OPC_SPECIAL,
235 OPC_TLTU = 0x33 | OPC_SPECIAL,
236 OPC_TEQ = 0x34 | OPC_SPECIAL,
237 OPC_TNE = 0x36 | OPC_SPECIAL,
238
239 OPC_MFHI = 0x10 | OPC_SPECIAL,
240 OPC_MTHI = 0x11 | OPC_SPECIAL,
241 OPC_MFLO = 0x12 | OPC_SPECIAL,
242 OPC_MTLO = 0x13 | OPC_SPECIAL,
243
244 OPC_MOVZ = 0x0A | OPC_SPECIAL,
245 OPC_MOVN = 0x0B | OPC_SPECIAL,
246
247 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
248 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
249
250 OPC_MOVCI = 0x01 | OPC_SPECIAL,
251
252
253 OPC_PMON = 0x05 | OPC_SPECIAL,
254 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
255 OPC_BREAK = 0x0D | OPC_SPECIAL,
256 OPC_SPIM = 0x0E | OPC_SPECIAL,
257 OPC_SYNC = 0x0F | OPC_SPECIAL,
258
259 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
260 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
261 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
262 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
263};
264
265
266
267
268
269#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
270
271enum {
272 R6_OPC_MUL = OPC_MULT | (2 << 6),
273 R6_OPC_MUH = OPC_MULT | (3 << 6),
274 R6_OPC_MULU = OPC_MULTU | (2 << 6),
275 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
276 R6_OPC_DIV = OPC_DIV | (2 << 6),
277 R6_OPC_MOD = OPC_DIV | (3 << 6),
278 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
279 R6_OPC_MODU = OPC_DIVU | (3 << 6),
280
281 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
282 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
283 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
284 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
285 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
286 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
287 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
288 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
289
290 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
291 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
292 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
293 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
294 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
295};
296
297
298#define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
299
300enum {
301 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
302 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
303 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
304 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
305 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
306 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
307 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
308 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
309 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
310 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
311 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
312 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
313 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
314 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
315 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
316 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
317
318 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
319 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
320};
321
322
323#define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
324
325enum {
326
327 OPC_MADD = 0x00 | OPC_SPECIAL2,
328 OPC_MADDU = 0x01 | OPC_SPECIAL2,
329 OPC_MUL = 0x02 | OPC_SPECIAL2,
330 OPC_MSUB = 0x04 | OPC_SPECIAL2,
331 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
332
333 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
334 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
335 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
336 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
337 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
338 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
339 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
340 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
341 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
342 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
343 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
344 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
345
346 OPC_CLZ = 0x20 | OPC_SPECIAL2,
347 OPC_CLO = 0x21 | OPC_SPECIAL2,
348 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
349 OPC_DCLO = 0x25 | OPC_SPECIAL2,
350
351 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
352};
353
354
355#define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
356
357enum {
358 OPC_EXT = 0x00 | OPC_SPECIAL3,
359 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
360 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
361 OPC_DEXT = 0x03 | OPC_SPECIAL3,
362 OPC_INS = 0x04 | OPC_SPECIAL3,
363 OPC_DINSM = 0x05 | OPC_SPECIAL3,
364 OPC_DINSU = 0x06 | OPC_SPECIAL3,
365 OPC_DINS = 0x07 | OPC_SPECIAL3,
366 OPC_FORK = 0x08 | OPC_SPECIAL3,
367 OPC_YIELD = 0x09 | OPC_SPECIAL3,
368 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
369 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
370 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
371 OPC_GINV = 0x3D | OPC_SPECIAL3,
372
373
374 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
375 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
376 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
377 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
378 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
379 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
380 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
381 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
382 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
383 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
384 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
385 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
386
387
388 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
389
390 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
391 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
392 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
393 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
394
395
396 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
397 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
398
399 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
400 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
401
402
403
404 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
405 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
406
407 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
408 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
409
410 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
411 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
412
413 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
414 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
415
416
417 OPC_LWLE = 0x19 | OPC_SPECIAL3,
418 OPC_LWRE = 0x1A | OPC_SPECIAL3,
419 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
420 OPC_SBE = 0x1C | OPC_SPECIAL3,
421 OPC_SHE = 0x1D | OPC_SPECIAL3,
422 OPC_SCE = 0x1E | OPC_SPECIAL3,
423 OPC_SWE = 0x1F | OPC_SPECIAL3,
424 OPC_SWLE = 0x21 | OPC_SPECIAL3,
425 OPC_SWRE = 0x22 | OPC_SPECIAL3,
426 OPC_PREFE = 0x23 | OPC_SPECIAL3,
427 OPC_LBUE = 0x28 | OPC_SPECIAL3,
428 OPC_LHUE = 0x29 | OPC_SPECIAL3,
429 OPC_LBE = 0x2C | OPC_SPECIAL3,
430 OPC_LHE = 0x2D | OPC_SPECIAL3,
431 OPC_LLE = 0x2E | OPC_SPECIAL3,
432 OPC_LWE = 0x2F | OPC_SPECIAL3,
433
434
435 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
436 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
437 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
438 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
439 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
440 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
441};
442
443
444#define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
445enum {
446 OPC_GSLQ = 0x0020 | OPC_LWC2,
447 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
448 OPC_GSSHFL = OPC_LWC2,
449 OPC_GSSQ = 0x0020 | OPC_SWC2,
450 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
451 OPC_GSSHFS = OPC_SWC2,
452};
453
454
455#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
456enum {
457 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
458 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
459 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
460 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
461 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
462 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
463 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
464 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
465};
466
467
468#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
469
470enum {
471 OPC_GSLBX = 0x0 | OPC_LDC2,
472 OPC_GSLHX = 0x1 | OPC_LDC2,
473 OPC_GSLWX = 0x2 | OPC_LDC2,
474 OPC_GSLDX = 0x3 | OPC_LDC2,
475 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
476 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
477 OPC_GSSBX = 0x0 | OPC_SDC2,
478 OPC_GSSHX = 0x1 | OPC_SDC2,
479 OPC_GSSWX = 0x2 | OPC_SDC2,
480 OPC_GSSDX = 0x3 | OPC_SDC2,
481 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
482 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
483};
484
485
486#define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
487
488enum {
489 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
490 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
491 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
492 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL,
493 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
494 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
495 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
496 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL
497};
498
499
500#define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
501
502enum {
503 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
504 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
505 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL,
506 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
507 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
508 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
509 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
510 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
511 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
512 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
513 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL,
514};
515
516
517enum {
518 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
519 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
520};
521
522#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
523
524enum {
525 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
526 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
527 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
528 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
529};
530
531#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
532enum {
533
534 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
535 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
536 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
537 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
538 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
539 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
540 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
541 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
542 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
543 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
544 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
545 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
546 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
547 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
548 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
549 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
550 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
551 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
552
553 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
554 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
555 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
556 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
557 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
558 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
559};
560
561#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
562#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
563enum {
564
565 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
566 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
567 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
568 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
569 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
570 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
571 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
572 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
573 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
574 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
575 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
576 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
577
578 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
579 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
580 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
581 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
582};
583
584#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
585enum {
586
587 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
588 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
589 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
590 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
591 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
592 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
593 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
594 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
595 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
596 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
597 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
598 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
599 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
600
601 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
602 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
603 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
604 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
605 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
606};
607
608#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
609enum {
610
611 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
612 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
613 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
614 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
615 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
616 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
617 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
618
619 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
620 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
621 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
622 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
623 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
624 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
625 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
626 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
627 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
628 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
629 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
630 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
631 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
633 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
634};
635
636#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637enum {
638
639 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
640 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
641 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
642 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
643 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
644 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
645 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
646 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
647 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
648 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
649 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
650 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
651 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
652 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
653 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
654 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
655 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
656 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
657 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
658 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
659 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
660 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
661};
662
663#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
664enum {
665
666 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
667 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
668 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
669 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
670 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
671 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
672 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
673 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
674 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
675 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
676 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
677 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
678 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
679 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
680 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
681 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
682 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
683 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
684 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
685 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
686 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
687 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
688};
689
690#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
691enum {
692
693 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
694};
695
696#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
697enum {
698
699 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
700 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
701 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
702};
703
704#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705enum {
706
707 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
708 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
709 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
710 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
711 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
712 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
713 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
714 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
715 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
716 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
717 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
718 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
719 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
720 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
721 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
722 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
723 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
724};
725
726#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
727enum {
728
729 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
730 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
731 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
732 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
733 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
734 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
735 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
736 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
737 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
738 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
739 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
740 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
741 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
742 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
743 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
744 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
745 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
746
747 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
748 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
749 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
752 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
753};
754
755#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
756enum {
757
758 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
759 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
760 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
761 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
762 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
763
764 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
765 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
766 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
767 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
768 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
769 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
770 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
771 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
772 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
773 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
774 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
775 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
776 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
777 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
778 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
779 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
780 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
781 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
782 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
783 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
784 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
785};
786
787#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
788enum {
789
790 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
793 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
794 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
795 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
796 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
797 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
798 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
799 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
800 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
801 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
802 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
803 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
804 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
805 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
806 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
807 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
808 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
809
810 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
817 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
818};
819
820#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
821enum {
822
823 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
824 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
825 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
826 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
827};
828
829#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830enum {
831
832 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
833 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
834 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
835 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
836 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
837 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
838 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
839 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
840 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
841 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
842 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
843 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
844 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
845 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
846 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
847 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
848 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
849 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
850 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
851 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
852 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
853};
854
855#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
856enum {
857
858 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
859};
860
861#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
862enum {
863
864 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
865 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
866 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
867 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
868 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
869 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
870 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
871 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
872 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
873 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
874 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
875 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
876 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
877 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
878 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
879 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
880 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
881 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
882 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
883 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
884 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
889 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
890};
891
892#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
893enum {
894
895 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
896 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
897 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
898 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
899 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
900 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
901 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
902 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
903 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
904 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
905 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
906 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
907 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
908 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
909 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
910 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
911 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
912 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
913 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
914 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
915 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
920 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
921};
922
923
924#define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
925
926enum {
927 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
928 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
929 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
930 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
931 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
932 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
933 OPC_MFTR = (0x08 << 21) | OPC_CP0,
934 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
935 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
936 OPC_MTTR = (0x0C << 21) | OPC_CP0,
937 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
938 OPC_C0 = (0x10 << 21) | OPC_CP0,
939 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
940 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
941 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
942 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
943 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
944 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
945 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
946 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
947 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
948 OPC_C0_A = (0x1A << 21) | OPC_CP0,
949 OPC_C0_B = (0x1B << 21) | OPC_CP0,
950 OPC_C0_C = (0x1C << 21) | OPC_CP0,
951 OPC_C0_D = (0x1D << 21) | OPC_CP0,
952 OPC_C0_E = (0x1E << 21) | OPC_CP0,
953 OPC_C0_F = (0x1F << 21) | OPC_CP0,
954};
955
956
957#define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
958
959enum {
960 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
961 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
962 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
963 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
964 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
965 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
966 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
967 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
968};
969
970
971#define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
972
973enum {
974 OPC_TLBR = 0x01 | OPC_C0,
975 OPC_TLBWI = 0x02 | OPC_C0,
976 OPC_TLBINV = 0x03 | OPC_C0,
977 OPC_TLBINVF = 0x04 | OPC_C0,
978 OPC_TLBWR = 0x06 | OPC_C0,
979 OPC_TLBP = 0x08 | OPC_C0,
980 OPC_RFE = 0x10 | OPC_C0,
981 OPC_ERET = 0x18 | OPC_C0,
982 OPC_DERET = 0x1F | OPC_C0,
983 OPC_WAIT = 0x20 | OPC_C0,
984};
985
986#define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
987
988enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1000};
1001
1002#define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1013
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1022
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1031
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1040
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1047
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
1099#define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1100
1101enum {
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
1117 OPC_NMADD_D = 0x31 | OPC_CP3,
1118 OPC_NMADD_PS = 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS = 0x3E | OPC_CP3,
1122};
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160enum {
1161 MMI_OPC_CLASS_MMI = 0x1C << 26,
1162 MMI_OPC_SQ = 0x1F << 26,
1163};
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1188enum {
1189 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI,
1190 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI,
1191 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI,
1192 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI,
1193 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI,
1194 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI,
1195 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1196 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1197};
1198
1199
1200TCGv cpu_gpr[32], cpu_PC;
1201
1202
1203
1204
1205TCGv_i64 cpu_gpr_hi[32];
1206TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1207static TCGv cpu_dspctrl, btarget;
1208TCGv bcond;
1209static TCGv cpu_lladdr, cpu_llval;
1210static TCGv_i32 hflags;
1211TCGv_i32 fpu_fcr0, fpu_fcr31;
1212TCGv_i64 fpu_f64[32];
1213
1214#include "exec/gen-icount.h"
1215
1216#define DISAS_STOP DISAS_TARGET_0
1217#define DISAS_EXIT DISAS_TARGET_1
1218
1219static const char regnames_HI[][4] = {
1220 "HI0", "HI1", "HI2", "HI3",
1221};
1222
1223static const char regnames_LO[][4] = {
1224 "LO0", "LO1", "LO2", "LO3",
1225};
1226
1227
1228void gen_load_gpr(TCGv t, int reg)
1229{
1230 if (reg == 0) {
1231 tcg_gen_movi_tl(t, 0);
1232 } else {
1233 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1234 }
1235}
1236
1237void gen_store_gpr(TCGv t, int reg)
1238{
1239 if (reg != 0) {
1240 tcg_gen_mov_tl(cpu_gpr[reg], t);
1241 }
1242}
1243
1244#if defined(TARGET_MIPS64)
1245void gen_load_gpr_hi(TCGv_i64 t, int reg)
1246{
1247 if (reg == 0) {
1248 tcg_gen_movi_i64(t, 0);
1249 } else {
1250 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1251 }
1252}
1253
1254void gen_store_gpr_hi(TCGv_i64 t, int reg)
1255{
1256 if (reg != 0) {
1257 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1258 }
1259}
1260#endif
1261
1262
1263static inline void gen_load_srsgpr(int from, int to)
1264{
1265 TCGv t0 = tcg_temp_new();
1266
1267 if (from == 0) {
1268 tcg_gen_movi_tl(t0, 0);
1269 } else {
1270 TCGv_i32 t2 = tcg_temp_new_i32();
1271 TCGv_ptr addr = tcg_temp_new_ptr();
1272
1273 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1274 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1275 tcg_gen_andi_i32(t2, t2, 0xf);
1276 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1277 tcg_gen_ext_i32_ptr(addr, t2);
1278 tcg_gen_add_ptr(addr, cpu_env, addr);
1279
1280 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1281 tcg_temp_free_ptr(addr);
1282 tcg_temp_free_i32(t2);
1283 }
1284 gen_store_gpr(t0, to);
1285 tcg_temp_free(t0);
1286}
1287
1288static inline void gen_store_srsgpr(int from, int to)
1289{
1290 if (to != 0) {
1291 TCGv t0 = tcg_temp_new();
1292 TCGv_i32 t2 = tcg_temp_new_i32();
1293 TCGv_ptr addr = tcg_temp_new_ptr();
1294
1295 gen_load_gpr(t0, from);
1296 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1297 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1298 tcg_gen_andi_i32(t2, t2, 0xf);
1299 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1300 tcg_gen_ext_i32_ptr(addr, t2);
1301 tcg_gen_add_ptr(addr, cpu_env, addr);
1302
1303 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1304 tcg_temp_free_ptr(addr);
1305 tcg_temp_free_i32(t2);
1306 tcg_temp_free(t0);
1307 }
1308}
1309
1310
1311static inline void gen_save_pc(target_ulong pc)
1312{
1313 tcg_gen_movi_tl(cpu_PC, pc);
1314}
1315
1316static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1317{
1318 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1319 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1320 gen_save_pc(ctx->base.pc_next);
1321 ctx->saved_pc = ctx->base.pc_next;
1322 }
1323 if (ctx->hflags != ctx->saved_hflags) {
1324 tcg_gen_movi_i32(hflags, ctx->hflags);
1325 ctx->saved_hflags = ctx->hflags;
1326 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1327 case MIPS_HFLAG_BR:
1328 break;
1329 case MIPS_HFLAG_BC:
1330 case MIPS_HFLAG_BL:
1331 case MIPS_HFLAG_B:
1332 tcg_gen_movi_tl(btarget, ctx->btarget);
1333 break;
1334 }
1335 }
1336}
1337
1338static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1339{
1340 ctx->saved_hflags = ctx->hflags;
1341 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1342 case MIPS_HFLAG_BR:
1343 break;
1344 case MIPS_HFLAG_BC:
1345 case MIPS_HFLAG_BL:
1346 case MIPS_HFLAG_B:
1347 ctx->btarget = env->btarget;
1348 break;
1349 }
1350}
1351
1352void generate_exception_err(DisasContext *ctx, int excp, int err)
1353{
1354 save_cpu_state(ctx, 1);
1355 gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1356 tcg_constant_i32(err));
1357 ctx->base.is_jmp = DISAS_NORETURN;
1358}
1359
1360void generate_exception(DisasContext *ctx, int excp)
1361{
1362 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
1363}
1364
1365void generate_exception_end(DisasContext *ctx, int excp)
1366{
1367 generate_exception_err(ctx, excp, 0);
1368}
1369
1370void gen_reserved_instruction(DisasContext *ctx)
1371{
1372 generate_exception_end(ctx, EXCP_RI);
1373}
1374
1375
1376void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1377{
1378 if (ctx->hflags & MIPS_HFLAG_FRE) {
1379 generate_exception(ctx, EXCP_RI);
1380 }
1381 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1382}
1383
1384void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1385{
1386 TCGv_i64 t64;
1387 if (ctx->hflags & MIPS_HFLAG_FRE) {
1388 generate_exception(ctx, EXCP_RI);
1389 }
1390 t64 = tcg_temp_new_i64();
1391 tcg_gen_extu_i32_i64(t64, t);
1392 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1393 tcg_temp_free_i64(t64);
1394}
1395
1396static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1397{
1398 if (ctx->hflags & MIPS_HFLAG_F64) {
1399 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1400 } else {
1401 gen_load_fpr32(ctx, t, reg | 1);
1402 }
1403}
1404
1405static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1406{
1407 if (ctx->hflags & MIPS_HFLAG_F64) {
1408 TCGv_i64 t64 = tcg_temp_new_i64();
1409 tcg_gen_extu_i32_i64(t64, t);
1410 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1411 tcg_temp_free_i64(t64);
1412 } else {
1413 gen_store_fpr32(ctx, t, reg | 1);
1414 }
1415}
1416
1417void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1418{
1419 if (ctx->hflags & MIPS_HFLAG_F64) {
1420 tcg_gen_mov_i64(t, fpu_f64[reg]);
1421 } else {
1422 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1423 }
1424}
1425
1426void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1427{
1428 if (ctx->hflags & MIPS_HFLAG_F64) {
1429 tcg_gen_mov_i64(fpu_f64[reg], t);
1430 } else {
1431 TCGv_i64 t0;
1432 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1433 t0 = tcg_temp_new_i64();
1434 tcg_gen_shri_i64(t0, t, 32);
1435 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1436 tcg_temp_free_i64(t0);
1437 }
1438}
1439
1440int get_fp_bit(int cc)
1441{
1442 if (cc) {
1443 return 24 + cc;
1444 } else {
1445 return 23;
1446 }
1447}
1448
1449
1450void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1451{
1452 tcg_gen_add_tl(ret, arg0, arg1);
1453
1454#if defined(TARGET_MIPS64)
1455 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1456 tcg_gen_ext32s_i64(ret, ret);
1457 }
1458#endif
1459}
1460
1461static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1462 target_long ofs)
1463{
1464 tcg_gen_addi_tl(ret, base, ofs);
1465
1466#if defined(TARGET_MIPS64)
1467 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1468 tcg_gen_ext32s_i64(ret, ret);
1469 }
1470#endif
1471}
1472
1473
1474static target_long addr_add(DisasContext *ctx, target_long base,
1475 target_long offset)
1476{
1477 target_long sum = base + offset;
1478
1479#if defined(TARGET_MIPS64)
1480 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1481 sum = (int32_t)sum;
1482 }
1483#endif
1484 return sum;
1485}
1486
1487
1488void gen_move_low32(TCGv ret, TCGv_i64 arg)
1489{
1490#if defined(TARGET_MIPS64)
1491 tcg_gen_ext32s_i64(ret, arg);
1492#else
1493 tcg_gen_extrl_i64_i32(ret, arg);
1494#endif
1495}
1496
1497
1498void gen_move_high32(TCGv ret, TCGv_i64 arg)
1499{
1500#if defined(TARGET_MIPS64)
1501 tcg_gen_sari_i64(ret, arg, 32);
1502#else
1503 tcg_gen_extrh_i64_i32(ret, arg);
1504#endif
1505}
1506
1507bool check_cp0_enabled(DisasContext *ctx)
1508{
1509 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1510 generate_exception_end(ctx, EXCP_CpU);
1511 return false;
1512 }
1513 return true;
1514}
1515
1516void check_cp1_enabled(DisasContext *ctx)
1517{
1518 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1519 generate_exception_err(ctx, EXCP_CpU, 1);
1520 }
1521}
1522
1523
1524
1525
1526
1527
1528void check_cop1x(DisasContext *ctx)
1529{
1530 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1531 gen_reserved_instruction(ctx);
1532 }
1533}
1534
1535
1536
1537
1538
1539void check_cp1_64bitmode(DisasContext *ctx)
1540{
1541 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1542 gen_reserved_instruction(ctx);
1543 }
1544}
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557void check_cp1_registers(DisasContext *ctx, int regs)
1558{
1559 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1560 gen_reserved_instruction(ctx);
1561 }
1562}
1563
1564
1565
1566
1567
1568static inline void check_dsp(DisasContext *ctx)
1569{
1570 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1571 if (ctx->insn_flags & ASE_DSP) {
1572 generate_exception_end(ctx, EXCP_DSPDIS);
1573 } else {
1574 gen_reserved_instruction(ctx);
1575 }
1576 }
1577}
1578
1579static inline void check_dsp_r2(DisasContext *ctx)
1580{
1581 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1582 if (ctx->insn_flags & ASE_DSP) {
1583 generate_exception_end(ctx, EXCP_DSPDIS);
1584 } else {
1585 gen_reserved_instruction(ctx);
1586 }
1587 }
1588}
1589
1590static inline void check_dsp_r3(DisasContext *ctx)
1591{
1592 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1593 if (ctx->insn_flags & ASE_DSP) {
1594 generate_exception_end(ctx, EXCP_DSPDIS);
1595 } else {
1596 gen_reserved_instruction(ctx);
1597 }
1598 }
1599}
1600
1601
1602
1603
1604
1605void check_insn(DisasContext *ctx, uint64_t flags)
1606{
1607 if (unlikely(!(ctx->insn_flags & flags))) {
1608 gen_reserved_instruction(ctx);
1609 }
1610}
1611
1612
1613
1614
1615
1616
1617static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1618{
1619 if (unlikely(ctx->insn_flags & flags)) {
1620 gen_reserved_instruction(ctx);
1621 }
1622}
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1633{
1634#ifndef CONFIG_USER_ONLY
1635 check_insn_opc_removed(ctx, flags);
1636#endif
1637}
1638
1639
1640
1641
1642
1643static inline void check_ps(DisasContext *ctx)
1644{
1645 if (unlikely(!ctx->ps)) {
1646 generate_exception(ctx, EXCP_RI);
1647 }
1648 check_cp1_64bitmode(ctx);
1649}
1650
1651
1652
1653
1654
1655void check_mips_64(DisasContext *ctx)
1656{
1657 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1658 gen_reserved_instruction(ctx);
1659 }
1660}
1661
1662#ifndef CONFIG_USER_ONLY
1663static inline void check_mvh(DisasContext *ctx)
1664{
1665 if (unlikely(!ctx->mvh)) {
1666 generate_exception(ctx, EXCP_RI);
1667 }
1668}
1669#endif
1670
1671
1672
1673
1674
1675static inline void check_xnp(DisasContext *ctx)
1676{
1677 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1678 gen_reserved_instruction(ctx);
1679 }
1680}
1681
1682#ifndef CONFIG_USER_ONLY
1683
1684
1685
1686
1687static inline void check_pw(DisasContext *ctx)
1688{
1689 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1690 gen_reserved_instruction(ctx);
1691 }
1692}
1693#endif
1694
1695
1696
1697
1698
1699static inline void check_mt(DisasContext *ctx)
1700{
1701 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1702 gen_reserved_instruction(ctx);
1703 }
1704}
1705
1706#ifndef CONFIG_USER_ONLY
1707
1708
1709
1710
1711
1712
1713static inline void check_cp0_mt(DisasContext *ctx)
1714{
1715 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1716 generate_exception_end(ctx, EXCP_CpU);
1717 } else {
1718 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1719 gen_reserved_instruction(ctx);
1720 }
1721 }
1722}
1723#endif
1724
1725
1726
1727
1728
1729static inline void check_nms(DisasContext *ctx)
1730{
1731 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1732 gen_reserved_instruction(ctx);
1733 }
1734}
1735
1736
1737
1738
1739
1740
1741static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1742{
1743 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1744 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1745 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1746 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1747 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1748 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1749 gen_reserved_instruction(ctx);
1750 }
1751}
1752
1753
1754
1755
1756
1757static inline void check_eva(DisasContext *ctx)
1758{
1759 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1760 gen_reserved_instruction(ctx);
1761 }
1762}
1763
1764
1765
1766
1767
1768
1769
1770
1771#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1772#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1773#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1774static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1775 int ft, int fs, int cc) \
1776{ \
1777 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1778 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1779 switch (ifmt) { \
1780 case FMT_PS: \
1781 check_ps(ctx); \
1782 break; \
1783 case FMT_D: \
1784 if (abs) { \
1785 check_cop1x(ctx); \
1786 } \
1787 check_cp1_registers(ctx, fs | ft); \
1788 break; \
1789 case FMT_S: \
1790 if (abs) { \
1791 check_cop1x(ctx); \
1792 } \
1793 break; \
1794 } \
1795 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1796 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1797 switch (n) { \
1798 case 0: \
1799 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1800 break; \
1801 case 1: \
1802 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1803 break; \
1804 case 2: \
1805 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1806 break; \
1807 case 3: \
1808 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1809 break; \
1810 case 4: \
1811 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1812 break; \
1813 case 5: \
1814 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1815 break; \
1816 case 6: \
1817 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1818 break; \
1819 case 7: \
1820 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1821 break; \
1822 case 8: \
1823 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1824 break; \
1825 case 9: \
1826 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1827 break; \
1828 case 10: \
1829 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1830 break; \
1831 case 11: \
1832 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1833 break; \
1834 case 12: \
1835 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1836 break; \
1837 case 13: \
1838 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1839 break; \
1840 case 14: \
1841 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1842 break; \
1843 case 15: \
1844 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1845 break; \
1846 default: \
1847 abort(); \
1848 } \
1849 tcg_temp_free_i##bits(fp0); \
1850 tcg_temp_free_i##bits(fp1); \
1851}
1852
1853FOP_CONDS(, 0, d, FMT_D, 64)
1854FOP_CONDS(abs, 1, d, FMT_D, 64)
1855FOP_CONDS(, 0, s, FMT_S, 32)
1856FOP_CONDS(abs, 1, s, FMT_S, 32)
1857FOP_CONDS(, 0, ps, FMT_PS, 64)
1858FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1859#undef FOP_CONDS
1860
1861#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1862static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1863 int ft, int fs, int fd) \
1864{ \
1865 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1866 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1867 if (ifmt == FMT_D) { \
1868 check_cp1_registers(ctx, fs | ft | fd); \
1869 } \
1870 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1871 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1872 switch (n) { \
1873 case 0: \
1874 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1875 break; \
1876 case 1: \
1877 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1878 break; \
1879 case 2: \
1880 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1881 break; \
1882 case 3: \
1883 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1884 break; \
1885 case 4: \
1886 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1887 break; \
1888 case 5: \
1889 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1890 break; \
1891 case 6: \
1892 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1893 break; \
1894 case 7: \
1895 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1896 break; \
1897 case 8: \
1898 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1899 break; \
1900 case 9: \
1901 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1902 break; \
1903 case 10: \
1904 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1905 break; \
1906 case 11: \
1907 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1908 break; \
1909 case 12: \
1910 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1911 break; \
1912 case 13: \
1913 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1914 break; \
1915 case 14: \
1916 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1917 break; \
1918 case 15: \
1919 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1920 break; \
1921 case 17: \
1922 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1923 break; \
1924 case 18: \
1925 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1926 break; \
1927 case 19: \
1928 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1929 break; \
1930 case 25: \
1931 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1932 break; \
1933 case 26: \
1934 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1935 break; \
1936 case 27: \
1937 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1938 break; \
1939 default: \
1940 abort(); \
1941 } \
1942 STORE; \
1943 tcg_temp_free_i ## bits(fp0); \
1944 tcg_temp_free_i ## bits(fp1); \
1945}
1946
1947FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1948FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1949#undef FOP_CONDNS
1950#undef gen_ldcmp_fpr32
1951#undef gen_ldcmp_fpr64
1952
1953
1954#ifdef CONFIG_USER_ONLY
1955#define OP_LD_ATOMIC(insn, fname) \
1956static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1957 DisasContext *ctx) \
1958{ \
1959 TCGv t0 = tcg_temp_new(); \
1960 tcg_gen_mov_tl(t0, arg1); \
1961 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1962 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1963 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1964 tcg_temp_free(t0); \
1965}
1966#else
1967#define OP_LD_ATOMIC(insn, fname) \
1968static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1969 DisasContext *ctx) \
1970{ \
1971 gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \
1972}
1973#endif
1974OP_LD_ATOMIC(ll, ld32s);
1975#if defined(TARGET_MIPS64)
1976OP_LD_ATOMIC(lld, ld64);
1977#endif
1978#undef OP_LD_ATOMIC
1979
1980void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1981{
1982 if (base == 0) {
1983 tcg_gen_movi_tl(addr, offset);
1984 } else if (offset == 0) {
1985 gen_load_gpr(addr, base);
1986 } else {
1987 tcg_gen_movi_tl(addr, offset);
1988 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1989 }
1990}
1991
1992static target_ulong pc_relative_pc(DisasContext *ctx)
1993{
1994 target_ulong pc = ctx->base.pc_next;
1995
1996 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1997 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1998
1999 pc -= branch_bytes;
2000 }
2001
2002 pc &= ~(target_ulong)3;
2003 return pc;
2004}
2005
2006
2007static void gen_ld(DisasContext *ctx, uint32_t opc,
2008 int rt, int base, int offset)
2009{
2010 TCGv t0, t1, t2;
2011 int mem_idx = ctx->mem_idx;
2012
2013 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2014 INSN_LOONGSON3A)) {
2015
2016
2017
2018
2019
2020 return;
2021 }
2022
2023 t0 = tcg_temp_new();
2024 gen_base_offset_addr(ctx, t0, base, offset);
2025
2026 switch (opc) {
2027#if defined(TARGET_MIPS64)
2028 case OPC_LWU:
2029 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2030 ctx->default_tcg_memop_mask);
2031 gen_store_gpr(t0, rt);
2032 break;
2033 case OPC_LD:
2034 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2035 ctx->default_tcg_memop_mask);
2036 gen_store_gpr(t0, rt);
2037 break;
2038 case OPC_LLD:
2039 case R6_OPC_LLD:
2040 op_ld_lld(t0, t0, mem_idx, ctx);
2041 gen_store_gpr(t0, rt);
2042 break;
2043 case OPC_LDL:
2044 t1 = tcg_temp_new();
2045
2046
2047
2048
2049 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2050 tcg_gen_andi_tl(t1, t0, 7);
2051 if (!cpu_is_bigendian(ctx)) {
2052 tcg_gen_xori_tl(t1, t1, 7);
2053 }
2054 tcg_gen_shli_tl(t1, t1, 3);
2055 tcg_gen_andi_tl(t0, t0, ~7);
2056 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2057 tcg_gen_shl_tl(t0, t0, t1);
2058 t2 = tcg_const_tl(-1);
2059 tcg_gen_shl_tl(t2, t2, t1);
2060 gen_load_gpr(t1, rt);
2061 tcg_gen_andc_tl(t1, t1, t2);
2062 tcg_temp_free(t2);
2063 tcg_gen_or_tl(t0, t0, t1);
2064 tcg_temp_free(t1);
2065 gen_store_gpr(t0, rt);
2066 break;
2067 case OPC_LDR:
2068 t1 = tcg_temp_new();
2069
2070
2071
2072
2073 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2074 tcg_gen_andi_tl(t1, t0, 7);
2075 if (cpu_is_bigendian(ctx)) {
2076 tcg_gen_xori_tl(t1, t1, 7);
2077 }
2078 tcg_gen_shli_tl(t1, t1, 3);
2079 tcg_gen_andi_tl(t0, t0, ~7);
2080 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2081 tcg_gen_shr_tl(t0, t0, t1);
2082 tcg_gen_xori_tl(t1, t1, 63);
2083 t2 = tcg_const_tl(0xfffffffffffffffeull);
2084 tcg_gen_shl_tl(t2, t2, t1);
2085 gen_load_gpr(t1, rt);
2086 tcg_gen_and_tl(t1, t1, t2);
2087 tcg_temp_free(t2);
2088 tcg_gen_or_tl(t0, t0, t1);
2089 tcg_temp_free(t1);
2090 gen_store_gpr(t0, rt);
2091 break;
2092 case OPC_LDPC:
2093 t1 = tcg_const_tl(pc_relative_pc(ctx));
2094 gen_op_addr_add(ctx, t0, t0, t1);
2095 tcg_temp_free(t1);
2096 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2097 gen_store_gpr(t0, rt);
2098 break;
2099#endif
2100 case OPC_LWPC:
2101 t1 = tcg_const_tl(pc_relative_pc(ctx));
2102 gen_op_addr_add(ctx, t0, t0, t1);
2103 tcg_temp_free(t1);
2104 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2105 gen_store_gpr(t0, rt);
2106 break;
2107 case OPC_LWE:
2108 mem_idx = MIPS_HFLAG_UM;
2109
2110 case OPC_LW:
2111 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2112 ctx->default_tcg_memop_mask);
2113 gen_store_gpr(t0, rt);
2114 break;
2115 case OPC_LHE:
2116 mem_idx = MIPS_HFLAG_UM;
2117
2118 case OPC_LH:
2119 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2120 ctx->default_tcg_memop_mask);
2121 gen_store_gpr(t0, rt);
2122 break;
2123 case OPC_LHUE:
2124 mem_idx = MIPS_HFLAG_UM;
2125
2126 case OPC_LHU:
2127 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2128 ctx->default_tcg_memop_mask);
2129 gen_store_gpr(t0, rt);
2130 break;
2131 case OPC_LBE:
2132 mem_idx = MIPS_HFLAG_UM;
2133
2134 case OPC_LB:
2135 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2136 gen_store_gpr(t0, rt);
2137 break;
2138 case OPC_LBUE:
2139 mem_idx = MIPS_HFLAG_UM;
2140
2141 case OPC_LBU:
2142 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2143 gen_store_gpr(t0, rt);
2144 break;
2145 case OPC_LWLE:
2146 mem_idx = MIPS_HFLAG_UM;
2147
2148 case OPC_LWL:
2149 t1 = tcg_temp_new();
2150
2151
2152
2153
2154 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2155 tcg_gen_andi_tl(t1, t0, 3);
2156 if (!cpu_is_bigendian(ctx)) {
2157 tcg_gen_xori_tl(t1, t1, 3);
2158 }
2159 tcg_gen_shli_tl(t1, t1, 3);
2160 tcg_gen_andi_tl(t0, t0, ~3);
2161 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2162 tcg_gen_shl_tl(t0, t0, t1);
2163 t2 = tcg_const_tl(-1);
2164 tcg_gen_shl_tl(t2, t2, t1);
2165 gen_load_gpr(t1, rt);
2166 tcg_gen_andc_tl(t1, t1, t2);
2167 tcg_temp_free(t2);
2168 tcg_gen_or_tl(t0, t0, t1);
2169 tcg_temp_free(t1);
2170 tcg_gen_ext32s_tl(t0, t0);
2171 gen_store_gpr(t0, rt);
2172 break;
2173 case OPC_LWRE:
2174 mem_idx = MIPS_HFLAG_UM;
2175
2176 case OPC_LWR:
2177 t1 = tcg_temp_new();
2178
2179
2180
2181
2182 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2183 tcg_gen_andi_tl(t1, t0, 3);
2184 if (cpu_is_bigendian(ctx)) {
2185 tcg_gen_xori_tl(t1, t1, 3);
2186 }
2187 tcg_gen_shli_tl(t1, t1, 3);
2188 tcg_gen_andi_tl(t0, t0, ~3);
2189 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2190 tcg_gen_shr_tl(t0, t0, t1);
2191 tcg_gen_xori_tl(t1, t1, 31);
2192 t2 = tcg_const_tl(0xfffffffeull);
2193 tcg_gen_shl_tl(t2, t2, t1);
2194 gen_load_gpr(t1, rt);
2195 tcg_gen_and_tl(t1, t1, t2);
2196 tcg_temp_free(t2);
2197 tcg_gen_or_tl(t0, t0, t1);
2198 tcg_temp_free(t1);
2199 tcg_gen_ext32s_tl(t0, t0);
2200 gen_store_gpr(t0, rt);
2201 break;
2202 case OPC_LLE:
2203 mem_idx = MIPS_HFLAG_UM;
2204
2205 case OPC_LL:
2206 case R6_OPC_LL:
2207 op_ld_ll(t0, t0, mem_idx, ctx);
2208 gen_store_gpr(t0, rt);
2209 break;
2210 }
2211 tcg_temp_free(t0);
2212}
2213
2214
2215static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2216 int base, int offset)
2217{
2218 TCGv t0 = tcg_temp_new();
2219 TCGv t1 = tcg_temp_new();
2220 int mem_idx = ctx->mem_idx;
2221
2222 gen_base_offset_addr(ctx, t0, base, offset);
2223 gen_load_gpr(t1, rt);
2224 switch (opc) {
2225#if defined(TARGET_MIPS64)
2226 case OPC_SD:
2227 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
2228 ctx->default_tcg_memop_mask);
2229 break;
2230 case OPC_SDL:
2231 gen_helper_0e2i(sdl, t1, t0, mem_idx);
2232 break;
2233 case OPC_SDR:
2234 gen_helper_0e2i(sdr, t1, t0, mem_idx);
2235 break;
2236#endif
2237 case OPC_SWE:
2238 mem_idx = MIPS_HFLAG_UM;
2239
2240 case OPC_SW:
2241 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2242 ctx->default_tcg_memop_mask);
2243 break;
2244 case OPC_SHE:
2245 mem_idx = MIPS_HFLAG_UM;
2246
2247 case OPC_SH:
2248 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2249 ctx->default_tcg_memop_mask);
2250 break;
2251 case OPC_SBE:
2252 mem_idx = MIPS_HFLAG_UM;
2253
2254 case OPC_SB:
2255 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2256 break;
2257 case OPC_SWLE:
2258 mem_idx = MIPS_HFLAG_UM;
2259
2260 case OPC_SWL:
2261 gen_helper_0e2i(swl, t1, t0, mem_idx);
2262 break;
2263 case OPC_SWRE:
2264 mem_idx = MIPS_HFLAG_UM;
2265
2266 case OPC_SWR:
2267 gen_helper_0e2i(swr, t1, t0, mem_idx);
2268 break;
2269 }
2270 tcg_temp_free(t0);
2271 tcg_temp_free(t1);
2272}
2273
2274
2275
2276static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2277 MemOp tcg_mo, bool eva)
2278{
2279 TCGv addr, t0, val;
2280 TCGLabel *l1 = gen_new_label();
2281 TCGLabel *done = gen_new_label();
2282
2283 t0 = tcg_temp_new();
2284 addr = tcg_temp_new();
2285
2286 gen_base_offset_addr(ctx, addr, base, offset);
2287 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2288 tcg_temp_free(addr);
2289 tcg_gen_movi_tl(t0, 0);
2290 gen_store_gpr(t0, rt);
2291 tcg_gen_br(done);
2292
2293 gen_set_label(l1);
2294
2295 val = tcg_temp_new();
2296 gen_load_gpr(val, rt);
2297 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2298 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2299 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2300 gen_store_gpr(t0, rt);
2301 tcg_temp_free(val);
2302
2303 gen_set_label(done);
2304 tcg_temp_free(t0);
2305}
2306
2307
2308static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2309 TCGv t0)
2310{
2311
2312
2313
2314
2315 switch (opc) {
2316 case OPC_LWC1:
2317 {
2318 TCGv_i32 fp0 = tcg_temp_new_i32();
2319 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2320 ctx->default_tcg_memop_mask);
2321 gen_store_fpr32(ctx, fp0, ft);
2322 tcg_temp_free_i32(fp0);
2323 }
2324 break;
2325 case OPC_SWC1:
2326 {
2327 TCGv_i32 fp0 = tcg_temp_new_i32();
2328 gen_load_fpr32(ctx, fp0, ft);
2329 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2330 ctx->default_tcg_memop_mask);
2331 tcg_temp_free_i32(fp0);
2332 }
2333 break;
2334 case OPC_LDC1:
2335 {
2336 TCGv_i64 fp0 = tcg_temp_new_i64();
2337 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2338 ctx->default_tcg_memop_mask);
2339 gen_store_fpr64(ctx, fp0, ft);
2340 tcg_temp_free_i64(fp0);
2341 }
2342 break;
2343 case OPC_SDC1:
2344 {
2345 TCGv_i64 fp0 = tcg_temp_new_i64();
2346 gen_load_fpr64(ctx, fp0, ft);
2347 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2348 ctx->default_tcg_memop_mask);
2349 tcg_temp_free_i64(fp0);
2350 }
2351 break;
2352 default:
2353 MIPS_INVAL("flt_ldst");
2354 gen_reserved_instruction(ctx);
2355 break;
2356 }
2357}
2358
2359static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2360 int rs, int16_t imm)
2361{
2362 TCGv t0 = tcg_temp_new();
2363
2364 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2365 check_cp1_enabled(ctx);
2366 switch (op) {
2367 case OPC_LDC1:
2368 case OPC_SDC1:
2369 check_insn(ctx, ISA_MIPS2);
2370
2371 default:
2372 gen_base_offset_addr(ctx, t0, rs, imm);
2373 gen_flt_ldst(ctx, op, rt, t0);
2374 }
2375 } else {
2376 generate_exception_err(ctx, EXCP_CpU, 1);
2377 }
2378 tcg_temp_free(t0);
2379}
2380
2381
2382static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2383 int rt, int rs, int imm)
2384{
2385 target_ulong uimm = (target_long)imm;
2386
2387 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2388
2389
2390
2391
2392 return;
2393 }
2394 switch (opc) {
2395 case OPC_ADDI:
2396 {
2397 TCGv t0 = tcg_temp_local_new();
2398 TCGv t1 = tcg_temp_new();
2399 TCGv t2 = tcg_temp_new();
2400 TCGLabel *l1 = gen_new_label();
2401
2402 gen_load_gpr(t1, rs);
2403 tcg_gen_addi_tl(t0, t1, uimm);
2404 tcg_gen_ext32s_tl(t0, t0);
2405
2406 tcg_gen_xori_tl(t1, t1, ~uimm);
2407 tcg_gen_xori_tl(t2, t0, uimm);
2408 tcg_gen_and_tl(t1, t1, t2);
2409 tcg_temp_free(t2);
2410 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2411 tcg_temp_free(t1);
2412
2413 generate_exception(ctx, EXCP_OVERFLOW);
2414 gen_set_label(l1);
2415 tcg_gen_ext32s_tl(t0, t0);
2416 gen_store_gpr(t0, rt);
2417 tcg_temp_free(t0);
2418 }
2419 break;
2420 case OPC_ADDIU:
2421 if (rs != 0) {
2422 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2423 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2424 } else {
2425 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2426 }
2427 break;
2428#if defined(TARGET_MIPS64)
2429 case OPC_DADDI:
2430 {
2431 TCGv t0 = tcg_temp_local_new();
2432 TCGv t1 = tcg_temp_new();
2433 TCGv t2 = tcg_temp_new();
2434 TCGLabel *l1 = gen_new_label();
2435
2436 gen_load_gpr(t1, rs);
2437 tcg_gen_addi_tl(t0, t1, uimm);
2438
2439 tcg_gen_xori_tl(t1, t1, ~uimm);
2440 tcg_gen_xori_tl(t2, t0, uimm);
2441 tcg_gen_and_tl(t1, t1, t2);
2442 tcg_temp_free(t2);
2443 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2444 tcg_temp_free(t1);
2445
2446 generate_exception(ctx, EXCP_OVERFLOW);
2447 gen_set_label(l1);
2448 gen_store_gpr(t0, rt);
2449 tcg_temp_free(t0);
2450 }
2451 break;
2452 case OPC_DADDIU:
2453 if (rs != 0) {
2454 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2455 } else {
2456 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2457 }
2458 break;
2459#endif
2460 }
2461}
2462
2463
2464static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2465 int rt, int rs, int16_t imm)
2466{
2467 target_ulong uimm;
2468
2469 if (rt == 0) {
2470
2471 return;
2472 }
2473 uimm = (uint16_t)imm;
2474 switch (opc) {
2475 case OPC_ANDI:
2476 if (likely(rs != 0)) {
2477 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2478 } else {
2479 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2480 }
2481 break;
2482 case OPC_ORI:
2483 if (rs != 0) {
2484 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2485 } else {
2486 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2487 }
2488 break;
2489 case OPC_XORI:
2490 if (likely(rs != 0)) {
2491 tcg_gen_xori_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_LUI:
2497 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2498
2499 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2500 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2501 } else {
2502 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2503 }
2504 break;
2505
2506 default:
2507 break;
2508 }
2509}
2510
2511
2512static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2513 int rt, int rs, int16_t imm)
2514{
2515 target_ulong uimm = (target_long)imm;
2516 TCGv t0;
2517
2518 if (rt == 0) {
2519
2520 return;
2521 }
2522 t0 = tcg_temp_new();
2523 gen_load_gpr(t0, rs);
2524 switch (opc) {
2525 case OPC_SLTI:
2526 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2527 break;
2528 case OPC_SLTIU:
2529 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2530 break;
2531 }
2532 tcg_temp_free(t0);
2533}
2534
2535
2536static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2537 int rt, int rs, int16_t imm)
2538{
2539 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2540 TCGv t0;
2541
2542 if (rt == 0) {
2543
2544 return;
2545 }
2546
2547 t0 = tcg_temp_new();
2548 gen_load_gpr(t0, rs);
2549 switch (opc) {
2550 case OPC_SLL:
2551 tcg_gen_shli_tl(t0, t0, uimm);
2552 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2553 break;
2554 case OPC_SRA:
2555 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2556 break;
2557 case OPC_SRL:
2558 if (uimm != 0) {
2559 tcg_gen_ext32u_tl(t0, t0);
2560 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2561 } else {
2562 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2563 }
2564 break;
2565 case OPC_ROTR:
2566 if (uimm != 0) {
2567 TCGv_i32 t1 = tcg_temp_new_i32();
2568
2569 tcg_gen_trunc_tl_i32(t1, t0);
2570 tcg_gen_rotri_i32(t1, t1, uimm);
2571 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2572 tcg_temp_free_i32(t1);
2573 } else {
2574 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2575 }
2576 break;
2577#if defined(TARGET_MIPS64)
2578 case OPC_DSLL:
2579 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2580 break;
2581 case OPC_DSRA:
2582 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2583 break;
2584 case OPC_DSRL:
2585 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2586 break;
2587 case OPC_DROTR:
2588 if (uimm != 0) {
2589 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2590 } else {
2591 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2592 }
2593 break;
2594 case OPC_DSLL32:
2595 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2596 break;
2597 case OPC_DSRA32:
2598 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2599 break;
2600 case OPC_DSRL32:
2601 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2602 break;
2603 case OPC_DROTR32:
2604 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2605 break;
2606#endif
2607 }
2608 tcg_temp_free(t0);
2609}
2610
2611
2612static void gen_arith(DisasContext *ctx, uint32_t opc,
2613 int rd, int rs, int rt)
2614{
2615 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2616 && opc != OPC_DADD && opc != OPC_DSUB) {
2617
2618
2619
2620
2621 return;
2622 }
2623
2624 switch (opc) {
2625 case OPC_ADD:
2626 {
2627 TCGv t0 = tcg_temp_local_new();
2628 TCGv t1 = tcg_temp_new();
2629 TCGv t2 = tcg_temp_new();
2630 TCGLabel *l1 = gen_new_label();
2631
2632 gen_load_gpr(t1, rs);
2633 gen_load_gpr(t2, rt);
2634 tcg_gen_add_tl(t0, t1, t2);
2635 tcg_gen_ext32s_tl(t0, t0);
2636 tcg_gen_xor_tl(t1, t1, t2);
2637 tcg_gen_xor_tl(t2, t0, t2);
2638 tcg_gen_andc_tl(t1, t2, t1);
2639 tcg_temp_free(t2);
2640 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2641 tcg_temp_free(t1);
2642
2643 generate_exception(ctx, EXCP_OVERFLOW);
2644 gen_set_label(l1);
2645 gen_store_gpr(t0, rd);
2646 tcg_temp_free(t0);
2647 }
2648 break;
2649 case OPC_ADDU:
2650 if (rs != 0 && rt != 0) {
2651 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2652 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2653 } else if (rs == 0 && rt != 0) {
2654 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2655 } else if (rs != 0 && rt == 0) {
2656 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2657 } else {
2658 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2659 }
2660 break;
2661 case OPC_SUB:
2662 {
2663 TCGv t0 = tcg_temp_local_new();
2664 TCGv t1 = tcg_temp_new();
2665 TCGv t2 = tcg_temp_new();
2666 TCGLabel *l1 = gen_new_label();
2667
2668 gen_load_gpr(t1, rs);
2669 gen_load_gpr(t2, rt);
2670 tcg_gen_sub_tl(t0, t1, t2);
2671 tcg_gen_ext32s_tl(t0, t0);
2672 tcg_gen_xor_tl(t2, t1, t2);
2673 tcg_gen_xor_tl(t1, t0, t1);
2674 tcg_gen_and_tl(t1, t1, t2);
2675 tcg_temp_free(t2);
2676 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2677 tcg_temp_free(t1);
2678
2679
2680
2681
2682 generate_exception(ctx, EXCP_OVERFLOW);
2683 gen_set_label(l1);
2684 gen_store_gpr(t0, rd);
2685 tcg_temp_free(t0);
2686 }
2687 break;
2688 case OPC_SUBU:
2689 if (rs != 0 && rt != 0) {
2690 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2691 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2692 } else if (rs == 0 && rt != 0) {
2693 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2694 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2695 } else if (rs != 0 && rt == 0) {
2696 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2697 } else {
2698 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2699 }
2700 break;
2701#if defined(TARGET_MIPS64)
2702 case OPC_DADD:
2703 {
2704 TCGv t0 = tcg_temp_local_new();
2705 TCGv t1 = tcg_temp_new();
2706 TCGv t2 = tcg_temp_new();
2707 TCGLabel *l1 = gen_new_label();
2708
2709 gen_load_gpr(t1, rs);
2710 gen_load_gpr(t2, rt);
2711 tcg_gen_add_tl(t0, t1, t2);
2712 tcg_gen_xor_tl(t1, t1, t2);
2713 tcg_gen_xor_tl(t2, t0, t2);
2714 tcg_gen_andc_tl(t1, t2, t1);
2715 tcg_temp_free(t2);
2716 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2717 tcg_temp_free(t1);
2718
2719 generate_exception(ctx, EXCP_OVERFLOW);
2720 gen_set_label(l1);
2721 gen_store_gpr(t0, rd);
2722 tcg_temp_free(t0);
2723 }
2724 break;
2725 case OPC_DADDU:
2726 if (rs != 0 && rt != 0) {
2727 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2728 } else if (rs == 0 && rt != 0) {
2729 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2730 } else if (rs != 0 && rt == 0) {
2731 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2732 } else {
2733 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2734 }
2735 break;
2736 case OPC_DSUB:
2737 {
2738 TCGv t0 = tcg_temp_local_new();
2739 TCGv t1 = tcg_temp_new();
2740 TCGv t2 = tcg_temp_new();
2741 TCGLabel *l1 = gen_new_label();
2742
2743 gen_load_gpr(t1, rs);
2744 gen_load_gpr(t2, rt);
2745 tcg_gen_sub_tl(t0, t1, t2);
2746 tcg_gen_xor_tl(t2, t1, t2);
2747 tcg_gen_xor_tl(t1, t0, t1);
2748 tcg_gen_and_tl(t1, t1, t2);
2749 tcg_temp_free(t2);
2750 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2751 tcg_temp_free(t1);
2752
2753
2754
2755
2756 generate_exception(ctx, EXCP_OVERFLOW);
2757 gen_set_label(l1);
2758 gen_store_gpr(t0, rd);
2759 tcg_temp_free(t0);
2760 }
2761 break;
2762 case OPC_DSUBU:
2763 if (rs != 0 && rt != 0) {
2764 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2765 } else if (rs == 0 && rt != 0) {
2766 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2767 } else if (rs != 0 && rt == 0) {
2768 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2769 } else {
2770 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2771 }
2772 break;
2773#endif
2774 case OPC_MUL:
2775 if (likely(rs != 0 && rt != 0)) {
2776 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2777 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2778 } else {
2779 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2780 }
2781 break;
2782 }
2783}
2784
2785
2786static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2787 int rd, int rs, int rt)
2788{
2789 TCGv t0, t1, t2;
2790
2791 if (rd == 0) {
2792
2793 return;
2794 }
2795
2796 t0 = tcg_temp_new();
2797 gen_load_gpr(t0, rt);
2798 t1 = tcg_const_tl(0);
2799 t2 = tcg_temp_new();
2800 gen_load_gpr(t2, rs);
2801 switch (opc) {
2802 case OPC_MOVN:
2803 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2804 break;
2805 case OPC_MOVZ:
2806 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2807 break;
2808 case OPC_SELNEZ:
2809 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2810 break;
2811 case OPC_SELEQZ:
2812 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2813 break;
2814 }
2815 tcg_temp_free(t2);
2816 tcg_temp_free(t1);
2817 tcg_temp_free(t0);
2818}
2819
2820
2821static void gen_logic(DisasContext *ctx, uint32_t opc,
2822 int rd, int rs, int rt)
2823{
2824 if (rd == 0) {
2825
2826 return;
2827 }
2828
2829 switch (opc) {
2830 case OPC_AND:
2831 if (likely(rs != 0 && rt != 0)) {
2832 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2833 } else {
2834 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2835 }
2836 break;
2837 case OPC_NOR:
2838 if (rs != 0 && rt != 0) {
2839 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2840 } else if (rs == 0 && rt != 0) {
2841 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2842 } else if (rs != 0 && rt == 0) {
2843 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2844 } else {
2845 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2846 }
2847 break;
2848 case OPC_OR:
2849 if (likely(rs != 0 && rt != 0)) {
2850 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2851 } else if (rs == 0 && rt != 0) {
2852 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2853 } else if (rs != 0 && rt == 0) {
2854 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2855 } else {
2856 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2857 }
2858 break;
2859 case OPC_XOR:
2860 if (likely(rs != 0 && rt != 0)) {
2861 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2862 } else if (rs == 0 && rt != 0) {
2863 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2864 } else if (rs != 0 && rt == 0) {
2865 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2866 } else {
2867 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2868 }
2869 break;
2870 }
2871}
2872
2873
2874static void gen_slt(DisasContext *ctx, uint32_t opc,
2875 int rd, int rs, int rt)
2876{
2877 TCGv t0, t1;
2878
2879 if (rd == 0) {
2880
2881 return;
2882 }
2883
2884 t0 = tcg_temp_new();
2885 t1 = tcg_temp_new();
2886 gen_load_gpr(t0, rs);
2887 gen_load_gpr(t1, rt);
2888 switch (opc) {
2889 case OPC_SLT:
2890 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2891 break;
2892 case OPC_SLTU:
2893 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2894 break;
2895 }
2896 tcg_temp_free(t0);
2897 tcg_temp_free(t1);
2898}
2899
2900
2901static void gen_shift(DisasContext *ctx, uint32_t opc,
2902 int rd, int rs, int rt)
2903{
2904 TCGv t0, t1;
2905
2906 if (rd == 0) {
2907
2908
2909
2910
2911 return;
2912 }
2913
2914 t0 = tcg_temp_new();
2915 t1 = tcg_temp_new();
2916 gen_load_gpr(t0, rs);
2917 gen_load_gpr(t1, rt);
2918 switch (opc) {
2919 case OPC_SLLV:
2920 tcg_gen_andi_tl(t0, t0, 0x1f);
2921 tcg_gen_shl_tl(t0, t1, t0);
2922 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2923 break;
2924 case OPC_SRAV:
2925 tcg_gen_andi_tl(t0, t0, 0x1f);
2926 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2927 break;
2928 case OPC_SRLV:
2929 tcg_gen_ext32u_tl(t1, t1);
2930 tcg_gen_andi_tl(t0, t0, 0x1f);
2931 tcg_gen_shr_tl(t0, t1, t0);
2932 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2933 break;
2934 case OPC_ROTRV:
2935 {
2936 TCGv_i32 t2 = tcg_temp_new_i32();
2937 TCGv_i32 t3 = tcg_temp_new_i32();
2938
2939 tcg_gen_trunc_tl_i32(t2, t0);
2940 tcg_gen_trunc_tl_i32(t3, t1);
2941 tcg_gen_andi_i32(t2, t2, 0x1f);
2942 tcg_gen_rotr_i32(t2, t3, t2);
2943 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2944 tcg_temp_free_i32(t2);
2945 tcg_temp_free_i32(t3);
2946 }
2947 break;
2948#if defined(TARGET_MIPS64)
2949 case OPC_DSLLV:
2950 tcg_gen_andi_tl(t0, t0, 0x3f);
2951 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2952 break;
2953 case OPC_DSRAV:
2954 tcg_gen_andi_tl(t0, t0, 0x3f);
2955 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2956 break;
2957 case OPC_DSRLV:
2958 tcg_gen_andi_tl(t0, t0, 0x3f);
2959 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2960 break;
2961 case OPC_DROTRV:
2962 tcg_gen_andi_tl(t0, t0, 0x3f);
2963 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2964 break;
2965#endif
2966 }
2967 tcg_temp_free(t0);
2968 tcg_temp_free(t1);
2969}
2970
2971
2972static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2973{
2974 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2975
2976 return;
2977 }
2978
2979 if (acc != 0) {
2980 check_dsp(ctx);
2981 }
2982
2983 switch (opc) {
2984 case OPC_MFHI:
2985#if defined(TARGET_MIPS64)
2986 if (acc != 0) {
2987 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2988 } else
2989#endif
2990 {
2991 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2992 }
2993 break;
2994 case OPC_MFLO:
2995#if defined(TARGET_MIPS64)
2996 if (acc != 0) {
2997 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2998 } else
2999#endif
3000 {
3001 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3002 }
3003 break;
3004 case OPC_MTHI:
3005 if (reg != 0) {
3006#if defined(TARGET_MIPS64)
3007 if (acc != 0) {
3008 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3009 } else
3010#endif
3011 {
3012 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3013 }
3014 } else {
3015 tcg_gen_movi_tl(cpu_HI[acc], 0);
3016 }
3017 break;
3018 case OPC_MTLO:
3019 if (reg != 0) {
3020#if defined(TARGET_MIPS64)
3021 if (acc != 0) {
3022 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3023 } else
3024#endif
3025 {
3026 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3027 }
3028 } else {
3029 tcg_gen_movi_tl(cpu_LO[acc], 0);
3030 }
3031 break;
3032 }
3033}
3034
3035static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3036 MemOp memop)
3037{
3038 TCGv t0 = tcg_const_tl(addr);
3039 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3040 gen_store_gpr(t0, reg);
3041 tcg_temp_free(t0);
3042}
3043
3044static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3045 int rs)
3046{
3047 target_long offset;
3048 target_long addr;
3049
3050 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3051 case OPC_ADDIUPC:
3052 if (rs != 0) {
3053 offset = sextract32(ctx->opcode << 2, 0, 21);
3054 addr = addr_add(ctx, pc, offset);
3055 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3056 }
3057 break;
3058 case R6_OPC_LWPC:
3059 offset = sextract32(ctx->opcode << 2, 0, 21);
3060 addr = addr_add(ctx, pc, offset);
3061 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3062 break;
3063#if defined(TARGET_MIPS64)
3064 case OPC_LWUPC:
3065 check_mips_64(ctx);
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_TEUL);
3069 break;
3070#endif
3071 default:
3072 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3073 case OPC_AUIPC:
3074 if (rs != 0) {
3075 offset = sextract32(ctx->opcode, 0, 16) << 16;
3076 addr = addr_add(ctx, pc, offset);
3077 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3078 }
3079 break;
3080 case OPC_ALUIPC:
3081 if (rs != 0) {
3082 offset = sextract32(ctx->opcode, 0, 16) << 16;
3083 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3084 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3085 }
3086 break;
3087#if defined(TARGET_MIPS64)
3088 case R6_OPC_LDPC:
3089 case R6_OPC_LDPC + (1 << 16):
3090 case R6_OPC_LDPC + (2 << 16):
3091 case R6_OPC_LDPC + (3 << 16):
3092 check_mips_64(ctx);
3093 offset = sextract32(ctx->opcode << 3, 0, 21);
3094 addr = addr_add(ctx, (pc & ~0x7), offset);
3095 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3096 break;
3097#endif
3098 default:
3099 MIPS_INVAL("OPC_PCREL");
3100 gen_reserved_instruction(ctx);
3101 break;
3102 }
3103 break;
3104 }
3105}
3106
3107static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3108{
3109 TCGv t0, t1;
3110
3111 if (rd == 0) {
3112
3113 return;
3114 }
3115
3116 t0 = tcg_temp_new();
3117 t1 = tcg_temp_new();
3118
3119 gen_load_gpr(t0, rs);
3120 gen_load_gpr(t1, rt);
3121
3122 switch (opc) {
3123 case R6_OPC_DIV:
3124 {
3125 TCGv t2 = tcg_temp_new();
3126 TCGv t3 = tcg_temp_new();
3127 tcg_gen_ext32s_tl(t0, t0);
3128 tcg_gen_ext32s_tl(t1, t1);
3129 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3130 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3131 tcg_gen_and_tl(t2, t2, t3);
3132 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3133 tcg_gen_or_tl(t2, t2, t3);
3134 tcg_gen_movi_tl(t3, 0);
3135 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3136 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3137 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3138 tcg_temp_free(t3);
3139 tcg_temp_free(t2);
3140 }
3141 break;
3142 case R6_OPC_MOD:
3143 {
3144 TCGv t2 = tcg_temp_new();
3145 TCGv t3 = tcg_temp_new();
3146 tcg_gen_ext32s_tl(t0, t0);
3147 tcg_gen_ext32s_tl(t1, t1);
3148 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3149 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3150 tcg_gen_and_tl(t2, t2, t3);
3151 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3152 tcg_gen_or_tl(t2, t2, t3);
3153 tcg_gen_movi_tl(t3, 0);
3154 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3155 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3156 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3157 tcg_temp_free(t3);
3158 tcg_temp_free(t2);
3159 }
3160 break;
3161 case R6_OPC_DIVU:
3162 {
3163 TCGv t2 = tcg_const_tl(0);
3164 TCGv t3 = tcg_const_tl(1);
3165 tcg_gen_ext32u_tl(t0, t0);
3166 tcg_gen_ext32u_tl(t1, t1);
3167 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3168 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3169 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3170 tcg_temp_free(t3);
3171 tcg_temp_free(t2);
3172 }
3173 break;
3174 case R6_OPC_MODU:
3175 {
3176 TCGv t2 = tcg_const_tl(0);
3177 TCGv t3 = tcg_const_tl(1);
3178 tcg_gen_ext32u_tl(t0, t0);
3179 tcg_gen_ext32u_tl(t1, t1);
3180 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3181 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3182 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3183 tcg_temp_free(t3);
3184 tcg_temp_free(t2);
3185 }
3186 break;
3187 case R6_OPC_MUL:
3188 {
3189 TCGv_i32 t2 = tcg_temp_new_i32();
3190 TCGv_i32 t3 = tcg_temp_new_i32();
3191 tcg_gen_trunc_tl_i32(t2, t0);
3192 tcg_gen_trunc_tl_i32(t3, t1);
3193 tcg_gen_mul_i32(t2, t2, t3);
3194 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3195 tcg_temp_free_i32(t2);
3196 tcg_temp_free_i32(t3);
3197 }
3198 break;
3199 case R6_OPC_MUH:
3200 {
3201 TCGv_i32 t2 = tcg_temp_new_i32();
3202 TCGv_i32 t3 = tcg_temp_new_i32();
3203 tcg_gen_trunc_tl_i32(t2, t0);
3204 tcg_gen_trunc_tl_i32(t3, t1);
3205 tcg_gen_muls2_i32(t2, t3, t2, t3);
3206 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3207 tcg_temp_free_i32(t2);
3208 tcg_temp_free_i32(t3);
3209 }
3210 break;
3211 case R6_OPC_MULU:
3212 {
3213 TCGv_i32 t2 = tcg_temp_new_i32();
3214 TCGv_i32 t3 = tcg_temp_new_i32();
3215 tcg_gen_trunc_tl_i32(t2, t0);
3216 tcg_gen_trunc_tl_i32(t3, t1);
3217 tcg_gen_mul_i32(t2, t2, t3);
3218 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3219 tcg_temp_free_i32(t2);
3220 tcg_temp_free_i32(t3);
3221 }
3222 break;
3223 case R6_OPC_MUHU:
3224 {
3225 TCGv_i32 t2 = tcg_temp_new_i32();
3226 TCGv_i32 t3 = tcg_temp_new_i32();
3227 tcg_gen_trunc_tl_i32(t2, t0);
3228 tcg_gen_trunc_tl_i32(t3, t1);
3229 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3230 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3231 tcg_temp_free_i32(t2);
3232 tcg_temp_free_i32(t3);
3233 }
3234 break;
3235#if defined(TARGET_MIPS64)
3236 case R6_OPC_DDIV:
3237 {
3238 TCGv t2 = tcg_temp_new();
3239 TCGv t3 = tcg_temp_new();
3240 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3241 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3242 tcg_gen_and_tl(t2, t2, t3);
3243 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3244 tcg_gen_or_tl(t2, t2, t3);
3245 tcg_gen_movi_tl(t3, 0);
3246 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3247 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3248 tcg_temp_free(t3);
3249 tcg_temp_free(t2);
3250 }
3251 break;
3252 case R6_OPC_DMOD:
3253 {
3254 TCGv t2 = tcg_temp_new();
3255 TCGv t3 = tcg_temp_new();
3256 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3257 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3258 tcg_gen_and_tl(t2, t2, t3);
3259 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3260 tcg_gen_or_tl(t2, t2, t3);
3261 tcg_gen_movi_tl(t3, 0);
3262 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3263 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3264 tcg_temp_free(t3);
3265 tcg_temp_free(t2);
3266 }
3267 break;
3268 case R6_OPC_DDIVU:
3269 {
3270 TCGv t2 = tcg_const_tl(0);
3271 TCGv t3 = tcg_const_tl(1);
3272 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3273 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3274 tcg_temp_free(t3);
3275 tcg_temp_free(t2);
3276 }
3277 break;
3278 case R6_OPC_DMODU:
3279 {
3280 TCGv t2 = tcg_const_tl(0);
3281 TCGv t3 = tcg_const_tl(1);
3282 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3284 tcg_temp_free(t3);
3285 tcg_temp_free(t2);
3286 }
3287 break;
3288 case R6_OPC_DMUL:
3289 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3290 break;
3291 case R6_OPC_DMUH:
3292 {
3293 TCGv t2 = tcg_temp_new();
3294 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3295 tcg_temp_free(t2);
3296 }
3297 break;
3298 case R6_OPC_DMULU:
3299 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3300 break;
3301 case R6_OPC_DMUHU:
3302 {
3303 TCGv t2 = tcg_temp_new();
3304 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3305 tcg_temp_free(t2);
3306 }
3307 break;
3308#endif
3309 default:
3310 MIPS_INVAL("r6 mul/div");
3311 gen_reserved_instruction(ctx);
3312 goto out;
3313 }
3314 out:
3315 tcg_temp_free(t0);
3316 tcg_temp_free(t1);
3317}
3318
3319#if defined(TARGET_MIPS64)
3320static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3321{
3322 TCGv t0, t1;
3323
3324 t0 = tcg_temp_new();
3325 t1 = tcg_temp_new();
3326
3327 gen_load_gpr(t0, rs);
3328 gen_load_gpr(t1, rt);
3329
3330 switch (opc) {
3331 case MMI_OPC_DIV1:
3332 {
3333 TCGv t2 = tcg_temp_new();
3334 TCGv t3 = tcg_temp_new();
3335 tcg_gen_ext32s_tl(t0, t0);
3336 tcg_gen_ext32s_tl(t1, t1);
3337 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3338 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3339 tcg_gen_and_tl(t2, t2, t3);
3340 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3341 tcg_gen_or_tl(t2, t2, t3);
3342 tcg_gen_movi_tl(t3, 0);
3343 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3344 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3345 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3346 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3347 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3348 tcg_temp_free(t3);
3349 tcg_temp_free(t2);
3350 }
3351 break;
3352 case MMI_OPC_DIVU1:
3353 {
3354 TCGv t2 = tcg_const_tl(0);
3355 TCGv t3 = tcg_const_tl(1);
3356 tcg_gen_ext32u_tl(t0, t0);
3357 tcg_gen_ext32u_tl(t1, t1);
3358 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3359 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3360 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3361 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3362 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3363 tcg_temp_free(t3);
3364 tcg_temp_free(t2);
3365 }
3366 break;
3367 default:
3368 MIPS_INVAL("div1 TX79");
3369 gen_reserved_instruction(ctx);
3370 goto out;
3371 }
3372 out:
3373 tcg_temp_free(t0);
3374 tcg_temp_free(t1);
3375}
3376#endif
3377
3378static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3379 int acc, int rs, int rt)
3380{
3381 TCGv t0, t1;
3382
3383 t0 = tcg_temp_new();
3384 t1 = tcg_temp_new();
3385
3386 gen_load_gpr(t0, rs);
3387 gen_load_gpr(t1, rt);
3388
3389 if (acc != 0) {
3390 check_dsp(ctx);
3391 }
3392
3393 switch (opc) {
3394 case OPC_DIV:
3395 {
3396 TCGv t2 = tcg_temp_new();
3397 TCGv t3 = tcg_temp_new();
3398 tcg_gen_ext32s_tl(t0, t0);
3399 tcg_gen_ext32s_tl(t1, t1);
3400 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3401 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3402 tcg_gen_and_tl(t2, t2, t3);
3403 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3404 tcg_gen_or_tl(t2, t2, t3);
3405 tcg_gen_movi_tl(t3, 0);
3406 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3407 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3408 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3409 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3410 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3411 tcg_temp_free(t3);
3412 tcg_temp_free(t2);
3413 }
3414 break;
3415 case OPC_DIVU:
3416 {
3417 TCGv t2 = tcg_const_tl(0);
3418 TCGv t3 = tcg_const_tl(1);
3419 tcg_gen_ext32u_tl(t0, t0);
3420 tcg_gen_ext32u_tl(t1, t1);
3421 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3422 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3423 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3424 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3425 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3426 tcg_temp_free(t3);
3427 tcg_temp_free(t2);
3428 }
3429 break;
3430 case OPC_MULT:
3431 {
3432 TCGv_i32 t2 = tcg_temp_new_i32();
3433 TCGv_i32 t3 = tcg_temp_new_i32();
3434 tcg_gen_trunc_tl_i32(t2, t0);
3435 tcg_gen_trunc_tl_i32(t3, t1);
3436 tcg_gen_muls2_i32(t2, t3, t2, t3);
3437 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3438 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3439 tcg_temp_free_i32(t2);
3440 tcg_temp_free_i32(t3);
3441 }
3442 break;
3443 case OPC_MULTU:
3444 {
3445 TCGv_i32 t2 = tcg_temp_new_i32();
3446 TCGv_i32 t3 = tcg_temp_new_i32();
3447 tcg_gen_trunc_tl_i32(t2, t0);
3448 tcg_gen_trunc_tl_i32(t3, t1);
3449 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3450 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3451 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3452 tcg_temp_free_i32(t2);
3453 tcg_temp_free_i32(t3);
3454 }
3455 break;
3456#if defined(TARGET_MIPS64)
3457 case OPC_DDIV:
3458 {
3459 TCGv t2 = tcg_temp_new();
3460 TCGv t3 = tcg_temp_new();
3461 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3462 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3463 tcg_gen_and_tl(t2, t2, t3);
3464 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3465 tcg_gen_or_tl(t2, t2, t3);
3466 tcg_gen_movi_tl(t3, 0);
3467 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3468 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3469 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3470 tcg_temp_free(t3);
3471 tcg_temp_free(t2);
3472 }
3473 break;
3474 case OPC_DDIVU:
3475 {
3476 TCGv t2 = tcg_const_tl(0);
3477 TCGv t3 = tcg_const_tl(1);
3478 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3479 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3480 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3481 tcg_temp_free(t3);
3482 tcg_temp_free(t2);
3483 }
3484 break;
3485 case OPC_DMULT:
3486 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3487 break;
3488 case OPC_DMULTU:
3489 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3490 break;
3491#endif
3492 case OPC_MADD:
3493 {
3494 TCGv_i64 t2 = tcg_temp_new_i64();
3495 TCGv_i64 t3 = tcg_temp_new_i64();
3496
3497 tcg_gen_ext_tl_i64(t2, t0);
3498 tcg_gen_ext_tl_i64(t3, t1);
3499 tcg_gen_mul_i64(t2, t2, t3);
3500 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3501 tcg_gen_add_i64(t2, t2, t3);
3502 tcg_temp_free_i64(t3);
3503 gen_move_low32(cpu_LO[acc], t2);
3504 gen_move_high32(cpu_HI[acc], t2);
3505 tcg_temp_free_i64(t2);
3506 }
3507 break;
3508 case OPC_MADDU:
3509 {
3510 TCGv_i64 t2 = tcg_temp_new_i64();
3511 TCGv_i64 t3 = tcg_temp_new_i64();
3512
3513 tcg_gen_ext32u_tl(t0, t0);
3514 tcg_gen_ext32u_tl(t1, t1);
3515 tcg_gen_extu_tl_i64(t2, t0);
3516 tcg_gen_extu_tl_i64(t3, t1);
3517 tcg_gen_mul_i64(t2, t2, t3);
3518 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3519 tcg_gen_add_i64(t2, t2, t3);
3520 tcg_temp_free_i64(t3);
3521 gen_move_low32(cpu_LO[acc], t2);
3522 gen_move_high32(cpu_HI[acc], t2);
3523 tcg_temp_free_i64(t2);
3524 }
3525 break;
3526 case OPC_MSUB:
3527 {
3528 TCGv_i64 t2 = tcg_temp_new_i64();
3529 TCGv_i64 t3 = tcg_temp_new_i64();
3530
3531 tcg_gen_ext_tl_i64(t2, t0);
3532 tcg_gen_ext_tl_i64(t3, t1);
3533 tcg_gen_mul_i64(t2, t2, t3);
3534 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3535 tcg_gen_sub_i64(t2, t3, t2);
3536 tcg_temp_free_i64(t3);
3537 gen_move_low32(cpu_LO[acc], t2);
3538 gen_move_high32(cpu_HI[acc], t2);
3539 tcg_temp_free_i64(t2);
3540 }
3541 break;
3542 case OPC_MSUBU:
3543 {
3544 TCGv_i64 t2 = tcg_temp_new_i64();
3545 TCGv_i64 t3 = tcg_temp_new_i64();
3546
3547 tcg_gen_ext32u_tl(t0, t0);
3548 tcg_gen_ext32u_tl(t1, t1);
3549 tcg_gen_extu_tl_i64(t2, t0);
3550 tcg_gen_extu_tl_i64(t3, t1);
3551 tcg_gen_mul_i64(t2, t2, t3);
3552 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3553 tcg_gen_sub_i64(t2, t3, t2);
3554 tcg_temp_free_i64(t3);
3555 gen_move_low32(cpu_LO[acc], t2);
3556 gen_move_high32(cpu_HI[acc], t2);
3557 tcg_temp_free_i64(t2);
3558 }
3559 break;
3560 default:
3561 MIPS_INVAL("mul/div");
3562 gen_reserved_instruction(ctx);
3563 goto out;
3564 }
3565 out:
3566 tcg_temp_free(t0);
3567 tcg_temp_free(t1);
3568}
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3597 int rd, int rs, int rt)
3598{
3599 TCGv t0 = tcg_temp_new();
3600 TCGv t1 = tcg_temp_new();
3601 int acc = 0;
3602
3603 gen_load_gpr(t0, rs);
3604 gen_load_gpr(t1, rt);
3605
3606 switch (opc) {
3607 case MMI_OPC_MULT1:
3608 acc = 1;
3609
3610 case OPC_MULT:
3611 {
3612 TCGv_i32 t2 = tcg_temp_new_i32();
3613 TCGv_i32 t3 = tcg_temp_new_i32();
3614 tcg_gen_trunc_tl_i32(t2, t0);
3615 tcg_gen_trunc_tl_i32(t3, t1);
3616 tcg_gen_muls2_i32(t2, t3, t2, t3);
3617 if (rd) {
3618 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3619 }
3620 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3621 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3622 tcg_temp_free_i32(t2);
3623 tcg_temp_free_i32(t3);
3624 }
3625 break;
3626 case MMI_OPC_MULTU1:
3627 acc = 1;
3628
3629 case OPC_MULTU:
3630 {
3631 TCGv_i32 t2 = tcg_temp_new_i32();
3632 TCGv_i32 t3 = tcg_temp_new_i32();
3633 tcg_gen_trunc_tl_i32(t2, t0);
3634 tcg_gen_trunc_tl_i32(t3, t1);
3635 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3636 if (rd) {
3637 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3638 }
3639 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3640 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3641 tcg_temp_free_i32(t2);
3642 tcg_temp_free_i32(t3);
3643 }
3644 break;
3645 case MMI_OPC_MADD1:
3646 acc = 1;
3647
3648 case MMI_OPC_MADD:
3649 {
3650 TCGv_i64 t2 = tcg_temp_new_i64();
3651 TCGv_i64 t3 = tcg_temp_new_i64();
3652
3653 tcg_gen_ext_tl_i64(t2, t0);
3654 tcg_gen_ext_tl_i64(t3, t1);
3655 tcg_gen_mul_i64(t2, t2, t3);
3656 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3657 tcg_gen_add_i64(t2, t2, t3);
3658 tcg_temp_free_i64(t3);
3659 gen_move_low32(cpu_LO[acc], t2);
3660 gen_move_high32(cpu_HI[acc], t2);
3661 if (rd) {
3662 gen_move_low32(cpu_gpr[rd], t2);
3663 }
3664 tcg_temp_free_i64(t2);
3665 }
3666 break;
3667 case MMI_OPC_MADDU1:
3668 acc = 1;
3669
3670 case MMI_OPC_MADDU:
3671 {
3672 TCGv_i64 t2 = tcg_temp_new_i64();
3673 TCGv_i64 t3 = tcg_temp_new_i64();
3674
3675 tcg_gen_ext32u_tl(t0, t0);
3676 tcg_gen_ext32u_tl(t1, t1);
3677 tcg_gen_extu_tl_i64(t2, t0);
3678 tcg_gen_extu_tl_i64(t3, t1);
3679 tcg_gen_mul_i64(t2, t2, t3);
3680 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3681 tcg_gen_add_i64(t2, t2, t3);
3682 tcg_temp_free_i64(t3);
3683 gen_move_low32(cpu_LO[acc], t2);
3684 gen_move_high32(cpu_HI[acc], t2);
3685 if (rd) {
3686 gen_move_low32(cpu_gpr[rd], t2);
3687 }
3688 tcg_temp_free_i64(t2);
3689 }
3690 break;
3691 default:
3692 MIPS_INVAL("mul/madd TXx9");
3693 gen_reserved_instruction(ctx);
3694 goto out;
3695 }
3696
3697 out:
3698 tcg_temp_free(t0);
3699 tcg_temp_free(t1);
3700}
3701
3702static void gen_cl(DisasContext *ctx, uint32_t opc,
3703 int rd, int rs)
3704{
3705 TCGv t0;
3706
3707 if (rd == 0) {
3708
3709 return;
3710 }
3711 t0 = cpu_gpr[rd];
3712 gen_load_gpr(t0, rs);
3713
3714 switch (opc) {
3715 case OPC_CLO:
3716 case R6_OPC_CLO:
3717#if defined(TARGET_MIPS64)
3718 case OPC_DCLO:
3719 case R6_OPC_DCLO:
3720#endif
3721 tcg_gen_not_tl(t0, t0);
3722 break;
3723 }
3724
3725 switch (opc) {
3726 case OPC_CLO:
3727 case R6_OPC_CLO:
3728 case OPC_CLZ:
3729 case R6_OPC_CLZ:
3730 tcg_gen_ext32u_tl(t0, t0);
3731 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3732 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3733 break;
3734#if defined(TARGET_MIPS64)
3735 case OPC_DCLO:
3736 case R6_OPC_DCLO:
3737 case OPC_DCLZ:
3738 case R6_OPC_DCLZ:
3739 tcg_gen_clzi_i64(t0, t0, 64);
3740 break;
3741#endif
3742 }
3743}
3744
3745
3746static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3747 int rd, int rs, int rt)
3748{
3749 TCGv t0, t1;
3750
3751 if (rd == 0) {
3752
3753 return;
3754 }
3755
3756 switch (opc) {
3757 case OPC_MULT_G_2E:
3758 case OPC_MULT_G_2F:
3759 case OPC_MULTU_G_2E:
3760 case OPC_MULTU_G_2F:
3761#if defined(TARGET_MIPS64)
3762 case OPC_DMULT_G_2E:
3763 case OPC_DMULT_G_2F:
3764 case OPC_DMULTU_G_2E:
3765 case OPC_DMULTU_G_2F:
3766#endif
3767 t0 = tcg_temp_new();
3768 t1 = tcg_temp_new();
3769 break;
3770 default:
3771 t0 = tcg_temp_local_new();
3772 t1 = tcg_temp_local_new();
3773 break;
3774 }
3775
3776 gen_load_gpr(t0, rs);
3777 gen_load_gpr(t1, rt);
3778
3779 switch (opc) {
3780 case OPC_MULT_G_2E:
3781 case OPC_MULT_G_2F:
3782 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3783 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3784 break;
3785 case OPC_MULTU_G_2E:
3786 case OPC_MULTU_G_2F:
3787 tcg_gen_ext32u_tl(t0, t0);
3788 tcg_gen_ext32u_tl(t1, t1);
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_DIV_G_2E:
3793 case OPC_DIV_G_2F:
3794 {
3795 TCGLabel *l1 = gen_new_label();
3796 TCGLabel *l2 = gen_new_label();
3797 TCGLabel *l3 = gen_new_label();
3798 tcg_gen_ext32s_tl(t0, t0);
3799 tcg_gen_ext32s_tl(t1, t1);
3800 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3801 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3802 tcg_gen_br(l3);
3803 gen_set_label(l1);
3804 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3805 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3806 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3807 tcg_gen_br(l3);
3808 gen_set_label(l2);
3809 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3810 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3811 gen_set_label(l3);
3812 }
3813 break;
3814 case OPC_DIVU_G_2E:
3815 case OPC_DIVU_G_2F:
3816 {
3817 TCGLabel *l1 = gen_new_label();
3818 TCGLabel *l2 = gen_new_label();
3819 tcg_gen_ext32u_tl(t0, t0);
3820 tcg_gen_ext32u_tl(t1, t1);
3821 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3822 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3823 tcg_gen_br(l2);
3824 gen_set_label(l1);
3825 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3826 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3827 gen_set_label(l2);
3828 }
3829 break;
3830 case OPC_MOD_G_2E:
3831 case OPC_MOD_G_2F:
3832 {
3833 TCGLabel *l1 = gen_new_label();
3834 TCGLabel *l2 = gen_new_label();
3835 TCGLabel *l3 = gen_new_label();
3836 tcg_gen_ext32u_tl(t0, t0);
3837 tcg_gen_ext32u_tl(t1, t1);
3838 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3839 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3840 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3841 gen_set_label(l1);
3842 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3843 tcg_gen_br(l3);
3844 gen_set_label(l2);
3845 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3846 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3847 gen_set_label(l3);
3848 }
3849 break;
3850 case OPC_MODU_G_2E:
3851 case OPC_MODU_G_2F:
3852 {
3853 TCGLabel *l1 = gen_new_label();
3854 TCGLabel *l2 = gen_new_label();
3855 tcg_gen_ext32u_tl(t0, t0);
3856 tcg_gen_ext32u_tl(t1, t1);
3857 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3858 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3859 tcg_gen_br(l2);
3860 gen_set_label(l1);
3861 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3862 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3863 gen_set_label(l2);
3864 }
3865 break;
3866#if defined(TARGET_MIPS64)
3867 case OPC_DMULT_G_2E:
3868 case OPC_DMULT_G_2F:
3869 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3870 break;
3871 case OPC_DMULTU_G_2E:
3872 case OPC_DMULTU_G_2F:
3873 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3874 break;
3875 case OPC_DDIV_G_2E:
3876 case OPC_DDIV_G_2F:
3877 {
3878 TCGLabel *l1 = gen_new_label();
3879 TCGLabel *l2 = gen_new_label();
3880 TCGLabel *l3 = gen_new_label();
3881 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3882 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3883 tcg_gen_br(l3);
3884 gen_set_label(l1);
3885 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3886 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3887 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3888 tcg_gen_br(l3);
3889 gen_set_label(l2);
3890 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3891 gen_set_label(l3);
3892 }
3893 break;
3894 case OPC_DDIVU_G_2E:
3895 case OPC_DDIVU_G_2F:
3896 {
3897 TCGLabel *l1 = gen_new_label();
3898 TCGLabel *l2 = gen_new_label();
3899 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3900 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3901 tcg_gen_br(l2);
3902 gen_set_label(l1);
3903 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3904 gen_set_label(l2);
3905 }
3906 break;
3907 case OPC_DMOD_G_2E:
3908 case OPC_DMOD_G_2F:
3909 {
3910 TCGLabel *l1 = gen_new_label();
3911 TCGLabel *l2 = gen_new_label();
3912 TCGLabel *l3 = gen_new_label();
3913 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3914 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3915 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3916 gen_set_label(l1);
3917 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3918 tcg_gen_br(l3);
3919 gen_set_label(l2);
3920 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3921 gen_set_label(l3);
3922 }
3923 break;
3924 case OPC_DMODU_G_2E:
3925 case OPC_DMODU_G_2F:
3926 {
3927 TCGLabel *l1 = gen_new_label();
3928 TCGLabel *l2 = gen_new_label();
3929 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3930 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3931 tcg_gen_br(l2);
3932 gen_set_label(l1);
3933 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3934 gen_set_label(l2);
3935 }
3936 break;
3937#endif
3938 }
3939
3940 tcg_temp_free(t0);
3941 tcg_temp_free(t1);
3942}
3943
3944
3945static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3946{
3947 uint32_t opc, shift_max;
3948 TCGv_i64 t0, t1;
3949 TCGCond cond;
3950
3951 opc = MASK_LMMI(ctx->opcode);
3952 switch (opc) {
3953 case OPC_ADD_CP2:
3954 case OPC_SUB_CP2:
3955 case OPC_DADD_CP2:
3956 case OPC_DSUB_CP2:
3957 t0 = tcg_temp_local_new_i64();
3958 t1 = tcg_temp_local_new_i64();
3959 break;
3960 default:
3961 t0 = tcg_temp_new_i64();
3962 t1 = tcg_temp_new_i64();
3963 break;
3964 }
3965
3966 check_cp1_enabled(ctx);
3967 gen_load_fpr64(ctx, t0, rs);
3968 gen_load_fpr64(ctx, t1, rt);
3969
3970 switch (opc) {
3971 case OPC_PADDSH:
3972 gen_helper_paddsh(t0, t0, t1);
3973 break;
3974 case OPC_PADDUSH:
3975 gen_helper_paddush(t0, t0, t1);
3976 break;
3977 case OPC_PADDH:
3978 gen_helper_paddh(t0, t0, t1);
3979 break;
3980 case OPC_PADDW:
3981 gen_helper_paddw(t0, t0, t1);
3982 break;
3983 case OPC_PADDSB:
3984 gen_helper_paddsb(t0, t0, t1);
3985 break;
3986 case OPC_PADDUSB:
3987 gen_helper_paddusb(t0, t0, t1);
3988 break;
3989 case OPC_PADDB:
3990 gen_helper_paddb(t0, t0, t1);
3991 break;
3992
3993 case OPC_PSUBSH:
3994 gen_helper_psubsh(t0, t0, t1);
3995 break;
3996 case OPC_PSUBUSH:
3997 gen_helper_psubush(t0, t0, t1);
3998 break;
3999 case OPC_PSUBH:
4000 gen_helper_psubh(t0, t0, t1);
4001 break;
4002 case OPC_PSUBW:
4003 gen_helper_psubw(t0, t0, t1);
4004 break;
4005 case OPC_PSUBSB:
4006 gen_helper_psubsb(t0, t0, t1);
4007 break;
4008 case OPC_PSUBUSB:
4009 gen_helper_psubusb(t0, t0, t1);
4010 break;
4011 case OPC_PSUBB:
4012 gen_helper_psubb(t0, t0, t1);
4013 break;
4014
4015 case OPC_PSHUFH:
4016 gen_helper_pshufh(t0, t0, t1);
4017 break;
4018 case OPC_PACKSSWH:
4019 gen_helper_packsswh(t0, t0, t1);
4020 break;
4021 case OPC_PACKSSHB:
4022 gen_helper_packsshb(t0, t0, t1);
4023 break;
4024 case OPC_PACKUSHB:
4025 gen_helper_packushb(t0, t0, t1);
4026 break;
4027
4028 case OPC_PUNPCKLHW:
4029 gen_helper_punpcklhw(t0, t0, t1);
4030 break;
4031 case OPC_PUNPCKHHW:
4032 gen_helper_punpckhhw(t0, t0, t1);
4033 break;
4034 case OPC_PUNPCKLBH:
4035 gen_helper_punpcklbh(t0, t0, t1);
4036 break;
4037 case OPC_PUNPCKHBH:
4038 gen_helper_punpckhbh(t0, t0, t1);
4039 break;
4040 case OPC_PUNPCKLWD:
4041 gen_helper_punpcklwd(t0, t0, t1);
4042 break;
4043 case OPC_PUNPCKHWD:
4044 gen_helper_punpckhwd(t0, t0, t1);
4045 break;
4046
4047 case OPC_PAVGH:
4048 gen_helper_pavgh(t0, t0, t1);
4049 break;
4050 case OPC_PAVGB:
4051 gen_helper_pavgb(t0, t0, t1);
4052 break;
4053 case OPC_PMAXSH:
4054 gen_helper_pmaxsh(t0, t0, t1);
4055 break;
4056 case OPC_PMINSH:
4057 gen_helper_pminsh(t0, t0, t1);
4058 break;
4059 case OPC_PMAXUB:
4060 gen_helper_pmaxub(t0, t0, t1);
4061 break;
4062 case OPC_PMINUB:
4063 gen_helper_pminub(t0, t0, t1);
4064 break;
4065
4066 case OPC_PCMPEQW:
4067 gen_helper_pcmpeqw(t0, t0, t1);
4068 break;
4069 case OPC_PCMPGTW:
4070 gen_helper_pcmpgtw(t0, t0, t1);
4071 break;
4072 case OPC_PCMPEQH:
4073 gen_helper_pcmpeqh(t0, t0, t1);
4074 break;
4075 case OPC_PCMPGTH:
4076 gen_helper_pcmpgth(t0, t0, t1);
4077 break;
4078 case OPC_PCMPEQB:
4079 gen_helper_pcmpeqb(t0, t0, t1);
4080 break;
4081 case OPC_PCMPGTB:
4082 gen_helper_pcmpgtb(t0, t0, t1);
4083 break;
4084
4085 case OPC_PSLLW:
4086 gen_helper_psllw(t0, t0, t1);
4087 break;
4088 case OPC_PSLLH:
4089 gen_helper_psllh(t0, t0, t1);
4090 break;
4091 case OPC_PSRLW:
4092 gen_helper_psrlw(t0, t0, t1);
4093 break;
4094 case OPC_PSRLH:
4095 gen_helper_psrlh(t0, t0, t1);
4096 break;
4097 case OPC_PSRAW:
4098 gen_helper_psraw(t0, t0, t1);
4099 break;
4100 case OPC_PSRAH:
4101 gen_helper_psrah(t0, t0, t1);
4102 break;
4103
4104 case OPC_PMULLH:
4105 gen_helper_pmullh(t0, t0, t1);
4106 break;
4107 case OPC_PMULHH:
4108 gen_helper_pmulhh(t0, t0, t1);
4109 break;
4110 case OPC_PMULHUH:
4111 gen_helper_pmulhuh(t0, t0, t1);
4112 break;
4113 case OPC_PMADDHW:
4114 gen_helper_pmaddhw(t0, t0, t1);
4115 break;
4116
4117 case OPC_PASUBUB:
4118 gen_helper_pasubub(t0, t0, t1);
4119 break;
4120 case OPC_BIADD:
4121 gen_helper_biadd(t0, t0);
4122 break;
4123 case OPC_PMOVMSKB:
4124 gen_helper_pmovmskb(t0, t0);
4125 break;
4126
4127 case OPC_PADDD:
4128 tcg_gen_add_i64(t0, t0, t1);
4129 break;
4130 case OPC_PSUBD:
4131 tcg_gen_sub_i64(t0, t0, t1);
4132 break;
4133 case OPC_XOR_CP2:
4134 tcg_gen_xor_i64(t0, t0, t1);
4135 break;
4136 case OPC_NOR_CP2:
4137 tcg_gen_nor_i64(t0, t0, t1);
4138 break;
4139 case OPC_AND_CP2:
4140 tcg_gen_and_i64(t0, t0, t1);
4141 break;
4142 case OPC_OR_CP2:
4143 tcg_gen_or_i64(t0, t0, t1);
4144 break;
4145
4146 case OPC_PANDN:
4147 tcg_gen_andc_i64(t0, t1, t0);
4148 break;
4149
4150 case OPC_PINSRH_0:
4151 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4152 break;
4153 case OPC_PINSRH_1:
4154 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4155 break;
4156 case OPC_PINSRH_2:
4157 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4158 break;
4159 case OPC_PINSRH_3:
4160 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4161 break;
4162
4163 case OPC_PEXTRH:
4164 tcg_gen_andi_i64(t1, t1, 3);
4165 tcg_gen_shli_i64(t1, t1, 4);
4166 tcg_gen_shr_i64(t0, t0, t1);
4167 tcg_gen_ext16u_i64(t0, t0);
4168 break;
4169
4170 case OPC_ADDU_CP2:
4171 tcg_gen_add_i64(t0, t0, t1);
4172 tcg_gen_ext32s_i64(t0, t0);
4173 break;
4174 case OPC_SUBU_CP2:
4175 tcg_gen_sub_i64(t0, t0, t1);
4176 tcg_gen_ext32s_i64(t0, t0);
4177 break;
4178
4179 case OPC_SLL_CP2:
4180 shift_max = 32;
4181 goto do_shift;
4182 case OPC_SRL_CP2:
4183 shift_max = 32;
4184 goto do_shift;
4185 case OPC_SRA_CP2:
4186 shift_max = 32;
4187 goto do_shift;
4188 case OPC_DSLL_CP2:
4189 shift_max = 64;
4190 goto do_shift;
4191 case OPC_DSRL_CP2:
4192 shift_max = 64;
4193 goto do_shift;
4194 case OPC_DSRA_CP2:
4195 shift_max = 64;
4196 goto do_shift;
4197 do_shift:
4198
4199 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4200
4201 switch (opc) {
4202 case OPC_SLL_CP2:
4203 case OPC_DSLL_CP2:
4204 tcg_gen_shl_i64(t0, t0, t1);
4205 break;
4206 case OPC_SRA_CP2:
4207 case OPC_DSRA_CP2:
4208
4209
4210
4211
4212 tcg_gen_sar_i64(t0, t0, t1);
4213 break;
4214 case OPC_SRL_CP2:
4215
4216 tcg_gen_ext32u_i64(t0, t0);
4217
4218 case OPC_DSRL_CP2:
4219 tcg_gen_shr_i64(t0, t0, t1);
4220 break;
4221 }
4222
4223 if (shift_max == 32) {
4224 tcg_gen_ext32s_i64(t0, t0);
4225 }
4226
4227
4228 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4229 tcg_gen_neg_i64(t1, t1);
4230 tcg_gen_and_i64(t0, t0, t1);
4231 break;
4232
4233 case OPC_ADD_CP2:
4234 case OPC_DADD_CP2:
4235 {
4236 TCGv_i64 t2 = tcg_temp_new_i64();
4237 TCGLabel *lab = gen_new_label();
4238
4239 tcg_gen_mov_i64(t2, t0);
4240 tcg_gen_add_i64(t0, t1, t2);
4241 if (opc == OPC_ADD_CP2) {
4242 tcg_gen_ext32s_i64(t0, t0);
4243 }
4244 tcg_gen_xor_i64(t1, t1, t2);
4245 tcg_gen_xor_i64(t2, t2, t0);
4246 tcg_gen_andc_i64(t1, t2, t1);
4247 tcg_temp_free_i64(t2);
4248 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4249 generate_exception(ctx, EXCP_OVERFLOW);
4250 gen_set_label(lab);
4251 break;
4252 }
4253
4254 case OPC_SUB_CP2:
4255 case OPC_DSUB_CP2:
4256 {
4257 TCGv_i64 t2 = tcg_temp_new_i64();
4258 TCGLabel *lab = gen_new_label();
4259
4260 tcg_gen_mov_i64(t2, t0);
4261 tcg_gen_sub_i64(t0, t1, t2);
4262 if (opc == OPC_SUB_CP2) {
4263 tcg_gen_ext32s_i64(t0, t0);
4264 }
4265 tcg_gen_xor_i64(t1, t1, t2);
4266 tcg_gen_xor_i64(t2, t2, t0);
4267 tcg_gen_and_i64(t1, t1, t2);
4268 tcg_temp_free_i64(t2);
4269 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4270 generate_exception(ctx, EXCP_OVERFLOW);
4271 gen_set_label(lab);
4272 break;
4273 }
4274
4275 case OPC_PMULUW:
4276 tcg_gen_ext32u_i64(t0, t0);
4277 tcg_gen_ext32u_i64(t1, t1);
4278 tcg_gen_mul_i64(t0, t0, t1);
4279 break;
4280
4281 case OPC_SEQU_CP2:
4282 case OPC_SEQ_CP2:
4283 cond = TCG_COND_EQ;
4284 goto do_cc_cond;
4285 break;
4286 case OPC_SLTU_CP2:
4287 cond = TCG_COND_LTU;
4288 goto do_cc_cond;
4289 break;
4290 case OPC_SLT_CP2:
4291 cond = TCG_COND_LT;
4292 goto do_cc_cond;
4293 break;
4294 case OPC_SLEU_CP2:
4295 cond = TCG_COND_LEU;
4296 goto do_cc_cond;
4297 break;
4298 case OPC_SLE_CP2:
4299 cond = TCG_COND_LE;
4300 do_cc_cond:
4301 {
4302 int cc = (ctx->opcode >> 8) & 0x7;
4303 TCGv_i64 t64 = tcg_temp_new_i64();
4304 TCGv_i32 t32 = tcg_temp_new_i32();
4305
4306 tcg_gen_setcond_i64(cond, t64, t0, t1);
4307 tcg_gen_extrl_i64_i32(t32, t64);
4308 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4309 get_fp_bit(cc), 1);
4310
4311 tcg_temp_free_i32(t32);
4312 tcg_temp_free_i64(t64);
4313 }
4314 goto no_rd;
4315 break;
4316 default:
4317 MIPS_INVAL("loongson_cp2");
4318 gen_reserved_instruction(ctx);
4319 return;
4320 }
4321
4322 gen_store_fpr64(ctx, t0, rd);
4323
4324no_rd:
4325 tcg_temp_free_i64(t0);
4326 tcg_temp_free_i64(t1);
4327}
4328
4329static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4330 int rs, int rd)
4331{
4332 TCGv t0, t1, t2;
4333 TCGv_i32 fp0;
4334#if defined(TARGET_MIPS64)
4335 int lsq_rt1 = ctx->opcode & 0x1f;
4336 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4337#endif
4338 int shf_offset = sextract32(ctx->opcode, 6, 8);
4339
4340 t0 = tcg_temp_new();
4341
4342 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4343#if defined(TARGET_MIPS64)
4344 case OPC_GSLQ:
4345 t1 = tcg_temp_new();
4346 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4347 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4348 ctx->default_tcg_memop_mask);
4349 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4350 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4351 ctx->default_tcg_memop_mask);
4352 gen_store_gpr(t1, rt);
4353 gen_store_gpr(t0, lsq_rt1);
4354 tcg_temp_free(t1);
4355 break;
4356 case OPC_GSLQC1:
4357 check_cp1_enabled(ctx);
4358 t1 = tcg_temp_new();
4359 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4360 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4361 ctx->default_tcg_memop_mask);
4362 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4363 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4364 ctx->default_tcg_memop_mask);
4365 gen_store_fpr64(ctx, t1, rt);
4366 gen_store_fpr64(ctx, t0, lsq_rt1);
4367 tcg_temp_free(t1);
4368 break;
4369 case OPC_GSSQ:
4370 t1 = tcg_temp_new();
4371 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4372 gen_load_gpr(t1, rt);
4373 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4374 ctx->default_tcg_memop_mask);
4375 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4376 gen_load_gpr(t1, lsq_rt1);
4377 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4378 ctx->default_tcg_memop_mask);
4379 tcg_temp_free(t1);
4380 break;
4381 case OPC_GSSQC1:
4382 check_cp1_enabled(ctx);
4383 t1 = tcg_temp_new();
4384 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4385 gen_load_fpr64(ctx, t1, rt);
4386 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4387 ctx->default_tcg_memop_mask);
4388 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4389 gen_load_fpr64(ctx, t1, lsq_rt1);
4390 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4391 ctx->default_tcg_memop_mask);
4392 tcg_temp_free(t1);
4393 break;
4394#endif
4395 case OPC_GSSHFL:
4396 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4397 case OPC_GSLWLC1:
4398 check_cp1_enabled(ctx);
4399 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4400 t1 = tcg_temp_new();
4401 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4402 tcg_gen_andi_tl(t1, t0, 3);
4403 if (!cpu_is_bigendian(ctx)) {
4404 tcg_gen_xori_tl(t1, t1, 3);
4405 }
4406 tcg_gen_shli_tl(t1, t1, 3);
4407 tcg_gen_andi_tl(t0, t0, ~3);
4408 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4409 tcg_gen_shl_tl(t0, t0, t1);
4410 t2 = tcg_const_tl(-1);
4411 tcg_gen_shl_tl(t2, t2, t1);
4412 fp0 = tcg_temp_new_i32();
4413 gen_load_fpr32(ctx, fp0, rt);
4414 tcg_gen_ext_i32_tl(t1, fp0);
4415 tcg_gen_andc_tl(t1, t1, t2);
4416 tcg_temp_free(t2);
4417 tcg_gen_or_tl(t0, t0, t1);
4418 tcg_temp_free(t1);
4419#if defined(TARGET_MIPS64)
4420 tcg_gen_extrl_i64_i32(fp0, t0);
4421#else
4422 tcg_gen_ext32s_tl(fp0, t0);
4423#endif
4424 gen_store_fpr32(ctx, fp0, rt);
4425 tcg_temp_free_i32(fp0);
4426 break;
4427 case OPC_GSLWRC1:
4428 check_cp1_enabled(ctx);
4429 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4430 t1 = tcg_temp_new();
4431 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4432 tcg_gen_andi_tl(t1, t0, 3);
4433 if (cpu_is_bigendian(ctx)) {
4434 tcg_gen_xori_tl(t1, t1, 3);
4435 }
4436 tcg_gen_shli_tl(t1, t1, 3);
4437 tcg_gen_andi_tl(t0, t0, ~3);
4438 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4439 tcg_gen_shr_tl(t0, t0, t1);
4440 tcg_gen_xori_tl(t1, t1, 31);
4441 t2 = tcg_const_tl(0xfffffffeull);
4442 tcg_gen_shl_tl(t2, t2, t1);
4443 fp0 = tcg_temp_new_i32();
4444 gen_load_fpr32(ctx, fp0, rt);
4445 tcg_gen_ext_i32_tl(t1, fp0);
4446 tcg_gen_and_tl(t1, t1, t2);
4447 tcg_temp_free(t2);
4448 tcg_gen_or_tl(t0, t0, t1);
4449 tcg_temp_free(t1);
4450#if defined(TARGET_MIPS64)
4451 tcg_gen_extrl_i64_i32(fp0, t0);
4452#else
4453 tcg_gen_ext32s_tl(fp0, t0);
4454#endif
4455 gen_store_fpr32(ctx, fp0, rt);
4456 tcg_temp_free_i32(fp0);
4457 break;
4458#if defined(TARGET_MIPS64)
4459 case OPC_GSLDLC1:
4460 check_cp1_enabled(ctx);
4461 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4462 t1 = tcg_temp_new();
4463 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4464 tcg_gen_andi_tl(t1, t0, 7);
4465 if (!cpu_is_bigendian(ctx)) {
4466 tcg_gen_xori_tl(t1, t1, 7);
4467 }
4468 tcg_gen_shli_tl(t1, t1, 3);
4469 tcg_gen_andi_tl(t0, t0, ~7);
4470 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4471 tcg_gen_shl_tl(t0, t0, t1);
4472 t2 = tcg_const_tl(-1);
4473 tcg_gen_shl_tl(t2, t2, t1);
4474 gen_load_fpr64(ctx, t1, rt);
4475 tcg_gen_andc_tl(t1, t1, t2);
4476 tcg_temp_free(t2);
4477 tcg_gen_or_tl(t0, t0, t1);
4478 tcg_temp_free(t1);
4479 gen_store_fpr64(ctx, t0, rt);
4480 break;
4481 case OPC_GSLDRC1:
4482 check_cp1_enabled(ctx);
4483 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4484 t1 = tcg_temp_new();
4485 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4486 tcg_gen_andi_tl(t1, t0, 7);
4487 if (cpu_is_bigendian(ctx)) {
4488 tcg_gen_xori_tl(t1, t1, 7);
4489 }
4490 tcg_gen_shli_tl(t1, t1, 3);
4491 tcg_gen_andi_tl(t0, t0, ~7);
4492 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4493 tcg_gen_shr_tl(t0, t0, t1);
4494 tcg_gen_xori_tl(t1, t1, 63);
4495 t2 = tcg_const_tl(0xfffffffffffffffeull);
4496 tcg_gen_shl_tl(t2, t2, t1);
4497 gen_load_fpr64(ctx, t1, rt);
4498 tcg_gen_and_tl(t1, t1, t2);
4499 tcg_temp_free(t2);
4500 tcg_gen_or_tl(t0, t0, t1);
4501 tcg_temp_free(t1);
4502 gen_store_fpr64(ctx, t0, rt);
4503 break;
4504#endif
4505 default:
4506 MIPS_INVAL("loongson_gsshfl");
4507 gen_reserved_instruction(ctx);
4508 break;
4509 }
4510 break;
4511 case OPC_GSSHFS:
4512 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4513 case OPC_GSSWLC1:
4514 check_cp1_enabled(ctx);
4515 t1 = tcg_temp_new();
4516 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4517 fp0 = tcg_temp_new_i32();
4518 gen_load_fpr32(ctx, fp0, rt);
4519 tcg_gen_ext_i32_tl(t1, fp0);
4520 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4521 tcg_temp_free_i32(fp0);
4522 tcg_temp_free(t1);
4523 break;
4524 case OPC_GSSWRC1:
4525 check_cp1_enabled(ctx);
4526 t1 = tcg_temp_new();
4527 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4528 fp0 = tcg_temp_new_i32();
4529 gen_load_fpr32(ctx, fp0, rt);
4530 tcg_gen_ext_i32_tl(t1, fp0);
4531 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4532 tcg_temp_free_i32(fp0);
4533 tcg_temp_free(t1);
4534 break;
4535#if defined(TARGET_MIPS64)
4536 case OPC_GSSDLC1:
4537 check_cp1_enabled(ctx);
4538 t1 = tcg_temp_new();
4539 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4540 gen_load_fpr64(ctx, t1, rt);
4541 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4542 tcg_temp_free(t1);
4543 break;
4544 case OPC_GSSDRC1:
4545 check_cp1_enabled(ctx);
4546 t1 = tcg_temp_new();
4547 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4548 gen_load_fpr64(ctx, t1, rt);
4549 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4550 tcg_temp_free(t1);
4551 break;
4552#endif
4553 default:
4554 MIPS_INVAL("loongson_gsshfs");
4555 gen_reserved_instruction(ctx);
4556 break;
4557 }
4558 break;
4559 default:
4560 MIPS_INVAL("loongson_gslsq");
4561 gen_reserved_instruction(ctx);
4562 break;
4563 }
4564 tcg_temp_free(t0);
4565}
4566
4567
4568static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4569 int rs, int rd)
4570{
4571 int offset = sextract32(ctx->opcode, 3, 8);
4572 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4573 TCGv t0, t1;
4574 TCGv_i32 fp0;
4575
4576
4577 switch (opc) {
4578 case OPC_GSLBX:
4579 case OPC_GSLHX:
4580 case OPC_GSLWX:
4581 case OPC_GSLDX:
4582
4583 if (rt == 0) {
4584 return;
4585 }
4586 break;
4587 case OPC_GSSBX:
4588 case OPC_GSSHX:
4589 case OPC_GSSWX:
4590 case OPC_GSSDX:
4591 break;
4592 case OPC_GSLWXC1:
4593#if defined(TARGET_MIPS64)
4594 case OPC_GSLDXC1:
4595#endif
4596 check_cp1_enabled(ctx);
4597
4598 if (rt == 0) {
4599 return;
4600 }
4601 break;
4602 case OPC_GSSWXC1:
4603#if defined(TARGET_MIPS64)
4604 case OPC_GSSDXC1:
4605#endif
4606 check_cp1_enabled(ctx);
4607 break;
4608 default:
4609 MIPS_INVAL("loongson_lsdc2");
4610 gen_reserved_instruction(ctx);
4611 return;
4612 break;
4613 }
4614
4615 t0 = tcg_temp_new();
4616
4617 gen_base_offset_addr(ctx, t0, rs, offset);
4618 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4619
4620 switch (opc) {
4621 case OPC_GSLBX:
4622 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4623 gen_store_gpr(t0, rt);
4624 break;
4625 case OPC_GSLHX:
4626 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4627 ctx->default_tcg_memop_mask);
4628 gen_store_gpr(t0, rt);
4629 break;
4630 case OPC_GSLWX:
4631 gen_base_offset_addr(ctx, t0, rs, offset);
4632 if (rd) {
4633 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4634 }
4635 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4636 ctx->default_tcg_memop_mask);
4637 gen_store_gpr(t0, rt);
4638 break;
4639#if defined(TARGET_MIPS64)
4640 case OPC_GSLDX:
4641 gen_base_offset_addr(ctx, t0, rs, offset);
4642 if (rd) {
4643 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4644 }
4645 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4646 ctx->default_tcg_memop_mask);
4647 gen_store_gpr(t0, rt);
4648 break;
4649#endif
4650 case OPC_GSLWXC1:
4651 gen_base_offset_addr(ctx, t0, rs, offset);
4652 if (rd) {
4653 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4654 }
4655 fp0 = tcg_temp_new_i32();
4656 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4657 ctx->default_tcg_memop_mask);
4658 gen_store_fpr32(ctx, fp0, rt);
4659 tcg_temp_free_i32(fp0);
4660 break;
4661#if defined(TARGET_MIPS64)
4662 case OPC_GSLDXC1:
4663 gen_base_offset_addr(ctx, t0, rs, offset);
4664 if (rd) {
4665 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4666 }
4667 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4668 ctx->default_tcg_memop_mask);
4669 gen_store_fpr64(ctx, t0, rt);
4670 break;
4671#endif
4672 case OPC_GSSBX:
4673 t1 = tcg_temp_new();
4674 gen_load_gpr(t1, rt);
4675 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4676 tcg_temp_free(t1);
4677 break;
4678 case OPC_GSSHX:
4679 t1 = tcg_temp_new();
4680 gen_load_gpr(t1, rt);
4681 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4682 ctx->default_tcg_memop_mask);
4683 tcg_temp_free(t1);
4684 break;
4685 case OPC_GSSWX:
4686 t1 = tcg_temp_new();
4687 gen_load_gpr(t1, rt);
4688 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4689 ctx->default_tcg_memop_mask);
4690 tcg_temp_free(t1);
4691 break;
4692#if defined(TARGET_MIPS64)
4693 case OPC_GSSDX:
4694 t1 = tcg_temp_new();
4695 gen_load_gpr(t1, rt);
4696 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4697 ctx->default_tcg_memop_mask);
4698 tcg_temp_free(t1);
4699 break;
4700#endif
4701 case OPC_GSSWXC1:
4702 fp0 = tcg_temp_new_i32();
4703 gen_load_fpr32(ctx, fp0, rt);
4704 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4705 ctx->default_tcg_memop_mask);
4706 tcg_temp_free_i32(fp0);
4707 break;
4708#if defined(TARGET_MIPS64)
4709 case OPC_GSSDXC1:
4710 t1 = tcg_temp_new();
4711 gen_load_fpr64(ctx, t1, rt);
4712 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
4713 ctx->default_tcg_memop_mask);
4714 tcg_temp_free(t1);
4715 break;
4716#endif
4717 default:
4718 break;
4719 }
4720
4721 tcg_temp_free(t0);
4722}
4723
4724
4725static void gen_trap(DisasContext *ctx, uint32_t opc,
4726 int rs, int rt, int16_t imm)
4727{
4728 int cond;
4729 TCGv t0 = tcg_temp_new();
4730 TCGv t1 = tcg_temp_new();
4731
4732 cond = 0;
4733
4734 switch (opc) {
4735 case OPC_TEQ:
4736 case OPC_TGE:
4737 case OPC_TGEU:
4738 case OPC_TLT:
4739 case OPC_TLTU:
4740 case OPC_TNE:
4741
4742 if (rs != rt) {
4743 gen_load_gpr(t0, rs);
4744 gen_load_gpr(t1, rt);
4745 cond = 1;
4746 }
4747 break;
4748 case OPC_TEQI:
4749 case OPC_TGEI:
4750 case OPC_TGEIU:
4751 case OPC_TLTI:
4752 case OPC_TLTIU:
4753 case OPC_TNEI:
4754
4755 if (rs != 0 || imm != 0) {
4756 gen_load_gpr(t0, rs);
4757 tcg_gen_movi_tl(t1, (int32_t)imm);
4758 cond = 1;
4759 }
4760 break;
4761 }
4762 if (cond == 0) {
4763 switch (opc) {
4764 case OPC_TEQ:
4765 case OPC_TEQI:
4766 case OPC_TGE:
4767 case OPC_TGEI:
4768 case OPC_TGEU:
4769 case OPC_TGEIU:
4770
4771 generate_exception_end(ctx, EXCP_TRAP);
4772 break;
4773 case OPC_TLT:
4774 case OPC_TLTI:
4775 case OPC_TLTU:
4776 case OPC_TLTIU:
4777 case OPC_TNE:
4778 case OPC_TNEI:
4779
4780 break;
4781 }
4782 } else {
4783 TCGLabel *l1 = gen_new_label();
4784
4785 switch (opc) {
4786 case OPC_TEQ:
4787 case OPC_TEQI:
4788 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4789 break;
4790 case OPC_TGE:
4791 case OPC_TGEI:
4792 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4793 break;
4794 case OPC_TGEU:
4795 case OPC_TGEIU:
4796 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4797 break;
4798 case OPC_TLT:
4799 case OPC_TLTI:
4800 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4801 break;
4802 case OPC_TLTU:
4803 case OPC_TLTIU:
4804 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4805 break;
4806 case OPC_TNE:
4807 case OPC_TNEI:
4808 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4809 break;
4810 }
4811 generate_exception(ctx, EXCP_TRAP);
4812 gen_set_label(l1);
4813 }
4814 tcg_temp_free(t0);
4815 tcg_temp_free(t1);
4816}
4817
4818static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4819{
4820 if (translator_use_goto_tb(&ctx->base, dest)) {
4821 tcg_gen_goto_tb(n);
4822 gen_save_pc(dest);
4823 tcg_gen_exit_tb(ctx->base.tb, n);
4824 } else {
4825 gen_save_pc(dest);
4826 tcg_gen_lookup_and_goto_ptr();
4827 }
4828}
4829
4830
4831static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4832 int insn_bytes,
4833 int rs, int rt, int32_t offset,
4834 int delayslot_size)
4835{
4836 target_ulong btgt = -1;
4837 int blink = 0;
4838 int bcond_compute = 0;
4839 TCGv t0 = tcg_temp_new();
4840 TCGv t1 = tcg_temp_new();
4841
4842 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4843#ifdef MIPS_DEBUG_DISAS
4844 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4845 TARGET_FMT_lx "\n", ctx->base.pc_next);
4846#endif
4847 gen_reserved_instruction(ctx);
4848 goto out;
4849 }
4850
4851
4852 switch (opc) {
4853 case OPC_BEQ:
4854 case OPC_BEQL:
4855 case OPC_BNE:
4856 case OPC_BNEL:
4857
4858 if (rs != rt) {
4859 gen_load_gpr(t0, rs);
4860 gen_load_gpr(t1, rt);
4861 bcond_compute = 1;
4862 }
4863 btgt = ctx->base.pc_next + insn_bytes + offset;
4864 break;
4865 case OPC_BGEZ:
4866 case OPC_BGEZAL:
4867 case OPC_BGEZALL:
4868 case OPC_BGEZL:
4869 case OPC_BGTZ:
4870 case OPC_BGTZL:
4871 case OPC_BLEZ:
4872 case OPC_BLEZL:
4873 case OPC_BLTZ:
4874 case OPC_BLTZAL:
4875 case OPC_BLTZALL:
4876 case OPC_BLTZL:
4877
4878 if (rs != 0) {
4879 gen_load_gpr(t0, rs);
4880 bcond_compute = 1;
4881 }
4882 btgt = ctx->base.pc_next + insn_bytes + offset;
4883 break;
4884 case OPC_BPOSGE32:
4885#if defined(TARGET_MIPS64)
4886 case OPC_BPOSGE64:
4887 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4888#else
4889 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4890#endif
4891 bcond_compute = 1;
4892 btgt = ctx->base.pc_next + insn_bytes + offset;
4893 break;
4894 case OPC_J:
4895 case OPC_JAL:
4896 case OPC_JALX:
4897
4898 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4899 (uint32_t)offset;
4900 break;
4901 case OPC_JR:
4902 case OPC_JALR:
4903
4904 if (offset != 0 && offset != 16) {
4905
4906
4907
4908
4909 MIPS_INVAL("jump hint");
4910 gen_reserved_instruction(ctx);
4911 goto out;
4912 }
4913 gen_load_gpr(btarget, rs);
4914 break;
4915 default:
4916 MIPS_INVAL("branch/jump");
4917 gen_reserved_instruction(ctx);
4918 goto out;
4919 }
4920 if (bcond_compute == 0) {
4921
4922 switch (opc) {
4923 case OPC_BEQ:
4924 case OPC_BEQL:
4925 case OPC_BGEZ:
4926 case OPC_BGEZL:
4927 case OPC_BLEZ:
4928 case OPC_BLEZL:
4929
4930 ctx->hflags |= MIPS_HFLAG_B;
4931 break;
4932 case OPC_BGEZAL:
4933 case OPC_BGEZALL:
4934
4935 blink = 31;
4936 ctx->hflags |= MIPS_HFLAG_B;
4937 break;
4938 case OPC_BNE:
4939 case OPC_BGTZ:
4940 case OPC_BLTZ:
4941
4942 goto out;
4943 case OPC_BLTZAL:
4944
4945
4946
4947
4948 blink = 31;
4949 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4950 ctx->hflags |= MIPS_HFLAG_B;
4951 break;
4952 case OPC_BLTZALL:
4953 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4954
4955 ctx->base.pc_next += 4;
4956 goto out;
4957 case OPC_BNEL:
4958 case OPC_BGTZL:
4959 case OPC_BLTZL:
4960
4961 ctx->base.pc_next += 4;
4962 goto out;
4963 case OPC_J:
4964 ctx->hflags |= MIPS_HFLAG_B;
4965 break;
4966 case OPC_JALX:
4967 ctx->hflags |= MIPS_HFLAG_BX;
4968
4969 case OPC_JAL:
4970 blink = 31;
4971 ctx->hflags |= MIPS_HFLAG_B;
4972 break;
4973 case OPC_JR:
4974 ctx->hflags |= MIPS_HFLAG_BR;
4975 break;
4976 case OPC_JALR:
4977 blink = rt;
4978 ctx->hflags |= MIPS_HFLAG_BR;
4979 break;
4980 default:
4981 MIPS_INVAL("branch/jump");
4982 gen_reserved_instruction(ctx);
4983 goto out;
4984 }
4985 } else {
4986 switch (opc) {
4987 case OPC_BEQ:
4988 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4989 goto not_likely;
4990 case OPC_BEQL:
4991 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4992 goto likely;
4993 case OPC_BNE:
4994 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4995 goto not_likely;
4996 case OPC_BNEL:
4997 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4998 goto likely;
4999 case OPC_BGEZ:
5000 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5001 goto not_likely;
5002 case OPC_BGEZL:
5003 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5004 goto likely;
5005 case OPC_BGEZAL:
5006 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5007 blink = 31;
5008 goto not_likely;
5009 case OPC_BGEZALL:
5010 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5011 blink = 31;
5012 goto likely;
5013 case OPC_BGTZ:
5014 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5015 goto not_likely;
5016 case OPC_BGTZL:
5017 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5018 goto likely;
5019 case OPC_BLEZ:
5020 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5021 goto not_likely;
5022 case OPC_BLEZL:
5023 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5024 goto likely;
5025 case OPC_BLTZ:
5026 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5027 goto not_likely;
5028 case OPC_BLTZL:
5029 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5030 goto likely;
5031 case OPC_BPOSGE32:
5032 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5033 goto not_likely;
5034#if defined(TARGET_MIPS64)
5035 case OPC_BPOSGE64:
5036 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5037 goto not_likely;
5038#endif
5039 case OPC_BLTZAL:
5040 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5041 blink = 31;
5042 not_likely:
5043 ctx->hflags |= MIPS_HFLAG_BC;
5044 break;
5045 case OPC_BLTZALL:
5046 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5047 blink = 31;
5048 likely:
5049 ctx->hflags |= MIPS_HFLAG_BL;
5050 break;
5051 default:
5052 MIPS_INVAL("conditional branch/jump");
5053 gen_reserved_instruction(ctx);
5054 goto out;
5055 }
5056 }
5057
5058 ctx->btarget = btgt;
5059
5060 switch (delayslot_size) {
5061 case 2:
5062 ctx->hflags |= MIPS_HFLAG_BDS16;
5063 break;
5064 case 4:
5065 ctx->hflags |= MIPS_HFLAG_BDS32;
5066 break;
5067 }
5068
5069 if (blink > 0) {
5070 int post_delay = insn_bytes + delayslot_size;
5071 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5072
5073 tcg_gen_movi_tl(cpu_gpr[blink],
5074 ctx->base.pc_next + post_delay + lowbit);
5075 }
5076
5077 out:
5078 if (insn_bytes == 2) {
5079 ctx->hflags |= MIPS_HFLAG_B16;
5080 }
5081 tcg_temp_free(t0);
5082 tcg_temp_free(t1);
5083}
5084
5085
5086
5087static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5088 int rs, int lsb, int msb)
5089{
5090 TCGv t0 = tcg_temp_new();
5091 TCGv t1 = tcg_temp_new();
5092
5093 gen_load_gpr(t1, rs);
5094 switch (opc) {
5095 case OPC_EXT:
5096 if (lsb + msb > 31) {
5097 goto fail;
5098 }
5099 if (msb != 31) {
5100 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5101 } else {
5102
5103
5104
5105
5106 tcg_gen_ext32s_tl(t0, t1);
5107 }
5108 break;
5109#if defined(TARGET_MIPS64)
5110 case OPC_DEXTU:
5111 lsb += 32;
5112 goto do_dext;
5113 case OPC_DEXTM:
5114 msb += 32;
5115 goto do_dext;
5116 case OPC_DEXT:
5117 do_dext:
5118 if (lsb + msb > 63) {
5119 goto fail;
5120 }
5121 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5122 break;
5123#endif
5124 case OPC_INS:
5125 if (lsb > msb) {
5126 goto fail;
5127 }
5128 gen_load_gpr(t0, rt);
5129 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5130 tcg_gen_ext32s_tl(t0, t0);
5131 break;
5132#if defined(TARGET_MIPS64)
5133 case OPC_DINSU:
5134 lsb += 32;
5135
5136 case OPC_DINSM:
5137 msb += 32;
5138
5139 case OPC_DINS:
5140 if (lsb > msb) {
5141 goto fail;
5142 }
5143 gen_load_gpr(t0, rt);
5144 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5145 break;
5146#endif
5147 default:
5148fail:
5149 MIPS_INVAL("bitops");
5150 gen_reserved_instruction(ctx);
5151 tcg_temp_free(t0);
5152 tcg_temp_free(t1);
5153 return;
5154 }
5155 gen_store_gpr(t0, rt);
5156 tcg_temp_free(t0);
5157 tcg_temp_free(t1);
5158}
5159
5160static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5161{
5162 TCGv t0;
5163
5164 if (rd == 0) {
5165
5166 return;
5167 }
5168
5169 t0 = tcg_temp_new();
5170 gen_load_gpr(t0, rt);
5171 switch (op2) {
5172 case OPC_WSBH:
5173 {
5174 TCGv t1 = tcg_temp_new();
5175 TCGv t2 = tcg_const_tl(0x00FF00FF);
5176
5177 tcg_gen_shri_tl(t1, t0, 8);
5178 tcg_gen_and_tl(t1, t1, t2);
5179 tcg_gen_and_tl(t0, t0, t2);
5180 tcg_gen_shli_tl(t0, t0, 8);
5181 tcg_gen_or_tl(t0, t0, t1);
5182 tcg_temp_free(t2);
5183 tcg_temp_free(t1);
5184 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5185 }
5186 break;
5187 case OPC_SEB:
5188 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5189 break;
5190 case OPC_SEH:
5191 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5192 break;
5193#if defined(TARGET_MIPS64)
5194 case OPC_DSBH:
5195 {
5196 TCGv t1 = tcg_temp_new();
5197 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5198
5199 tcg_gen_shri_tl(t1, t0, 8);
5200 tcg_gen_and_tl(t1, t1, t2);
5201 tcg_gen_and_tl(t0, t0, t2);
5202 tcg_gen_shli_tl(t0, t0, 8);
5203 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5204 tcg_temp_free(t2);
5205 tcg_temp_free(t1);
5206 }
5207 break;
5208 case OPC_DSHD:
5209 {
5210 TCGv t1 = tcg_temp_new();
5211 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5212
5213 tcg_gen_shri_tl(t1, t0, 16);
5214 tcg_gen_and_tl(t1, t1, t2);
5215 tcg_gen_and_tl(t0, t0, t2);
5216 tcg_gen_shli_tl(t0, t0, 16);
5217 tcg_gen_or_tl(t0, t0, t1);
5218 tcg_gen_shri_tl(t1, t0, 32);
5219 tcg_gen_shli_tl(t0, t0, 32);
5220 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5221 tcg_temp_free(t2);
5222 tcg_temp_free(t1);
5223 }
5224 break;
5225#endif
5226 default:
5227 MIPS_INVAL("bsfhl");
5228 gen_reserved_instruction(ctx);
5229 tcg_temp_free(t0);
5230 return;
5231 }
5232 tcg_temp_free(t0);
5233}
5234
5235static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5236 int rt, int bits)
5237{
5238 TCGv t0;
5239 if (rd == 0) {
5240
5241 return;
5242 }
5243 t0 = tcg_temp_new();
5244 if (bits == 0 || bits == wordsz) {
5245 if (bits == 0) {
5246 gen_load_gpr(t0, rt);
5247 } else {
5248 gen_load_gpr(t0, rs);
5249 }
5250 switch (wordsz) {
5251 case 32:
5252 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5253 break;
5254#if defined(TARGET_MIPS64)
5255 case 64:
5256 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5257 break;
5258#endif
5259 }
5260 } else {
5261 TCGv t1 = tcg_temp_new();
5262 gen_load_gpr(t0, rt);
5263 gen_load_gpr(t1, rs);
5264 switch (wordsz) {
5265 case 32:
5266 {
5267 TCGv_i64 t2 = tcg_temp_new_i64();
5268 tcg_gen_concat_tl_i64(t2, t1, t0);
5269 tcg_gen_shri_i64(t2, t2, 32 - bits);
5270 gen_move_low32(cpu_gpr[rd], t2);
5271 tcg_temp_free_i64(t2);
5272 }
5273 break;
5274#if defined(TARGET_MIPS64)
5275 case 64:
5276 tcg_gen_shli_tl(t0, t0, bits);
5277 tcg_gen_shri_tl(t1, t1, 64 - bits);
5278 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5279 break;
5280#endif
5281 }
5282 tcg_temp_free(t1);
5283 }
5284
5285 tcg_temp_free(t0);
5286}
5287
5288void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5289{
5290 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5291}
5292
5293static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5294{
5295 TCGv t0;
5296 if (rd == 0) {
5297
5298 return;
5299 }
5300 t0 = tcg_temp_new();
5301 gen_load_gpr(t0, rt);
5302 switch (opc) {
5303 case OPC_BITSWAP:
5304 gen_helper_bitswap(cpu_gpr[rd], t0);
5305 break;
5306#if defined(TARGET_MIPS64)
5307 case OPC_DBITSWAP:
5308 gen_helper_dbitswap(cpu_gpr[rd], t0);
5309 break;
5310#endif
5311 }
5312 tcg_temp_free(t0);
5313}
5314
5315#ifndef CONFIG_USER_ONLY
5316
5317static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5318{
5319 TCGv_i64 t0 = tcg_temp_new_i64();
5320 TCGv_i64 t1 = tcg_temp_new_i64();
5321
5322 tcg_gen_ext_tl_i64(t0, arg);
5323 tcg_gen_ld_i64(t1, cpu_env, off);
5324#if defined(TARGET_MIPS64)
5325 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5326#else
5327 tcg_gen_concat32_i64(t1, t1, t0);
5328#endif
5329 tcg_gen_st_i64(t1, cpu_env, off);
5330 tcg_temp_free_i64(t1);
5331 tcg_temp_free_i64(t0);
5332}
5333
5334static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5335{
5336 TCGv_i64 t0 = tcg_temp_new_i64();
5337 TCGv_i64 t1 = tcg_temp_new_i64();
5338
5339 tcg_gen_ext_tl_i64(t0, arg);
5340 tcg_gen_ld_i64(t1, cpu_env, off);
5341 tcg_gen_concat32_i64(t1, t1, t0);
5342 tcg_gen_st_i64(t1, cpu_env, off);
5343 tcg_temp_free_i64(t1);
5344 tcg_temp_free_i64(t0);
5345}
5346
5347static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5348{
5349 TCGv_i64 t0 = tcg_temp_new_i64();
5350
5351 tcg_gen_ld_i64(t0, cpu_env, off);
5352#if defined(TARGET_MIPS64)
5353 tcg_gen_shri_i64(t0, t0, 30);
5354#else
5355 tcg_gen_shri_i64(t0, t0, 32);
5356#endif
5357 gen_move_low32(arg, t0);
5358 tcg_temp_free_i64(t0);
5359}
5360
5361static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5362{
5363 TCGv_i64 t0 = tcg_temp_new_i64();
5364
5365 tcg_gen_ld_i64(t0, cpu_env, off);
5366 tcg_gen_shri_i64(t0, t0, 32 + shift);
5367 gen_move_low32(arg, t0);
5368 tcg_temp_free_i64(t0);
5369}
5370
5371static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5372{
5373 TCGv_i32 t0 = tcg_temp_new_i32();
5374
5375 tcg_gen_ld_i32(t0, cpu_env, off);
5376 tcg_gen_ext_i32_tl(arg, t0);
5377 tcg_temp_free_i32(t0);
5378}
5379
5380static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5381{
5382 tcg_gen_ld_tl(arg, cpu_env, off);
5383 tcg_gen_ext32s_tl(arg, arg);
5384}
5385
5386static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5387{
5388 TCGv_i32 t0 = tcg_temp_new_i32();
5389
5390 tcg_gen_trunc_tl_i32(t0, arg);
5391 tcg_gen_st_i32(t0, cpu_env, off);
5392 tcg_temp_free_i32(t0);
5393}
5394
5395#define CP0_CHECK(c) \
5396 do { \
5397 if (!(c)) { \
5398 goto cp0_unimplemented; \
5399 } \
5400 } while (0)
5401
5402static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5403{
5404 const char *register_name = "invalid";
5405
5406 switch (reg) {
5407 case CP0_REGISTER_02:
5408 switch (sel) {
5409 case 0:
5410 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5411 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5412 register_name = "EntryLo0";
5413 break;
5414 default:
5415 goto cp0_unimplemented;
5416 }
5417 break;
5418 case CP0_REGISTER_03:
5419 switch (sel) {
5420 case CP0_REG03__ENTRYLO1:
5421 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5422 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5423 register_name = "EntryLo1";
5424 break;
5425 default:
5426 goto cp0_unimplemented;
5427 }
5428 break;
5429 case CP0_REGISTER_09:
5430 switch (sel) {
5431 case CP0_REG09__SAAR:
5432 CP0_CHECK(ctx->saar);
5433 gen_helper_mfhc0_saar(arg, cpu_env);
5434 register_name = "SAAR";
5435 break;
5436 default:
5437 goto cp0_unimplemented;
5438 }
5439 break;
5440 case CP0_REGISTER_17:
5441 switch (sel) {
5442 case CP0_REG17__LLADDR:
5443 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5444 ctx->CP0_LLAddr_shift);
5445 register_name = "LLAddr";
5446 break;
5447 case CP0_REG17__MAAR:
5448 CP0_CHECK(ctx->mrp);
5449 gen_helper_mfhc0_maar(arg, cpu_env);
5450 register_name = "MAAR";
5451 break;
5452 default:
5453 goto cp0_unimplemented;
5454 }
5455 break;
5456 case CP0_REGISTER_19:
5457 switch (sel) {
5458 case CP0_REG19__WATCHHI0:
5459 case CP0_REG19__WATCHHI1:
5460 case CP0_REG19__WATCHHI2:
5461 case CP0_REG19__WATCHHI3:
5462 case CP0_REG19__WATCHHI4:
5463 case CP0_REG19__WATCHHI5:
5464 case CP0_REG19__WATCHHI6:
5465 case CP0_REG19__WATCHHI7:
5466
5467 CP0_CHECK(ctx->mi);
5468 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5469 register_name = "WatchHi";
5470 break;
5471 default:
5472 goto cp0_unimplemented;
5473 }
5474 break;
5475 case CP0_REGISTER_28:
5476 switch (sel) {
5477 case 0:
5478 case 2:
5479 case 4:
5480 case 6:
5481 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5482 register_name = "TagLo";
5483 break;
5484 default:
5485 goto cp0_unimplemented;
5486 }
5487 break;
5488 default:
5489 goto cp0_unimplemented;
5490 }
5491 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5492 return;
5493
5494cp0_unimplemented:
5495 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5496 register_name, reg, sel);
5497 tcg_gen_movi_tl(arg, 0);
5498}
5499
5500static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5501{
5502 const char *register_name = "invalid";
5503 uint64_t mask = ctx->PAMask >> 36;
5504
5505 switch (reg) {
5506 case CP0_REGISTER_02:
5507 switch (sel) {
5508 case 0:
5509 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5510 tcg_gen_andi_tl(arg, arg, mask);
5511 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5512 register_name = "EntryLo0";
5513 break;
5514 default:
5515 goto cp0_unimplemented;
5516 }
5517 break;
5518 case CP0_REGISTER_03:
5519 switch (sel) {
5520 case CP0_REG03__ENTRYLO1:
5521 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5522 tcg_gen_andi_tl(arg, arg, mask);
5523 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5524 register_name = "EntryLo1";
5525 break;
5526 default:
5527 goto cp0_unimplemented;
5528 }
5529 break;
5530 case CP0_REGISTER_09:
5531 switch (sel) {
5532 case CP0_REG09__SAAR:
5533 CP0_CHECK(ctx->saar);
5534 gen_helper_mthc0_saar(cpu_env, arg);
5535 register_name = "SAAR";
5536 break;
5537 default:
5538 goto cp0_unimplemented;
5539 }
5540 break;
5541 case CP0_REGISTER_17:
5542 switch (sel) {
5543 case CP0_REG17__LLADDR:
5544
5545
5546
5547
5548
5549
5550 register_name = "LLAddr";
5551 break;
5552 case CP0_REG17__MAAR:
5553 CP0_CHECK(ctx->mrp);
5554 gen_helper_mthc0_maar(cpu_env, arg);
5555 register_name = "MAAR";
5556 break;
5557 default:
5558 goto cp0_unimplemented;
5559 }
5560 break;
5561 case CP0_REGISTER_19:
5562 switch (sel) {
5563 case CP0_REG19__WATCHHI0:
5564 case CP0_REG19__WATCHHI1:
5565 case CP0_REG19__WATCHHI2:
5566 case CP0_REG19__WATCHHI3:
5567 case CP0_REG19__WATCHHI4:
5568 case CP0_REG19__WATCHHI5:
5569 case CP0_REG19__WATCHHI6:
5570 case CP0_REG19__WATCHHI7:
5571
5572 CP0_CHECK(ctx->mi);
5573 gen_helper_0e1i(mthc0_watchhi, arg, sel);
5574 register_name = "WatchHi";
5575 break;
5576 default:
5577 goto cp0_unimplemented;
5578 }
5579 break;
5580 case CP0_REGISTER_28:
5581 switch (sel) {
5582 case 0:
5583 case 2:
5584 case 4:
5585 case 6:
5586 tcg_gen_andi_tl(arg, arg, mask);
5587 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5588 register_name = "TagLo";
5589 break;
5590 default:
5591 goto cp0_unimplemented;
5592 }
5593 break;
5594 default:
5595 goto cp0_unimplemented;
5596 }
5597 trace_mips_translate_c0("mthc0", register_name, reg, sel);
5598 return;
5599
5600cp0_unimplemented:
5601 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5602 register_name, reg, sel);
5603}
5604
5605static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5606{
5607 if (ctx->insn_flags & ISA_MIPS_R6) {
5608 tcg_gen_movi_tl(arg, 0);
5609 } else {
5610 tcg_gen_movi_tl(arg, ~0);
5611 }
5612}
5613
5614static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5615{
5616 const char *register_name = "invalid";
5617
5618 if (sel != 0) {
5619 check_insn(ctx, ISA_MIPS_R1);
5620 }
5621
5622 switch (reg) {
5623 case CP0_REGISTER_00:
5624 switch (sel) {
5625 case CP0_REG00__INDEX:
5626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5627 register_name = "Index";
5628 break;
5629 case CP0_REG00__MVPCONTROL:
5630 CP0_CHECK(ctx->insn_flags & ASE_MT);
5631 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5632 register_name = "MVPControl";
5633 break;
5634 case CP0_REG00__MVPCONF0:
5635 CP0_CHECK(ctx->insn_flags & ASE_MT);
5636 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5637 register_name = "MVPConf0";
5638 break;
5639 case CP0_REG00__MVPCONF1:
5640 CP0_CHECK(ctx->insn_flags & ASE_MT);
5641 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5642 register_name = "MVPConf1";
5643 break;
5644 case CP0_REG00__VPCONTROL:
5645 CP0_CHECK(ctx->vp);
5646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5647 register_name = "VPControl";
5648 break;
5649 default:
5650 goto cp0_unimplemented;
5651 }
5652 break;
5653 case CP0_REGISTER_01:
5654 switch (sel) {
5655 case CP0_REG01__RANDOM:
5656 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5657 gen_helper_mfc0_random(arg, cpu_env);
5658 register_name = "Random";
5659 break;
5660 case CP0_REG01__VPECONTROL:
5661 CP0_CHECK(ctx->insn_flags & ASE_MT);
5662 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5663 register_name = "VPEControl";
5664 break;
5665 case CP0_REG01__VPECONF0:
5666 CP0_CHECK(ctx->insn_flags & ASE_MT);
5667 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5668 register_name = "VPEConf0";
5669 break;
5670 case CP0_REG01__VPECONF1:
5671 CP0_CHECK(ctx->insn_flags & ASE_MT);
5672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5673 register_name = "VPEConf1";
5674 break;
5675 case CP0_REG01__YQMASK:
5676 CP0_CHECK(ctx->insn_flags & ASE_MT);
5677 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5678 register_name = "YQMask";
5679 break;
5680 case CP0_REG01__VPESCHEDULE:
5681 CP0_CHECK(ctx->insn_flags & ASE_MT);
5682 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5683 register_name = "VPESchedule";
5684 break;
5685 case CP0_REG01__VPESCHEFBACK:
5686 CP0_CHECK(ctx->insn_flags & ASE_MT);
5687 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5688 register_name = "VPEScheFBack";
5689 break;
5690 case CP0_REG01__VPEOPT:
5691 CP0_CHECK(ctx->insn_flags & ASE_MT);
5692 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5693 register_name = "VPEOpt";
5694 break;
5695 default:
5696 goto cp0_unimplemented;
5697 }
5698 break;
5699 case CP0_REGISTER_02:
5700 switch (sel) {
5701 case CP0_REG02__ENTRYLO0:
5702 {
5703 TCGv_i64 tmp = tcg_temp_new_i64();
5704 tcg_gen_ld_i64(tmp, cpu_env,
5705 offsetof(CPUMIPSState, CP0_EntryLo0));
5706#if defined(TARGET_MIPS64)
5707 if (ctx->rxi) {
5708
5709 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5710 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5711 }
5712#endif
5713 gen_move_low32(arg, tmp);
5714 tcg_temp_free_i64(tmp);
5715 }
5716 register_name = "EntryLo0";
5717 break;
5718 case CP0_REG02__TCSTATUS:
5719 CP0_CHECK(ctx->insn_flags & ASE_MT);
5720 gen_helper_mfc0_tcstatus(arg, cpu_env);
5721 register_name = "TCStatus";
5722 break;
5723 case CP0_REG02__TCBIND:
5724 CP0_CHECK(ctx->insn_flags & ASE_MT);
5725 gen_helper_mfc0_tcbind(arg, cpu_env);
5726 register_name = "TCBind";
5727 break;
5728 case CP0_REG02__TCRESTART:
5729 CP0_CHECK(ctx->insn_flags & ASE_MT);
5730 gen_helper_mfc0_tcrestart(arg, cpu_env);
5731 register_name = "TCRestart";
5732 break;
5733 case CP0_REG02__TCHALT:
5734 CP0_CHECK(ctx->insn_flags & ASE_MT);
5735 gen_helper_mfc0_tchalt(arg, cpu_env);
5736 register_name = "TCHalt";
5737 break;
5738 case CP0_REG02__TCCONTEXT:
5739 CP0_CHECK(ctx->insn_flags & ASE_MT);
5740 gen_helper_mfc0_tccontext(arg, cpu_env);
5741 register_name = "TCContext";
5742 break;
5743 case CP0_REG02__TCSCHEDULE:
5744 CP0_CHECK(ctx->insn_flags & ASE_MT);
5745 gen_helper_mfc0_tcschedule(arg, cpu_env);
5746 register_name = "TCSchedule";
5747 break;
5748 case CP0_REG02__TCSCHEFBACK:
5749 CP0_CHECK(ctx->insn_flags & ASE_MT);
5750 gen_helper_mfc0_tcschefback(arg, cpu_env);
5751 register_name = "TCScheFBack";
5752 break;
5753 default:
5754 goto cp0_unimplemented;
5755 }
5756 break;
5757 case CP0_REGISTER_03:
5758 switch (sel) {
5759 case CP0_REG03__ENTRYLO1:
5760 {
5761 TCGv_i64 tmp = tcg_temp_new_i64();
5762 tcg_gen_ld_i64(tmp, cpu_env,
5763 offsetof(CPUMIPSState, CP0_EntryLo1));
5764#if defined(TARGET_MIPS64)
5765 if (ctx->rxi) {
5766
5767 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5768 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5769 }
5770#endif
5771 gen_move_low32(arg, tmp);
5772 tcg_temp_free_i64(tmp);
5773 }
5774 register_name = "EntryLo1";
5775 break;
5776 case CP0_REG03__GLOBALNUM:
5777 CP0_CHECK(ctx->vp);
5778 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5779 register_name = "GlobalNumber";
5780 break;
5781 default:
5782 goto cp0_unimplemented;
5783 }
5784 break;
5785 case CP0_REGISTER_04:
5786 switch (sel) {
5787 case CP0_REG04__CONTEXT:
5788 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5789 tcg_gen_ext32s_tl(arg, arg);
5790 register_name = "Context";
5791 break;
5792 case CP0_REG04__CONTEXTCONFIG:
5793
5794
5795 register_name = "ContextConfig";
5796 goto cp0_unimplemented;
5797 case CP0_REG04__USERLOCAL:
5798 CP0_CHECK(ctx->ulri);
5799 tcg_gen_ld_tl(arg, cpu_env,
5800 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5801 tcg_gen_ext32s_tl(arg, arg);
5802 register_name = "UserLocal";
5803 break;
5804 case CP0_REG04__MMID:
5805 CP0_CHECK(ctx->mi);
5806 gen_helper_mtc0_memorymapid(cpu_env, arg);
5807 register_name = "MMID";
5808 break;
5809 default:
5810 goto cp0_unimplemented;
5811 }
5812 break;
5813 case CP0_REGISTER_05:
5814 switch (sel) {
5815 case CP0_REG05__PAGEMASK:
5816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5817 register_name = "PageMask";
5818 break;
5819 case CP0_REG05__PAGEGRAIN:
5820 check_insn(ctx, ISA_MIPS_R2);
5821 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5822 register_name = "PageGrain";
5823 break;
5824 case CP0_REG05__SEGCTL0:
5825 CP0_CHECK(ctx->sc);
5826 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5827 tcg_gen_ext32s_tl(arg, arg);
5828 register_name = "SegCtl0";
5829 break;
5830 case CP0_REG05__SEGCTL1:
5831 CP0_CHECK(ctx->sc);
5832 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5833 tcg_gen_ext32s_tl(arg, arg);
5834 register_name = "SegCtl1";
5835 break;
5836 case CP0_REG05__SEGCTL2:
5837 CP0_CHECK(ctx->sc);
5838 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5839 tcg_gen_ext32s_tl(arg, arg);
5840 register_name = "SegCtl2";
5841 break;
5842 case CP0_REG05__PWBASE:
5843 check_pw(ctx);
5844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5845 register_name = "PWBase";
5846 break;
5847 case CP0_REG05__PWFIELD:
5848 check_pw(ctx);
5849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5850 register_name = "PWField";
5851 break;
5852 case CP0_REG05__PWSIZE:
5853 check_pw(ctx);
5854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5855 register_name = "PWSize";
5856 break;
5857 default:
5858 goto cp0_unimplemented;
5859 }
5860 break;
5861 case CP0_REGISTER_06:
5862 switch (sel) {
5863 case CP0_REG06__WIRED:
5864 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5865 register_name = "Wired";
5866 break;
5867 case CP0_REG06__SRSCONF0:
5868 check_insn(ctx, ISA_MIPS_R2);
5869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5870 register_name = "SRSConf0";
5871 break;
5872 case CP0_REG06__SRSCONF1:
5873 check_insn(ctx, ISA_MIPS_R2);
5874 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5875 register_name = "SRSConf1";
5876 break;
5877 case CP0_REG06__SRSCONF2:
5878 check_insn(ctx, ISA_MIPS_R2);
5879 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5880 register_name = "SRSConf2";
5881 break;
5882 case CP0_REG06__SRSCONF3:
5883 check_insn(ctx, ISA_MIPS_R2);
5884 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5885 register_name = "SRSConf3";
5886 break;
5887 case CP0_REG06__SRSCONF4:
5888 check_insn(ctx, ISA_MIPS_R2);
5889 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5890 register_name = "SRSConf4";
5891 break;
5892 case CP0_REG06__PWCTL:
5893 check_pw(ctx);
5894 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5895 register_name = "PWCtl";
5896 break;
5897 default:
5898 goto cp0_unimplemented;
5899 }
5900 break;
5901 case CP0_REGISTER_07:
5902 switch (sel) {
5903 case CP0_REG07__HWRENA:
5904 check_insn(ctx, ISA_MIPS_R2);
5905 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5906 register_name = "HWREna";
5907 break;
5908 default:
5909 goto cp0_unimplemented;
5910 }
5911 break;
5912 case CP0_REGISTER_08:
5913 switch (sel) {
5914 case CP0_REG08__BADVADDR:
5915 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5916 tcg_gen_ext32s_tl(arg, arg);
5917 register_name = "BadVAddr";
5918 break;
5919 case CP0_REG08__BADINSTR:
5920 CP0_CHECK(ctx->bi);
5921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5922 register_name = "BadInstr";
5923 break;
5924 case CP0_REG08__BADINSTRP:
5925 CP0_CHECK(ctx->bp);
5926 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5927 register_name = "BadInstrP";
5928 break;
5929 case CP0_REG08__BADINSTRX:
5930 CP0_CHECK(ctx->bi);
5931 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5932 tcg_gen_andi_tl(arg, arg, ~0xffff);
5933 register_name = "BadInstrX";
5934 break;
5935 default:
5936 goto cp0_unimplemented;
5937 }
5938 break;
5939 case CP0_REGISTER_09:
5940 switch (sel) {
5941 case CP0_REG09__COUNT:
5942
5943 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
5944 gen_io_start();
5945 }
5946 gen_helper_mfc0_count(arg, cpu_env);
5947
5948
5949
5950
5951
5952 gen_save_pc(ctx->base.pc_next + 4);
5953 ctx->base.is_jmp = DISAS_EXIT;
5954 register_name = "Count";
5955 break;
5956 case CP0_REG09__SAARI:
5957 CP0_CHECK(ctx->saar);
5958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5959 register_name = "SAARI";
5960 break;
5961 case CP0_REG09__SAAR:
5962 CP0_CHECK(ctx->saar);
5963 gen_helper_mfc0_saar(arg, cpu_env);
5964 register_name = "SAAR";
5965 break;
5966 default:
5967 goto cp0_unimplemented;
5968 }
5969 break;
5970 case CP0_REGISTER_10:
5971 switch (sel) {
5972 case CP0_REG10__ENTRYHI:
5973 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5974 tcg_gen_ext32s_tl(arg, arg);
5975 register_name = "EntryHi";
5976 break;
5977 default:
5978 goto cp0_unimplemented;
5979 }
5980 break;
5981 case CP0_REGISTER_11:
5982 switch (sel) {
5983 case CP0_REG11__COMPARE:
5984 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5985 register_name = "Compare";
5986 break;
5987
5988 default:
5989 goto cp0_unimplemented;
5990 }
5991 break;
5992 case CP0_REGISTER_12:
5993 switch (sel) {
5994 case CP0_REG12__STATUS:
5995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5996 register_name = "Status";
5997 break;
5998 case CP0_REG12__INTCTL:
5999 check_insn(ctx, ISA_MIPS_R2);
6000 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6001 register_name = "IntCtl";
6002 break;
6003 case CP0_REG12__SRSCTL:
6004 check_insn(ctx, ISA_MIPS_R2);
6005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6006 register_name = "SRSCtl";
6007 break;
6008 case CP0_REG12__SRSMAP:
6009 check_insn(ctx, ISA_MIPS_R2);
6010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6011 register_name = "SRSMap";
6012 break;
6013 default:
6014 goto cp0_unimplemented;
6015 }
6016 break;
6017 case CP0_REGISTER_13:
6018 switch (sel) {
6019 case CP0_REG13__CAUSE:
6020 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6021 register_name = "Cause";
6022 break;
6023 default:
6024 goto cp0_unimplemented;
6025 }
6026 break;
6027 case CP0_REGISTER_14:
6028 switch (sel) {
6029 case CP0_REG14__EPC:
6030 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6031 tcg_gen_ext32s_tl(arg, arg);
6032 register_name = "EPC";
6033 break;
6034 default:
6035 goto cp0_unimplemented;
6036 }
6037 break;
6038 case CP0_REGISTER_15:
6039 switch (sel) {
6040 case CP0_REG15__PRID:
6041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6042 register_name = "PRid";
6043 break;
6044 case CP0_REG15__EBASE:
6045 check_insn(ctx, ISA_MIPS_R2);
6046 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6047 tcg_gen_ext32s_tl(arg, arg);
6048 register_name = "EBase";
6049 break;
6050 case CP0_REG15__CMGCRBASE:
6051 check_insn(ctx, ISA_MIPS_R2);
6052 CP0_CHECK(ctx->cmgcr);
6053 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6054 tcg_gen_ext32s_tl(arg, arg);
6055 register_name = "CMGCRBase";
6056 break;
6057 default:
6058 goto cp0_unimplemented;
6059 }
6060 break;
6061 case CP0_REGISTER_16:
6062 switch (sel) {
6063 case CP0_REG16__CONFIG:
6064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6065 register_name = "Config";
6066 break;
6067 case CP0_REG16__CONFIG1:
6068 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6069 register_name = "Config1";
6070 break;
6071 case CP0_REG16__CONFIG2:
6072 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6073 register_name = "Config2";
6074 break;
6075 case CP0_REG16__CONFIG3:
6076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6077 register_name = "Config3";
6078 break;
6079 case CP0_REG16__CONFIG4:
6080 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6081 register_name = "Config4";
6082 break;
6083 case CP0_REG16__CONFIG5:
6084 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6085 register_name = "Config5";
6086 break;
6087
6088 case CP0_REG16__CONFIG6:
6089 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6090 register_name = "Config6";
6091 break;
6092 case CP0_REG16__CONFIG7:
6093 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6094 register_name = "Config7";
6095 break;
6096 default:
6097 goto cp0_unimplemented;
6098 }
6099 break;
6100 case CP0_REGISTER_17:
6101 switch (sel) {
6102 case CP0_REG17__LLADDR:
6103 gen_helper_mfc0_lladdr(arg, cpu_env);
6104 register_name = "LLAddr";
6105 break;
6106 case CP0_REG17__MAAR:
6107 CP0_CHECK(ctx->mrp);
6108 gen_helper_mfc0_maar(arg, cpu_env);
6109 register_name = "MAAR";
6110 break;
6111 case CP0_REG17__MAARI:
6112 CP0_CHECK(ctx->mrp);
6113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6114 register_name = "MAARI";
6115 break;
6116 default:
6117 goto cp0_unimplemented;
6118 }
6119 break;
6120 case CP0_REGISTER_18:
6121 switch (sel) {
6122 case CP0_REG18__WATCHLO0:
6123 case CP0_REG18__WATCHLO1:
6124 case CP0_REG18__WATCHLO2:
6125 case CP0_REG18__WATCHLO3:
6126 case CP0_REG18__WATCHLO4:
6127 case CP0_REG18__WATCHLO5:
6128 case CP0_REG18__WATCHLO6:
6129 case CP0_REG18__WATCHLO7:
6130 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6131 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6132 register_name = "WatchLo";
6133 break;
6134 default:
6135 goto cp0_unimplemented;
6136 }
6137 break;
6138 case CP0_REGISTER_19:
6139 switch (sel) {
6140 case CP0_REG19__WATCHHI0:
6141 case CP0_REG19__WATCHHI1:
6142 case CP0_REG19__WATCHHI2:
6143 case CP0_REG19__WATCHHI3:
6144 case CP0_REG19__WATCHHI4:
6145 case CP0_REG19__WATCHHI5:
6146 case CP0_REG19__WATCHHI6:
6147 case CP0_REG19__WATCHHI7:
6148 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6149 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6150 register_name = "WatchHi";
6151 break;
6152 default:
6153 goto cp0_unimplemented;
6154 }
6155 break;
6156 case CP0_REGISTER_20:
6157 switch (sel) {
6158 case CP0_REG20__XCONTEXT:
6159#if defined(TARGET_MIPS64)
6160 check_insn(ctx, ISA_MIPS3);
6161 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6162 tcg_gen_ext32s_tl(arg, arg);
6163 register_name = "XContext";
6164 break;
6165#endif
6166 default:
6167 goto cp0_unimplemented;
6168 }
6169 break;
6170 case CP0_REGISTER_21:
6171
6172 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6173 switch (sel) {
6174 case 0:
6175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6176 register_name = "Framemask";
6177 break;
6178 default:
6179 goto cp0_unimplemented;
6180 }
6181 break;
6182 case CP0_REGISTER_22:
6183 tcg_gen_movi_tl(arg, 0);
6184 register_name = "'Diagnostic";
6185 break;
6186 case CP0_REGISTER_23:
6187 switch (sel) {
6188 case CP0_REG23__DEBUG:
6189 gen_helper_mfc0_debug(arg, cpu_env);
6190 register_name = "Debug";
6191 break;
6192 case CP0_REG23__TRACECONTROL:
6193
6194
6195 register_name = "TraceControl";
6196 goto cp0_unimplemented;
6197 case CP0_REG23__TRACECONTROL2:
6198
6199
6200 register_name = "TraceControl2";
6201 goto cp0_unimplemented;
6202 case CP0_REG23__USERTRACEDATA1:
6203
6204
6205 register_name = "UserTraceData1";
6206 goto cp0_unimplemented;
6207 case CP0_REG23__TRACEIBPC:
6208
6209
6210 register_name = "TraceIBPC";
6211 goto cp0_unimplemented;
6212 case CP0_REG23__TRACEDBPC:
6213
6214
6215 register_name = "TraceDBPC";
6216 goto cp0_unimplemented;
6217 default:
6218 goto cp0_unimplemented;
6219 }
6220 break;
6221 case CP0_REGISTER_24:
6222 switch (sel) {
6223 case CP0_REG24__DEPC:
6224
6225 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6226 tcg_gen_ext32s_tl(arg, arg);
6227 register_name = "DEPC";
6228 break;
6229 default:
6230 goto cp0_unimplemented;
6231 }
6232 break;
6233 case CP0_REGISTER_25:
6234 switch (sel) {
6235 case CP0_REG25__PERFCTL0:
6236 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6237 register_name = "Performance0";
6238 break;
6239 case CP0_REG25__PERFCNT0:
6240
6241 register_name = "Performance1";
6242 goto cp0_unimplemented;
6243 case CP0_REG25__PERFCTL1:
6244
6245 register_name = "Performance2";
6246 goto cp0_unimplemented;
6247 case CP0_REG25__PERFCNT1:
6248
6249 register_name = "Performance3";
6250 goto cp0_unimplemented;
6251 case CP0_REG25__PERFCTL2:
6252
6253 register_name = "Performance4";
6254 goto cp0_unimplemented;
6255 case CP0_REG25__PERFCNT2:
6256
6257 register_name = "Performance5";
6258 goto cp0_unimplemented;
6259 case CP0_REG25__PERFCTL3:
6260
6261 register_name = "Performance6";
6262 goto cp0_unimplemented;
6263 case CP0_REG25__PERFCNT3:
6264
6265 register_name = "Performance7";
6266 goto cp0_unimplemented;
6267 default:
6268 goto cp0_unimplemented;
6269 }
6270 break;
6271 case CP0_REGISTER_26:
6272 switch (sel) {
6273 case CP0_REG26__ERRCTL:
6274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6275 register_name = "ErrCtl";
6276 break;
6277 default:
6278 goto cp0_unimplemented;
6279 }
6280 break;
6281 case CP0_REGISTER_27:
6282 switch (sel) {
6283 case CP0_REG27__CACHERR:
6284 tcg_gen_movi_tl(arg, 0);
6285 register_name = "CacheErr";
6286 break;
6287 default:
6288 goto cp0_unimplemented;
6289 }
6290 break;
6291 case CP0_REGISTER_28:
6292 switch (sel) {
6293 case CP0_REG28__TAGLO:
6294 case CP0_REG28__TAGLO1:
6295 case CP0_REG28__TAGLO2:
6296 case CP0_REG28__TAGLO3:
6297 {
6298 TCGv_i64 tmp = tcg_temp_new_i64();
6299 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6300 gen_move_low32(arg, tmp);
6301 tcg_temp_free_i64(tmp);
6302 }
6303 register_name = "TagLo";
6304 break;
6305 case CP0_REG28__DATALO:
6306 case CP0_REG28__DATALO1:
6307 case CP0_REG28__DATALO2:
6308 case CP0_REG28__DATALO3:
6309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6310 register_name = "DataLo";
6311 break;
6312 default:
6313 goto cp0_unimplemented;
6314 }
6315 break;
6316 case CP0_REGISTER_29:
6317 switch (sel) {
6318 case CP0_REG29__TAGHI:
6319 case CP0_REG29__TAGHI1:
6320 case CP0_REG29__TAGHI2:
6321 case CP0_REG29__TAGHI3:
6322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6323 register_name = "TagHi";
6324 break;
6325 case CP0_REG29__DATAHI:
6326 case CP0_REG29__DATAHI1:
6327 case CP0_REG29__DATAHI2:
6328 case CP0_REG29__DATAHI3:
6329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6330 register_name = "DataHi";
6331 break;
6332 default:
6333 goto cp0_unimplemented;
6334 }
6335 break;
6336 case CP0_REGISTER_30:
6337 switch (sel) {
6338 case CP0_REG30__ERROREPC:
6339 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6340 tcg_gen_ext32s_tl(arg, arg);
6341 register_name = "ErrorEPC";
6342 break;
6343 default:
6344 goto cp0_unimplemented;
6345 }
6346 break;
6347 case CP0_REGISTER_31:
6348 switch (sel) {
6349 case CP0_REG31__DESAVE:
6350
6351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6352 register_name = "DESAVE";
6353 break;
6354 case CP0_REG31__KSCRATCH1:
6355 case CP0_REG31__KSCRATCH2:
6356 case CP0_REG31__KSCRATCH3:
6357 case CP0_REG31__KSCRATCH4:
6358 case CP0_REG31__KSCRATCH5:
6359 case CP0_REG31__KSCRATCH6:
6360 CP0_CHECK(ctx->kscrexist & (1 << sel));
6361 tcg_gen_ld_tl(arg, cpu_env,
6362 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6363 tcg_gen_ext32s_tl(arg, arg);
6364 register_name = "KScratch";
6365 break;
6366 default:
6367 goto cp0_unimplemented;
6368 }
6369 break;
6370 default:
6371 goto cp0_unimplemented;
6372 }
6373 trace_mips_translate_c0("mfc0", register_name, reg, sel);
6374 return;
6375
6376cp0_unimplemented:
6377 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6378 register_name, reg, sel);
6379 gen_mfc0_unimplemented(ctx, arg);
6380}
6381
6382static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6383{
6384 const char *register_name = "invalid";
6385
6386 if (sel != 0) {
6387 check_insn(ctx, ISA_MIPS_R1);
6388 }
6389
6390 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6391 gen_io_start();
6392 }
6393
6394 switch (reg) {
6395 case CP0_REGISTER_00:
6396 switch (sel) {
6397 case CP0_REG00__INDEX:
6398 gen_helper_mtc0_index(cpu_env, arg);
6399 register_name = "Index";
6400 break;
6401 case CP0_REG00__MVPCONTROL:
6402 CP0_CHECK(ctx->insn_flags & ASE_MT);
6403 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6404 register_name = "MVPControl";
6405 break;
6406 case CP0_REG00__MVPCONF0:
6407 CP0_CHECK(ctx->insn_flags & ASE_MT);
6408
6409 register_name = "MVPConf0";
6410 break;
6411 case CP0_REG00__MVPCONF1:
6412 CP0_CHECK(ctx->insn_flags & ASE_MT);
6413
6414 register_name = "MVPConf1";
6415 break;
6416 case CP0_REG00__VPCONTROL:
6417 CP0_CHECK(ctx->vp);
6418
6419 register_name = "VPControl";
6420 break;
6421 default:
6422 goto cp0_unimplemented;
6423 }
6424 break;
6425 case CP0_REGISTER_01:
6426 switch (sel) {
6427 case CP0_REG01__RANDOM:
6428
6429 register_name = "Random";
6430 break;
6431 case CP0_REG01__VPECONTROL:
6432 CP0_CHECK(ctx->insn_flags & ASE_MT);
6433 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6434 register_name = "VPEControl";
6435 break;
6436 case CP0_REG01__VPECONF0:
6437 CP0_CHECK(ctx->insn_flags & ASE_MT);
6438 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6439 register_name = "VPEConf0";
6440 break;
6441 case CP0_REG01__VPECONF1:
6442 CP0_CHECK(ctx->insn_flags & ASE_MT);
6443 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6444 register_name = "VPEConf1";
6445 break;
6446 case CP0_REG01__YQMASK:
6447 CP0_CHECK(ctx->insn_flags & ASE_MT);
6448 gen_helper_mtc0_yqmask(cpu_env, arg);
6449 register_name = "YQMask";
6450 break;
6451 case CP0_REG01__VPESCHEDULE:
6452 CP0_CHECK(ctx->insn_flags & ASE_MT);
6453 tcg_gen_st_tl(arg, cpu_env,
6454 offsetof(CPUMIPSState, CP0_VPESchedule));
6455 register_name = "VPESchedule";
6456 break;
6457 case CP0_REG01__VPESCHEFBACK:
6458 CP0_CHECK(ctx->insn_flags & ASE_MT);
6459 tcg_gen_st_tl(arg, cpu_env,
6460 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6461 register_name = "VPEScheFBack";
6462 break;
6463 case CP0_REG01__VPEOPT:
6464 CP0_CHECK(ctx->insn_flags & ASE_MT);
6465 gen_helper_mtc0_vpeopt(cpu_env, arg);
6466 register_name = "VPEOpt";
6467 break;
6468 default:
6469 goto cp0_unimplemented;
6470 }
6471 break;
6472 case CP0_REGISTER_02:
6473 switch (sel) {
6474 case CP0_REG02__ENTRYLO0:
6475 gen_helper_mtc0_entrylo0(cpu_env, arg);
6476 register_name = "EntryLo0";
6477 break;
6478 case CP0_REG02__TCSTATUS:
6479 CP0_CHECK(ctx->insn_flags & ASE_MT);
6480 gen_helper_mtc0_tcstatus(cpu_env, arg);
6481 register_name = "TCStatus";
6482 break;
6483 case CP0_REG02__TCBIND:
6484 CP0_CHECK(ctx->insn_flags & ASE_MT);
6485 gen_helper_mtc0_tcbind(cpu_env, arg);
6486 register_name = "TCBind";
6487 break;
6488 case CP0_REG02__TCRESTART:
6489 CP0_CHECK(ctx->insn_flags & ASE_MT);
6490 gen_helper_mtc0_tcrestart(cpu_env, arg);
6491 register_name = "TCRestart";
6492 break;
6493 case CP0_REG02__TCHALT:
6494 CP0_CHECK(ctx->insn_flags & ASE_MT);
6495 gen_helper_mtc0_tchalt(cpu_env, arg);
6496 register_name = "TCHalt";
6497 break;
6498 case CP0_REG02__TCCONTEXT:
6499 CP0_CHECK(ctx->insn_flags & ASE_MT);
6500 gen_helper_mtc0_tccontext(cpu_env, arg);
6501 register_name = "TCContext";
6502 break;
6503 case CP0_REG02__TCSCHEDULE:
6504 CP0_CHECK(ctx->insn_flags & ASE_MT);
6505 gen_helper_mtc0_tcschedule(cpu_env, arg);
6506 register_name = "TCSchedule";
6507 break;
6508 case CP0_REG02__TCSCHEFBACK:
6509 CP0_CHECK(ctx->insn_flags & ASE_MT);
6510 gen_helper_mtc0_tcschefback(cpu_env, arg);
6511 register_name = "TCScheFBack";
6512 break;
6513 default:
6514 goto cp0_unimplemented;
6515 }
6516 break;
6517 case CP0_REGISTER_03:
6518 switch (sel) {
6519 case CP0_REG03__ENTRYLO1:
6520 gen_helper_mtc0_entrylo1(cpu_env, arg);
6521 register_name = "EntryLo1";
6522 break;
6523 case CP0_REG03__GLOBALNUM:
6524 CP0_CHECK(ctx->vp);
6525
6526 register_name = "GlobalNumber";
6527 break;
6528 default:
6529 goto cp0_unimplemented;
6530 }
6531 break;
6532 case CP0_REGISTER_04:
6533 switch (sel) {
6534 case CP0_REG04__CONTEXT:
6535 gen_helper_mtc0_context(cpu_env, arg);
6536 register_name = "Context";
6537 break;
6538 case CP0_REG04__CONTEXTCONFIG:
6539
6540
6541 register_name = "ContextConfig";
6542 goto cp0_unimplemented;
6543 case CP0_REG04__USERLOCAL:
6544 CP0_CHECK(ctx->ulri);
6545 tcg_gen_st_tl(arg, cpu_env,
6546 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6547 register_name = "UserLocal";
6548 break;
6549 case CP0_REG04__MMID:
6550 CP0_CHECK(ctx->mi);
6551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6552 register_name = "MMID";
6553 break;
6554 default:
6555 goto cp0_unimplemented;
6556 }
6557 break;
6558 case CP0_REGISTER_05:
6559 switch (sel) {
6560 case CP0_REG05__PAGEMASK:
6561 gen_helper_mtc0_pagemask(cpu_env, arg);
6562 register_name = "PageMask";
6563 break;
6564 case CP0_REG05__PAGEGRAIN:
6565 check_insn(ctx, ISA_MIPS_R2);
6566 gen_helper_mtc0_pagegrain(cpu_env, arg);
6567 register_name = "PageGrain";
6568 ctx->base.is_jmp = DISAS_STOP;
6569 break;
6570 case CP0_REG05__SEGCTL0:
6571 CP0_CHECK(ctx->sc);
6572 gen_helper_mtc0_segctl0(cpu_env, arg);
6573 register_name = "SegCtl0";
6574 break;
6575 case CP0_REG05__SEGCTL1:
6576 CP0_CHECK(ctx->sc);
6577 gen_helper_mtc0_segctl1(cpu_env, arg);
6578 register_name = "SegCtl1";
6579 break;
6580 case CP0_REG05__SEGCTL2:
6581 CP0_CHECK(ctx->sc);
6582 gen_helper_mtc0_segctl2(cpu_env, arg);
6583 register_name = "SegCtl2";
6584 break;
6585 case CP0_REG05__PWBASE:
6586 check_pw(ctx);
6587 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6588 register_name = "PWBase";
6589 break;
6590 case CP0_REG05__PWFIELD:
6591 check_pw(ctx);
6592 gen_helper_mtc0_pwfield(cpu_env, arg);
6593 register_name = "PWField";
6594 break;
6595 case CP0_REG05__PWSIZE:
6596 check_pw(ctx);
6597 gen_helper_mtc0_pwsize(cpu_env, arg);
6598 register_name = "PWSize";
6599 break;
6600 default:
6601 goto cp0_unimplemented;
6602 }
6603 break;
6604 case CP0_REGISTER_06:
6605 switch (sel) {
6606 case CP0_REG06__WIRED:
6607 gen_helper_mtc0_wired(cpu_env, arg);
6608 register_name = "Wired";
6609 break;
6610 case CP0_REG06__SRSCONF0:
6611 check_insn(ctx, ISA_MIPS_R2);
6612 gen_helper_mtc0_srsconf0(cpu_env, arg);
6613 register_name = "SRSConf0";
6614 break;
6615 case CP0_REG06__SRSCONF1:
6616 check_insn(ctx, ISA_MIPS_R2);
6617 gen_helper_mtc0_srsconf1(cpu_env, arg);
6618 register_name = "SRSConf1";
6619 break;
6620 case CP0_REG06__SRSCONF2:
6621 check_insn(ctx, ISA_MIPS_R2);
6622 gen_helper_mtc0_srsconf2(cpu_env, arg);
6623 register_name = "SRSConf2";
6624 break;
6625 case CP0_REG06__SRSCONF3:
6626 check_insn(ctx, ISA_MIPS_R2);
6627 gen_helper_mtc0_srsconf3(cpu_env, arg);
6628 register_name = "SRSConf3";
6629 break;
6630 case CP0_REG06__SRSCONF4:
6631 check_insn(ctx, ISA_MIPS_R2);
6632 gen_helper_mtc0_srsconf4(cpu_env, arg);
6633 register_name = "SRSConf4";
6634 break;
6635 case CP0_REG06__PWCTL:
6636 check_pw(ctx);
6637 gen_helper_mtc0_pwctl(cpu_env, arg);
6638 register_name = "PWCtl";
6639 break;
6640 default:
6641 goto cp0_unimplemented;
6642 }
6643 break;
6644 case CP0_REGISTER_07:
6645 switch (sel) {
6646 case CP0_REG07__HWRENA:
6647 check_insn(ctx, ISA_MIPS_R2);
6648 gen_helper_mtc0_hwrena(cpu_env, arg);
6649 ctx->base.is_jmp = DISAS_STOP;
6650 register_name = "HWREna";
6651 break;
6652 default:
6653 goto cp0_unimplemented;
6654 }
6655 break;
6656 case CP0_REGISTER_08:
6657 switch (sel) {
6658 case CP0_REG08__BADVADDR:
6659
6660 register_name = "BadVAddr";
6661 break;
6662 case CP0_REG08__BADINSTR:
6663
6664 register_name = "BadInstr";
6665 break;
6666 case CP0_REG08__BADINSTRP:
6667
6668 register_name = "BadInstrP";
6669 break;
6670 case CP0_REG08__BADINSTRX:
6671
6672 register_name = "BadInstrX";
6673 break;
6674 default:
6675 goto cp0_unimplemented;
6676 }
6677 break;
6678 case CP0_REGISTER_09:
6679 switch (sel) {
6680 case CP0_REG09__COUNT:
6681 gen_helper_mtc0_count(cpu_env, arg);
6682 register_name = "Count";
6683 break;
6684 case CP0_REG09__SAARI:
6685 CP0_CHECK(ctx->saar);
6686 gen_helper_mtc0_saari(cpu_env, arg);
6687 register_name = "SAARI";
6688 break;
6689 case CP0_REG09__SAAR:
6690 CP0_CHECK(ctx->saar);
6691 gen_helper_mtc0_saar(cpu_env, arg);
6692 register_name = "SAAR";
6693 break;
6694 default:
6695 goto cp0_unimplemented;
6696 }
6697 break;
6698 case CP0_REGISTER_10:
6699 switch (sel) {
6700 case CP0_REG10__ENTRYHI:
6701 gen_helper_mtc0_entryhi(cpu_env, arg);
6702 register_name = "EntryHi";
6703 break;
6704 default:
6705 goto cp0_unimplemented;
6706 }
6707 break;
6708 case CP0_REGISTER_11:
6709 switch (sel) {
6710 case CP0_REG11__COMPARE:
6711 gen_helper_mtc0_compare(cpu_env, arg);
6712 register_name = "Compare";
6713 break;
6714
6715 default:
6716 goto cp0_unimplemented;
6717 }
6718 break;
6719 case CP0_REGISTER_12:
6720 switch (sel) {
6721 case CP0_REG12__STATUS:
6722 save_cpu_state(ctx, 1);
6723 gen_helper_mtc0_status(cpu_env, arg);
6724
6725 gen_save_pc(ctx->base.pc_next + 4);
6726 ctx->base.is_jmp = DISAS_EXIT;
6727 register_name = "Status";
6728 break;
6729 case CP0_REG12__INTCTL:
6730 check_insn(ctx, ISA_MIPS_R2);
6731 gen_helper_mtc0_intctl(cpu_env, arg);
6732
6733 ctx->base.is_jmp = DISAS_STOP;
6734 register_name = "IntCtl";
6735 break;
6736 case CP0_REG12__SRSCTL:
6737 check_insn(ctx, ISA_MIPS_R2);
6738 gen_helper_mtc0_srsctl(cpu_env, arg);
6739
6740 ctx->base.is_jmp = DISAS_STOP;
6741 register_name = "SRSCtl";
6742 break;
6743 case CP0_REG12__SRSMAP:
6744 check_insn(ctx, ISA_MIPS_R2);
6745 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6746
6747 ctx->base.is_jmp = DISAS_STOP;
6748 register_name = "SRSMap";
6749 break;
6750 default:
6751 goto cp0_unimplemented;
6752 }
6753 break;
6754 case CP0_REGISTER_13:
6755 switch (sel) {
6756 case CP0_REG13__CAUSE:
6757 save_cpu_state(ctx, 1);
6758 gen_helper_mtc0_cause(cpu_env, arg);
6759
6760
6761
6762
6763
6764 gen_save_pc(ctx->base.pc_next + 4);
6765 ctx->base.is_jmp = DISAS_EXIT;
6766 register_name = "Cause";
6767 break;
6768 default:
6769 goto cp0_unimplemented;
6770 }
6771 break;
6772 case CP0_REGISTER_14:
6773 switch (sel) {
6774 case CP0_REG14__EPC:
6775 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6776 register_name = "EPC";
6777 break;
6778 default:
6779 goto cp0_unimplemented;
6780 }
6781 break;
6782 case CP0_REGISTER_15:
6783 switch (sel) {
6784 case CP0_REG15__PRID:
6785
6786 register_name = "PRid";
6787 break;
6788 case CP0_REG15__EBASE:
6789 check_insn(ctx, ISA_MIPS_R2);
6790 gen_helper_mtc0_ebase(cpu_env, arg);
6791 register_name = "EBase";
6792 break;
6793 default:
6794 goto cp0_unimplemented;
6795 }
6796 break;
6797 case CP0_REGISTER_16:
6798 switch (sel) {
6799 case CP0_REG16__CONFIG:
6800 gen_helper_mtc0_config0(cpu_env, arg);
6801 register_name = "Config";
6802
6803 ctx->base.is_jmp = DISAS_STOP;
6804 break;
6805 case CP0_REG16__CONFIG1:
6806
6807 register_name = "Config1";
6808 break;
6809 case CP0_REG16__CONFIG2:
6810 gen_helper_mtc0_config2(cpu_env, arg);
6811 register_name = "Config2";
6812
6813 ctx->base.is_jmp = DISAS_STOP;
6814 break;
6815 case CP0_REG16__CONFIG3:
6816 gen_helper_mtc0_config3(cpu_env, arg);
6817 register_name = "Config3";
6818
6819 ctx->base.is_jmp = DISAS_STOP;
6820 break;
6821 case CP0_REG16__CONFIG4:
6822 gen_helper_mtc0_config4(cpu_env, arg);
6823 register_name = "Config4";
6824 ctx->base.is_jmp = DISAS_STOP;
6825 break;
6826 case CP0_REG16__CONFIG5:
6827 gen_helper_mtc0_config5(cpu_env, arg);
6828 register_name = "Config5";
6829
6830 ctx->base.is_jmp = DISAS_STOP;
6831 break;
6832
6833 case CP0_REG16__CONFIG6:
6834
6835 register_name = "Config6";
6836 break;
6837 case CP0_REG16__CONFIG7:
6838
6839 register_name = "Config7";
6840 break;
6841 default:
6842 register_name = "Invalid config selector";
6843 goto cp0_unimplemented;
6844 }
6845 break;
6846 case CP0_REGISTER_17:
6847 switch (sel) {
6848 case CP0_REG17__LLADDR:
6849 gen_helper_mtc0_lladdr(cpu_env, arg);
6850 register_name = "LLAddr";
6851 break;
6852 case CP0_REG17__MAAR:
6853 CP0_CHECK(ctx->mrp);
6854 gen_helper_mtc0_maar(cpu_env, arg);
6855 register_name = "MAAR";
6856 break;
6857 case CP0_REG17__MAARI:
6858 CP0_CHECK(ctx->mrp);
6859 gen_helper_mtc0_maari(cpu_env, arg);
6860 register_name = "MAARI";
6861 break;
6862 default:
6863 goto cp0_unimplemented;
6864 }
6865 break;
6866 case CP0_REGISTER_18:
6867 switch (sel) {
6868 case CP0_REG18__WATCHLO0:
6869 case CP0_REG18__WATCHLO1:
6870 case CP0_REG18__WATCHLO2:
6871 case CP0_REG18__WATCHLO3:
6872 case CP0_REG18__WATCHLO4:
6873 case CP0_REG18__WATCHLO5:
6874 case CP0_REG18__WATCHLO6:
6875 case CP0_REG18__WATCHLO7:
6876 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6877 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6878 register_name = "WatchLo";
6879 break;
6880 default:
6881 goto cp0_unimplemented;
6882 }
6883 break;
6884 case CP0_REGISTER_19:
6885 switch (sel) {
6886 case CP0_REG19__WATCHHI0:
6887 case CP0_REG19__WATCHHI1:
6888 case CP0_REG19__WATCHHI2:
6889 case CP0_REG19__WATCHHI3:
6890 case CP0_REG19__WATCHHI4:
6891 case CP0_REG19__WATCHHI5:
6892 case CP0_REG19__WATCHHI6:
6893 case CP0_REG19__WATCHHI7:
6894 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6895 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6896 register_name = "WatchHi";
6897 break;
6898 default:
6899 goto cp0_unimplemented;
6900 }
6901 break;
6902 case CP0_REGISTER_20:
6903 switch (sel) {
6904 case CP0_REG20__XCONTEXT:
6905#if defined(TARGET_MIPS64)
6906 check_insn(ctx, ISA_MIPS3);
6907 gen_helper_mtc0_xcontext(cpu_env, arg);
6908 register_name = "XContext";
6909 break;
6910#endif
6911 default:
6912 goto cp0_unimplemented;
6913 }
6914 break;
6915 case CP0_REGISTER_21:
6916
6917 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6918 switch (sel) {
6919 case 0:
6920 gen_helper_mtc0_framemask(cpu_env, arg);
6921 register_name = "Framemask";
6922 break;
6923 default:
6924 goto cp0_unimplemented;
6925 }
6926 break;
6927 case CP0_REGISTER_22:
6928
6929 register_name = "Diagnostic";
6930 break;
6931 case CP0_REGISTER_23:
6932 switch (sel) {
6933 case CP0_REG23__DEBUG:
6934 gen_helper_mtc0_debug(cpu_env, arg);
6935
6936 gen_save_pc(ctx->base.pc_next + 4);
6937 ctx->base.is_jmp = DISAS_EXIT;
6938 register_name = "Debug";
6939 break;
6940 case CP0_REG23__TRACECONTROL:
6941
6942
6943 register_name = "TraceControl";
6944
6945 ctx->base.is_jmp = DISAS_STOP;
6946 goto cp0_unimplemented;
6947 case CP0_REG23__TRACECONTROL2:
6948
6949
6950 register_name = "TraceControl2";
6951
6952 ctx->base.is_jmp = DISAS_STOP;
6953 goto cp0_unimplemented;
6954 case CP0_REG23__USERTRACEDATA1:
6955
6956 ctx->base.is_jmp = DISAS_STOP;
6957
6958
6959 register_name = "UserTraceData";
6960
6961 ctx->base.is_jmp = DISAS_STOP;
6962 goto cp0_unimplemented;
6963 case CP0_REG23__TRACEIBPC:
6964
6965
6966
6967 ctx->base.is_jmp = DISAS_STOP;
6968 register_name = "TraceIBPC";
6969 goto cp0_unimplemented;
6970 case CP0_REG23__TRACEDBPC:
6971
6972
6973
6974 ctx->base.is_jmp = DISAS_STOP;
6975 register_name = "TraceDBPC";
6976 goto cp0_unimplemented;
6977 default:
6978 goto cp0_unimplemented;
6979 }
6980 break;
6981 case CP0_REGISTER_24:
6982 switch (sel) {
6983 case CP0_REG24__DEPC:
6984
6985 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6986 register_name = "DEPC";
6987 break;
6988 default:
6989 goto cp0_unimplemented;
6990 }
6991 break;
6992 case CP0_REGISTER_25:
6993 switch (sel) {
6994 case CP0_REG25__PERFCTL0:
6995 gen_helper_mtc0_performance0(cpu_env, arg);
6996 register_name = "Performance0";
6997 break;
6998 case CP0_REG25__PERFCNT0:
6999
7000 register_name = "Performance1";
7001 goto cp0_unimplemented;
7002 case CP0_REG25__PERFCTL1:
7003
7004 register_name = "Performance2";
7005 goto cp0_unimplemented;
7006 case CP0_REG25__PERFCNT1:
7007
7008 register_name = "Performance3";
7009 goto cp0_unimplemented;
7010 case CP0_REG25__PERFCTL2:
7011
7012 register_name = "Performance4";
7013 goto cp0_unimplemented;
7014 case CP0_REG25__PERFCNT2:
7015
7016 register_name = "Performance5";
7017 goto cp0_unimplemented;
7018 case CP0_REG25__PERFCTL3:
7019
7020 register_name = "Performance6";
7021 goto cp0_unimplemented;
7022 case CP0_REG25__PERFCNT3:
7023
7024 register_name = "Performance7";
7025 goto cp0_unimplemented;
7026 default:
7027 goto cp0_unimplemented;
7028 }
7029 break;
7030 case CP0_REGISTER_26:
7031 switch (sel) {
7032 case CP0_REG26__ERRCTL:
7033 gen_helper_mtc0_errctl(cpu_env, arg);
7034 ctx->base.is_jmp = DISAS_STOP;
7035 register_name = "ErrCtl";
7036 break;
7037 default:
7038 goto cp0_unimplemented;
7039 }
7040 break;
7041 case CP0_REGISTER_27:
7042 switch (sel) {
7043 case CP0_REG27__CACHERR:
7044
7045 register_name = "CacheErr";
7046 break;
7047 default:
7048 goto cp0_unimplemented;
7049 }
7050 break;
7051 case CP0_REGISTER_28:
7052 switch (sel) {
7053 case CP0_REG28__TAGLO:
7054 case CP0_REG28__TAGLO1:
7055 case CP0_REG28__TAGLO2:
7056 case CP0_REG28__TAGLO3:
7057 gen_helper_mtc0_taglo(cpu_env, arg);
7058 register_name = "TagLo";
7059 break;
7060 case CP0_REG28__DATALO:
7061 case CP0_REG28__DATALO1:
7062 case CP0_REG28__DATALO2:
7063 case CP0_REG28__DATALO3:
7064 gen_helper_mtc0_datalo(cpu_env, arg);
7065 register_name = "DataLo";
7066 break;
7067 default:
7068 goto cp0_unimplemented;
7069 }
7070 break;
7071 case CP0_REGISTER_29:
7072 switch (sel) {
7073 case CP0_REG29__TAGHI:
7074 case CP0_REG29__TAGHI1:
7075 case CP0_REG29__TAGHI2:
7076 case CP0_REG29__TAGHI3:
7077 gen_helper_mtc0_taghi(cpu_env, arg);
7078 register_name = "TagHi";
7079 break;
7080 case CP0_REG29__DATAHI:
7081 case CP0_REG29__DATAHI1:
7082 case CP0_REG29__DATAHI2:
7083 case CP0_REG29__DATAHI3:
7084 gen_helper_mtc0_datahi(cpu_env, arg);
7085 register_name = "DataHi";
7086 break;
7087 default:
7088 register_name = "invalid sel";
7089 goto cp0_unimplemented;
7090 }
7091 break;
7092 case CP0_REGISTER_30:
7093 switch (sel) {
7094 case CP0_REG30__ERROREPC:
7095 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7096 register_name = "ErrorEPC";
7097 break;
7098 default:
7099 goto cp0_unimplemented;
7100 }
7101 break;
7102 case CP0_REGISTER_31:
7103 switch (sel) {
7104 case CP0_REG31__DESAVE:
7105
7106 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7107 register_name = "DESAVE";
7108 break;
7109 case CP0_REG31__KSCRATCH1:
7110 case CP0_REG31__KSCRATCH2:
7111 case CP0_REG31__KSCRATCH3:
7112 case CP0_REG31__KSCRATCH4:
7113 case CP0_REG31__KSCRATCH5:
7114 case CP0_REG31__KSCRATCH6:
7115 CP0_CHECK(ctx->kscrexist & (1 << sel));
7116 tcg_gen_st_tl(arg, cpu_env,
7117 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7118 register_name = "KScratch";
7119 break;
7120 default:
7121 goto cp0_unimplemented;
7122 }
7123 break;
7124 default:
7125 goto cp0_unimplemented;
7126 }
7127 trace_mips_translate_c0("mtc0", register_name, reg, sel);
7128
7129
7130 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7131
7132
7133
7134
7135 gen_save_pc(ctx->base.pc_next + 4);
7136 ctx->base.is_jmp = DISAS_EXIT;
7137 }
7138 return;
7139
7140cp0_unimplemented:
7141 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7142 register_name, reg, sel);
7143}
7144
7145#if defined(TARGET_MIPS64)
7146static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7147{
7148 const char *register_name = "invalid";
7149
7150 if (sel != 0) {
7151 check_insn(ctx, ISA_MIPS_R1);
7152 }
7153
7154 switch (reg) {
7155 case CP0_REGISTER_00:
7156 switch (sel) {
7157 case CP0_REG00__INDEX:
7158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7159 register_name = "Index";
7160 break;
7161 case CP0_REG00__MVPCONTROL:
7162 CP0_CHECK(ctx->insn_flags & ASE_MT);
7163 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7164 register_name = "MVPControl";
7165 break;
7166 case CP0_REG00__MVPCONF0:
7167 CP0_CHECK(ctx->insn_flags & ASE_MT);
7168 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7169 register_name = "MVPConf0";
7170 break;
7171 case CP0_REG00__MVPCONF1:
7172 CP0_CHECK(ctx->insn_flags & ASE_MT);
7173 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7174 register_name = "MVPConf1";
7175 break;
7176 case CP0_REG00__VPCONTROL:
7177 CP0_CHECK(ctx->vp);
7178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7179 register_name = "VPControl";
7180 break;
7181 default:
7182 goto cp0_unimplemented;
7183 }
7184 break;
7185 case CP0_REGISTER_01:
7186 switch (sel) {
7187 case CP0_REG01__RANDOM:
7188 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7189 gen_helper_mfc0_random(arg, cpu_env);
7190 register_name = "Random";
7191 break;
7192 case CP0_REG01__VPECONTROL:
7193 CP0_CHECK(ctx->insn_flags & ASE_MT);
7194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7195 register_name = "VPEControl";
7196 break;
7197 case CP0_REG01__VPECONF0:
7198 CP0_CHECK(ctx->insn_flags & ASE_MT);
7199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7200 register_name = "VPEConf0";
7201 break;
7202 case CP0_REG01__VPECONF1:
7203 CP0_CHECK(ctx->insn_flags & ASE_MT);
7204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7205 register_name = "VPEConf1";
7206 break;
7207 case CP0_REG01__YQMASK:
7208 CP0_CHECK(ctx->insn_flags & ASE_MT);
7209 tcg_gen_ld_tl(arg, cpu_env,
7210 offsetof(CPUMIPSState, CP0_YQMask));
7211 register_name = "YQMask";
7212 break;
7213 case CP0_REG01__VPESCHEDULE:
7214 CP0_CHECK(ctx->insn_flags & ASE_MT);
7215 tcg_gen_ld_tl(arg, cpu_env,
7216 offsetof(CPUMIPSState, CP0_VPESchedule));
7217 register_name = "VPESchedule";
7218 break;
7219 case CP0_REG01__VPESCHEFBACK:
7220 CP0_CHECK(ctx->insn_flags & ASE_MT);
7221 tcg_gen_ld_tl(arg, cpu_env,
7222 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7223 register_name = "VPEScheFBack";
7224 break;
7225 case CP0_REG01__VPEOPT:
7226 CP0_CHECK(ctx->insn_flags & ASE_MT);
7227 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7228 register_name = "VPEOpt";
7229 break;
7230 default:
7231 goto cp0_unimplemented;
7232 }
7233 break;
7234 case CP0_REGISTER_02:
7235 switch (sel) {
7236 case CP0_REG02__ENTRYLO0:
7237 tcg_gen_ld_tl(arg, cpu_env,
7238 offsetof(CPUMIPSState, CP0_EntryLo0));
7239 register_name = "EntryLo0";
7240 break;
7241 case CP0_REG02__TCSTATUS:
7242 CP0_CHECK(ctx->insn_flags & ASE_MT);
7243 gen_helper_mfc0_tcstatus(arg, cpu_env);
7244 register_name = "TCStatus";
7245 break;
7246 case CP0_REG02__TCBIND:
7247 CP0_CHECK(ctx->insn_flags & ASE_MT);
7248 gen_helper_mfc0_tcbind(arg, cpu_env);
7249 register_name = "TCBind";
7250 break;
7251 case CP0_REG02__TCRESTART:
7252 CP0_CHECK(ctx->insn_flags & ASE_MT);
7253 gen_helper_dmfc0_tcrestart(arg, cpu_env);
7254 register_name = "TCRestart";
7255 break;
7256 case CP0_REG02__TCHALT:
7257 CP0_CHECK(ctx->insn_flags & ASE_MT);
7258 gen_helper_dmfc0_tchalt(arg, cpu_env);
7259 register_name = "TCHalt";
7260 break;
7261 case CP0_REG02__TCCONTEXT:
7262 CP0_CHECK(ctx->insn_flags & ASE_MT);
7263 gen_helper_dmfc0_tccontext(arg, cpu_env);
7264 register_name = "TCContext";
7265 break;
7266 case CP0_REG02__TCSCHEDULE:
7267 CP0_CHECK(ctx->insn_flags & ASE_MT);
7268 gen_helper_dmfc0_tcschedule(arg, cpu_env);
7269 register_name = "TCSchedule";
7270 break;
7271 case CP0_REG02__TCSCHEFBACK:
7272 CP0_CHECK(ctx->insn_flags & ASE_MT);
7273 gen_helper_dmfc0_tcschefback(arg, cpu_env);
7274 register_name = "TCScheFBack";
7275 break;
7276 default:
7277 goto cp0_unimplemented;
7278 }
7279 break;
7280 case CP0_REGISTER_03:
7281 switch (sel) {
7282 case CP0_REG03__ENTRYLO1:
7283 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7284 register_name = "EntryLo1";
7285 break;
7286 case CP0_REG03__GLOBALNUM:
7287 CP0_CHECK(ctx->vp);
7288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7289 register_name = "GlobalNumber";
7290 break;
7291 default:
7292 goto cp0_unimplemented;
7293 }
7294 break;
7295 case CP0_REGISTER_04:
7296 switch (sel) {
7297 case CP0_REG04__CONTEXT:
7298 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7299 register_name = "Context";
7300 break;
7301 case CP0_REG04__CONTEXTCONFIG:
7302
7303
7304 register_name = "ContextConfig";
7305 goto cp0_unimplemented;
7306 case CP0_REG04__USERLOCAL:
7307 CP0_CHECK(ctx->ulri);
7308 tcg_gen_ld_tl(arg, cpu_env,
7309 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7310 register_name = "UserLocal";
7311 break;
7312 case CP0_REG04__MMID:
7313 CP0_CHECK(ctx->mi);
7314 gen_helper_mtc0_memorymapid(cpu_env, arg);
7315 register_name = "MMID";
7316 break;
7317 default:
7318 goto cp0_unimplemented;
7319 }
7320 break;
7321 case CP0_REGISTER_05:
7322 switch (sel) {
7323 case CP0_REG05__PAGEMASK:
7324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7325 register_name = "PageMask";
7326 break;
7327 case CP0_REG05__PAGEGRAIN:
7328 check_insn(ctx, ISA_MIPS_R2);
7329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7330 register_name = "PageGrain";
7331 break;
7332 case CP0_REG05__SEGCTL0:
7333 CP0_CHECK(ctx->sc);
7334 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7335 register_name = "SegCtl0";
7336 break;
7337 case CP0_REG05__SEGCTL1:
7338 CP0_CHECK(ctx->sc);
7339 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7340 register_name = "SegCtl1";
7341 break;
7342 case CP0_REG05__SEGCTL2:
7343 CP0_CHECK(ctx->sc);
7344 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7345 register_name = "SegCtl2";
7346 break;
7347 case CP0_REG05__PWBASE:
7348 check_pw(ctx);
7349 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7350 register_name = "PWBase";
7351 break;
7352 case CP0_REG05__PWFIELD:
7353 check_pw(ctx);
7354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7355 register_name = "PWField";
7356 break;
7357 case CP0_REG05__PWSIZE:
7358 check_pw(ctx);
7359 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7360 register_name = "PWSize";
7361 break;
7362 default:
7363 goto cp0_unimplemented;
7364 }
7365 break;
7366 case CP0_REGISTER_06:
7367 switch (sel) {
7368 case CP0_REG06__WIRED:
7369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7370 register_name = "Wired";
7371 break;
7372 case CP0_REG06__SRSCONF0:
7373 check_insn(ctx, ISA_MIPS_R2);
7374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7375 register_name = "SRSConf0";
7376 break;
7377 case CP0_REG06__SRSCONF1:
7378 check_insn(ctx, ISA_MIPS_R2);
7379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7380 register_name = "SRSConf1";
7381 break;
7382 case CP0_REG06__SRSCONF2:
7383 check_insn(ctx, ISA_MIPS_R2);
7384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7385 register_name = "SRSConf2";
7386 break;
7387 case CP0_REG06__SRSCONF3:
7388 check_insn(ctx, ISA_MIPS_R2);
7389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7390 register_name = "SRSConf3";
7391 break;
7392 case CP0_REG06__SRSCONF4:
7393 check_insn(ctx, ISA_MIPS_R2);
7394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7395 register_name = "SRSConf4";
7396 break;
7397 case CP0_REG06__PWCTL:
7398 check_pw(ctx);
7399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7400 register_name = "PWCtl";
7401 break;
7402 default:
7403 goto cp0_unimplemented;
7404 }
7405 break;
7406 case CP0_REGISTER_07:
7407 switch (sel) {
7408 case CP0_REG07__HWRENA:
7409 check_insn(ctx, ISA_MIPS_R2);
7410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7411 register_name = "HWREna";
7412 break;
7413 default:
7414 goto cp0_unimplemented;
7415 }
7416 break;
7417 case CP0_REGISTER_08:
7418 switch (sel) {
7419 case CP0_REG08__BADVADDR:
7420 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7421 register_name = "BadVAddr";
7422 break;
7423 case CP0_REG08__BADINSTR:
7424 CP0_CHECK(ctx->bi);
7425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7426 register_name = "BadInstr";
7427 break;
7428 case CP0_REG08__BADINSTRP:
7429 CP0_CHECK(ctx->bp);
7430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7431 register_name = "BadInstrP";
7432 break;
7433 case CP0_REG08__BADINSTRX:
7434 CP0_CHECK(ctx->bi);
7435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7436 tcg_gen_andi_tl(arg, arg, ~0xffff);
7437 register_name = "BadInstrX";
7438 break;
7439 default:
7440 goto cp0_unimplemented;
7441 }
7442 break;
7443 case CP0_REGISTER_09:
7444 switch (sel) {
7445 case CP0_REG09__COUNT:
7446
7447 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7448 gen_io_start();
7449 }
7450 gen_helper_mfc0_count(arg, cpu_env);
7451
7452
7453
7454
7455
7456 gen_save_pc(ctx->base.pc_next + 4);
7457 ctx->base.is_jmp = DISAS_EXIT;
7458 register_name = "Count";
7459 break;
7460 case CP0_REG09__SAARI:
7461 CP0_CHECK(ctx->saar);
7462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7463 register_name = "SAARI";
7464 break;
7465 case CP0_REG09__SAAR:
7466 CP0_CHECK(ctx->saar);
7467 gen_helper_dmfc0_saar(arg, cpu_env);
7468 register_name = "SAAR";
7469 break;
7470 default:
7471 goto cp0_unimplemented;
7472 }
7473 break;
7474 case CP0_REGISTER_10:
7475 switch (sel) {
7476 case CP0_REG10__ENTRYHI:
7477 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7478 register_name = "EntryHi";
7479 break;
7480 default:
7481 goto cp0_unimplemented;
7482 }
7483 break;
7484 case CP0_REGISTER_11:
7485 switch (sel) {
7486 case CP0_REG11__COMPARE:
7487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7488 register_name = "Compare";
7489 break;
7490
7491 default:
7492 goto cp0_unimplemented;
7493 }
7494 break;
7495 case CP0_REGISTER_12:
7496 switch (sel) {
7497 case CP0_REG12__STATUS:
7498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7499 register_name = "Status";
7500 break;
7501 case CP0_REG12__INTCTL:
7502 check_insn(ctx, ISA_MIPS_R2);
7503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7504 register_name = "IntCtl";
7505 break;
7506 case CP0_REG12__SRSCTL:
7507 check_insn(ctx, ISA_MIPS_R2);
7508 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7509 register_name = "SRSCtl";
7510 break;
7511 case CP0_REG12__SRSMAP:
7512 check_insn(ctx, ISA_MIPS_R2);
7513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7514 register_name = "SRSMap";
7515 break;
7516 default:
7517 goto cp0_unimplemented;
7518 }
7519 break;
7520 case CP0_REGISTER_13:
7521 switch (sel) {
7522 case CP0_REG13__CAUSE:
7523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7524 register_name = "Cause";
7525 break;
7526 default:
7527 goto cp0_unimplemented;
7528 }
7529 break;
7530 case CP0_REGISTER_14:
7531 switch (sel) {
7532 case CP0_REG14__EPC:
7533 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7534 register_name = "EPC";
7535 break;
7536 default:
7537 goto cp0_unimplemented;
7538 }
7539 break;
7540 case CP0_REGISTER_15:
7541 switch (sel) {
7542 case CP0_REG15__PRID:
7543 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7544 register_name = "PRid";
7545 break;
7546 case CP0_REG15__EBASE:
7547 check_insn(ctx, ISA_MIPS_R2);
7548 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7549 register_name = "EBase";
7550 break;
7551 case CP0_REG15__CMGCRBASE:
7552 check_insn(ctx, ISA_MIPS_R2);
7553 CP0_CHECK(ctx->cmgcr);
7554 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7555 register_name = "CMGCRBase";
7556 break;
7557 default:
7558 goto cp0_unimplemented;
7559 }
7560 break;
7561 case CP0_REGISTER_16:
7562 switch (sel) {
7563 case CP0_REG16__CONFIG:
7564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7565 register_name = "Config";
7566 break;
7567 case CP0_REG16__CONFIG1:
7568 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7569 register_name = "Config1";
7570 break;
7571 case CP0_REG16__CONFIG2:
7572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7573 register_name = "Config2";
7574 break;
7575 case CP0_REG16__CONFIG3:
7576 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7577 register_name = "Config3";
7578 break;
7579 case CP0_REG16__CONFIG4:
7580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7581 register_name = "Config4";
7582 break;
7583 case CP0_REG16__CONFIG5:
7584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7585 register_name = "Config5";
7586 break;
7587
7588 case CP0_REG16__CONFIG6:
7589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7590 register_name = "Config6";
7591 break;
7592 case CP0_REG16__CONFIG7:
7593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7594 register_name = "Config7";
7595 break;
7596 default:
7597 goto cp0_unimplemented;
7598 }
7599 break;
7600 case CP0_REGISTER_17:
7601 switch (sel) {
7602 case CP0_REG17__LLADDR:
7603 gen_helper_dmfc0_lladdr(arg, cpu_env);
7604 register_name = "LLAddr";
7605 break;
7606 case CP0_REG17__MAAR:
7607 CP0_CHECK(ctx->mrp);
7608 gen_helper_dmfc0_maar(arg, cpu_env);
7609 register_name = "MAAR";
7610 break;
7611 case CP0_REG17__MAARI:
7612 CP0_CHECK(ctx->mrp);
7613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7614 register_name = "MAARI";
7615 break;
7616 default:
7617 goto cp0_unimplemented;
7618 }
7619 break;
7620 case CP0_REGISTER_18:
7621 switch (sel) {
7622 case CP0_REG18__WATCHLO0:
7623 case CP0_REG18__WATCHLO1:
7624 case CP0_REG18__WATCHLO2:
7625 case CP0_REG18__WATCHLO3:
7626 case CP0_REG18__WATCHLO4:
7627 case CP0_REG18__WATCHLO5:
7628 case CP0_REG18__WATCHLO6:
7629 case CP0_REG18__WATCHLO7:
7630 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7631 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7632 register_name = "WatchLo";
7633 break;
7634 default:
7635 goto cp0_unimplemented;
7636 }
7637 break;
7638 case CP0_REGISTER_19:
7639 switch (sel) {
7640 case CP0_REG19__WATCHHI0:
7641 case CP0_REG19__WATCHHI1:
7642 case CP0_REG19__WATCHHI2:
7643 case CP0_REG19__WATCHHI3:
7644 case CP0_REG19__WATCHHI4:
7645 case CP0_REG19__WATCHHI5:
7646 case CP0_REG19__WATCHHI6:
7647 case CP0_REG19__WATCHHI7:
7648 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7649 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7650 register_name = "WatchHi";
7651 break;
7652 default:
7653 goto cp0_unimplemented;
7654 }
7655 break;
7656 case CP0_REGISTER_20:
7657 switch (sel) {
7658 case CP0_REG20__XCONTEXT:
7659 check_insn(ctx, ISA_MIPS3);
7660 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7661 register_name = "XContext";
7662 break;
7663 default:
7664 goto cp0_unimplemented;
7665 }
7666 break;
7667 case CP0_REGISTER_21:
7668
7669 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7670 switch (sel) {
7671 case 0:
7672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7673 register_name = "Framemask";
7674 break;
7675 default:
7676 goto cp0_unimplemented;
7677 }
7678 break;
7679 case CP0_REGISTER_22:
7680 tcg_gen_movi_tl(arg, 0);
7681 register_name = "'Diagnostic";
7682 break;
7683 case CP0_REGISTER_23:
7684 switch (sel) {
7685 case CP0_REG23__DEBUG:
7686 gen_helper_mfc0_debug(arg, cpu_env);
7687 register_name = "Debug";
7688 break;
7689 case CP0_REG23__TRACECONTROL:
7690
7691
7692 register_name = "TraceControl";
7693 goto cp0_unimplemented;
7694 case CP0_REG23__TRACECONTROL2:
7695
7696
7697 register_name = "TraceControl2";
7698 goto cp0_unimplemented;
7699 case CP0_REG23__USERTRACEDATA1:
7700
7701
7702 register_name = "UserTraceData1";
7703 goto cp0_unimplemented;
7704 case CP0_REG23__TRACEIBPC:
7705
7706
7707 register_name = "TraceIBPC";
7708 goto cp0_unimplemented;
7709 case CP0_REG23__TRACEDBPC:
7710
7711
7712 register_name = "TraceDBPC";
7713 goto cp0_unimplemented;
7714 default:
7715 goto cp0_unimplemented;
7716 }
7717 break;
7718 case CP0_REGISTER_24:
7719 switch (sel) {
7720 case CP0_REG24__DEPC:
7721
7722 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7723 register_name = "DEPC";
7724 break;
7725 default:
7726 goto cp0_unimplemented;
7727 }
7728 break;
7729 case CP0_REGISTER_25:
7730 switch (sel) {
7731 case CP0_REG25__PERFCTL0:
7732 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7733 register_name = "Performance0";
7734 break;
7735 case CP0_REG25__PERFCNT0:
7736
7737 register_name = "Performance1";
7738 goto cp0_unimplemented;
7739 case CP0_REG25__PERFCTL1:
7740
7741 register_name = "Performance2";
7742 goto cp0_unimplemented;
7743 case CP0_REG25__PERFCNT1:
7744
7745 register_name = "Performance3";
7746 goto cp0_unimplemented;
7747 case CP0_REG25__PERFCTL2:
7748
7749 register_name = "Performance4";
7750 goto cp0_unimplemented;
7751 case CP0_REG25__PERFCNT2:
7752
7753 register_name = "Performance5";
7754 goto cp0_unimplemented;
7755 case CP0_REG25__PERFCTL3:
7756
7757 register_name = "Performance6";
7758 goto cp0_unimplemented;
7759 case CP0_REG25__PERFCNT3:
7760
7761 register_name = "Performance7";
7762 goto cp0_unimplemented;
7763 default:
7764 goto cp0_unimplemented;
7765 }
7766 break;
7767 case CP0_REGISTER_26:
7768 switch (sel) {
7769 case CP0_REG26__ERRCTL:
7770 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7771 register_name = "ErrCtl";
7772 break;
7773 default:
7774 goto cp0_unimplemented;
7775 }
7776 break;
7777 case CP0_REGISTER_27:
7778 switch (sel) {
7779
7780 case CP0_REG27__CACHERR:
7781 tcg_gen_movi_tl(arg, 0);
7782 register_name = "CacheErr";
7783 break;
7784 default:
7785 goto cp0_unimplemented;
7786 }
7787 break;
7788 case CP0_REGISTER_28:
7789 switch (sel) {
7790 case CP0_REG28__TAGLO:
7791 case CP0_REG28__TAGLO1:
7792 case CP0_REG28__TAGLO2:
7793 case CP0_REG28__TAGLO3:
7794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7795 register_name = "TagLo";
7796 break;
7797 case CP0_REG28__DATALO:
7798 case CP0_REG28__DATALO1:
7799 case CP0_REG28__DATALO2:
7800 case CP0_REG28__DATALO3:
7801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7802 register_name = "DataLo";
7803 break;
7804 default:
7805 goto cp0_unimplemented;
7806 }
7807 break;
7808 case CP0_REGISTER_29:
7809 switch (sel) {
7810 case CP0_REG29__TAGHI:
7811 case CP0_REG29__TAGHI1:
7812 case CP0_REG29__TAGHI2:
7813 case CP0_REG29__TAGHI3:
7814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7815 register_name = "TagHi";
7816 break;
7817 case CP0_REG29__DATAHI:
7818 case CP0_REG29__DATAHI1:
7819 case CP0_REG29__DATAHI2:
7820 case CP0_REG29__DATAHI3:
7821 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7822 register_name = "DataHi";
7823 break;
7824 default:
7825 goto cp0_unimplemented;
7826 }
7827 break;
7828 case CP0_REGISTER_30:
7829 switch (sel) {
7830 case CP0_REG30__ERROREPC:
7831 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7832 register_name = "ErrorEPC";
7833 break;
7834 default:
7835 goto cp0_unimplemented;
7836 }
7837 break;
7838 case CP0_REGISTER_31:
7839 switch (sel) {
7840 case CP0_REG31__DESAVE:
7841
7842 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7843 register_name = "DESAVE";
7844 break;
7845 case CP0_REG31__KSCRATCH1:
7846 case CP0_REG31__KSCRATCH2:
7847 case CP0_REG31__KSCRATCH3:
7848 case CP0_REG31__KSCRATCH4:
7849 case CP0_REG31__KSCRATCH5:
7850 case CP0_REG31__KSCRATCH6:
7851 CP0_CHECK(ctx->kscrexist & (1 << sel));
7852 tcg_gen_ld_tl(arg, cpu_env,
7853 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7854 register_name = "KScratch";
7855 break;
7856 default:
7857 goto cp0_unimplemented;
7858 }
7859 break;
7860 default:
7861 goto cp0_unimplemented;
7862 }
7863 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7864 return;
7865
7866cp0_unimplemented:
7867 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7868 register_name, reg, sel);
7869 gen_mfc0_unimplemented(ctx, arg);
7870}
7871
7872static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7873{
7874 const char *register_name = "invalid";
7875
7876 if (sel != 0) {
7877 check_insn(ctx, ISA_MIPS_R1);
7878 }
7879
7880 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7881 gen_io_start();
7882 }
7883
7884 switch (reg) {
7885 case CP0_REGISTER_00:
7886 switch (sel) {
7887 case CP0_REG00__INDEX:
7888 gen_helper_mtc0_index(cpu_env, arg);
7889 register_name = "Index";
7890 break;
7891 case CP0_REG00__MVPCONTROL:
7892 CP0_CHECK(ctx->insn_flags & ASE_MT);
7893 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7894 register_name = "MVPControl";
7895 break;
7896 case CP0_REG00__MVPCONF0:
7897 CP0_CHECK(ctx->insn_flags & ASE_MT);
7898
7899 register_name = "MVPConf0";
7900 break;
7901 case CP0_REG00__MVPCONF1:
7902 CP0_CHECK(ctx->insn_flags & ASE_MT);
7903
7904 register_name = "MVPConf1";
7905 break;
7906 case CP0_REG00__VPCONTROL:
7907 CP0_CHECK(ctx->vp);
7908
7909 register_name = "VPControl";
7910 break;
7911 default:
7912 goto cp0_unimplemented;
7913 }
7914 break;
7915 case CP0_REGISTER_01:
7916 switch (sel) {
7917 case CP0_REG01__RANDOM:
7918
7919 register_name = "Random";
7920 break;
7921 case CP0_REG01__VPECONTROL:
7922 CP0_CHECK(ctx->insn_flags & ASE_MT);
7923 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7924 register_name = "VPEControl";
7925 break;
7926 case CP0_REG01__VPECONF0:
7927 CP0_CHECK(ctx->insn_flags & ASE_MT);
7928 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7929 register_name = "VPEConf0";
7930 break;
7931 case CP0_REG01__VPECONF1:
7932 CP0_CHECK(ctx->insn_flags & ASE_MT);
7933 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7934 register_name = "VPEConf1";
7935 break;
7936 case CP0_REG01__YQMASK:
7937 CP0_CHECK(ctx->insn_flags & ASE_MT);
7938 gen_helper_mtc0_yqmask(cpu_env, arg);
7939 register_name = "YQMask";
7940 break;
7941 case CP0_REG01__VPESCHEDULE:
7942 CP0_CHECK(ctx->insn_flags & ASE_MT);
7943 tcg_gen_st_tl(arg, cpu_env,
7944 offsetof(CPUMIPSState, CP0_VPESchedule));
7945 register_name = "VPESchedule";
7946 break;
7947 case CP0_REG01__VPESCHEFBACK:
7948 CP0_CHECK(ctx->insn_flags & ASE_MT);
7949 tcg_gen_st_tl(arg, cpu_env,
7950 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7951 register_name = "VPEScheFBack";
7952 break;
7953 case CP0_REG01__VPEOPT:
7954 CP0_CHECK(ctx->insn_flags & ASE_MT);
7955 gen_helper_mtc0_vpeopt(cpu_env, arg);
7956 register_name = "VPEOpt";
7957 break;
7958 default:
7959 goto cp0_unimplemented;
7960 }
7961 break;
7962 case CP0_REGISTER_02:
7963 switch (sel) {
7964 case CP0_REG02__ENTRYLO0:
7965 gen_helper_dmtc0_entrylo0(cpu_env, arg);
7966 register_name = "EntryLo0";
7967 break;
7968 case CP0_REG02__TCSTATUS:
7969 CP0_CHECK(ctx->insn_flags & ASE_MT);
7970 gen_helper_mtc0_tcstatus(cpu_env, arg);
7971 register_name = "TCStatus";
7972 break;
7973 case CP0_REG02__TCBIND:
7974 CP0_CHECK(ctx->insn_flags & ASE_MT);
7975 gen_helper_mtc0_tcbind(cpu_env, arg);
7976 register_name = "TCBind";
7977 break;
7978 case CP0_REG02__TCRESTART:
7979 CP0_CHECK(ctx->insn_flags & ASE_MT);
7980 gen_helper_mtc0_tcrestart(cpu_env, arg);
7981 register_name = "TCRestart";
7982 break;
7983 case CP0_REG02__TCHALT:
7984 CP0_CHECK(ctx->insn_flags & ASE_MT);
7985 gen_helper_mtc0_tchalt(cpu_env, arg);
7986 register_name = "TCHalt";
7987 break;
7988 case CP0_REG02__TCCONTEXT:
7989 CP0_CHECK(ctx->insn_flags & ASE_MT);
7990 gen_helper_mtc0_tccontext(cpu_env, arg);
7991 register_name = "TCContext";
7992 break;
7993 case CP0_REG02__TCSCHEDULE:
7994 CP0_CHECK(ctx->insn_flags & ASE_MT);
7995 gen_helper_mtc0_tcschedule(cpu_env, arg);
7996 register_name = "TCSchedule";
7997 break;
7998 case CP0_REG02__TCSCHEFBACK:
7999 CP0_CHECK(ctx->insn_flags & ASE_MT);
8000 gen_helper_mtc0_tcschefback(cpu_env, arg);
8001 register_name = "TCScheFBack";
8002 break;
8003 default:
8004 goto cp0_unimplemented;
8005 }
8006 break;
8007 case CP0_REGISTER_03:
8008 switch (sel) {
8009 case CP0_REG03__ENTRYLO1:
8010 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8011 register_name = "EntryLo1";
8012 break;
8013 case CP0_REG03__GLOBALNUM:
8014 CP0_CHECK(ctx->vp);
8015
8016 register_name = "GlobalNumber";
8017 break;
8018 default:
8019 goto cp0_unimplemented;
8020 }
8021 break;
8022 case CP0_REGISTER_04:
8023 switch (sel) {
8024 case CP0_REG04__CONTEXT:
8025 gen_helper_mtc0_context(cpu_env, arg);
8026 register_name = "Context";
8027 break;
8028 case CP0_REG04__CONTEXTCONFIG:
8029
8030
8031 register_name = "ContextConfig";
8032 goto cp0_unimplemented;
8033 case CP0_REG04__USERLOCAL:
8034 CP0_CHECK(ctx->ulri);
8035 tcg_gen_st_tl(arg, cpu_env,
8036 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8037 register_name = "UserLocal";
8038 break;
8039 case CP0_REG04__MMID:
8040 CP0_CHECK(ctx->mi);
8041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8042 register_name = "MMID";
8043 break;
8044 default:
8045 goto cp0_unimplemented;
8046 }
8047 break;
8048 case CP0_REGISTER_05:
8049 switch (sel) {
8050 case CP0_REG05__PAGEMASK:
8051 gen_helper_mtc0_pagemask(cpu_env, arg);
8052 register_name = "PageMask";
8053 break;
8054 case CP0_REG05__PAGEGRAIN:
8055 check_insn(ctx, ISA_MIPS_R2);
8056 gen_helper_mtc0_pagegrain(cpu_env, arg);
8057 register_name = "PageGrain";
8058 break;
8059 case CP0_REG05__SEGCTL0:
8060 CP0_CHECK(ctx->sc);
8061 gen_helper_mtc0_segctl0(cpu_env, arg);
8062 register_name = "SegCtl0";
8063 break;
8064 case CP0_REG05__SEGCTL1:
8065 CP0_CHECK(ctx->sc);
8066 gen_helper_mtc0_segctl1(cpu_env, arg);
8067 register_name = "SegCtl1";
8068 break;
8069 case CP0_REG05__SEGCTL2:
8070 CP0_CHECK(ctx->sc);
8071 gen_helper_mtc0_segctl2(cpu_env, arg);
8072 register_name = "SegCtl2";
8073 break;
8074 case CP0_REG05__PWBASE:
8075 check_pw(ctx);
8076 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8077 register_name = "PWBase";
8078 break;
8079 case CP0_REG05__PWFIELD:
8080 check_pw(ctx);
8081 gen_helper_mtc0_pwfield(cpu_env, arg);
8082 register_name = "PWField";
8083 break;
8084 case CP0_REG05__PWSIZE:
8085 check_pw(ctx);
8086 gen_helper_mtc0_pwsize(cpu_env, arg);
8087 register_name = "PWSize";
8088 break;
8089 default:
8090 goto cp0_unimplemented;
8091 }
8092 break;
8093 case CP0_REGISTER_06:
8094 switch (sel) {
8095 case CP0_REG06__WIRED:
8096 gen_helper_mtc0_wired(cpu_env, arg);
8097 register_name = "Wired";
8098 break;
8099 case CP0_REG06__SRSCONF0:
8100 check_insn(ctx, ISA_MIPS_R2);
8101 gen_helper_mtc0_srsconf0(cpu_env, arg);
8102 register_name = "SRSConf0";
8103 break;
8104 case CP0_REG06__SRSCONF1:
8105 check_insn(ctx, ISA_MIPS_R2);
8106 gen_helper_mtc0_srsconf1(cpu_env, arg);
8107 register_name = "SRSConf1";
8108 break;
8109 case CP0_REG06__SRSCONF2:
8110 check_insn(ctx, ISA_MIPS_R2);
8111 gen_helper_mtc0_srsconf2(cpu_env, arg);
8112 register_name = "SRSConf2";
8113 break;
8114 case CP0_REG06__SRSCONF3:
8115 check_insn(ctx, ISA_MIPS_R2);
8116 gen_helper_mtc0_srsconf3(cpu_env, arg);
8117 register_name = "SRSConf3";
8118 break;
8119 case CP0_REG06__SRSCONF4:
8120 check_insn(ctx, ISA_MIPS_R2);
8121 gen_helper_mtc0_srsconf4(cpu_env, arg);
8122 register_name = "SRSConf4";
8123 break;
8124 case CP0_REG06__PWCTL:
8125 check_pw(ctx);
8126 gen_helper_mtc0_pwctl(cpu_env, arg);
8127 register_name = "PWCtl";
8128 break;
8129 default:
8130 goto cp0_unimplemented;
8131 }
8132 break;
8133 case CP0_REGISTER_07:
8134 switch (sel) {
8135 case CP0_REG07__HWRENA:
8136 check_insn(ctx, ISA_MIPS_R2);
8137 gen_helper_mtc0_hwrena(cpu_env, arg);
8138 ctx->base.is_jmp = DISAS_STOP;
8139 register_name = "HWREna";
8140 break;
8141 default:
8142 goto cp0_unimplemented;
8143 }
8144 break;
8145 case CP0_REGISTER_08:
8146 switch (sel) {
8147 case CP0_REG08__BADVADDR:
8148
8149 register_name = "BadVAddr";
8150 break;
8151 case CP0_REG08__BADINSTR:
8152
8153 register_name = "BadInstr";
8154 break;
8155 case CP0_REG08__BADINSTRP:
8156
8157 register_name = "BadInstrP";
8158 break;
8159 case CP0_REG08__BADINSTRX:
8160
8161 register_name = "BadInstrX";
8162 break;
8163 default:
8164 goto cp0_unimplemented;
8165 }
8166 break;
8167 case CP0_REGISTER_09:
8168 switch (sel) {
8169 case CP0_REG09__COUNT:
8170 gen_helper_mtc0_count(cpu_env, arg);
8171 register_name = "Count";
8172 break;
8173 case CP0_REG09__SAARI:
8174 CP0_CHECK(ctx->saar);
8175 gen_helper_mtc0_saari(cpu_env, arg);
8176 register_name = "SAARI";
8177 break;
8178 case CP0_REG09__SAAR:
8179 CP0_CHECK(ctx->saar);
8180 gen_helper_mtc0_saar(cpu_env, arg);
8181 register_name = "SAAR";
8182 break;
8183 default:
8184 goto cp0_unimplemented;
8185 }
8186
8187 ctx->base.is_jmp = DISAS_STOP;
8188 break;
8189 case CP0_REGISTER_10:
8190 switch (sel) {
8191 case CP0_REG10__ENTRYHI:
8192 gen_helper_mtc0_entryhi(cpu_env, arg);
8193 register_name = "EntryHi";
8194 break;
8195 default:
8196 goto cp0_unimplemented;
8197 }
8198 break;
8199 case CP0_REGISTER_11:
8200 switch (sel) {
8201 case CP0_REG11__COMPARE:
8202 gen_helper_mtc0_compare(cpu_env, arg);
8203 register_name = "Compare";
8204 break;
8205
8206 default:
8207 goto cp0_unimplemented;
8208 }
8209
8210 ctx->base.is_jmp = DISAS_STOP;
8211 break;
8212 case CP0_REGISTER_12:
8213 switch (sel) {
8214 case CP0_REG12__STATUS:
8215 save_cpu_state(ctx, 1);
8216 gen_helper_mtc0_status(cpu_env, arg);
8217
8218 gen_save_pc(ctx->base.pc_next + 4);
8219 ctx->base.is_jmp = DISAS_EXIT;
8220 register_name = "Status";
8221 break;
8222 case CP0_REG12__INTCTL:
8223 check_insn(ctx, ISA_MIPS_R2);
8224 gen_helper_mtc0_intctl(cpu_env, arg);
8225
8226 ctx->base.is_jmp = DISAS_STOP;
8227 register_name = "IntCtl";
8228 break;
8229 case CP0_REG12__SRSCTL:
8230 check_insn(ctx, ISA_MIPS_R2);
8231 gen_helper_mtc0_srsctl(cpu_env, arg);
8232
8233 ctx->base.is_jmp = DISAS_STOP;
8234 register_name = "SRSCtl";
8235 break;
8236 case CP0_REG12__SRSMAP:
8237 check_insn(ctx, ISA_MIPS_R2);
8238 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8239
8240 ctx->base.is_jmp = DISAS_STOP;
8241 register_name = "SRSMap";
8242 break;
8243 default:
8244 goto cp0_unimplemented;
8245 }
8246 break;
8247 case CP0_REGISTER_13:
8248 switch (sel) {
8249 case CP0_REG13__CAUSE:
8250 save_cpu_state(ctx, 1);
8251 gen_helper_mtc0_cause(cpu_env, arg);
8252
8253
8254
8255
8256
8257 gen_save_pc(ctx->base.pc_next + 4);
8258 ctx->base.is_jmp = DISAS_EXIT;
8259 register_name = "Cause";
8260 break;
8261 default:
8262 goto cp0_unimplemented;
8263 }
8264 break;
8265 case CP0_REGISTER_14:
8266 switch (sel) {
8267 case CP0_REG14__EPC:
8268 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8269 register_name = "EPC";
8270 break;
8271 default:
8272 goto cp0_unimplemented;
8273 }
8274 break;
8275 case CP0_REGISTER_15:
8276 switch (sel) {
8277 case CP0_REG15__PRID:
8278
8279 register_name = "PRid";
8280 break;
8281 case CP0_REG15__EBASE:
8282 check_insn(ctx, ISA_MIPS_R2);
8283 gen_helper_mtc0_ebase(cpu_env, arg);
8284 register_name = "EBase";
8285 break;
8286 default:
8287 goto cp0_unimplemented;
8288 }
8289 break;
8290 case CP0_REGISTER_16:
8291 switch (sel) {
8292 case CP0_REG16__CONFIG:
8293 gen_helper_mtc0_config0(cpu_env, arg);
8294 register_name = "Config";
8295
8296 ctx->base.is_jmp = DISAS_STOP;
8297 break;
8298 case CP0_REG16__CONFIG1:
8299
8300 register_name = "Config1";
8301 break;
8302 case CP0_REG16__CONFIG2:
8303 gen_helper_mtc0_config2(cpu_env, arg);
8304 register_name = "Config2";
8305
8306 ctx->base.is_jmp = DISAS_STOP;
8307 break;
8308 case CP0_REG16__CONFIG3:
8309 gen_helper_mtc0_config3(cpu_env, arg);
8310 register_name = "Config3";
8311
8312 ctx->base.is_jmp = DISAS_STOP;
8313 break;
8314 case CP0_REG16__CONFIG4:
8315
8316 register_name = "Config4";
8317 break;
8318 case CP0_REG16__CONFIG5:
8319 gen_helper_mtc0_config5(cpu_env, arg);
8320 register_name = "Config5";
8321
8322 ctx->base.is_jmp = DISAS_STOP;
8323 break;
8324
8325 default:
8326 register_name = "Invalid config selector";
8327 goto cp0_unimplemented;
8328 }
8329 break;
8330 case CP0_REGISTER_17:
8331 switch (sel) {
8332 case CP0_REG17__LLADDR:
8333 gen_helper_mtc0_lladdr(cpu_env, arg);
8334 register_name = "LLAddr";
8335 break;
8336 case CP0_REG17__MAAR:
8337 CP0_CHECK(ctx->mrp);
8338 gen_helper_mtc0_maar(cpu_env, arg);
8339 register_name = "MAAR";
8340 break;
8341 case CP0_REG17__MAARI:
8342 CP0_CHECK(ctx->mrp);
8343 gen_helper_mtc0_maari(cpu_env, arg);
8344 register_name = "MAARI";
8345 break;
8346 default:
8347 goto cp0_unimplemented;
8348 }
8349 break;
8350 case CP0_REGISTER_18:
8351 switch (sel) {
8352 case CP0_REG18__WATCHLO0:
8353 case CP0_REG18__WATCHLO1:
8354 case CP0_REG18__WATCHLO2:
8355 case CP0_REG18__WATCHLO3:
8356 case CP0_REG18__WATCHLO4:
8357 case CP0_REG18__WATCHLO5:
8358 case CP0_REG18__WATCHLO6:
8359 case CP0_REG18__WATCHLO7:
8360 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8361 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8362 register_name = "WatchLo";
8363 break;
8364 default:
8365 goto cp0_unimplemented;
8366 }
8367 break;
8368 case CP0_REGISTER_19:
8369 switch (sel) {
8370 case CP0_REG19__WATCHHI0:
8371 case CP0_REG19__WATCHHI1:
8372 case CP0_REG19__WATCHHI2:
8373 case CP0_REG19__WATCHHI3:
8374 case CP0_REG19__WATCHHI4:
8375 case CP0_REG19__WATCHHI5:
8376 case CP0_REG19__WATCHHI6:
8377 case CP0_REG19__WATCHHI7:
8378 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8379 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8380 register_name = "WatchHi";
8381 break;
8382 default:
8383 goto cp0_unimplemented;
8384 }
8385 break;
8386 case CP0_REGISTER_20:
8387 switch (sel) {
8388 case CP0_REG20__XCONTEXT:
8389 check_insn(ctx, ISA_MIPS3);
8390 gen_helper_mtc0_xcontext(cpu_env, arg);
8391 register_name = "XContext";
8392 break;
8393 default:
8394 goto cp0_unimplemented;
8395 }
8396 break;
8397 case CP0_REGISTER_21:
8398
8399 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8400 switch (sel) {
8401 case 0:
8402 gen_helper_mtc0_framemask(cpu_env, arg);
8403 register_name = "Framemask";
8404 break;
8405 default:
8406 goto cp0_unimplemented;
8407 }
8408 break;
8409 case CP0_REGISTER_22:
8410
8411 register_name = "Diagnostic";
8412 break;
8413 case CP0_REGISTER_23:
8414 switch (sel) {
8415 case CP0_REG23__DEBUG:
8416 gen_helper_mtc0_debug(cpu_env, arg);
8417
8418 gen_save_pc(ctx->base.pc_next + 4);
8419 ctx->base.is_jmp = DISAS_EXIT;
8420 register_name = "Debug";
8421 break;
8422 case CP0_REG23__TRACECONTROL:
8423
8424
8425
8426 ctx->base.is_jmp = DISAS_STOP;
8427 register_name = "TraceControl";
8428 goto cp0_unimplemented;
8429 case CP0_REG23__TRACECONTROL2:
8430
8431
8432
8433 ctx->base.is_jmp = DISAS_STOP;
8434 register_name = "TraceControl2";
8435 goto cp0_unimplemented;
8436 case CP0_REG23__USERTRACEDATA1:
8437
8438
8439
8440 ctx->base.is_jmp = DISAS_STOP;
8441 register_name = "UserTraceData1";
8442 goto cp0_unimplemented;
8443 case CP0_REG23__TRACEIBPC:
8444
8445
8446
8447 ctx->base.is_jmp = DISAS_STOP;
8448 register_name = "TraceIBPC";
8449 goto cp0_unimplemented;
8450 case CP0_REG23__TRACEDBPC:
8451
8452
8453
8454 ctx->base.is_jmp = DISAS_STOP;
8455 register_name = "TraceDBPC";
8456 goto cp0_unimplemented;
8457 default:
8458 goto cp0_unimplemented;
8459 }
8460 break;
8461 case CP0_REGISTER_24:
8462 switch (sel) {
8463 case CP0_REG24__DEPC:
8464
8465 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8466 register_name = "DEPC";
8467 break;
8468 default:
8469 goto cp0_unimplemented;
8470 }
8471 break;
8472 case CP0_REGISTER_25:
8473 switch (sel) {
8474 case CP0_REG25__PERFCTL0:
8475 gen_helper_mtc0_performance0(cpu_env, arg);
8476 register_name = "Performance0";
8477 break;
8478 case CP0_REG25__PERFCNT0:
8479
8480 register_name = "Performance1";
8481 goto cp0_unimplemented;
8482 case CP0_REG25__PERFCTL1:
8483
8484 register_name = "Performance2";
8485 goto cp0_unimplemented;
8486 case CP0_REG25__PERFCNT1:
8487
8488 register_name = "Performance3";
8489 goto cp0_unimplemented;
8490 case CP0_REG25__PERFCTL2:
8491
8492 register_name = "Performance4";
8493 goto cp0_unimplemented;
8494 case CP0_REG25__PERFCNT2:
8495
8496 register_name = "Performance5";
8497 goto cp0_unimplemented;
8498 case CP0_REG25__PERFCTL3:
8499
8500 register_name = "Performance6";
8501 goto cp0_unimplemented;
8502 case CP0_REG25__PERFCNT3:
8503
8504 register_name = "Performance7";
8505 goto cp0_unimplemented;
8506 default:
8507 goto cp0_unimplemented;
8508 }
8509 break;
8510 case CP0_REGISTER_26:
8511 switch (sel) {
8512 case CP0_REG26__ERRCTL:
8513 gen_helper_mtc0_errctl(cpu_env, arg);
8514 ctx->base.is_jmp = DISAS_STOP;
8515 register_name = "ErrCtl";
8516 break;
8517 default:
8518 goto cp0_unimplemented;
8519 }
8520 break;
8521 case CP0_REGISTER_27:
8522 switch (sel) {
8523 case CP0_REG27__CACHERR:
8524
8525 register_name = "CacheErr";
8526 break;
8527 default:
8528 goto cp0_unimplemented;
8529 }
8530 break;
8531 case CP0_REGISTER_28:
8532 switch (sel) {
8533 case CP0_REG28__TAGLO:
8534 case CP0_REG28__TAGLO1:
8535 case CP0_REG28__TAGLO2:
8536 case CP0_REG28__TAGLO3:
8537 gen_helper_mtc0_taglo(cpu_env, arg);
8538 register_name = "TagLo";
8539 break;
8540 case CP0_REG28__DATALO:
8541 case CP0_REG28__DATALO1:
8542 case CP0_REG28__DATALO2:
8543 case CP0_REG28__DATALO3:
8544 gen_helper_mtc0_datalo(cpu_env, arg);
8545 register_name = "DataLo";
8546 break;
8547 default:
8548 goto cp0_unimplemented;
8549 }
8550 break;
8551 case CP0_REGISTER_29:
8552 switch (sel) {
8553 case CP0_REG29__TAGHI:
8554 case CP0_REG29__TAGHI1:
8555 case CP0_REG29__TAGHI2:
8556 case CP0_REG29__TAGHI3:
8557 gen_helper_mtc0_taghi(cpu_env, arg);
8558 register_name = "TagHi";
8559 break;
8560 case CP0_REG29__DATAHI:
8561 case CP0_REG29__DATAHI1:
8562 case CP0_REG29__DATAHI2:
8563 case CP0_REG29__DATAHI3:
8564 gen_helper_mtc0_datahi(cpu_env, arg);
8565 register_name = "DataHi";
8566 break;
8567 default:
8568 register_name = "invalid sel";
8569 goto cp0_unimplemented;
8570 }
8571 break;
8572 case CP0_REGISTER_30:
8573 switch (sel) {
8574 case CP0_REG30__ERROREPC:
8575 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8576 register_name = "ErrorEPC";
8577 break;
8578 default:
8579 goto cp0_unimplemented;
8580 }
8581 break;
8582 case CP0_REGISTER_31:
8583 switch (sel) {
8584 case CP0_REG31__DESAVE:
8585
8586 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8587 register_name = "DESAVE";
8588 break;
8589 case CP0_REG31__KSCRATCH1:
8590 case CP0_REG31__KSCRATCH2:
8591 case CP0_REG31__KSCRATCH3:
8592 case CP0_REG31__KSCRATCH4:
8593 case CP0_REG31__KSCRATCH5:
8594 case CP0_REG31__KSCRATCH6:
8595 CP0_CHECK(ctx->kscrexist & (1 << sel));
8596 tcg_gen_st_tl(arg, cpu_env,
8597 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8598 register_name = "KScratch";
8599 break;
8600 default:
8601 goto cp0_unimplemented;
8602 }
8603 break;
8604 default:
8605 goto cp0_unimplemented;
8606 }
8607 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8608
8609
8610 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8611
8612
8613
8614
8615 gen_save_pc(ctx->base.pc_next + 4);
8616 ctx->base.is_jmp = DISAS_EXIT;
8617 }
8618 return;
8619
8620cp0_unimplemented:
8621 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8622 register_name, reg, sel);
8623}
8624#endif
8625
8626static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8627 int u, int sel, int h)
8628{
8629 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8630 TCGv t0 = tcg_temp_local_new();
8631
8632 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8633 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8634 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8635 tcg_gen_movi_tl(t0, -1);
8636 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8637 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8638 tcg_gen_movi_tl(t0, -1);
8639 } else if (u == 0) {
8640 switch (rt) {
8641 case 1:
8642 switch (sel) {
8643 case 1:
8644 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8645 break;
8646 case 2:
8647 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8648 break;
8649 default:
8650 goto die;
8651 break;
8652 }
8653 break;
8654 case 2:
8655 switch (sel) {
8656 case 1:
8657 gen_helper_mftc0_tcstatus(t0, cpu_env);
8658 break;
8659 case 2:
8660 gen_helper_mftc0_tcbind(t0, cpu_env);
8661 break;
8662 case 3:
8663 gen_helper_mftc0_tcrestart(t0, cpu_env);
8664 break;
8665 case 4:
8666 gen_helper_mftc0_tchalt(t0, cpu_env);
8667 break;
8668 case 5:
8669 gen_helper_mftc0_tccontext(t0, cpu_env);
8670 break;
8671 case 6:
8672 gen_helper_mftc0_tcschedule(t0, cpu_env);
8673 break;
8674 case 7:
8675 gen_helper_mftc0_tcschefback(t0, cpu_env);
8676 break;
8677 default:
8678 gen_mfc0(ctx, t0, rt, sel);
8679 break;
8680 }
8681 break;
8682 case 10:
8683 switch (sel) {
8684 case 0:
8685 gen_helper_mftc0_entryhi(t0, cpu_env);
8686 break;
8687 default:
8688 gen_mfc0(ctx, t0, rt, sel);
8689 break;
8690 }
8691 break;
8692 case 12:
8693 switch (sel) {
8694 case 0:
8695 gen_helper_mftc0_status(t0, cpu_env);
8696 break;
8697 default:
8698 gen_mfc0(ctx, t0, rt, sel);
8699 break;
8700 }
8701 break;
8702 case 13:
8703 switch (sel) {
8704 case 0:
8705 gen_helper_mftc0_cause(t0, cpu_env);
8706 break;
8707 default:
8708 goto die;
8709 break;
8710 }
8711 break;
8712 case 14:
8713 switch (sel) {
8714 case 0:
8715 gen_helper_mftc0_epc(t0, cpu_env);
8716 break;
8717 default:
8718 goto die;
8719 break;
8720 }
8721 break;
8722 case 15:
8723 switch (sel) {
8724 case 1:
8725 gen_helper_mftc0_ebase(t0, cpu_env);
8726 break;
8727 default:
8728 goto die;
8729 break;
8730 }
8731 break;
8732 case 16:
8733 switch (sel) {
8734 case 0:
8735 case 1:
8736 case 2:
8737 case 3:
8738 case 4:
8739 case 5:
8740 case 6:
8741 case 7:
8742 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8743 break;
8744 default:
8745 goto die;
8746 break;
8747 }
8748 break;
8749 case 23:
8750 switch (sel) {
8751 case 0:
8752 gen_helper_mftc0_debug(t0, cpu_env);
8753 break;
8754 default:
8755 gen_mfc0(ctx, t0, rt, sel);
8756 break;
8757 }
8758 break;
8759 default:
8760 gen_mfc0(ctx, t0, rt, sel);
8761 }
8762 } else {
8763 switch (sel) {
8764
8765 case 0:
8766 gen_helper_1e0i(mftgpr, t0, rt);
8767 break;
8768
8769 case 1:
8770 switch (rt) {
8771 case 0:
8772 gen_helper_1e0i(mftlo, t0, 0);
8773 break;
8774 case 1:
8775 gen_helper_1e0i(mfthi, t0, 0);
8776 break;
8777 case 2:
8778 gen_helper_1e0i(mftacx, t0, 0);
8779 break;
8780 case 4:
8781 gen_helper_1e0i(mftlo, t0, 1);
8782 break;
8783 case 5:
8784 gen_helper_1e0i(mfthi, t0, 1);
8785 break;
8786 case 6:
8787 gen_helper_1e0i(mftacx, t0, 1);
8788 break;
8789 case 8:
8790 gen_helper_1e0i(mftlo, t0, 2);
8791 break;
8792 case 9:
8793 gen_helper_1e0i(mfthi, t0, 2);
8794 break;
8795 case 10:
8796 gen_helper_1e0i(mftacx, t0, 2);
8797 break;
8798 case 12:
8799 gen_helper_1e0i(mftlo, t0, 3);
8800 break;
8801 case 13:
8802 gen_helper_1e0i(mfthi, t0, 3);
8803 break;
8804 case 14:
8805 gen_helper_1e0i(mftacx, t0, 3);
8806 break;
8807 case 16:
8808 gen_helper_mftdsp(t0, cpu_env);
8809 break;
8810 default:
8811 goto die;
8812 }
8813 break;
8814
8815 case 2:
8816
8817 if (h == 0) {
8818 TCGv_i32 fp0 = tcg_temp_new_i32();
8819
8820 gen_load_fpr32(ctx, fp0, rt);
8821 tcg_gen_ext_i32_tl(t0, fp0);
8822 tcg_temp_free_i32(fp0);
8823 } else {
8824 TCGv_i32 fp0 = tcg_temp_new_i32();
8825
8826 gen_load_fpr32h(ctx, fp0, rt);
8827 tcg_gen_ext_i32_tl(t0, fp0);
8828 tcg_temp_free_i32(fp0);
8829 }
8830 break;
8831 case 3:
8832
8833 gen_helper_1e0i(cfc1, t0, rt);
8834 break;
8835
8836 case 4:
8837 case 5:
8838
8839 default:
8840 goto die;
8841 }
8842 }
8843 trace_mips_translate_tr("mftr", rt, u, sel, h);
8844 gen_store_gpr(t0, rd);
8845 tcg_temp_free(t0);
8846 return;
8847
8848die:
8849 tcg_temp_free(t0);
8850 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8851 gen_reserved_instruction(ctx);
8852}
8853
8854static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8855 int u, int sel, int h)
8856{
8857 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8858 TCGv t0 = tcg_temp_local_new();
8859
8860 gen_load_gpr(t0, rt);
8861 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8862 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8863 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8864
8865 ;
8866 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8867 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8868
8869 ;
8870 } else if (u == 0) {
8871 switch (rd) {
8872 case 1:
8873 switch (sel) {
8874 case 1:
8875 gen_helper_mttc0_vpecontrol(cpu_env, t0);
8876 break;
8877 case 2:
8878 gen_helper_mttc0_vpeconf0(cpu_env, t0);
8879 break;
8880 default:
8881 goto die;
8882 break;
8883 }
8884 break;
8885 case 2:
8886 switch (sel) {
8887 case 1:
8888 gen_helper_mttc0_tcstatus(cpu_env, t0);
8889 break;
8890 case 2:
8891 gen_helper_mttc0_tcbind(cpu_env, t0);
8892 break;
8893 case 3:
8894 gen_helper_mttc0_tcrestart(cpu_env, t0);
8895 break;
8896 case 4:
8897 gen_helper_mttc0_tchalt(cpu_env, t0);
8898 break;
8899 case 5:
8900 gen_helper_mttc0_tccontext(cpu_env, t0);
8901 break;
8902 case 6:
8903 gen_helper_mttc0_tcschedule(cpu_env, t0);
8904 break;
8905 case 7:
8906 gen_helper_mttc0_tcschefback(cpu_env, t0);
8907 break;
8908 default:
8909 gen_mtc0(ctx, t0, rd, sel);
8910 break;
8911 }
8912 break;
8913 case 10:
8914 switch (sel) {
8915 case 0:
8916 gen_helper_mttc0_entryhi(cpu_env, t0);
8917 break;
8918 default:
8919 gen_mtc0(ctx, t0, rd, sel);
8920 break;
8921 }
8922 break;
8923 case 12:
8924 switch (sel) {
8925 case 0:
8926 gen_helper_mttc0_status(cpu_env, t0);
8927 break;
8928 default:
8929 gen_mtc0(ctx, t0, rd, sel);
8930 break;
8931 }
8932 break;
8933 case 13:
8934 switch (sel) {
8935 case 0:
8936 gen_helper_mttc0_cause(cpu_env, t0);
8937 break;
8938 default:
8939 goto die;
8940 break;
8941 }
8942 break;
8943 case 15:
8944 switch (sel) {
8945 case 1:
8946 gen_helper_mttc0_ebase(cpu_env, t0);
8947 break;
8948 default:
8949 goto die;
8950 break;
8951 }
8952 break;
8953 case 23:
8954 switch (sel) {
8955 case 0:
8956 gen_helper_mttc0_debug(cpu_env, t0);
8957 break;
8958 default:
8959 gen_mtc0(ctx, t0, rd, sel);
8960 break;
8961 }
8962 break;
8963 default:
8964 gen_mtc0(ctx, t0, rd, sel);
8965 }
8966 } else {
8967 switch (sel) {
8968
8969 case 0:
8970 gen_helper_0e1i(mttgpr, t0, rd);
8971 break;
8972
8973 case 1:
8974 switch (rd) {
8975 case 0:
8976 gen_helper_0e1i(mttlo, t0, 0);
8977 break;
8978 case 1:
8979 gen_helper_0e1i(mtthi, t0, 0);
8980 break;
8981 case 2:
8982 gen_helper_0e1i(mttacx, t0, 0);
8983 break;
8984 case 4:
8985 gen_helper_0e1i(mttlo, t0, 1);
8986 break;
8987 case 5:
8988 gen_helper_0e1i(mtthi, t0, 1);
8989 break;
8990 case 6:
8991 gen_helper_0e1i(mttacx, t0, 1);
8992 break;
8993 case 8:
8994 gen_helper_0e1i(mttlo, t0, 2);
8995 break;
8996 case 9:
8997 gen_helper_0e1i(mtthi, t0, 2);
8998 break;
8999 case 10:
9000 gen_helper_0e1i(mttacx, t0, 2);
9001 break;
9002 case 12:
9003 gen_helper_0e1i(mttlo, t0, 3);
9004 break;
9005 case 13:
9006 gen_helper_0e1i(mtthi, t0, 3);
9007 break;
9008 case 14:
9009 gen_helper_0e1i(mttacx, t0, 3);
9010 break;
9011 case 16:
9012 gen_helper_mttdsp(cpu_env, t0);
9013 break;
9014 default:
9015 goto die;
9016 }
9017 break;
9018
9019 case 2:
9020
9021 if (h == 0) {
9022 TCGv_i32 fp0 = tcg_temp_new_i32();
9023
9024 tcg_gen_trunc_tl_i32(fp0, t0);
9025 gen_store_fpr32(ctx, fp0, rd);
9026 tcg_temp_free_i32(fp0);
9027 } else {
9028 TCGv_i32 fp0 = tcg_temp_new_i32();
9029
9030 tcg_gen_trunc_tl_i32(fp0, t0);
9031 gen_store_fpr32h(ctx, fp0, rd);
9032 tcg_temp_free_i32(fp0);
9033 }
9034 break;
9035 case 3:
9036
9037 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
9038
9039 ctx->base.is_jmp = DISAS_STOP;
9040 break;
9041
9042 case 4:
9043 case 5:
9044
9045 default:
9046 goto die;
9047 }
9048 }
9049 trace_mips_translate_tr("mttr", rd, u, sel, h);
9050 tcg_temp_free(t0);
9051 return;
9052
9053die:
9054 tcg_temp_free(t0);
9055 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9056 gen_reserved_instruction(ctx);
9057}
9058
9059static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9060 int rt, int rd)
9061{
9062 const char *opn = "ldst";
9063
9064 check_cp0_enabled(ctx);
9065 switch (opc) {
9066 case OPC_MFC0:
9067 if (rt == 0) {
9068
9069 return;
9070 }
9071 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9072 opn = "mfc0";
9073 break;
9074 case OPC_MTC0:
9075 {
9076 TCGv t0 = tcg_temp_new();
9077
9078 gen_load_gpr(t0, rt);
9079 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9080 tcg_temp_free(t0);
9081 }
9082 opn = "mtc0";
9083 break;
9084#if defined(TARGET_MIPS64)
9085 case OPC_DMFC0:
9086 check_insn(ctx, ISA_MIPS3);
9087 if (rt == 0) {
9088
9089 return;
9090 }
9091 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9092 opn = "dmfc0";
9093 break;
9094 case OPC_DMTC0:
9095 check_insn(ctx, ISA_MIPS3);
9096 {
9097 TCGv t0 = tcg_temp_new();
9098
9099 gen_load_gpr(t0, rt);
9100 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9101 tcg_temp_free(t0);
9102 }
9103 opn = "dmtc0";
9104 break;
9105#endif
9106 case OPC_MFHC0:
9107 check_mvh(ctx);
9108 if (rt == 0) {
9109
9110 return;
9111 }
9112 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9113 opn = "mfhc0";
9114 break;
9115 case OPC_MTHC0:
9116 check_mvh(ctx);
9117 {
9118 TCGv t0 = tcg_temp_new();
9119 gen_load_gpr(t0, rt);
9120 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9121 tcg_temp_free(t0);
9122 }
9123 opn = "mthc0";
9124 break;
9125 case OPC_MFTR:
9126 check_cp0_enabled(ctx);
9127 if (rd == 0) {
9128
9129 return;
9130 }
9131 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9132 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9133 opn = "mftr";
9134 break;
9135 case OPC_MTTR:
9136 check_cp0_enabled(ctx);
9137 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9138 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9139 opn = "mttr";
9140 break;
9141 case OPC_TLBWI:
9142 opn = "tlbwi";
9143 if (!env->tlb->helper_tlbwi) {
9144 goto die;
9145 }
9146 gen_helper_tlbwi(cpu_env);
9147 break;
9148 case OPC_TLBINV:
9149 opn = "tlbinv";
9150 if (ctx->ie >= 2) {
9151 if (!env->tlb->helper_tlbinv) {
9152 goto die;
9153 }
9154 gen_helper_tlbinv(cpu_env);
9155 }
9156 break;
9157 case OPC_TLBINVF:
9158 opn = "tlbinvf";
9159 if (ctx->ie >= 2) {
9160 if (!env->tlb->helper_tlbinvf) {
9161 goto die;
9162 }
9163 gen_helper_tlbinvf(cpu_env);
9164 }
9165 break;
9166 case OPC_TLBWR:
9167 opn = "tlbwr";
9168 if (!env->tlb->helper_tlbwr) {
9169 goto die;
9170 }
9171 gen_helper_tlbwr(cpu_env);
9172 break;
9173 case OPC_TLBP:
9174 opn = "tlbp";
9175 if (!env->tlb->helper_tlbp) {
9176 goto die;
9177 }
9178 gen_helper_tlbp(cpu_env);
9179 break;
9180 case OPC_TLBR:
9181 opn = "tlbr";
9182 if (!env->tlb->helper_tlbr) {
9183 goto die;
9184 }
9185 gen_helper_tlbr(cpu_env);
9186 break;
9187 case OPC_ERET:
9188 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9189 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9190 goto die;
9191 } else {
9192 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9193 if (ctx->opcode & (1 << bit_shift)) {
9194
9195 opn = "eretnc";
9196 check_insn(ctx, ISA_MIPS_R5);
9197 gen_helper_eretnc(cpu_env);
9198 } else {
9199
9200 opn = "eret";
9201 check_insn(ctx, ISA_MIPS2);
9202 gen_helper_eret(cpu_env);
9203 }
9204 ctx->base.is_jmp = DISAS_EXIT;
9205 }
9206 break;
9207 case OPC_DERET:
9208 opn = "deret";
9209 check_insn(ctx, ISA_MIPS_R1);
9210 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9211 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9212 goto die;
9213 }
9214 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9215 MIPS_INVAL(opn);
9216 gen_reserved_instruction(ctx);
9217 } else {
9218 gen_helper_deret(cpu_env);
9219 ctx->base.is_jmp = DISAS_EXIT;
9220 }
9221 break;
9222 case OPC_WAIT:
9223 opn = "wait";
9224 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9225 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9226 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9227 goto die;
9228 }
9229
9230 ctx->base.pc_next += 4;
9231 save_cpu_state(ctx, 1);
9232 ctx->base.pc_next -= 4;
9233 gen_helper_wait(cpu_env);
9234 ctx->base.is_jmp = DISAS_NORETURN;
9235 break;
9236 default:
9237 die:
9238 MIPS_INVAL(opn);
9239 gen_reserved_instruction(ctx);
9240 return;
9241 }
9242 (void)opn;
9243}
9244#endif
9245
9246
9247static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9248 int32_t cc, int32_t offset)
9249{
9250 target_ulong btarget;
9251 TCGv_i32 t0 = tcg_temp_new_i32();
9252
9253 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9254 gen_reserved_instruction(ctx);
9255 goto out;
9256 }
9257
9258 if (cc != 0) {
9259 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9260 }
9261
9262 btarget = ctx->base.pc_next + 4 + offset;
9263
9264 switch (op) {
9265 case OPC_BC1F:
9266 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9267 tcg_gen_not_i32(t0, t0);
9268 tcg_gen_andi_i32(t0, t0, 1);
9269 tcg_gen_extu_i32_tl(bcond, t0);
9270 goto not_likely;
9271 case OPC_BC1FL:
9272 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9273 tcg_gen_not_i32(t0, t0);
9274 tcg_gen_andi_i32(t0, t0, 1);
9275 tcg_gen_extu_i32_tl(bcond, t0);
9276 goto likely;
9277 case OPC_BC1T:
9278 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9279 tcg_gen_andi_i32(t0, t0, 1);
9280 tcg_gen_extu_i32_tl(bcond, t0);
9281 goto not_likely;
9282 case OPC_BC1TL:
9283 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9284 tcg_gen_andi_i32(t0, t0, 1);
9285 tcg_gen_extu_i32_tl(bcond, t0);
9286 likely:
9287 ctx->hflags |= MIPS_HFLAG_BL;
9288 break;
9289 case OPC_BC1FANY2:
9290 {
9291 TCGv_i32 t1 = tcg_temp_new_i32();
9292 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9293 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9294 tcg_gen_nand_i32(t0, t0, t1);
9295 tcg_temp_free_i32(t1);
9296 tcg_gen_andi_i32(t0, t0, 1);
9297 tcg_gen_extu_i32_tl(bcond, t0);
9298 }
9299 goto not_likely;
9300 case OPC_BC1TANY2:
9301 {
9302 TCGv_i32 t1 = tcg_temp_new_i32();
9303 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9304 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9305 tcg_gen_or_i32(t0, t0, t1);
9306 tcg_temp_free_i32(t1);
9307 tcg_gen_andi_i32(t0, t0, 1);
9308 tcg_gen_extu_i32_tl(bcond, t0);
9309 }
9310 goto not_likely;
9311 case OPC_BC1FANY4:
9312 {
9313 TCGv_i32 t1 = tcg_temp_new_i32();
9314 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9315 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9316 tcg_gen_and_i32(t0, t0, t1);
9317 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9318 tcg_gen_and_i32(t0, t0, t1);
9319 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9320 tcg_gen_nand_i32(t0, t0, t1);
9321 tcg_temp_free_i32(t1);
9322 tcg_gen_andi_i32(t0, t0, 1);
9323 tcg_gen_extu_i32_tl(bcond, t0);
9324 }
9325 goto not_likely;
9326 case OPC_BC1TANY4:
9327 {
9328 TCGv_i32 t1 = tcg_temp_new_i32();
9329 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9330 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9331 tcg_gen_or_i32(t0, t0, t1);
9332 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9333 tcg_gen_or_i32(t0, t0, t1);
9334 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9335 tcg_gen_or_i32(t0, t0, t1);
9336 tcg_temp_free_i32(t1);
9337 tcg_gen_andi_i32(t0, t0, 1);
9338 tcg_gen_extu_i32_tl(bcond, t0);
9339 }
9340 not_likely:
9341 ctx->hflags |= MIPS_HFLAG_BC;
9342 break;
9343 default:
9344 MIPS_INVAL("cp1 cond branch");
9345 gen_reserved_instruction(ctx);
9346 goto out;
9347 }
9348 ctx->btarget = btarget;
9349 ctx->hflags |= MIPS_HFLAG_BDS32;
9350 out:
9351 tcg_temp_free_i32(t0);
9352}
9353
9354
9355static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9356 int32_t ft, int32_t offset,
9357 int delayslot_size)
9358{
9359 target_ulong btarget;
9360 TCGv_i64 t0 = tcg_temp_new_i64();
9361
9362 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9363#ifdef MIPS_DEBUG_DISAS
9364 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9365 "\n", ctx->base.pc_next);
9366#endif
9367 gen_reserved_instruction(ctx);
9368 goto out;
9369 }
9370
9371 gen_load_fpr64(ctx, t0, ft);
9372 tcg_gen_andi_i64(t0, t0, 1);
9373
9374 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9375
9376 switch (op) {
9377 case OPC_BC1EQZ:
9378 tcg_gen_xori_i64(t0, t0, 1);
9379 ctx->hflags |= MIPS_HFLAG_BC;
9380 break;
9381 case OPC_BC1NEZ:
9382
9383 ctx->hflags |= MIPS_HFLAG_BC;
9384 break;
9385 default:
9386 MIPS_INVAL("cp1 cond branch");
9387 gen_reserved_instruction(ctx);
9388 goto out;
9389 }
9390
9391 tcg_gen_trunc_i64_tl(bcond, t0);
9392
9393 ctx->btarget = btarget;
9394
9395 switch (delayslot_size) {
9396 case 2:
9397 ctx->hflags |= MIPS_HFLAG_BDS16;
9398 break;
9399 case 4:
9400 ctx->hflags |= MIPS_HFLAG_BDS32;
9401 break;
9402 }
9403
9404out:
9405 tcg_temp_free_i64(t0);
9406}
9407
9408
9409
9410#define FOP(func, fmt) (((fmt) << 21) | (func))
9411
9412enum fopcode {
9413 OPC_ADD_S = FOP(0, FMT_S),
9414 OPC_SUB_S = FOP(1, FMT_S),
9415 OPC_MUL_S = FOP(2, FMT_S),
9416 OPC_DIV_S = FOP(3, FMT_S),
9417 OPC_SQRT_S = FOP(4, FMT_S),
9418 OPC_ABS_S = FOP(5, FMT_S),
9419 OPC_MOV_S = FOP(6, FMT_S),
9420 OPC_NEG_S = FOP(7, FMT_S),
9421 OPC_ROUND_L_S = FOP(8, FMT_S),
9422 OPC_TRUNC_L_S = FOP(9, FMT_S),
9423 OPC_CEIL_L_S = FOP(10, FMT_S),
9424 OPC_FLOOR_L_S = FOP(11, FMT_S),
9425 OPC_ROUND_W_S = FOP(12, FMT_S),
9426 OPC_TRUNC_W_S = FOP(13, FMT_S),
9427 OPC_CEIL_W_S = FOP(14, FMT_S),
9428 OPC_FLOOR_W_S = FOP(15, FMT_S),
9429 OPC_SEL_S = FOP(16, FMT_S),
9430 OPC_MOVCF_S = FOP(17, FMT_S),
9431 OPC_MOVZ_S = FOP(18, FMT_S),
9432 OPC_MOVN_S = FOP(19, FMT_S),
9433 OPC_SELEQZ_S = FOP(20, FMT_S),
9434 OPC_RECIP_S = FOP(21, FMT_S),
9435 OPC_RSQRT_S = FOP(22, FMT_S),
9436 OPC_SELNEZ_S = FOP(23, FMT_S),
9437 OPC_MADDF_S = FOP(24, FMT_S),
9438 OPC_MSUBF_S = FOP(25, FMT_S),
9439 OPC_RINT_S = FOP(26, FMT_S),
9440 OPC_CLASS_S = FOP(27, FMT_S),
9441 OPC_MIN_S = FOP(28, FMT_S),
9442 OPC_RECIP2_S = FOP(28, FMT_S),
9443 OPC_MINA_S = FOP(29, FMT_S),
9444 OPC_RECIP1_S = FOP(29, FMT_S),
9445 OPC_MAX_S = FOP(30, FMT_S),
9446 OPC_RSQRT1_S = FOP(30, FMT_S),
9447 OPC_MAXA_S = FOP(31, FMT_S),
9448 OPC_RSQRT2_S = FOP(31, FMT_S),
9449 OPC_CVT_D_S = FOP(33, FMT_S),
9450 OPC_CVT_W_S = FOP(36, FMT_S),
9451 OPC_CVT_L_S = FOP(37, FMT_S),
9452 OPC_CVT_PS_S = FOP(38, FMT_S),
9453 OPC_CMP_F_S = FOP(48, FMT_S),
9454 OPC_CMP_UN_S = FOP(49, FMT_S),
9455 OPC_CMP_EQ_S = FOP(50, FMT_S),
9456 OPC_CMP_UEQ_S = FOP(51, FMT_S),
9457 OPC_CMP_OLT_S = FOP(52, FMT_S),
9458 OPC_CMP_ULT_S = FOP(53, FMT_S),
9459 OPC_CMP_OLE_S = FOP(54, FMT_S),
9460 OPC_CMP_ULE_S = FOP(55, FMT_S),
9461 OPC_CMP_SF_S = FOP(56, FMT_S),
9462 OPC_CMP_NGLE_S = FOP(57, FMT_S),
9463 OPC_CMP_SEQ_S = FOP(58, FMT_S),
9464 OPC_CMP_NGL_S = FOP(59, FMT_S),
9465 OPC_CMP_LT_S = FOP(60, FMT_S),
9466 OPC_CMP_NGE_S = FOP(61, FMT_S),
9467 OPC_CMP_LE_S = FOP(62, FMT_S),
9468 OPC_CMP_NGT_S = FOP(63, FMT_S),
9469
9470 OPC_ADD_D = FOP(0, FMT_D),
9471 OPC_SUB_D = FOP(1, FMT_D),
9472 OPC_MUL_D = FOP(2, FMT_D),
9473 OPC_DIV_D = FOP(3, FMT_D),
9474 OPC_SQRT_D = FOP(4, FMT_D),
9475 OPC_ABS_D = FOP(5, FMT_D),
9476 OPC_MOV_D = FOP(6, FMT_D),
9477 OPC_NEG_D = FOP(7, FMT_D),
9478 OPC_ROUND_L_D = FOP(8, FMT_D),
9479 OPC_TRUNC_L_D = FOP(9, FMT_D),
9480 OPC_CEIL_L_D = FOP(10, FMT_D),
9481 OPC_FLOOR_L_D = FOP(11, FMT_D),
9482 OPC_ROUND_W_D = FOP(12, FMT_D),
9483 OPC_TRUNC_W_D = FOP(13, FMT_D),
9484 OPC_CEIL_W_D = FOP(14, FMT_D),
9485 OPC_FLOOR_W_D = FOP(15, FMT_D),
9486 OPC_SEL_D = FOP(16, FMT_D),
9487 OPC_MOVCF_D = FOP(17, FMT_D),
9488 OPC_MOVZ_D = FOP(18, FMT_D),
9489 OPC_MOVN_D = FOP(19, FMT_D),
9490 OPC_SELEQZ_D = FOP(20, FMT_D),
9491 OPC_RECIP_D = FOP(21, FMT_D),
9492 OPC_RSQRT_D = FOP(22, FMT_D),
9493 OPC_SELNEZ_D = FOP(23, FMT_D),
9494 OPC_MADDF_D = FOP(24, FMT_D),
9495 OPC_MSUBF_D = FOP(25, FMT_D),
9496 OPC_RINT_D = FOP(26, FMT_D),
9497 OPC_CLASS_D = FOP(27, FMT_D),
9498 OPC_MIN_D = FOP(28, FMT_D),
9499 OPC_RECIP2_D = FOP(28, FMT_D),
9500 OPC_MINA_D = FOP(29, FMT_D),
9501 OPC_RECIP1_D = FOP(29, FMT_D),
9502 OPC_MAX_D = FOP(30, FMT_D),
9503 OPC_RSQRT1_D = FOP(30, FMT_D),
9504 OPC_MAXA_D = FOP(31, FMT_D),
9505 OPC_RSQRT2_D = FOP(31, FMT_D),
9506 OPC_CVT_S_D = FOP(32, FMT_D),
9507 OPC_CVT_W_D = FOP(36, FMT_D),
9508 OPC_CVT_L_D = FOP(37, FMT_D),
9509 OPC_CMP_F_D = FOP(48, FMT_D),
9510 OPC_CMP_UN_D = FOP(49, FMT_D),
9511 OPC_CMP_EQ_D = FOP(50, FMT_D),
9512 OPC_CMP_UEQ_D = FOP(51, FMT_D),
9513 OPC_CMP_OLT_D = FOP(52, FMT_D),
9514 OPC_CMP_ULT_D = FOP(53, FMT_D),
9515 OPC_CMP_OLE_D = FOP(54, FMT_D),
9516 OPC_CMP_ULE_D = FOP(55, FMT_D),
9517 OPC_CMP_SF_D = FOP(56, FMT_D),
9518 OPC_CMP_NGLE_D = FOP(57, FMT_D),
9519 OPC_CMP_SEQ_D = FOP(58, FMT_D),
9520 OPC_CMP_NGL_D = FOP(59, FMT_D),
9521 OPC_CMP_LT_D = FOP(60, FMT_D),
9522 OPC_CMP_NGE_D = FOP(61, FMT_D),
9523 OPC_CMP_LE_D = FOP(62, FMT_D),
9524 OPC_CMP_NGT_D = FOP(63, FMT_D),
9525
9526 OPC_CVT_S_W = FOP(32, FMT_W),
9527 OPC_CVT_D_W = FOP(33, FMT_W),
9528 OPC_CVT_S_L = FOP(32, FMT_L),
9529 OPC_CVT_D_L = FOP(33, FMT_L),
9530 OPC_CVT_PS_PW = FOP(38, FMT_W),
9531
9532 OPC_ADD_PS = FOP(0, FMT_PS),
9533 OPC_SUB_PS = FOP(1, FMT_PS),
9534 OPC_MUL_PS = FOP(2, FMT_PS),
9535 OPC_DIV_PS = FOP(3, FMT_PS),
9536 OPC_ABS_PS = FOP(5, FMT_PS),
9537 OPC_MOV_PS = FOP(6, FMT_PS),
9538 OPC_NEG_PS = FOP(7, FMT_PS),
9539 OPC_MOVCF_PS = FOP(17, FMT_PS),
9540 OPC_MOVZ_PS = FOP(18, FMT_PS),
9541 OPC_MOVN_PS = FOP(19, FMT_PS),
9542 OPC_ADDR_PS = FOP(24, FMT_PS),
9543 OPC_MULR_PS = FOP(26, FMT_PS),
9544 OPC_RECIP2_PS = FOP(28, FMT_PS),
9545 OPC_RECIP1_PS = FOP(29, FMT_PS),
9546 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9547 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9548
9549 OPC_CVT_S_PU = FOP(32, FMT_PS),
9550 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9551 OPC_CVT_S_PL = FOP(40, FMT_PS),
9552 OPC_PLL_PS = FOP(44, FMT_PS),
9553 OPC_PLU_PS = FOP(45, FMT_PS),
9554 OPC_PUL_PS = FOP(46, FMT_PS),
9555 OPC_PUU_PS = FOP(47, FMT_PS),
9556 OPC_CMP_F_PS = FOP(48, FMT_PS),
9557 OPC_CMP_UN_PS = FOP(49, FMT_PS),
9558 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9559 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9560 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9561 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9562 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9563 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9564 OPC_CMP_SF_PS = FOP(56, FMT_PS),
9565 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9566 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9567 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9568 OPC_CMP_LT_PS = FOP(60, FMT_PS),
9569 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9570 OPC_CMP_LE_PS = FOP(62, FMT_PS),
9571 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9572};
9573
9574enum r6_f_cmp_op {
9575 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9576 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9577 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9578 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9579 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9580 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9581 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9582 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9583 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9584 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9585 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9586 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9587 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9588 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9589 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9590 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9591 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9592 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9593 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9594 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9595 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9596 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9597
9598 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9599 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9600 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9601 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9602 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9603 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9604 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9605 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9606 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9607 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9608 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9609 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9610 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9611 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9612 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9613 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9614 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9615 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9616 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9617 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9618 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9619 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9620};
9621
9622static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9623{
9624 TCGv t0 = tcg_temp_new();
9625
9626 switch (opc) {
9627 case OPC_MFC1:
9628 {
9629 TCGv_i32 fp0 = tcg_temp_new_i32();
9630
9631 gen_load_fpr32(ctx, fp0, fs);
9632 tcg_gen_ext_i32_tl(t0, fp0);
9633 tcg_temp_free_i32(fp0);
9634 }
9635 gen_store_gpr(t0, rt);
9636 break;
9637 case OPC_MTC1:
9638 gen_load_gpr(t0, rt);
9639 {
9640 TCGv_i32 fp0 = tcg_temp_new_i32();
9641
9642 tcg_gen_trunc_tl_i32(fp0, t0);
9643 gen_store_fpr32(ctx, fp0, fs);
9644 tcg_temp_free_i32(fp0);
9645 }
9646 break;
9647 case OPC_CFC1:
9648 gen_helper_1e0i(cfc1, t0, fs);
9649 gen_store_gpr(t0, rt);
9650 break;
9651 case OPC_CTC1:
9652 gen_load_gpr(t0, rt);
9653 save_cpu_state(ctx, 0);
9654 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9655
9656 ctx->base.is_jmp = DISAS_STOP;
9657 break;
9658#if defined(TARGET_MIPS64)
9659 case OPC_DMFC1:
9660 gen_load_fpr64(ctx, t0, fs);
9661 gen_store_gpr(t0, rt);
9662 break;
9663 case OPC_DMTC1:
9664 gen_load_gpr(t0, rt);
9665 gen_store_fpr64(ctx, t0, fs);
9666 break;
9667#endif
9668 case OPC_MFHC1:
9669 {
9670 TCGv_i32 fp0 = tcg_temp_new_i32();
9671
9672 gen_load_fpr32h(ctx, fp0, fs);
9673 tcg_gen_ext_i32_tl(t0, fp0);
9674 tcg_temp_free_i32(fp0);
9675 }
9676 gen_store_gpr(t0, rt);
9677 break;
9678 case OPC_MTHC1:
9679 gen_load_gpr(t0, rt);
9680 {
9681 TCGv_i32 fp0 = tcg_temp_new_i32();
9682
9683 tcg_gen_trunc_tl_i32(fp0, t0);
9684 gen_store_fpr32h(ctx, fp0, fs);
9685 tcg_temp_free_i32(fp0);
9686 }
9687 break;
9688 default:
9689 MIPS_INVAL("cp1 move");
9690 gen_reserved_instruction(ctx);
9691 goto out;
9692 }
9693
9694 out:
9695 tcg_temp_free(t0);
9696}
9697
9698static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9699{
9700 TCGLabel *l1;
9701 TCGCond cond;
9702 TCGv_i32 t0;
9703
9704 if (rd == 0) {
9705
9706 return;
9707 }
9708
9709 if (tf) {
9710 cond = TCG_COND_EQ;
9711 } else {
9712 cond = TCG_COND_NE;
9713 }
9714
9715 l1 = gen_new_label();
9716 t0 = tcg_temp_new_i32();
9717 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9718 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9719 tcg_temp_free_i32(t0);
9720 gen_load_gpr(cpu_gpr[rd], rs);
9721 gen_set_label(l1);
9722}
9723
9724static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9725 int tf)
9726{
9727 int cond;
9728 TCGv_i32 t0 = tcg_temp_new_i32();
9729 TCGLabel *l1 = gen_new_label();
9730
9731 if (tf) {
9732 cond = TCG_COND_EQ;
9733 } else {
9734 cond = TCG_COND_NE;
9735 }
9736
9737 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9738 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9739 gen_load_fpr32(ctx, t0, fs);
9740 gen_store_fpr32(ctx, t0, fd);
9741 gen_set_label(l1);
9742 tcg_temp_free_i32(t0);
9743}
9744
9745static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9746 int tf)
9747{
9748 int cond;
9749 TCGv_i32 t0 = tcg_temp_new_i32();
9750 TCGv_i64 fp0;
9751 TCGLabel *l1 = gen_new_label();
9752
9753 if (tf) {
9754 cond = TCG_COND_EQ;
9755 } else {
9756 cond = TCG_COND_NE;
9757 }
9758
9759 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9760 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9761 tcg_temp_free_i32(t0);
9762 fp0 = tcg_temp_new_i64();
9763 gen_load_fpr64(ctx, fp0, fs);
9764 gen_store_fpr64(ctx, fp0, fd);
9765 tcg_temp_free_i64(fp0);
9766 gen_set_label(l1);
9767}
9768
9769static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9770 int cc, int tf)
9771{
9772 int cond;
9773 TCGv_i32 t0 = tcg_temp_new_i32();
9774 TCGLabel *l1 = gen_new_label();
9775 TCGLabel *l2 = 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 gen_load_fpr32(ctx, t0, fs);
9786 gen_store_fpr32(ctx, t0, fd);
9787 gen_set_label(l1);
9788
9789 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9790 tcg_gen_brcondi_i32(cond, t0, 0, l2);
9791 gen_load_fpr32h(ctx, t0, fs);
9792 gen_store_fpr32h(ctx, t0, fd);
9793 tcg_temp_free_i32(t0);
9794 gen_set_label(l2);
9795}
9796
9797static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9798 int fs)
9799{
9800 TCGv_i32 t1 = tcg_const_i32(0);
9801 TCGv_i32 fp0 = tcg_temp_new_i32();
9802 TCGv_i32 fp1 = tcg_temp_new_i32();
9803 TCGv_i32 fp2 = tcg_temp_new_i32();
9804 gen_load_fpr32(ctx, fp0, fd);
9805 gen_load_fpr32(ctx, fp1, ft);
9806 gen_load_fpr32(ctx, fp2, fs);
9807
9808 switch (op1) {
9809 case OPC_SEL_S:
9810 tcg_gen_andi_i32(fp0, fp0, 1);
9811 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9812 break;
9813 case OPC_SELEQZ_S:
9814 tcg_gen_andi_i32(fp1, fp1, 1);
9815 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9816 break;
9817 case OPC_SELNEZ_S:
9818 tcg_gen_andi_i32(fp1, fp1, 1);
9819 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9820 break;
9821 default:
9822 MIPS_INVAL("gen_sel_s");
9823 gen_reserved_instruction(ctx);
9824 break;
9825 }
9826
9827 gen_store_fpr32(ctx, fp0, fd);
9828 tcg_temp_free_i32(fp2);
9829 tcg_temp_free_i32(fp1);
9830 tcg_temp_free_i32(fp0);
9831 tcg_temp_free_i32(t1);
9832}
9833
9834static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9835 int fs)
9836{
9837 TCGv_i64 t1 = tcg_const_i64(0);
9838 TCGv_i64 fp0 = tcg_temp_new_i64();
9839 TCGv_i64 fp1 = tcg_temp_new_i64();
9840 TCGv_i64 fp2 = tcg_temp_new_i64();
9841 gen_load_fpr64(ctx, fp0, fd);
9842 gen_load_fpr64(ctx, fp1, ft);
9843 gen_load_fpr64(ctx, fp2, fs);
9844
9845 switch (op1) {
9846 case OPC_SEL_D:
9847 tcg_gen_andi_i64(fp0, fp0, 1);
9848 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9849 break;
9850 case OPC_SELEQZ_D:
9851 tcg_gen_andi_i64(fp1, fp1, 1);
9852 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9853 break;
9854 case OPC_SELNEZ_D:
9855 tcg_gen_andi_i64(fp1, fp1, 1);
9856 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9857 break;
9858 default:
9859 MIPS_INVAL("gen_sel_d");
9860 gen_reserved_instruction(ctx);
9861 break;
9862 }
9863
9864 gen_store_fpr64(ctx, fp0, fd);
9865 tcg_temp_free_i64(fp2);
9866 tcg_temp_free_i64(fp1);
9867 tcg_temp_free_i64(fp0);
9868 tcg_temp_free_i64(t1);
9869}
9870
9871static void gen_farith(DisasContext *ctx, enum fopcode op1,
9872 int ft, int fs, int fd, int cc)
9873{
9874 uint32_t func = ctx->opcode & 0x3f;
9875 switch (op1) {
9876 case OPC_ADD_S:
9877 {
9878 TCGv_i32 fp0 = tcg_temp_new_i32();
9879 TCGv_i32 fp1 = tcg_temp_new_i32();
9880
9881 gen_load_fpr32(ctx, fp0, fs);
9882 gen_load_fpr32(ctx, fp1, ft);
9883 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9884 tcg_temp_free_i32(fp1);
9885 gen_store_fpr32(ctx, fp0, fd);
9886 tcg_temp_free_i32(fp0);
9887 }
9888 break;
9889 case OPC_SUB_S:
9890 {
9891 TCGv_i32 fp0 = tcg_temp_new_i32();
9892 TCGv_i32 fp1 = tcg_temp_new_i32();
9893
9894 gen_load_fpr32(ctx, fp0, fs);
9895 gen_load_fpr32(ctx, fp1, ft);
9896 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9897 tcg_temp_free_i32(fp1);
9898 gen_store_fpr32(ctx, fp0, fd);
9899 tcg_temp_free_i32(fp0);
9900 }
9901 break;
9902 case OPC_MUL_S:
9903 {
9904 TCGv_i32 fp0 = tcg_temp_new_i32();
9905 TCGv_i32 fp1 = tcg_temp_new_i32();
9906
9907 gen_load_fpr32(ctx, fp0, fs);
9908 gen_load_fpr32(ctx, fp1, ft);
9909 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9910 tcg_temp_free_i32(fp1);
9911 gen_store_fpr32(ctx, fp0, fd);
9912 tcg_temp_free_i32(fp0);
9913 }
9914 break;
9915 case OPC_DIV_S:
9916 {
9917 TCGv_i32 fp0 = tcg_temp_new_i32();
9918 TCGv_i32 fp1 = tcg_temp_new_i32();
9919
9920 gen_load_fpr32(ctx, fp0, fs);
9921 gen_load_fpr32(ctx, fp1, ft);
9922 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9923 tcg_temp_free_i32(fp1);
9924 gen_store_fpr32(ctx, fp0, fd);
9925 tcg_temp_free_i32(fp0);
9926 }
9927 break;
9928 case OPC_SQRT_S:
9929 {
9930 TCGv_i32 fp0 = tcg_temp_new_i32();
9931
9932 gen_load_fpr32(ctx, fp0, fs);
9933 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9934 gen_store_fpr32(ctx, fp0, fd);
9935 tcg_temp_free_i32(fp0);
9936 }
9937 break;
9938 case OPC_ABS_S:
9939 {
9940 TCGv_i32 fp0 = tcg_temp_new_i32();
9941
9942 gen_load_fpr32(ctx, fp0, fs);
9943 if (ctx->abs2008) {
9944 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9945 } else {
9946 gen_helper_float_abs_s(fp0, fp0);
9947 }
9948 gen_store_fpr32(ctx, fp0, fd);
9949 tcg_temp_free_i32(fp0);
9950 }
9951 break;
9952 case OPC_MOV_S:
9953 {
9954 TCGv_i32 fp0 = tcg_temp_new_i32();
9955
9956 gen_load_fpr32(ctx, fp0, fs);
9957 gen_store_fpr32(ctx, fp0, fd);
9958 tcg_temp_free_i32(fp0);
9959 }
9960 break;
9961 case OPC_NEG_S:
9962 {
9963 TCGv_i32 fp0 = tcg_temp_new_i32();
9964
9965 gen_load_fpr32(ctx, fp0, fs);
9966 if (ctx->abs2008) {
9967 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9968 } else {
9969 gen_helper_float_chs_s(fp0, fp0);
9970 }
9971 gen_store_fpr32(ctx, fp0, fd);
9972 tcg_temp_free_i32(fp0);
9973 }
9974 break;
9975 case OPC_ROUND_L_S:
9976 check_cp1_64bitmode(ctx);
9977 {
9978 TCGv_i32 fp32 = tcg_temp_new_i32();
9979 TCGv_i64 fp64 = tcg_temp_new_i64();
9980
9981 gen_load_fpr32(ctx, fp32, fs);
9982 if (ctx->nan2008) {
9983 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9984 } else {
9985 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9986 }
9987 tcg_temp_free_i32(fp32);
9988 gen_store_fpr64(ctx, fp64, fd);
9989 tcg_temp_free_i64(fp64);
9990 }
9991 break;
9992 case OPC_TRUNC_L_S:
9993 check_cp1_64bitmode(ctx);
9994 {
9995 TCGv_i32 fp32 = tcg_temp_new_i32();
9996 TCGv_i64 fp64 = tcg_temp_new_i64();
9997
9998 gen_load_fpr32(ctx, fp32, fs);
9999 if (ctx->nan2008) {
10000 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10001 } else {
10002 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10003 }
10004 tcg_temp_free_i32(fp32);
10005 gen_store_fpr64(ctx, fp64, fd);
10006 tcg_temp_free_i64(fp64);
10007 }
10008 break;
10009 case OPC_CEIL_L_S:
10010 check_cp1_64bitmode(ctx);
10011 {
10012 TCGv_i32 fp32 = tcg_temp_new_i32();
10013 TCGv_i64 fp64 = tcg_temp_new_i64();
10014
10015 gen_load_fpr32(ctx, fp32, fs);
10016 if (ctx->nan2008) {
10017 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10018 } else {
10019 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10020 }
10021 tcg_temp_free_i32(fp32);
10022 gen_store_fpr64(ctx, fp64, fd);
10023 tcg_temp_free_i64(fp64);
10024 }
10025 break;
10026 case OPC_FLOOR_L_S:
10027 check_cp1_64bitmode(ctx);
10028 {
10029 TCGv_i32 fp32 = tcg_temp_new_i32();
10030 TCGv_i64 fp64 = tcg_temp_new_i64();
10031
10032 gen_load_fpr32(ctx, fp32, fs);
10033 if (ctx->nan2008) {
10034 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10035 } else {
10036 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10037 }
10038 tcg_temp_free_i32(fp32);
10039 gen_store_fpr64(ctx, fp64, fd);
10040 tcg_temp_free_i64(fp64);
10041 }
10042 break;
10043 case OPC_ROUND_W_S:
10044 {
10045 TCGv_i32 fp0 = tcg_temp_new_i32();
10046
10047 gen_load_fpr32(ctx, fp0, fs);
10048 if (ctx->nan2008) {
10049 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10050 } else {
10051 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10052 }
10053 gen_store_fpr32(ctx, fp0, fd);
10054 tcg_temp_free_i32(fp0);
10055 }
10056 break;
10057 case OPC_TRUNC_W_S:
10058 {
10059 TCGv_i32 fp0 = tcg_temp_new_i32();
10060
10061 gen_load_fpr32(ctx, fp0, fs);
10062 if (ctx->nan2008) {
10063 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10064 } else {
10065 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10066 }
10067 gen_store_fpr32(ctx, fp0, fd);
10068 tcg_temp_free_i32(fp0);
10069 }
10070 break;
10071 case OPC_CEIL_W_S:
10072 {
10073 TCGv_i32 fp0 = tcg_temp_new_i32();
10074
10075 gen_load_fpr32(ctx, fp0, fs);
10076 if (ctx->nan2008) {
10077 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10078 } else {
10079 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10080 }
10081 gen_store_fpr32(ctx, fp0, fd);
10082 tcg_temp_free_i32(fp0);
10083 }
10084 break;
10085 case OPC_FLOOR_W_S:
10086 {
10087 TCGv_i32 fp0 = tcg_temp_new_i32();
10088
10089 gen_load_fpr32(ctx, fp0, fs);
10090 if (ctx->nan2008) {
10091 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10092 } else {
10093 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10094 }
10095 gen_store_fpr32(ctx, fp0, fd);
10096 tcg_temp_free_i32(fp0);
10097 }
10098 break;
10099 case OPC_SEL_S:
10100 check_insn(ctx, ISA_MIPS_R6);
10101 gen_sel_s(ctx, op1, fd, ft, fs);
10102 break;
10103 case OPC_SELEQZ_S:
10104 check_insn(ctx, ISA_MIPS_R6);
10105 gen_sel_s(ctx, op1, fd, ft, fs);
10106 break;
10107 case OPC_SELNEZ_S:
10108 check_insn(ctx, ISA_MIPS_R6);
10109 gen_sel_s(ctx, op1, fd, ft, fs);
10110 break;
10111 case OPC_MOVCF_S:
10112 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10113 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10114 break;
10115 case OPC_MOVZ_S:
10116 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10117 {
10118 TCGLabel *l1 = gen_new_label();
10119 TCGv_i32 fp0;
10120
10121 if (ft != 0) {
10122 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10123 }
10124 fp0 = tcg_temp_new_i32();
10125 gen_load_fpr32(ctx, fp0, fs);
10126 gen_store_fpr32(ctx, fp0, fd);
10127 tcg_temp_free_i32(fp0);
10128 gen_set_label(l1);
10129 }
10130 break;
10131 case OPC_MOVN_S:
10132 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10133 {
10134 TCGLabel *l1 = gen_new_label();
10135 TCGv_i32 fp0;
10136
10137 if (ft != 0) {
10138 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10139 fp0 = tcg_temp_new_i32();
10140 gen_load_fpr32(ctx, fp0, fs);
10141 gen_store_fpr32(ctx, fp0, fd);
10142 tcg_temp_free_i32(fp0);
10143 gen_set_label(l1);
10144 }
10145 }
10146 break;
10147 case OPC_RECIP_S:
10148 {
10149 TCGv_i32 fp0 = tcg_temp_new_i32();
10150
10151 gen_load_fpr32(ctx, fp0, fs);
10152 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10153 gen_store_fpr32(ctx, fp0, fd);
10154 tcg_temp_free_i32(fp0);
10155 }
10156 break;
10157 case OPC_RSQRT_S:
10158 {
10159 TCGv_i32 fp0 = tcg_temp_new_i32();
10160
10161 gen_load_fpr32(ctx, fp0, fs);
10162 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10163 gen_store_fpr32(ctx, fp0, fd);
10164 tcg_temp_free_i32(fp0);
10165 }
10166 break;
10167 case OPC_MADDF_S:
10168 check_insn(ctx, ISA_MIPS_R6);
10169 {
10170 TCGv_i32 fp0 = tcg_temp_new_i32();
10171 TCGv_i32 fp1 = tcg_temp_new_i32();
10172 TCGv_i32 fp2 = tcg_temp_new_i32();
10173 gen_load_fpr32(ctx, fp0, fs);
10174 gen_load_fpr32(ctx, fp1, ft);
10175 gen_load_fpr32(ctx, fp2, fd);
10176 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10177 gen_store_fpr32(ctx, fp2, fd);
10178 tcg_temp_free_i32(fp2);
10179 tcg_temp_free_i32(fp1);
10180 tcg_temp_free_i32(fp0);
10181 }
10182 break;
10183 case OPC_MSUBF_S:
10184 check_insn(ctx, ISA_MIPS_R6);
10185 {
10186 TCGv_i32 fp0 = tcg_temp_new_i32();
10187 TCGv_i32 fp1 = tcg_temp_new_i32();
10188 TCGv_i32 fp2 = tcg_temp_new_i32();
10189 gen_load_fpr32(ctx, fp0, fs);
10190 gen_load_fpr32(ctx, fp1, ft);
10191 gen_load_fpr32(ctx, fp2, fd);
10192 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10193 gen_store_fpr32(ctx, fp2, fd);
10194 tcg_temp_free_i32(fp2);
10195 tcg_temp_free_i32(fp1);
10196 tcg_temp_free_i32(fp0);
10197 }
10198 break;
10199 case OPC_RINT_S:
10200 check_insn(ctx, ISA_MIPS_R6);
10201 {
10202 TCGv_i32 fp0 = tcg_temp_new_i32();
10203 gen_load_fpr32(ctx, fp0, fs);
10204 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10205 gen_store_fpr32(ctx, fp0, fd);
10206 tcg_temp_free_i32(fp0);
10207 }
10208 break;
10209 case OPC_CLASS_S:
10210 check_insn(ctx, ISA_MIPS_R6);
10211 {
10212 TCGv_i32 fp0 = tcg_temp_new_i32();
10213 gen_load_fpr32(ctx, fp0, fs);
10214 gen_helper_float_class_s(fp0, cpu_env, fp0);
10215 gen_store_fpr32(ctx, fp0, fd);
10216 tcg_temp_free_i32(fp0);
10217 }
10218 break;
10219 case OPC_MIN_S:
10220 if (ctx->insn_flags & ISA_MIPS_R6) {
10221
10222 TCGv_i32 fp0 = tcg_temp_new_i32();
10223 TCGv_i32 fp1 = tcg_temp_new_i32();
10224 TCGv_i32 fp2 = tcg_temp_new_i32();
10225 gen_load_fpr32(ctx, fp0, fs);
10226 gen_load_fpr32(ctx, fp1, ft);
10227 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10228 gen_store_fpr32(ctx, fp2, fd);
10229 tcg_temp_free_i32(fp2);
10230 tcg_temp_free_i32(fp1);
10231 tcg_temp_free_i32(fp0);
10232 } else {
10233
10234 check_cp1_64bitmode(ctx);
10235 {
10236 TCGv_i32 fp0 = tcg_temp_new_i32();
10237 TCGv_i32 fp1 = tcg_temp_new_i32();
10238
10239 gen_load_fpr32(ctx, fp0, fs);
10240 gen_load_fpr32(ctx, fp1, ft);
10241 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10242 tcg_temp_free_i32(fp1);
10243 gen_store_fpr32(ctx, fp0, fd);
10244 tcg_temp_free_i32(fp0);
10245 }
10246 }
10247 break;
10248 case OPC_MINA_S:
10249 if (ctx->insn_flags & ISA_MIPS_R6) {
10250
10251 TCGv_i32 fp0 = tcg_temp_new_i32();
10252 TCGv_i32 fp1 = tcg_temp_new_i32();
10253 TCGv_i32 fp2 = tcg_temp_new_i32();
10254 gen_load_fpr32(ctx, fp0, fs);
10255 gen_load_fpr32(ctx, fp1, ft);
10256 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10257 gen_store_fpr32(ctx, fp2, fd);
10258 tcg_temp_free_i32(fp2);
10259 tcg_temp_free_i32(fp1);
10260 tcg_temp_free_i32(fp0);
10261 } else {
10262
10263 check_cp1_64bitmode(ctx);
10264 {
10265 TCGv_i32 fp0 = tcg_temp_new_i32();
10266
10267 gen_load_fpr32(ctx, fp0, fs);
10268 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10269 gen_store_fpr32(ctx, fp0, fd);
10270 tcg_temp_free_i32(fp0);
10271 }
10272 }
10273 break;
10274 case OPC_MAX_S:
10275 if (ctx->insn_flags & ISA_MIPS_R6) {
10276
10277 TCGv_i32 fp0 = tcg_temp_new_i32();
10278 TCGv_i32 fp1 = tcg_temp_new_i32();
10279 gen_load_fpr32(ctx, fp0, fs);
10280 gen_load_fpr32(ctx, fp1, ft);
10281 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10282 gen_store_fpr32(ctx, fp1, fd);
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_rsqrt1_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_MAXA_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_maxa_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 TCGv_i32 fp1 = tcg_temp_new_i32();
10315
10316 gen_load_fpr32(ctx, fp0, fs);
10317 gen_load_fpr32(ctx, fp1, ft);
10318 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10319 tcg_temp_free_i32(fp1);
10320 gen_store_fpr32(ctx, fp0, fd);
10321 tcg_temp_free_i32(fp0);
10322 }
10323 }
10324 break;
10325 case OPC_CVT_D_S:
10326 check_cp1_registers(ctx, fd);
10327 {
10328 TCGv_i32 fp32 = tcg_temp_new_i32();
10329 TCGv_i64 fp64 = tcg_temp_new_i64();
10330
10331 gen_load_fpr32(ctx, fp32, fs);
10332 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10333 tcg_temp_free_i32(fp32);
10334 gen_store_fpr64(ctx, fp64, fd);
10335 tcg_temp_free_i64(fp64);
10336 }
10337 break;
10338 case OPC_CVT_W_S:
10339 {
10340 TCGv_i32 fp0 = tcg_temp_new_i32();
10341
10342 gen_load_fpr32(ctx, fp0, fs);
10343 if (ctx->nan2008) {
10344 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10345 } else {
10346 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10347 }
10348 gen_store_fpr32(ctx, fp0, fd);
10349 tcg_temp_free_i32(fp0);
10350 }
10351 break;
10352 case OPC_CVT_L_S:
10353 check_cp1_64bitmode(ctx);
10354 {
10355 TCGv_i32 fp32 = tcg_temp_new_i32();
10356 TCGv_i64 fp64 = tcg_temp_new_i64();
10357
10358 gen_load_fpr32(ctx, fp32, fs);
10359 if (ctx->nan2008) {
10360 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10361 } else {
10362 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10363 }
10364 tcg_temp_free_i32(fp32);
10365 gen_store_fpr64(ctx, fp64, fd);
10366 tcg_temp_free_i64(fp64);
10367 }
10368 break;
10369 case OPC_CVT_PS_S:
10370 check_ps(ctx);
10371 {
10372 TCGv_i64 fp64 = tcg_temp_new_i64();
10373 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10374 TCGv_i32 fp32_1 = tcg_temp_new_i32();
10375
10376 gen_load_fpr32(ctx, fp32_0, fs);
10377 gen_load_fpr32(ctx, fp32_1, ft);
10378 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10379 tcg_temp_free_i32(fp32_1);
10380 tcg_temp_free_i32(fp32_0);
10381 gen_store_fpr64(ctx, fp64, fd);
10382 tcg_temp_free_i64(fp64);
10383 }
10384 break;
10385 case OPC_CMP_F_S:
10386 case OPC_CMP_UN_S:
10387 case OPC_CMP_EQ_S:
10388 case OPC_CMP_UEQ_S:
10389 case OPC_CMP_OLT_S:
10390 case OPC_CMP_ULT_S:
10391 case OPC_CMP_OLE_S:
10392 case OPC_CMP_ULE_S:
10393 case OPC_CMP_SF_S:
10394 case OPC_CMP_NGLE_S:
10395 case OPC_CMP_SEQ_S:
10396 case OPC_CMP_NGL_S:
10397 case OPC_CMP_LT_S:
10398 case OPC_CMP_NGE_S:
10399 case OPC_CMP_LE_S:
10400 case OPC_CMP_NGT_S:
10401 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10402 if (ctx->opcode & (1 << 6)) {
10403 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10404 } else {
10405 gen_cmp_s(ctx, func - 48, ft, fs, cc);
10406 }
10407 break;
10408 case OPC_ADD_D:
10409 check_cp1_registers(ctx, fs | ft | fd);
10410 {
10411 TCGv_i64 fp0 = tcg_temp_new_i64();
10412 TCGv_i64 fp1 = tcg_temp_new_i64();
10413
10414 gen_load_fpr64(ctx, fp0, fs);
10415 gen_load_fpr64(ctx, fp1, ft);
10416 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10417 tcg_temp_free_i64(fp1);
10418 gen_store_fpr64(ctx, fp0, fd);
10419 tcg_temp_free_i64(fp0);
10420 }
10421 break;
10422 case OPC_SUB_D:
10423 check_cp1_registers(ctx, fs | ft | fd);
10424 {
10425 TCGv_i64 fp0 = tcg_temp_new_i64();
10426 TCGv_i64 fp1 = tcg_temp_new_i64();
10427
10428 gen_load_fpr64(ctx, fp0, fs);
10429 gen_load_fpr64(ctx, fp1, ft);
10430 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10431 tcg_temp_free_i64(fp1);
10432 gen_store_fpr64(ctx, fp0, fd);
10433 tcg_temp_free_i64(fp0);
10434 }
10435 break;
10436 case OPC_MUL_D:
10437 check_cp1_registers(ctx, fs | ft | fd);
10438 {
10439 TCGv_i64 fp0 = tcg_temp_new_i64();
10440 TCGv_i64 fp1 = tcg_temp_new_i64();
10441
10442 gen_load_fpr64(ctx, fp0, fs);
10443 gen_load_fpr64(ctx, fp1, ft);
10444 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10445 tcg_temp_free_i64(fp1);
10446 gen_store_fpr64(ctx, fp0, fd);
10447 tcg_temp_free_i64(fp0);
10448 }
10449 break;
10450 case OPC_DIV_D:
10451 check_cp1_registers(ctx, fs | ft | fd);
10452 {
10453 TCGv_i64 fp0 = tcg_temp_new_i64();
10454 TCGv_i64 fp1 = tcg_temp_new_i64();
10455
10456 gen_load_fpr64(ctx, fp0, fs);
10457 gen_load_fpr64(ctx, fp1, ft);
10458 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10459 tcg_temp_free_i64(fp1);
10460 gen_store_fpr64(ctx, fp0, fd);
10461 tcg_temp_free_i64(fp0);
10462 }
10463 break;
10464 case OPC_SQRT_D:
10465 check_cp1_registers(ctx, fs | fd);
10466 {
10467 TCGv_i64 fp0 = tcg_temp_new_i64();
10468
10469 gen_load_fpr64(ctx, fp0, fs);
10470 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10471 gen_store_fpr64(ctx, fp0, fd);
10472 tcg_temp_free_i64(fp0);
10473 }
10474 break;
10475 case OPC_ABS_D:
10476 check_cp1_registers(ctx, fs | fd);
10477 {
10478 TCGv_i64 fp0 = tcg_temp_new_i64();
10479
10480 gen_load_fpr64(ctx, fp0, fs);
10481 if (ctx->abs2008) {
10482 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10483 } else {
10484 gen_helper_float_abs_d(fp0, fp0);
10485 }
10486 gen_store_fpr64(ctx, fp0, fd);
10487 tcg_temp_free_i64(fp0);
10488 }
10489 break;
10490 case OPC_MOV_D:
10491 check_cp1_registers(ctx, fs | fd);
10492 {
10493 TCGv_i64 fp0 = tcg_temp_new_i64();
10494
10495 gen_load_fpr64(ctx, fp0, fs);
10496 gen_store_fpr64(ctx, fp0, fd);
10497 tcg_temp_free_i64(fp0);
10498 }
10499 break;
10500 case OPC_NEG_D:
10501 check_cp1_registers(ctx, fs | fd);
10502 {
10503 TCGv_i64 fp0 = tcg_temp_new_i64();
10504
10505 gen_load_fpr64(ctx, fp0, fs);
10506 if (ctx->abs2008) {
10507 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10508 } else {
10509 gen_helper_float_chs_d(fp0, fp0);
10510 }
10511 gen_store_fpr64(ctx, fp0, fd);
10512 tcg_temp_free_i64(fp0);
10513 }
10514 break;
10515 case OPC_ROUND_L_D:
10516 check_cp1_64bitmode(ctx);
10517 {
10518 TCGv_i64 fp0 = tcg_temp_new_i64();
10519
10520 gen_load_fpr64(ctx, fp0, fs);
10521 if (ctx->nan2008) {
10522 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10523 } else {
10524 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10525 }
10526 gen_store_fpr64(ctx, fp0, fd);
10527 tcg_temp_free_i64(fp0);
10528 }
10529 break;
10530 case OPC_TRUNC_L_D:
10531 check_cp1_64bitmode(ctx);
10532 {
10533 TCGv_i64 fp0 = tcg_temp_new_i64();
10534
10535 gen_load_fpr64(ctx, fp0, fs);
10536 if (ctx->nan2008) {
10537 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10538 } else {
10539 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10540 }
10541 gen_store_fpr64(ctx, fp0, fd);
10542 tcg_temp_free_i64(fp0);
10543 }
10544 break;
10545 case OPC_CEIL_L_D:
10546 check_cp1_64bitmode(ctx);
10547 {
10548 TCGv_i64 fp0 = tcg_temp_new_i64();
10549
10550 gen_load_fpr64(ctx, fp0, fs);
10551 if (ctx->nan2008) {
10552 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10553 } else {
10554 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10555 }
10556 gen_store_fpr64(ctx, fp0, fd);
10557 tcg_temp_free_i64(fp0);
10558 }
10559 break;
10560 case OPC_FLOOR_L_D:
10561 check_cp1_64bitmode(ctx);
10562 {
10563 TCGv_i64 fp0 = tcg_temp_new_i64();
10564
10565 gen_load_fpr64(ctx, fp0, fs);
10566 if (ctx->nan2008) {
10567 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10568 } else {
10569 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10570 }
10571 gen_store_fpr64(ctx, fp0, fd);
10572 tcg_temp_free_i64(fp0);
10573 }
10574 break;
10575 case OPC_ROUND_W_D:
10576 check_cp1_registers(ctx, fs);
10577 {
10578 TCGv_i32 fp32 = tcg_temp_new_i32();
10579 TCGv_i64 fp64 = tcg_temp_new_i64();
10580
10581 gen_load_fpr64(ctx, fp64, fs);
10582 if (ctx->nan2008) {
10583 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10584 } else {
10585 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10586 }
10587 tcg_temp_free_i64(fp64);
10588 gen_store_fpr32(ctx, fp32, fd);
10589 tcg_temp_free_i32(fp32);
10590 }
10591 break;
10592 case OPC_TRUNC_W_D:
10593 check_cp1_registers(ctx, fs);
10594 {
10595 TCGv_i32 fp32 = tcg_temp_new_i32();
10596 TCGv_i64 fp64 = tcg_temp_new_i64();
10597
10598 gen_load_fpr64(ctx, fp64, fs);
10599 if (ctx->nan2008) {
10600 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10601 } else {
10602 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10603 }
10604 tcg_temp_free_i64(fp64);
10605 gen_store_fpr32(ctx, fp32, fd);
10606 tcg_temp_free_i32(fp32);
10607 }
10608 break;
10609 case OPC_CEIL_W_D:
10610 check_cp1_registers(ctx, fs);
10611 {
10612 TCGv_i32 fp32 = tcg_temp_new_i32();
10613 TCGv_i64 fp64 = tcg_temp_new_i64();
10614
10615 gen_load_fpr64(ctx, fp64, fs);
10616 if (ctx->nan2008) {
10617 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10618 } else {
10619 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10620 }
10621 tcg_temp_free_i64(fp64);
10622 gen_store_fpr32(ctx, fp32, fd);
10623 tcg_temp_free_i32(fp32);
10624 }
10625 break;
10626 case OPC_FLOOR_W_D:
10627 check_cp1_registers(ctx, fs);
10628 {
10629 TCGv_i32 fp32 = tcg_temp_new_i32();
10630 TCGv_i64 fp64 = tcg_temp_new_i64();
10631
10632 gen_load_fpr64(ctx, fp64, fs);
10633 if (ctx->nan2008) {
10634 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10635 } else {
10636 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10637 }
10638 tcg_temp_free_i64(fp64);
10639 gen_store_fpr32(ctx, fp32, fd);
10640 tcg_temp_free_i32(fp32);
10641 }
10642 break;
10643 case OPC_SEL_D:
10644 check_insn(ctx, ISA_MIPS_R6);
10645 gen_sel_d(ctx, op1, fd, ft, fs);
10646 break;
10647 case OPC_SELEQZ_D:
10648 check_insn(ctx, ISA_MIPS_R6);
10649 gen_sel_d(ctx, op1, fd, ft, fs);
10650 break;
10651 case OPC_SELNEZ_D:
10652 check_insn(ctx, ISA_MIPS_R6);
10653 gen_sel_d(ctx, op1, fd, ft, fs);
10654 break;
10655 case OPC_MOVCF_D:
10656 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10657 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10658 break;
10659 case OPC_MOVZ_D:
10660 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10661 {
10662 TCGLabel *l1 = gen_new_label();
10663 TCGv_i64 fp0;
10664
10665 if (ft != 0) {
10666 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10667 }
10668 fp0 = tcg_temp_new_i64();
10669 gen_load_fpr64(ctx, fp0, fs);
10670 gen_store_fpr64(ctx, fp0, fd);
10671 tcg_temp_free_i64(fp0);
10672 gen_set_label(l1);
10673 }
10674 break;
10675 case OPC_MOVN_D:
10676 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10677 {
10678 TCGLabel *l1 = gen_new_label();
10679 TCGv_i64 fp0;
10680
10681 if (ft != 0) {
10682 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10683 fp0 = tcg_temp_new_i64();
10684 gen_load_fpr64(ctx, fp0, fs);
10685 gen_store_fpr64(ctx, fp0, fd);
10686 tcg_temp_free_i64(fp0);
10687 gen_set_label(l1);
10688 }
10689 }
10690 break;
10691 case OPC_RECIP_D:
10692 check_cp1_registers(ctx, fs | fd);
10693 {
10694 TCGv_i64 fp0 = tcg_temp_new_i64();
10695
10696 gen_load_fpr64(ctx, fp0, fs);
10697 gen_helper_float_recip_d(fp0, cpu_env, fp0);
10698 gen_store_fpr64(ctx, fp0, fd);
10699 tcg_temp_free_i64(fp0);
10700 }
10701 break;
10702 case OPC_RSQRT_D:
10703 check_cp1_registers(ctx, fs | fd);
10704 {
10705 TCGv_i64 fp0 = tcg_temp_new_i64();
10706
10707 gen_load_fpr64(ctx, fp0, fs);
10708 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10709 gen_store_fpr64(ctx, fp0, fd);
10710 tcg_temp_free_i64(fp0);
10711 }
10712 break;
10713 case OPC_MADDF_D:
10714 check_insn(ctx, ISA_MIPS_R6);
10715 {
10716 TCGv_i64 fp0 = tcg_temp_new_i64();
10717 TCGv_i64 fp1 = tcg_temp_new_i64();
10718 TCGv_i64 fp2 = tcg_temp_new_i64();
10719 gen_load_fpr64(ctx, fp0, fs);
10720 gen_load_fpr64(ctx, fp1, ft);
10721 gen_load_fpr64(ctx, fp2, fd);
10722 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10723 gen_store_fpr64(ctx, fp2, fd);
10724 tcg_temp_free_i64(fp2);
10725 tcg_temp_free_i64(fp1);
10726 tcg_temp_free_i64(fp0);
10727 }
10728 break;
10729 case OPC_MSUBF_D:
10730 check_insn(ctx, ISA_MIPS_R6);
10731 {
10732 TCGv_i64 fp0 = tcg_temp_new_i64();
10733 TCGv_i64 fp1 = tcg_temp_new_i64();
10734 TCGv_i64 fp2 = tcg_temp_new_i64();
10735 gen_load_fpr64(ctx, fp0, fs);
10736 gen_load_fpr64(ctx, fp1, ft);
10737 gen_load_fpr64(ctx, fp2, fd);
10738 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10739 gen_store_fpr64(ctx, fp2, fd);
10740 tcg_temp_free_i64(fp2);
10741 tcg_temp_free_i64(fp1);
10742 tcg_temp_free_i64(fp0);
10743 }
10744 break;
10745 case OPC_RINT_D:
10746 check_insn(ctx, ISA_MIPS_R6);
10747 {
10748 TCGv_i64 fp0 = tcg_temp_new_i64();
10749 gen_load_fpr64(ctx, fp0, fs);
10750 gen_helper_float_rint_d(fp0, cpu_env, fp0);
10751 gen_store_fpr64(ctx, fp0, fd);
10752 tcg_temp_free_i64(fp0);
10753 }
10754 break;
10755 case OPC_CLASS_D:
10756 check_insn(ctx, ISA_MIPS_R6);
10757 {
10758 TCGv_i64 fp0 = tcg_temp_new_i64();
10759 gen_load_fpr64(ctx, fp0, fs);
10760 gen_helper_float_class_d(fp0, cpu_env, fp0);
10761 gen_store_fpr64(ctx, fp0, fd);
10762 tcg_temp_free_i64(fp0);
10763 }
10764 break;
10765 case OPC_MIN_D:
10766 if (ctx->insn_flags & ISA_MIPS_R6) {
10767
10768 TCGv_i64 fp0 = tcg_temp_new_i64();
10769 TCGv_i64 fp1 = tcg_temp_new_i64();
10770 gen_load_fpr64(ctx, fp0, fs);
10771 gen_load_fpr64(ctx, fp1, ft);
10772 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10773 gen_store_fpr64(ctx, fp1, fd);
10774 tcg_temp_free_i64(fp1);
10775 tcg_temp_free_i64(fp0);
10776 } else {
10777
10778 check_cp1_64bitmode(ctx);
10779 {
10780 TCGv_i64 fp0 = tcg_temp_new_i64();
10781 TCGv_i64 fp1 = tcg_temp_new_i64();
10782
10783 gen_load_fpr64(ctx, fp0, fs);
10784 gen_load_fpr64(ctx, fp1, ft);
10785 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10786 tcg_temp_free_i64(fp1);
10787 gen_store_fpr64(ctx, fp0, fd);
10788 tcg_temp_free_i64(fp0);
10789 }
10790 }
10791 break;
10792 case OPC_MINA_D:
10793 if (ctx->insn_flags & ISA_MIPS_R6) {
10794
10795 TCGv_i64 fp0 = tcg_temp_new_i64();
10796 TCGv_i64 fp1 = tcg_temp_new_i64();
10797 gen_load_fpr64(ctx, fp0, fs);
10798 gen_load_fpr64(ctx, fp1, ft);
10799 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10800 gen_store_fpr64(ctx, fp1, fd);
10801 tcg_temp_free_i64(fp1);
10802 tcg_temp_free_i64(fp0);
10803 } else {
10804
10805 check_cp1_64bitmode(ctx);
10806 {
10807 TCGv_i64 fp0 = tcg_temp_new_i64();
10808
10809 gen_load_fpr64(ctx, fp0, fs);
10810 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10811 gen_store_fpr64(ctx, fp0, fd);
10812 tcg_temp_free_i64(fp0);
10813 }
10814 }
10815 break;
10816 case OPC_MAX_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_max_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_rsqrt1_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_MAXA_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_maxa_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 TCGv_i64 fp1 = tcg_temp_new_i64();
10857
10858 gen_load_fpr64(ctx, fp0, fs);
10859 gen_load_fpr64(ctx, fp1, ft);
10860 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10861 tcg_temp_free_i64(fp1);
10862 gen_store_fpr64(ctx, fp0, fd);
10863 tcg_temp_free_i64(fp0);
10864 }
10865 }
10866 break;
10867 case OPC_CMP_F_D:
10868 case OPC_CMP_UN_D:
10869 case OPC_CMP_EQ_D:
10870 case OPC_CMP_UEQ_D:
10871 case OPC_CMP_OLT_D:
10872 case OPC_CMP_ULT_D:
10873 case OPC_CMP_OLE_D:
10874 case OPC_CMP_ULE_D:
10875 case OPC_CMP_SF_D:
10876 case OPC_CMP_NGLE_D:
10877 case OPC_CMP_SEQ_D:
10878 case OPC_CMP_NGL_D:
10879 case OPC_CMP_LT_D:
10880 case OPC_CMP_NGE_D:
10881 case OPC_CMP_LE_D:
10882 case OPC_CMP_NGT_D:
10883 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10884 if (ctx->opcode & (1 << 6)) {
10885 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10886 } else {
10887 gen_cmp_d(ctx, func - 48, ft, fs, cc);
10888 }
10889 break;
10890 case OPC_CVT_S_D:
10891 check_cp1_registers(ctx, fs);
10892 {
10893 TCGv_i32 fp32 = tcg_temp_new_i32();
10894 TCGv_i64 fp64 = tcg_temp_new_i64();
10895
10896 gen_load_fpr64(ctx, fp64, fs);
10897 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10898 tcg_temp_free_i64(fp64);
10899 gen_store_fpr32(ctx, fp32, fd);
10900 tcg_temp_free_i32(fp32);
10901 }
10902 break;
10903 case OPC_CVT_W_D:
10904 check_cp1_registers(ctx, fs);
10905 {
10906 TCGv_i32 fp32 = tcg_temp_new_i32();
10907 TCGv_i64 fp64 = tcg_temp_new_i64();
10908
10909 gen_load_fpr64(ctx, fp64, fs);
10910 if (ctx->nan2008) {
10911 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10912 } else {
10913 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10914 }
10915 tcg_temp_free_i64(fp64);
10916 gen_store_fpr32(ctx, fp32, fd);
10917 tcg_temp_free_i32(fp32);
10918 }
10919 break;
10920 case OPC_CVT_L_D:
10921 check_cp1_64bitmode(ctx);
10922 {
10923 TCGv_i64 fp0 = tcg_temp_new_i64();
10924
10925 gen_load_fpr64(ctx, fp0, fs);
10926 if (ctx->nan2008) {
10927 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10928 } else {
10929 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10930 }
10931 gen_store_fpr64(ctx, fp0, fd);
10932 tcg_temp_free_i64(fp0);
10933 }
10934 break;
10935 case OPC_CVT_S_W:
10936 {
10937 TCGv_i32 fp0 = tcg_temp_new_i32();
10938
10939 gen_load_fpr32(ctx, fp0, fs);
10940 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10941 gen_store_fpr32(ctx, fp0, fd);
10942 tcg_temp_free_i32(fp0);
10943 }
10944 break;
10945 case OPC_CVT_D_W:
10946 check_cp1_registers(ctx, fd);
10947 {
10948 TCGv_i32 fp32 = tcg_temp_new_i32();
10949 TCGv_i64 fp64 = tcg_temp_new_i64();
10950
10951 gen_load_fpr32(ctx, fp32, fs);
10952 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10953 tcg_temp_free_i32(fp32);
10954 gen_store_fpr64(ctx, fp64, fd);
10955 tcg_temp_free_i64(fp64);
10956 }
10957 break;
10958 case OPC_CVT_S_L:
10959 check_cp1_64bitmode(ctx);
10960 {
10961 TCGv_i32 fp32 = tcg_temp_new_i32();
10962 TCGv_i64 fp64 = tcg_temp_new_i64();
10963
10964 gen_load_fpr64(ctx, fp64, fs);
10965 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10966 tcg_temp_free_i64(fp64);
10967 gen_store_fpr32(ctx, fp32, fd);
10968 tcg_temp_free_i32(fp32);
10969 }
10970 break;
10971 case OPC_CVT_D_L:
10972 check_cp1_64bitmode(ctx);
10973 {
10974 TCGv_i64 fp0 = tcg_temp_new_i64();
10975
10976 gen_load_fpr64(ctx, fp0, fs);
10977 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
10978 gen_store_fpr64(ctx, fp0, fd);
10979 tcg_temp_free_i64(fp0);
10980 }
10981 break;
10982 case OPC_CVT_PS_PW:
10983 check_ps(ctx);
10984 {
10985 TCGv_i64 fp0 = tcg_temp_new_i64();
10986
10987 gen_load_fpr64(ctx, fp0, fs);
10988 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
10989 gen_store_fpr64(ctx, fp0, fd);
10990 tcg_temp_free_i64(fp0);
10991 }
10992 break;
10993 case OPC_ADD_PS:
10994 check_ps(ctx);
10995 {
10996 TCGv_i64 fp0 = tcg_temp_new_i64();
10997 TCGv_i64 fp1 = tcg_temp_new_i64();
10998
10999 gen_load_fpr64(ctx, fp0, fs);
11000 gen_load_fpr64(ctx, fp1, ft);
11001 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11002 tcg_temp_free_i64(fp1);
11003 gen_store_fpr64(ctx, fp0, fd);
11004 tcg_temp_free_i64(fp0);
11005 }
11006 break;
11007 case OPC_SUB_PS:
11008 check_ps(ctx);
11009 {
11010 TCGv_i64 fp0 = tcg_temp_new_i64();
11011 TCGv_i64 fp1 = tcg_temp_new_i64();
11012
11013 gen_load_fpr64(ctx, fp0, fs);
11014 gen_load_fpr64(ctx, fp1, ft);
11015 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11016 tcg_temp_free_i64(fp1);
11017 gen_store_fpr64(ctx, fp0, fd);
11018 tcg_temp_free_i64(fp0);
11019 }
11020 break;
11021 case OPC_MUL_PS:
11022 check_ps(ctx);
11023 {
11024 TCGv_i64 fp0 = tcg_temp_new_i64();
11025 TCGv_i64 fp1 = tcg_temp_new_i64();
11026
11027 gen_load_fpr64(ctx, fp0, fs);
11028 gen_load_fpr64(ctx, fp1, ft);
11029 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11030 tcg_temp_free_i64(fp1);
11031 gen_store_fpr64(ctx, fp0, fd);
11032 tcg_temp_free_i64(fp0);
11033 }
11034 break;
11035 case OPC_ABS_PS:
11036 check_ps(ctx);
11037 {
11038 TCGv_i64 fp0 = tcg_temp_new_i64();
11039
11040 gen_load_fpr64(ctx, fp0, fs);
11041 gen_helper_float_abs_ps(fp0, fp0);
11042 gen_store_fpr64(ctx, fp0, fd);
11043 tcg_temp_free_i64(fp0);
11044 }
11045 break;
11046 case OPC_MOV_PS:
11047 check_ps(ctx);
11048 {
11049 TCGv_i64 fp0 = tcg_temp_new_i64();
11050
11051 gen_load_fpr64(ctx, fp0, fs);
11052 gen_store_fpr64(ctx, fp0, fd);
11053 tcg_temp_free_i64(fp0);
11054 }
11055 break;
11056 case OPC_NEG_PS:
11057 check_ps(ctx);
11058 {
11059 TCGv_i64 fp0 = tcg_temp_new_i64();
11060
11061 gen_load_fpr64(ctx, fp0, fs);
11062 gen_helper_float_chs_ps(fp0, fp0);
11063 gen_store_fpr64(ctx, fp0, fd);
11064 tcg_temp_free_i64(fp0);
11065 }
11066 break;
11067 case OPC_MOVCF_PS:
11068 check_ps(ctx);
11069 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11070 break;
11071 case OPC_MOVZ_PS:
11072 check_ps(ctx);
11073 {
11074 TCGLabel *l1 = gen_new_label();
11075 TCGv_i64 fp0;
11076
11077 if (ft != 0) {
11078 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11079 }
11080 fp0 = tcg_temp_new_i64();
11081 gen_load_fpr64(ctx, fp0, fs);
11082 gen_store_fpr64(ctx, fp0, fd);
11083 tcg_temp_free_i64(fp0);
11084 gen_set_label(l1);
11085 }
11086 break;
11087 case OPC_MOVN_PS:
11088 check_ps(ctx);
11089 {
11090 TCGLabel *l1 = gen_new_label();
11091 TCGv_i64 fp0;
11092
11093 if (ft != 0) {
11094 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11095 fp0 = tcg_temp_new_i64();
11096 gen_load_fpr64(ctx, fp0, fs);
11097 gen_store_fpr64(ctx, fp0, fd);
11098 tcg_temp_free_i64(fp0);
11099 gen_set_label(l1);
11100 }
11101 }
11102 break;
11103 case OPC_ADDR_PS:
11104 check_ps(ctx);
11105 {
11106 TCGv_i64 fp0 = tcg_temp_new_i64();
11107 TCGv_i64 fp1 = tcg_temp_new_i64();
11108
11109 gen_load_fpr64(ctx, fp0, ft);
11110 gen_load_fpr64(ctx, fp1, fs);
11111 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11112 tcg_temp_free_i64(fp1);
11113 gen_store_fpr64(ctx, fp0, fd);
11114 tcg_temp_free_i64(fp0);
11115 }
11116 break;
11117 case OPC_MULR_PS:
11118 check_ps(ctx);
11119 {
11120 TCGv_i64 fp0 = tcg_temp_new_i64();
11121 TCGv_i64 fp1 = tcg_temp_new_i64();
11122
11123 gen_load_fpr64(ctx, fp0, ft);
11124 gen_load_fpr64(ctx, fp1, fs);
11125 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11126 tcg_temp_free_i64(fp1);
11127 gen_store_fpr64(ctx, fp0, fd);
11128 tcg_temp_free_i64(fp0);
11129 }
11130 break;
11131 case OPC_RECIP2_PS:
11132 check_ps(ctx);
11133 {
11134 TCGv_i64 fp0 = tcg_temp_new_i64();
11135 TCGv_i64 fp1 = tcg_temp_new_i64();
11136
11137 gen_load_fpr64(ctx, fp0, fs);
11138 gen_load_fpr64(ctx, fp1, ft);
11139 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11140 tcg_temp_free_i64(fp1);
11141 gen_store_fpr64(ctx, fp0, fd);
11142 tcg_temp_free_i64(fp0);
11143 }
11144 break;
11145 case OPC_RECIP1_PS:
11146 check_ps(ctx);
11147 {
11148 TCGv_i64 fp0 = tcg_temp_new_i64();
11149
11150 gen_load_fpr64(ctx, fp0, fs);
11151 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11152 gen_store_fpr64(ctx, fp0, fd);
11153 tcg_temp_free_i64(fp0);
11154 }
11155 break;
11156 case OPC_RSQRT1_PS:
11157 check_ps(ctx);
11158 {
11159 TCGv_i64 fp0 = tcg_temp_new_i64();
11160
11161 gen_load_fpr64(ctx, fp0, fs);
11162 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11163 gen_store_fpr64(ctx, fp0, fd);
11164 tcg_temp_free_i64(fp0);
11165 }
11166 break;
11167 case OPC_RSQRT2_PS:
11168 check_ps(ctx);
11169 {
11170 TCGv_i64 fp0 = tcg_temp_new_i64();
11171 TCGv_i64 fp1 = tcg_temp_new_i64();
11172
11173 gen_load_fpr64(ctx, fp0, fs);
11174 gen_load_fpr64(ctx, fp1, ft);
11175 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11176 tcg_temp_free_i64(fp1);
11177 gen_store_fpr64(ctx, fp0, fd);
11178 tcg_temp_free_i64(fp0);
11179 }
11180 break;
11181 case OPC_CVT_S_PU:
11182 check_cp1_64bitmode(ctx);
11183 {
11184 TCGv_i32 fp0 = tcg_temp_new_i32();
11185
11186 gen_load_fpr32h(ctx, fp0, fs);
11187 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11188 gen_store_fpr32(ctx, fp0, fd);
11189 tcg_temp_free_i32(fp0);
11190 }
11191 break;
11192 case OPC_CVT_PW_PS:
11193 check_ps(ctx);
11194 {
11195 TCGv_i64 fp0 = tcg_temp_new_i64();
11196
11197 gen_load_fpr64(ctx, fp0, fs);
11198 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11199 gen_store_fpr64(ctx, fp0, fd);
11200 tcg_temp_free_i64(fp0);
11201 }
11202 break;
11203 case OPC_CVT_S_PL:
11204 check_cp1_64bitmode(ctx);
11205 {
11206 TCGv_i32 fp0 = tcg_temp_new_i32();
11207
11208 gen_load_fpr32(ctx, fp0, fs);
11209 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11210 gen_store_fpr32(ctx, fp0, fd);
11211 tcg_temp_free_i32(fp0);
11212 }
11213 break;
11214 case OPC_PLL_PS:
11215 check_ps(ctx);
11216 {
11217 TCGv_i32 fp0 = tcg_temp_new_i32();
11218 TCGv_i32 fp1 = tcg_temp_new_i32();
11219
11220 gen_load_fpr32(ctx, fp0, fs);
11221 gen_load_fpr32(ctx, fp1, ft);
11222 gen_store_fpr32h(ctx, fp0, fd);
11223 gen_store_fpr32(ctx, fp1, fd);
11224 tcg_temp_free_i32(fp0);
11225 tcg_temp_free_i32(fp1);
11226 }
11227 break;
11228 case OPC_PLU_PS:
11229 check_ps(ctx);
11230 {
11231 TCGv_i32 fp0 = tcg_temp_new_i32();
11232 TCGv_i32 fp1 = tcg_temp_new_i32();
11233
11234 gen_load_fpr32(ctx, fp0, fs);
11235 gen_load_fpr32h(ctx, fp1, ft);
11236 gen_store_fpr32(ctx, fp1, fd);
11237 gen_store_fpr32h(ctx, fp0, fd);
11238 tcg_temp_free_i32(fp0);
11239 tcg_temp_free_i32(fp1);
11240 }
11241 break;
11242 case OPC_PUL_PS:
11243 check_ps(ctx);
11244 {
11245 TCGv_i32 fp0 = tcg_temp_new_i32();
11246 TCGv_i32 fp1 = tcg_temp_new_i32();
11247
11248 gen_load_fpr32h(ctx, fp0, fs);
11249 gen_load_fpr32(ctx, fp1, ft);
11250 gen_store_fpr32(ctx, fp1, fd);
11251 gen_store_fpr32h(ctx, fp0, fd);
11252 tcg_temp_free_i32(fp0);
11253 tcg_temp_free_i32(fp1);
11254 }
11255 break;
11256 case OPC_PUU_PS:
11257 check_ps(ctx);
11258 {
11259 TCGv_i32 fp0 = tcg_temp_new_i32();
11260 TCGv_i32 fp1 = tcg_temp_new_i32();
11261
11262 gen_load_fpr32h(ctx, fp0, fs);
11263 gen_load_fpr32h(ctx, fp1, ft);
11264 gen_store_fpr32(ctx, fp1, fd);
11265 gen_store_fpr32h(ctx, fp0, fd);
11266 tcg_temp_free_i32(fp0);
11267 tcg_temp_free_i32(fp1);
11268 }
11269 break;
11270 case OPC_CMP_F_PS:
11271 case OPC_CMP_UN_PS:
11272 case OPC_CMP_EQ_PS:
11273 case OPC_CMP_UEQ_PS:
11274 case OPC_CMP_OLT_PS:
11275 case OPC_CMP_ULT_PS:
11276 case OPC_CMP_OLE_PS:
11277 case OPC_CMP_ULE_PS:
11278 case OPC_CMP_SF_PS:
11279 case OPC_CMP_NGLE_PS:
11280 case OPC_CMP_SEQ_PS:
11281 case OPC_CMP_NGL_PS:
11282 case OPC_CMP_LT_PS:
11283 case OPC_CMP_NGE_PS:
11284 case OPC_CMP_LE_PS:
11285 case OPC_CMP_NGT_PS:
11286 if (ctx->opcode & (1 << 6)) {
11287 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11288 } else {
11289 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11290 }
11291 break;
11292 default:
11293 MIPS_INVAL("farith");
11294 gen_reserved_instruction(ctx);
11295 return;
11296 }
11297}
11298
11299
11300static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11301 int fd, int fs, int base, int index)
11302{
11303 TCGv t0 = tcg_temp_new();
11304
11305 if (base == 0) {
11306 gen_load_gpr(t0, index);
11307 } else if (index == 0) {
11308 gen_load_gpr(t0, base);
11309 } else {
11310 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11311 }
11312
11313
11314
11315
11316 switch (opc) {
11317 case OPC_LWXC1:
11318 check_cop1x(ctx);
11319 {
11320 TCGv_i32 fp0 = tcg_temp_new_i32();
11321
11322 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11323 tcg_gen_trunc_tl_i32(fp0, t0);
11324 gen_store_fpr32(ctx, fp0, fd);
11325 tcg_temp_free_i32(fp0);
11326 }
11327 break;
11328 case OPC_LDXC1:
11329 check_cop1x(ctx);
11330 check_cp1_registers(ctx, fd);
11331 {
11332 TCGv_i64 fp0 = tcg_temp_new_i64();
11333 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11334 gen_store_fpr64(ctx, fp0, fd);
11335 tcg_temp_free_i64(fp0);
11336 }
11337 break;
11338 case OPC_LUXC1:
11339 check_cp1_64bitmode(ctx);
11340 tcg_gen_andi_tl(t0, t0, ~0x7);
11341 {
11342 TCGv_i64 fp0 = tcg_temp_new_i64();
11343
11344 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11345 gen_store_fpr64(ctx, fp0, fd);
11346 tcg_temp_free_i64(fp0);
11347 }
11348 break;
11349 case OPC_SWXC1:
11350 check_cop1x(ctx);
11351 {
11352 TCGv_i32 fp0 = tcg_temp_new_i32();
11353 gen_load_fpr32(ctx, fp0, fs);
11354 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11355 tcg_temp_free_i32(fp0);
11356 }
11357 break;
11358 case OPC_SDXC1:
11359 check_cop1x(ctx);
11360 check_cp1_registers(ctx, fs);
11361 {
11362 TCGv_i64 fp0 = tcg_temp_new_i64();
11363 gen_load_fpr64(ctx, fp0, fs);
11364 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11365 tcg_temp_free_i64(fp0);
11366 }
11367 break;
11368 case OPC_SUXC1:
11369 check_cp1_64bitmode(ctx);
11370 tcg_gen_andi_tl(t0, t0, ~0x7);
11371 {
11372 TCGv_i64 fp0 = tcg_temp_new_i64();
11373 gen_load_fpr64(ctx, fp0, fs);
11374 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11375 tcg_temp_free_i64(fp0);
11376 }
11377 break;
11378 }
11379 tcg_temp_free(t0);
11380}
11381
11382static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11383 int fd, int fr, int fs, int ft)
11384{
11385 switch (opc) {
11386 case OPC_ALNV_PS:
11387 check_ps(ctx);
11388 {
11389 TCGv t0 = tcg_temp_local_new();
11390 TCGv_i32 fp = tcg_temp_new_i32();
11391 TCGv_i32 fph = tcg_temp_new_i32();
11392 TCGLabel *l1 = gen_new_label();
11393 TCGLabel *l2 = gen_new_label();
11394
11395 gen_load_gpr(t0, fr);
11396 tcg_gen_andi_tl(t0, t0, 0x7);
11397
11398 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11399 gen_load_fpr32(ctx, fp, fs);
11400 gen_load_fpr32h(ctx, fph, fs);
11401 gen_store_fpr32(ctx, fp, fd);
11402 gen_store_fpr32h(ctx, fph, fd);
11403 tcg_gen_br(l2);
11404 gen_set_label(l1);
11405 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11406 tcg_temp_free(t0);
11407 if (cpu_is_bigendian(ctx)) {
11408 gen_load_fpr32(ctx, fp, fs);
11409 gen_load_fpr32h(ctx, fph, ft);
11410 gen_store_fpr32h(ctx, fp, fd);
11411 gen_store_fpr32(ctx, fph, fd);
11412 } else {
11413 gen_load_fpr32h(ctx, fph, fs);
11414 gen_load_fpr32(ctx, fp, ft);
11415 gen_store_fpr32(ctx, fph, fd);
11416 gen_store_fpr32h(ctx, fp, fd);
11417 }
11418 gen_set_label(l2);
11419 tcg_temp_free_i32(fp);
11420 tcg_temp_free_i32(fph);
11421 }
11422 break;
11423 case OPC_MADD_S:
11424 check_cop1x(ctx);
11425 {
11426 TCGv_i32 fp0 = tcg_temp_new_i32();
11427 TCGv_i32 fp1 = tcg_temp_new_i32();
11428 TCGv_i32 fp2 = tcg_temp_new_i32();
11429
11430 gen_load_fpr32(ctx, fp0, fs);
11431 gen_load_fpr32(ctx, fp1, ft);
11432 gen_load_fpr32(ctx, fp2, fr);
11433 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11434 tcg_temp_free_i32(fp0);
11435 tcg_temp_free_i32(fp1);
11436 gen_store_fpr32(ctx, fp2, fd);
11437 tcg_temp_free_i32(fp2);
11438 }
11439 break;
11440 case OPC_MADD_D:
11441 check_cop1x(ctx);
11442 check_cp1_registers(ctx, fd | fs | ft | fr);
11443 {
11444 TCGv_i64 fp0 = tcg_temp_new_i64();
11445 TCGv_i64 fp1 = tcg_temp_new_i64();
11446 TCGv_i64 fp2 = tcg_temp_new_i64();
11447
11448 gen_load_fpr64(ctx, fp0, fs);
11449 gen_load_fpr64(ctx, fp1, ft);
11450 gen_load_fpr64(ctx, fp2, fr);
11451 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11452 tcg_temp_free_i64(fp0);
11453 tcg_temp_free_i64(fp1);
11454 gen_store_fpr64(ctx, fp2, fd);
11455 tcg_temp_free_i64(fp2);
11456 }
11457 break;
11458 case OPC_MADD_PS:
11459 check_ps(ctx);
11460 {
11461 TCGv_i64 fp0 = tcg_temp_new_i64();
11462 TCGv_i64 fp1 = tcg_temp_new_i64();
11463 TCGv_i64 fp2 = tcg_temp_new_i64();
11464
11465 gen_load_fpr64(ctx, fp0, fs);
11466 gen_load_fpr64(ctx, fp1, ft);
11467 gen_load_fpr64(ctx, fp2, fr);
11468 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11469 tcg_temp_free_i64(fp0);
11470 tcg_temp_free_i64(fp1);
11471 gen_store_fpr64(ctx, fp2, fd);
11472 tcg_temp_free_i64(fp2);
11473 }
11474 break;
11475 case OPC_MSUB_S:
11476 check_cop1x(ctx);
11477 {
11478 TCGv_i32 fp0 = tcg_temp_new_i32();
11479 TCGv_i32 fp1 = tcg_temp_new_i32();
11480 TCGv_i32 fp2 = tcg_temp_new_i32();
11481
11482 gen_load_fpr32(ctx, fp0, fs);
11483 gen_load_fpr32(ctx, fp1, ft);
11484 gen_load_fpr32(ctx, fp2, fr);
11485 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11486 tcg_temp_free_i32(fp0);
11487 tcg_temp_free_i32(fp1);
11488 gen_store_fpr32(ctx, fp2, fd);
11489 tcg_temp_free_i32(fp2);
11490 }
11491 break;
11492 case OPC_MSUB_D:
11493 check_cop1x(ctx);
11494 check_cp1_registers(ctx, fd | fs | ft | fr);
11495 {
11496 TCGv_i64 fp0 = tcg_temp_new_i64();
11497 TCGv_i64 fp1 = tcg_temp_new_i64();
11498 TCGv_i64 fp2 = tcg_temp_new_i64();
11499
11500 gen_load_fpr64(ctx, fp0, fs);
11501 gen_load_fpr64(ctx, fp1, ft);
11502 gen_load_fpr64(ctx, fp2, fr);
11503 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11504 tcg_temp_free_i64(fp0);
11505 tcg_temp_free_i64(fp1);
11506 gen_store_fpr64(ctx, fp2, fd);
11507 tcg_temp_free_i64(fp2);
11508 }
11509 break;
11510 case OPC_MSUB_PS:
11511 check_ps(ctx);
11512 {
11513 TCGv_i64 fp0 = tcg_temp_new_i64();
11514 TCGv_i64 fp1 = tcg_temp_new_i64();
11515 TCGv_i64 fp2 = tcg_temp_new_i64();
11516
11517 gen_load_fpr64(ctx, fp0, fs);
11518 gen_load_fpr64(ctx, fp1, ft);
11519 gen_load_fpr64(ctx, fp2, fr);
11520 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11521 tcg_temp_free_i64(fp0);
11522 tcg_temp_free_i64(fp1);
11523 gen_store_fpr64(ctx, fp2, fd);
11524 tcg_temp_free_i64(fp2);
11525 }
11526 break;
11527 case OPC_NMADD_S:
11528 check_cop1x(ctx);
11529 {
11530 TCGv_i32 fp0 = tcg_temp_new_i32();
11531 TCGv_i32 fp1 = tcg_temp_new_i32();
11532 TCGv_i32 fp2 = tcg_temp_new_i32();
11533
11534 gen_load_fpr32(ctx, fp0, fs);
11535 gen_load_fpr32(ctx, fp1, ft);
11536 gen_load_fpr32(ctx, fp2, fr);
11537 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11538 tcg_temp_free_i32(fp0);
11539 tcg_temp_free_i32(fp1);
11540 gen_store_fpr32(ctx, fp2, fd);
11541 tcg_temp_free_i32(fp2);
11542 }
11543 break;
11544 case OPC_NMADD_D:
11545 check_cop1x(ctx);
11546 check_cp1_registers(ctx, fd | fs | ft | fr);
11547 {
11548 TCGv_i64 fp0 = tcg_temp_new_i64();
11549 TCGv_i64 fp1 = tcg_temp_new_i64();
11550 TCGv_i64 fp2 = tcg_temp_new_i64();
11551
11552 gen_load_fpr64(ctx, fp0, fs);
11553 gen_load_fpr64(ctx, fp1, ft);
11554 gen_load_fpr64(ctx, fp2, fr);
11555 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11556 tcg_temp_free_i64(fp0);
11557 tcg_temp_free_i64(fp1);
11558 gen_store_fpr64(ctx, fp2, fd);
11559 tcg_temp_free_i64(fp2);
11560 }
11561 break;
11562 case OPC_NMADD_PS:
11563 check_ps(ctx);
11564 {
11565 TCGv_i64 fp0 = tcg_temp_new_i64();
11566 TCGv_i64 fp1 = tcg_temp_new_i64();
11567 TCGv_i64 fp2 = tcg_temp_new_i64();
11568
11569 gen_load_fpr64(ctx, fp0, fs);
11570 gen_load_fpr64(ctx, fp1, ft);
11571 gen_load_fpr64(ctx, fp2, fr);
11572 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11573 tcg_temp_free_i64(fp0);
11574 tcg_temp_free_i64(fp1);
11575 gen_store_fpr64(ctx, fp2, fd);
11576 tcg_temp_free_i64(fp2);
11577 }
11578 break;
11579 case OPC_NMSUB_S:
11580 check_cop1x(ctx);
11581 {
11582 TCGv_i32 fp0 = tcg_temp_new_i32();
11583 TCGv_i32 fp1 = tcg_temp_new_i32();
11584 TCGv_i32 fp2 = tcg_temp_new_i32();
11585
11586 gen_load_fpr32(ctx, fp0, fs);
11587 gen_load_fpr32(ctx, fp1, ft);
11588 gen_load_fpr32(ctx, fp2, fr);
11589 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11590 tcg_temp_free_i32(fp0);
11591 tcg_temp_free_i32(fp1);
11592 gen_store_fpr32(ctx, fp2, fd);
11593 tcg_temp_free_i32(fp2);
11594 }
11595 break;
11596 case OPC_NMSUB_D:
11597 check_cop1x(ctx);
11598 check_cp1_registers(ctx, fd | fs | ft | fr);
11599 {
11600 TCGv_i64 fp0 = tcg_temp_new_i64();
11601 TCGv_i64 fp1 = tcg_temp_new_i64();
11602 TCGv_i64 fp2 = tcg_temp_new_i64();
11603
11604 gen_load_fpr64(ctx, fp0, fs);
11605 gen_load_fpr64(ctx, fp1, ft);
11606 gen_load_fpr64(ctx, fp2, fr);
11607 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11608 tcg_temp_free_i64(fp0);
11609 tcg_temp_free_i64(fp1);
11610 gen_store_fpr64(ctx, fp2, fd);
11611 tcg_temp_free_i64(fp2);
11612 }
11613 break;
11614 case OPC_NMSUB_PS:
11615 check_ps(ctx);
11616 {
11617 TCGv_i64 fp0 = tcg_temp_new_i64();
11618 TCGv_i64 fp1 = tcg_temp_new_i64();
11619 TCGv_i64 fp2 = tcg_temp_new_i64();
11620
11621 gen_load_fpr64(ctx, fp0, fs);
11622 gen_load_fpr64(ctx, fp1, ft);
11623 gen_load_fpr64(ctx, fp2, fr);
11624 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11625 tcg_temp_free_i64(fp0);
11626 tcg_temp_free_i64(fp1);
11627 gen_store_fpr64(ctx, fp2, fd);
11628 tcg_temp_free_i64(fp2);
11629 }
11630 break;
11631 default:
11632 MIPS_INVAL("flt3_arith");
11633 gen_reserved_instruction(ctx);
11634 return;
11635 }
11636}
11637
11638void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11639{
11640 TCGv t0;
11641
11642#if !defined(CONFIG_USER_ONLY)
11643
11644
11645
11646
11647 check_insn(ctx, ISA_MIPS_R2);
11648#endif
11649 t0 = tcg_temp_new();
11650
11651 switch (rd) {
11652 case 0:
11653 gen_helper_rdhwr_cpunum(t0, cpu_env);
11654 gen_store_gpr(t0, rt);
11655 break;
11656 case 1:
11657 gen_helper_rdhwr_synci_step(t0, cpu_env);
11658 gen_store_gpr(t0, rt);
11659 break;
11660 case 2:
11661 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11662 gen_io_start();
11663 }
11664 gen_helper_rdhwr_cc(t0, cpu_env);
11665 gen_store_gpr(t0, rt);
11666
11667
11668
11669
11670
11671 gen_save_pc(ctx->base.pc_next + 4);
11672 ctx->base.is_jmp = DISAS_EXIT;
11673 break;
11674 case 3:
11675 gen_helper_rdhwr_ccres(t0, cpu_env);
11676 gen_store_gpr(t0, rt);
11677 break;
11678 case 4:
11679 check_insn(ctx, ISA_MIPS_R6);
11680 if (sel != 0) {
11681
11682
11683
11684
11685 generate_exception(ctx, EXCP_RI);
11686 }
11687 gen_helper_rdhwr_performance(t0, cpu_env);
11688 gen_store_gpr(t0, rt);
11689 break;
11690 case 5:
11691 check_insn(ctx, ISA_MIPS_R6);
11692 gen_helper_rdhwr_xnp(t0, cpu_env);
11693 gen_store_gpr(t0, rt);
11694 break;
11695 case 29:
11696#if defined(CONFIG_USER_ONLY)
11697 tcg_gen_ld_tl(t0, cpu_env,
11698 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11699 gen_store_gpr(t0, rt);
11700 break;
11701#else
11702 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11703 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11704 tcg_gen_ld_tl(t0, cpu_env,
11705 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11706 gen_store_gpr(t0, rt);
11707 } else {
11708 gen_reserved_instruction(ctx);
11709 }
11710 break;
11711#endif
11712 default:
11713 MIPS_INVAL("rdhwr");
11714 gen_reserved_instruction(ctx);
11715 break;
11716 }
11717 tcg_temp_free(t0);
11718}
11719
11720static inline void clear_branch_hflags(DisasContext *ctx)
11721{
11722 ctx->hflags &= ~MIPS_HFLAG_BMASK;
11723 if (ctx->base.is_jmp == DISAS_NEXT) {
11724 save_cpu_state(ctx, 0);
11725 } else {
11726
11727
11728
11729
11730 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11731 }
11732}
11733
11734static void gen_branch(DisasContext *ctx, int insn_bytes)
11735{
11736 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11737 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11738
11739 clear_branch_hflags(ctx);
11740 ctx->base.is_jmp = DISAS_NORETURN;
11741
11742 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11743 case MIPS_HFLAG_FBNSLOT:
11744 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11745 break;
11746 case MIPS_HFLAG_B:
11747
11748 if (proc_hflags & MIPS_HFLAG_BX) {
11749 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11750 }
11751 gen_goto_tb(ctx, 0, ctx->btarget);
11752 break;
11753 case MIPS_HFLAG_BL:
11754
11755 gen_goto_tb(ctx, 0, ctx->btarget);
11756 break;
11757 case MIPS_HFLAG_BC:
11758
11759 {
11760 TCGLabel *l1 = gen_new_label();
11761
11762 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11763 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11764 gen_set_label(l1);
11765 gen_goto_tb(ctx, 0, ctx->btarget);
11766 }
11767 break;
11768 case MIPS_HFLAG_BR:
11769
11770 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11771 TCGv t0 = tcg_temp_new();
11772 TCGv_i32 t1 = tcg_temp_new_i32();
11773
11774 tcg_gen_andi_tl(t0, btarget, 0x1);
11775 tcg_gen_trunc_tl_i32(t1, t0);
11776 tcg_temp_free(t0);
11777 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11778 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11779 tcg_gen_or_i32(hflags, hflags, t1);
11780 tcg_temp_free_i32(t1);
11781
11782 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11783 } else {
11784 tcg_gen_mov_tl(cpu_PC, btarget);
11785 }
11786 tcg_gen_lookup_and_goto_ptr();
11787 break;
11788 default:
11789 LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11790 gen_reserved_instruction(ctx);
11791 }
11792 }
11793}
11794
11795
11796static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11797 int rs, int rt, int32_t offset)
11798{
11799 int bcond_compute = 0;
11800 TCGv t0 = tcg_temp_new();
11801 TCGv t1 = tcg_temp_new();
11802 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11803
11804 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11805#ifdef MIPS_DEBUG_DISAS
11806 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11807 "\n", ctx->base.pc_next);
11808#endif
11809 gen_reserved_instruction(ctx);
11810 goto out;
11811 }
11812
11813
11814 switch (opc) {
11815
11816 case OPC_BOVC:
11817 case OPC_BNVC:
11818 gen_load_gpr(t0, rs);
11819 gen_load_gpr(t1, rt);
11820 bcond_compute = 1;
11821 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11822 if (rs <= rt && rs == 0) {
11823
11824 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11825 }
11826 break;
11827 case OPC_BLEZC:
11828 case OPC_BGTZC:
11829 gen_load_gpr(t0, rs);
11830 gen_load_gpr(t1, rt);
11831 bcond_compute = 1;
11832 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11833 break;
11834 case OPC_BLEZALC:
11835 case OPC_BGTZALC:
11836 if (rs == 0 || rs == rt) {
11837
11838
11839 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11840 }
11841 gen_load_gpr(t0, rs);
11842 gen_load_gpr(t1, rt);
11843 bcond_compute = 1;
11844 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11845 break;
11846 case OPC_BC:
11847 case OPC_BALC:
11848 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11849 break;
11850 case OPC_BEQZC:
11851 case OPC_BNEZC:
11852 if (rs != 0) {
11853
11854 gen_load_gpr(t0, rs);
11855 bcond_compute = 1;
11856 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11857 } else {
11858
11859 TCGv tbase = tcg_temp_new();
11860 TCGv toffset = tcg_constant_tl(offset);
11861
11862 gen_load_gpr(tbase, rt);
11863 gen_op_addr_add(ctx, btarget, tbase, toffset);
11864 tcg_temp_free(tbase);
11865 }
11866 break;
11867 default:
11868 MIPS_INVAL("Compact branch/jump");
11869 gen_reserved_instruction(ctx);
11870 goto out;
11871 }
11872
11873 if (bcond_compute == 0) {
11874
11875 switch (opc) {
11876 case OPC_JIALC:
11877 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11878
11879 case OPC_JIC:
11880 ctx->hflags |= MIPS_HFLAG_BR;
11881 break;
11882 case OPC_BALC:
11883 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11884
11885 case OPC_BC:
11886 ctx->hflags |= MIPS_HFLAG_B;
11887 break;
11888 default:
11889 MIPS_INVAL("Compact branch/jump");
11890 gen_reserved_instruction(ctx);
11891 goto out;
11892 }
11893
11894
11895 gen_branch(ctx, 4);
11896 } else {
11897
11898 TCGLabel *fs = gen_new_label();
11899 save_cpu_state(ctx, 0);
11900
11901 switch (opc) {
11902 case OPC_BLEZALC:
11903 if (rs == 0 && rt != 0) {
11904
11905 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11906 } else if (rs != 0 && rt != 0 && rs == rt) {
11907
11908 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11909 } else {
11910
11911 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11912 }
11913 break;
11914 case OPC_BGTZALC:
11915 if (rs == 0 && rt != 0) {
11916
11917 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11918 } else if (rs != 0 && rt != 0 && rs == rt) {
11919
11920 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11921 } else {
11922
11923 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11924 }
11925 break;
11926 case OPC_BLEZC:
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_GE), t0, t1, fs);
11936 }
11937 break;
11938 case OPC_BGTZC:
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_LT), t0, t1, fs);
11948 }
11949 break;
11950 case OPC_BOVC:
11951 case OPC_BNVC:
11952 if (rs >= rt) {
11953
11954 TCGv t2 = tcg_temp_new();
11955 TCGv t3 = tcg_temp_new();
11956 TCGv t4 = tcg_temp_new();
11957 TCGv input_overflow = tcg_temp_new();
11958
11959 gen_load_gpr(t0, rs);
11960 gen_load_gpr(t1, rt);
11961 tcg_gen_ext32s_tl(t2, t0);
11962 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11963 tcg_gen_ext32s_tl(t3, t1);
11964 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11965 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11966
11967 tcg_gen_add_tl(t4, t2, t3);
11968 tcg_gen_ext32s_tl(t4, t4);
11969 tcg_gen_xor_tl(t2, t2, t3);
11970 tcg_gen_xor_tl(t3, t4, t3);
11971 tcg_gen_andc_tl(t2, t3, t2);
11972 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11973 tcg_gen_or_tl(t4, t4, input_overflow);
11974 if (opc == OPC_BOVC) {
11975
11976 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11977 } else {
11978
11979 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11980 }
11981 tcg_temp_free(input_overflow);
11982 tcg_temp_free(t4);
11983 tcg_temp_free(t3);
11984 tcg_temp_free(t2);
11985 } else if (rs < rt && rs == 0) {
11986
11987 if (opc == OPC_BEQZALC) {
11988
11989 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11990 } else {
11991
11992 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11993 }
11994 } else {
11995
11996 if (opc == OPC_BEQC) {
11997
11998 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11999 } else {
12000
12001 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12002 }
12003 }
12004 break;
12005 case OPC_BEQZC:
12006 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12007 break;
12008 case OPC_BNEZC:
12009 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12010 break;
12011 default:
12012 MIPS_INVAL("Compact conditional branch/jump");
12013 gen_reserved_instruction(ctx);
12014 goto out;
12015 }
12016
12017
12018 gen_goto_tb(ctx, 1, ctx->btarget);
12019 gen_set_label(fs);
12020
12021 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12022 }
12023
12024out:
12025 tcg_temp_free(t0);
12026 tcg_temp_free(t1);
12027}
12028
12029void gen_addiupc(DisasContext *ctx, int rx, int imm,
12030 int is_64_bit, int extended)
12031{
12032 TCGv t0;
12033
12034 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12035 gen_reserved_instruction(ctx);
12036 return;
12037 }
12038
12039 t0 = tcg_temp_new();
12040
12041 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12042 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12043 if (!is_64_bit) {
12044 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12045 }
12046
12047 tcg_temp_free(t0);
12048}
12049
12050static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12051 int16_t offset)
12052{
12053 TCGv_i32 t0 = tcg_const_i32(op);
12054 TCGv t1 = tcg_temp_new();
12055 gen_base_offset_addr(ctx, t1, base, offset);
12056 gen_helper_cache(cpu_env, t1, t0);
12057 tcg_temp_free(t1);
12058 tcg_temp_free_i32(t0);
12059}
12060
12061static inline bool is_uhi(int sdbbp_code)
12062{
12063#ifdef CONFIG_USER_ONLY
12064 return false;
12065#else
12066 return semihosting_enabled() && sdbbp_code == 1;
12067#endif
12068}
12069
12070#ifdef CONFIG_USER_ONLY
12071
12072static inline void gen_helper_do_semihosting(void *env)
12073{
12074 g_assert_not_reached();
12075}
12076#endif
12077
12078void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
12079{
12080 TCGv t0 = tcg_temp_new();
12081 TCGv t1 = tcg_temp_new();
12082
12083 gen_load_gpr(t0, base);
12084
12085 if (index != 0) {
12086 gen_load_gpr(t1, index);
12087 tcg_gen_shli_tl(t1, t1, 2);
12088 gen_op_addr_add(ctx, t0, t1, t0);
12089 }
12090
12091 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12092 gen_store_gpr(t1, rd);
12093
12094 tcg_temp_free(t0);
12095 tcg_temp_free(t1);
12096}
12097
12098static void gen_sync(int stype)
12099{
12100 TCGBar tcg_mo = TCG_BAR_SC;
12101
12102 switch (stype) {
12103 case 0x4:
12104 tcg_mo |= TCG_MO_ST_ST;
12105 break;
12106 case 0x10:
12107 tcg_mo |= TCG_MO_ALL;
12108 break;
12109 case 0x11:
12110 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12111 break;
12112 case 0x12:
12113 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12114 break;
12115 case 0x13:
12116 tcg_mo |= TCG_MO_LD_LD;
12117 break;
12118 default:
12119 tcg_mo |= TCG_MO_ALL;
12120 break;
12121 }
12122
12123 tcg_gen_mb(tcg_mo);
12124}
12125
12126
12127
12128
12129#include "mips16e_translate.c.inc"
12130
12131
12132
12133
12134
12135
12136
12137enum {
12138 FMT_SD_S = 0,
12139 FMT_SD_D = 1,
12140
12141 FMT_SDPS_S = 0,
12142 FMT_SDPS_D = 1,
12143 FMT_SDPS_PS = 2,
12144
12145 FMT_SWL_S = 0,
12146 FMT_SWL_W = 1,
12147 FMT_SWL_L = 2,
12148
12149 FMT_DWL_D = 0,
12150 FMT_DWL_W = 1,
12151 FMT_DWL_L = 2
12152};
12153
12154#include "micromips_translate.c.inc"
12155
12156#include "nanomips_translate.c.inc"
12157
12158
12159static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12160 int rd, int base, int offset)
12161{
12162 TCGv t0;
12163
12164 check_dsp(ctx);
12165 t0 = tcg_temp_new();
12166
12167 if (base == 0) {
12168 gen_load_gpr(t0, offset);
12169 } else if (offset == 0) {
12170 gen_load_gpr(t0, base);
12171 } else {
12172 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12173 }
12174
12175 switch (opc) {
12176 case OPC_LBUX:
12177 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12178 gen_store_gpr(t0, rd);
12179 break;
12180 case OPC_LHX:
12181 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12182 gen_store_gpr(t0, rd);
12183 break;
12184 case OPC_LWX:
12185 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12186 gen_store_gpr(t0, rd);
12187 break;
12188#if defined(TARGET_MIPS64)
12189 case OPC_LDX:
12190 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12191 gen_store_gpr(t0, rd);
12192 break;
12193#endif
12194 }
12195 tcg_temp_free(t0);
12196}
12197
12198static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12199 int ret, int v1, int v2)
12200{
12201 TCGv v1_t;
12202 TCGv v2_t;
12203
12204 if (ret == 0) {
12205
12206 return;
12207 }
12208
12209 v1_t = tcg_temp_new();
12210 v2_t = tcg_temp_new();
12211
12212 gen_load_gpr(v1_t, v1);
12213 gen_load_gpr(v2_t, v2);
12214
12215 switch (op1) {
12216
12217 case OPC_MULT_G_2E:
12218 check_dsp_r2(ctx);
12219 switch (op2) {
12220 case OPC_ADDUH_QB:
12221 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12222 break;
12223 case OPC_ADDUH_R_QB:
12224 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12225 break;
12226 case OPC_ADDQH_PH:
12227 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12228 break;
12229 case OPC_ADDQH_R_PH:
12230 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12231 break;
12232 case OPC_ADDQH_W:
12233 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12234 break;
12235 case OPC_ADDQH_R_W:
12236 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12237 break;
12238 case OPC_SUBUH_QB:
12239 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12240 break;
12241 case OPC_SUBUH_R_QB:
12242 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12243 break;
12244 case OPC_SUBQH_PH:
12245 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12246 break;
12247 case OPC_SUBQH_R_PH:
12248 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12249 break;
12250 case OPC_SUBQH_W:
12251 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12252 break;
12253 case OPC_SUBQH_R_W:
12254 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12255 break;
12256 }
12257 break;
12258 case OPC_ABSQ_S_PH_DSP:
12259 switch (op2) {
12260 case OPC_ABSQ_S_QB:
12261 check_dsp_r2(ctx);
12262 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12263 break;
12264 case OPC_ABSQ_S_PH:
12265 check_dsp(ctx);
12266 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12267 break;
12268 case OPC_ABSQ_S_W:
12269 check_dsp(ctx);
12270 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12271 break;
12272 case OPC_PRECEQ_W_PHL:
12273 check_dsp(ctx);
12274 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12275 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12276 break;
12277 case OPC_PRECEQ_W_PHR:
12278 check_dsp(ctx);
12279 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12280 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12281 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12282 break;
12283 case OPC_PRECEQU_PH_QBL:
12284 check_dsp(ctx);
12285 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12286 break;
12287 case OPC_PRECEQU_PH_QBR:
12288 check_dsp(ctx);
12289 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12290 break;
12291 case OPC_PRECEQU_PH_QBLA:
12292 check_dsp(ctx);
12293 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12294 break;
12295 case OPC_PRECEQU_PH_QBRA:
12296 check_dsp(ctx);
12297 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12298 break;
12299 case OPC_PRECEU_PH_QBL:
12300 check_dsp(ctx);
12301 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12302 break;
12303 case OPC_PRECEU_PH_QBR:
12304 check_dsp(ctx);
12305 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12306 break;
12307 case OPC_PRECEU_PH_QBLA:
12308 check_dsp(ctx);
12309 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12310 break;
12311 case OPC_PRECEU_PH_QBRA:
12312 check_dsp(ctx);
12313 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12314 break;
12315 }
12316 break;
12317 case OPC_ADDU_QB_DSP:
12318 switch (op2) {
12319 case OPC_ADDQ_PH:
12320 check_dsp(ctx);
12321 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12322 break;
12323 case OPC_ADDQ_S_PH:
12324 check_dsp(ctx);
12325 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12326 break;
12327 case OPC_ADDQ_S_W:
12328 check_dsp(ctx);
12329 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12330 break;
12331 case OPC_ADDU_QB:
12332 check_dsp(ctx);
12333 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12334 break;
12335 case OPC_ADDU_S_QB:
12336 check_dsp(ctx);
12337 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12338 break;
12339 case OPC_ADDU_PH:
12340 check_dsp_r2(ctx);
12341 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12342 break;
12343 case OPC_ADDU_S_PH:
12344 check_dsp_r2(ctx);
12345 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12346 break;
12347 case OPC_SUBQ_PH:
12348 check_dsp(ctx);
12349 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12350 break;
12351 case OPC_SUBQ_S_PH:
12352 check_dsp(ctx);
12353 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12354 break;
12355 case OPC_SUBQ_S_W:
12356 check_dsp(ctx);
12357 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12358 break;
12359 case OPC_SUBU_QB:
12360 check_dsp(ctx);
12361 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12362 break;
12363 case OPC_SUBU_S_QB:
12364 check_dsp(ctx);
12365 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12366 break;
12367 case OPC_SUBU_PH:
12368 check_dsp_r2(ctx);
12369 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12370 break;
12371 case OPC_SUBU_S_PH:
12372 check_dsp_r2(ctx);
12373 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12374 break;
12375 case OPC_ADDSC:
12376 check_dsp(ctx);
12377 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12378 break;
12379 case OPC_ADDWC:
12380 check_dsp(ctx);
12381 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12382 break;
12383 case OPC_MODSUB:
12384 check_dsp(ctx);
12385 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12386 break;
12387 case OPC_RADDU_W_QB:
12388 check_dsp(ctx);
12389 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12390 break;
12391 }
12392 break;
12393 case OPC_CMPU_EQ_QB_DSP:
12394 switch (op2) {
12395 case OPC_PRECR_QB_PH:
12396 check_dsp_r2(ctx);
12397 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12398 break;
12399 case OPC_PRECRQ_QB_PH:
12400 check_dsp(ctx);
12401 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12402 break;
12403 case OPC_PRECR_SRA_PH_W:
12404 check_dsp_r2(ctx);
12405 {
12406 TCGv_i32 sa_t = tcg_const_i32(v2);
12407 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12408 cpu_gpr[ret]);
12409 tcg_temp_free_i32(sa_t);
12410 break;
12411 }
12412 case OPC_PRECR_SRA_R_PH_W:
12413 check_dsp_r2(ctx);
12414 {
12415 TCGv_i32 sa_t = tcg_const_i32(v2);
12416 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12417 cpu_gpr[ret]);
12418 tcg_temp_free_i32(sa_t);
12419 break;
12420 }
12421 case OPC_PRECRQ_PH_W:
12422 check_dsp(ctx);
12423 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12424 break;
12425 case OPC_PRECRQ_RS_PH_W:
12426 check_dsp(ctx);
12427 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12428 break;
12429 case OPC_PRECRQU_S_QB_PH:
12430 check_dsp(ctx);
12431 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12432 break;
12433 }
12434 break;
12435#ifdef TARGET_MIPS64
12436 case OPC_ABSQ_S_QH_DSP:
12437 switch (op2) {
12438 case OPC_PRECEQ_L_PWL:
12439 check_dsp(ctx);
12440 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12441 break;
12442 case OPC_PRECEQ_L_PWR:
12443 check_dsp(ctx);
12444 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12445 break;
12446 case OPC_PRECEQ_PW_QHL:
12447 check_dsp(ctx);
12448 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12449 break;
12450 case OPC_PRECEQ_PW_QHR:
12451 check_dsp(ctx);
12452 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12453 break;
12454 case OPC_PRECEQ_PW_QHLA:
12455 check_dsp(ctx);
12456 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12457 break;
12458 case OPC_PRECEQ_PW_QHRA:
12459 check_dsp(ctx);
12460 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12461 break;
12462 case OPC_PRECEQU_QH_OBL:
12463 check_dsp(ctx);
12464 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12465 break;
12466 case OPC_PRECEQU_QH_OBR:
12467 check_dsp(ctx);
12468 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12469 break;
12470 case OPC_PRECEQU_QH_OBLA:
12471 check_dsp(ctx);
12472 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12473 break;
12474 case OPC_PRECEQU_QH_OBRA:
12475 check_dsp(ctx);
12476 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12477 break;
12478 case OPC_PRECEU_QH_OBL:
12479 check_dsp(ctx);
12480 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12481 break;
12482 case OPC_PRECEU_QH_OBR:
12483 check_dsp(ctx);
12484 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12485 break;
12486 case OPC_PRECEU_QH_OBLA:
12487 check_dsp(ctx);
12488 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12489 break;
12490 case OPC_PRECEU_QH_OBRA:
12491 check_dsp(ctx);
12492 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12493 break;
12494 case OPC_ABSQ_S_OB:
12495 check_dsp_r2(ctx);
12496 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12497 break;
12498 case OPC_ABSQ_S_PW:
12499 check_dsp(ctx);
12500 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12501 break;
12502 case OPC_ABSQ_S_QH:
12503 check_dsp(ctx);
12504 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12505 break;
12506 }
12507 break;
12508 case OPC_ADDU_OB_DSP:
12509 switch (op2) {
12510 case OPC_RADDU_L_OB:
12511 check_dsp(ctx);
12512 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12513 break;
12514 case OPC_SUBQ_PW:
12515 check_dsp(ctx);
12516 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12517 break;
12518 case OPC_SUBQ_S_PW:
12519 check_dsp(ctx);
12520 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12521 break;
12522 case OPC_SUBQ_QH:
12523 check_dsp(ctx);
12524 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12525 break;
12526 case OPC_SUBQ_S_QH:
12527 check_dsp(ctx);
12528 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12529 break;
12530 case OPC_SUBU_OB:
12531 check_dsp(ctx);
12532 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12533 break;
12534 case OPC_SUBU_S_OB:
12535 check_dsp(ctx);
12536 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12537 break;
12538 case OPC_SUBU_QH:
12539 check_dsp_r2(ctx);
12540 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12541 break;
12542 case OPC_SUBU_S_QH:
12543 check_dsp_r2(ctx);
12544 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12545 break;
12546 case OPC_SUBUH_OB:
12547 check_dsp_r2(ctx);
12548 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12549 break;
12550 case OPC_SUBUH_R_OB:
12551 check_dsp_r2(ctx);
12552 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12553 break;
12554 case OPC_ADDQ_PW:
12555 check_dsp(ctx);
12556 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12557 break;
12558 case OPC_ADDQ_S_PW:
12559 check_dsp(ctx);
12560 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12561 break;
12562 case OPC_ADDQ_QH:
12563 check_dsp(ctx);
12564 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12565 break;
12566 case OPC_ADDQ_S_QH:
12567 check_dsp(ctx);
12568 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12569 break;
12570 case OPC_ADDU_OB:
12571 check_dsp(ctx);
12572 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12573 break;
12574 case OPC_ADDU_S_OB:
12575 check_dsp(ctx);
12576 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12577 break;
12578 case OPC_ADDU_QH:
12579 check_dsp_r2(ctx);
12580 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12581 break;
12582 case OPC_ADDU_S_QH:
12583 check_dsp_r2(ctx);
12584 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12585 break;
12586 case OPC_ADDUH_OB:
12587 check_dsp_r2(ctx);
12588 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12589 break;
12590 case OPC_ADDUH_R_OB:
12591 check_dsp_r2(ctx);
12592 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12593 break;
12594 }
12595 break;
12596 case OPC_CMPU_EQ_OB_DSP:
12597 switch (op2) {
12598 case OPC_PRECR_OB_QH:
12599 check_dsp_r2(ctx);
12600 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12601 break;
12602 case OPC_PRECR_SRA_QH_PW:
12603 check_dsp_r2(ctx);
12604 {
12605 TCGv_i32 ret_t = tcg_const_i32(ret);
12606 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12607 tcg_temp_free_i32(ret_t);
12608 break;
12609 }
12610 case OPC_PRECR_SRA_R_QH_PW:
12611 check_dsp_r2(ctx);
12612 {
12613 TCGv_i32 sa_v = tcg_const_i32(ret);
12614 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12615 tcg_temp_free_i32(sa_v);
12616 break;
12617 }
12618 case OPC_PRECRQ_OB_QH:
12619 check_dsp(ctx);
12620 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12621 break;
12622 case OPC_PRECRQ_PW_L:
12623 check_dsp(ctx);
12624 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12625 break;
12626 case OPC_PRECRQ_QH_PW:
12627 check_dsp(ctx);
12628 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12629 break;
12630 case OPC_PRECRQ_RS_QH_PW:
12631 check_dsp(ctx);
12632 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12633 break;
12634 case OPC_PRECRQU_S_OB_QH:
12635 check_dsp(ctx);
12636 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12637 break;
12638 }
12639 break;
12640#endif
12641 }
12642
12643 tcg_temp_free(v1_t);
12644 tcg_temp_free(v2_t);
12645}
12646
12647static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12648 int ret, int v1, int v2)
12649{
12650 uint32_t op2;
12651 TCGv t0;
12652 TCGv v1_t;
12653 TCGv v2_t;
12654
12655 if (ret == 0) {
12656
12657 return;
12658 }
12659
12660 t0 = tcg_temp_new();
12661 v1_t = tcg_temp_new();
12662 v2_t = tcg_temp_new();
12663
12664 tcg_gen_movi_tl(t0, v1);
12665 gen_load_gpr(v1_t, v1);
12666 gen_load_gpr(v2_t, v2);
12667
12668 switch (opc) {
12669 case OPC_SHLL_QB_DSP:
12670 {
12671 op2 = MASK_SHLL_QB(ctx->opcode);
12672 switch (op2) {
12673 case OPC_SHLL_QB:
12674 check_dsp(ctx);
12675 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12676 break;
12677 case OPC_SHLLV_QB:
12678 check_dsp(ctx);
12679 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12680 break;
12681 case OPC_SHLL_PH:
12682 check_dsp(ctx);
12683 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12684 break;
12685 case OPC_SHLLV_PH:
12686 check_dsp(ctx);
12687 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12688 break;
12689 case OPC_SHLL_S_PH:
12690 check_dsp(ctx);
12691 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12692 break;
12693 case OPC_SHLLV_S_PH:
12694 check_dsp(ctx);
12695 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12696 break;
12697 case OPC_SHLL_S_W:
12698 check_dsp(ctx);
12699 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12700 break;
12701 case OPC_SHLLV_S_W:
12702 check_dsp(ctx);
12703 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12704 break;
12705 case OPC_SHRL_QB:
12706 check_dsp(ctx);
12707 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12708 break;
12709 case OPC_SHRLV_QB:
12710 check_dsp(ctx);
12711 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12712 break;
12713 case OPC_SHRL_PH:
12714 check_dsp_r2(ctx);
12715 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12716 break;
12717 case OPC_SHRLV_PH:
12718 check_dsp_r2(ctx);
12719 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12720 break;
12721 case OPC_SHRA_QB:
12722 check_dsp_r2(ctx);
12723 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12724 break;
12725 case OPC_SHRA_R_QB:
12726 check_dsp_r2(ctx);
12727 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12728 break;
12729 case OPC_SHRAV_QB:
12730 check_dsp_r2(ctx);
12731 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_SHRAV_R_QB:
12734 check_dsp_r2(ctx);
12735 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12736 break;
12737 case OPC_SHRA_PH:
12738 check_dsp(ctx);
12739 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12740 break;
12741 case OPC_SHRA_R_PH:
12742 check_dsp(ctx);
12743 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12744 break;
12745 case OPC_SHRAV_PH:
12746 check_dsp(ctx);
12747 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12748 break;
12749 case OPC_SHRAV_R_PH:
12750 check_dsp(ctx);
12751 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_SHRA_R_W:
12754 check_dsp(ctx);
12755 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12756 break;
12757 case OPC_SHRAV_R_W:
12758 check_dsp(ctx);
12759 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12760 break;
12761 default:
12762 MIPS_INVAL("MASK SHLL.QB");
12763 gen_reserved_instruction(ctx);
12764 break;
12765 }
12766 break;
12767 }
12768#ifdef TARGET_MIPS64
12769 case OPC_SHLL_OB_DSP:
12770 op2 = MASK_SHLL_OB(ctx->opcode);
12771 switch (op2) {
12772 case OPC_SHLL_PW:
12773 check_dsp(ctx);
12774 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12775 break;
12776 case OPC_SHLLV_PW:
12777 check_dsp(ctx);
12778 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12779 break;
12780 case OPC_SHLL_S_PW:
12781 check_dsp(ctx);
12782 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12783 break;
12784 case OPC_SHLLV_S_PW:
12785 check_dsp(ctx);
12786 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12787 break;
12788 case OPC_SHLL_OB:
12789 check_dsp(ctx);
12790 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12791 break;
12792 case OPC_SHLLV_OB:
12793 check_dsp(ctx);
12794 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12795 break;
12796 case OPC_SHLL_QH:
12797 check_dsp(ctx);
12798 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12799 break;
12800 case OPC_SHLLV_QH:
12801 check_dsp(ctx);
12802 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12803 break;
12804 case OPC_SHLL_S_QH:
12805 check_dsp(ctx);
12806 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12807 break;
12808 case OPC_SHLLV_S_QH:
12809 check_dsp(ctx);
12810 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12811 break;
12812 case OPC_SHRA_OB:
12813 check_dsp_r2(ctx);
12814 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12815 break;
12816 case OPC_SHRAV_OB:
12817 check_dsp_r2(ctx);
12818 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12819 break;
12820 case OPC_SHRA_R_OB:
12821 check_dsp_r2(ctx);
12822 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12823 break;
12824 case OPC_SHRAV_R_OB:
12825 check_dsp_r2(ctx);
12826 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12827 break;
12828 case OPC_SHRA_PW:
12829 check_dsp(ctx);
12830 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12831 break;
12832 case OPC_SHRAV_PW:
12833 check_dsp(ctx);
12834 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12835 break;
12836 case OPC_SHRA_R_PW:
12837 check_dsp(ctx);
12838 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12839 break;
12840 case OPC_SHRAV_R_PW:
12841 check_dsp(ctx);
12842 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12843 break;
12844 case OPC_SHRA_QH:
12845 check_dsp(ctx);
12846 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12847 break;
12848 case OPC_SHRAV_QH:
12849 check_dsp(ctx);
12850 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12851 break;
12852 case OPC_SHRA_R_QH:
12853 check_dsp(ctx);
12854 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12855 break;
12856 case OPC_SHRAV_R_QH:
12857 check_dsp(ctx);
12858 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12859 break;
12860 case OPC_SHRL_OB:
12861 check_dsp(ctx);
12862 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12863 break;
12864 case OPC_SHRLV_OB:
12865 check_dsp(ctx);
12866 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12867 break;
12868 case OPC_SHRL_QH:
12869 check_dsp_r2(ctx);
12870 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12871 break;
12872 case OPC_SHRLV_QH:
12873 check_dsp_r2(ctx);
12874 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12875 break;
12876 default:
12877 MIPS_INVAL("MASK SHLL.OB");
12878 gen_reserved_instruction(ctx);
12879 break;
12880 }
12881 break;
12882#endif
12883 }
12884
12885 tcg_temp_free(t0);
12886 tcg_temp_free(v1_t);
12887 tcg_temp_free(v2_t);
12888}
12889
12890static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12891 int ret, int v1, int v2, int check_ret)
12892{
12893 TCGv_i32 t0;
12894 TCGv v1_t;
12895 TCGv v2_t;
12896
12897 if ((ret == 0) && (check_ret == 1)) {
12898
12899 return;
12900 }
12901
12902 t0 = tcg_temp_new_i32();
12903 v1_t = tcg_temp_new();
12904 v2_t = tcg_temp_new();
12905
12906 tcg_gen_movi_i32(t0, ret);
12907 gen_load_gpr(v1_t, v1);
12908 gen_load_gpr(v2_t, v2);
12909
12910 switch (op1) {
12911
12912
12913
12914
12915 case OPC_MULT_G_2E:
12916 check_dsp_r2(ctx);
12917 switch (op2) {
12918 case OPC_MUL_PH:
12919 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12920 break;
12921 case OPC_MUL_S_PH:
12922 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12923 break;
12924 case OPC_MULQ_S_W:
12925 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12926 break;
12927 case OPC_MULQ_RS_W:
12928 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12929 break;
12930 }
12931 break;
12932 case OPC_DPA_W_PH_DSP:
12933 switch (op2) {
12934 case OPC_DPAU_H_QBL:
12935 check_dsp(ctx);
12936 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12937 break;
12938 case OPC_DPAU_H_QBR:
12939 check_dsp(ctx);
12940 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12941 break;
12942 case OPC_DPSU_H_QBL:
12943 check_dsp(ctx);
12944 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12945 break;
12946 case OPC_DPSU_H_QBR:
12947 check_dsp(ctx);
12948 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12949 break;
12950 case OPC_DPA_W_PH:
12951 check_dsp_r2(ctx);
12952 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12953 break;
12954 case OPC_DPAX_W_PH:
12955 check_dsp_r2(ctx);
12956 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12957 break;
12958 case OPC_DPAQ_S_W_PH:
12959 check_dsp(ctx);
12960 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12961 break;
12962 case OPC_DPAQX_S_W_PH:
12963 check_dsp_r2(ctx);
12964 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12965 break;
12966 case OPC_DPAQX_SA_W_PH:
12967 check_dsp_r2(ctx);
12968 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12969 break;
12970 case OPC_DPS_W_PH:
12971 check_dsp_r2(ctx);
12972 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
12973 break;
12974 case OPC_DPSX_W_PH:
12975 check_dsp_r2(ctx);
12976 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
12977 break;
12978 case OPC_DPSQ_S_W_PH:
12979 check_dsp(ctx);
12980 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12981 break;
12982 case OPC_DPSQX_S_W_PH:
12983 check_dsp_r2(ctx);
12984 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12985 break;
12986 case OPC_DPSQX_SA_W_PH:
12987 check_dsp_r2(ctx);
12988 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12989 break;
12990 case OPC_MULSAQ_S_W_PH:
12991 check_dsp(ctx);
12992 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12993 break;
12994 case OPC_DPAQ_SA_L_W:
12995 check_dsp(ctx);
12996 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
12997 break;
12998 case OPC_DPSQ_SA_L_W:
12999 check_dsp(ctx);
13000 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13001 break;
13002 case OPC_MAQ_S_W_PHL:
13003 check_dsp(ctx);
13004 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13005 break;
13006 case OPC_MAQ_S_W_PHR:
13007 check_dsp(ctx);
13008 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13009 break;
13010 case OPC_MAQ_SA_W_PHL:
13011 check_dsp(ctx);
13012 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13013 break;
13014 case OPC_MAQ_SA_W_PHR:
13015 check_dsp(ctx);
13016 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13017 break;
13018 case OPC_MULSA_W_PH:
13019 check_dsp_r2(ctx);
13020 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13021 break;
13022 }
13023 break;
13024#ifdef TARGET_MIPS64
13025 case OPC_DPAQ_W_QH_DSP:
13026 {
13027 int ac = ret & 0x03;
13028 tcg_gen_movi_i32(t0, ac);
13029
13030 switch (op2) {
13031 case OPC_DMADD:
13032 check_dsp(ctx);
13033 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13034 break;
13035 case OPC_DMADDU:
13036 check_dsp(ctx);
13037 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13038 break;
13039 case OPC_DMSUB:
13040 check_dsp(ctx);
13041 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13042 break;
13043 case OPC_DMSUBU:
13044 check_dsp(ctx);
13045 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13046 break;
13047 case OPC_DPA_W_QH:
13048 check_dsp_r2(ctx);
13049 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13050 break;
13051 case OPC_DPAQ_S_W_QH:
13052 check_dsp(ctx);
13053 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13054 break;
13055 case OPC_DPAQ_SA_L_PW:
13056 check_dsp(ctx);
13057 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13058 break;
13059 case OPC_DPAU_H_OBL:
13060 check_dsp(ctx);
13061 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13062 break;
13063 case OPC_DPAU_H_OBR:
13064 check_dsp(ctx);
13065 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13066 break;
13067 case OPC_DPS_W_QH:
13068 check_dsp_r2(ctx);
13069 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13070 break;
13071 case OPC_DPSQ_S_W_QH:
13072 check_dsp(ctx);
13073 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13074 break;
13075 case OPC_DPSQ_SA_L_PW:
13076 check_dsp(ctx);
13077 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13078 break;
13079 case OPC_DPSU_H_OBL:
13080 check_dsp(ctx);
13081 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13082 break;
13083 case OPC_DPSU_H_OBR:
13084 check_dsp(ctx);
13085 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13086 break;
13087 case OPC_MAQ_S_L_PWL:
13088 check_dsp(ctx);
13089 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13090 break;
13091 case OPC_MAQ_S_L_PWR:
13092 check_dsp(ctx);
13093 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13094 break;
13095 case OPC_MAQ_S_W_QHLL:
13096 check_dsp(ctx);
13097 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13098 break;
13099 case OPC_MAQ_SA_W_QHLL:
13100 check_dsp(ctx);
13101 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13102 break;
13103 case OPC_MAQ_S_W_QHLR:
13104 check_dsp(ctx);
13105 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13106 break;
13107 case OPC_MAQ_SA_W_QHLR:
13108 check_dsp(ctx);
13109 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13110 break;
13111 case OPC_MAQ_S_W_QHRL:
13112 check_dsp(ctx);
13113 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13114 break;
13115 case OPC_MAQ_SA_W_QHRL:
13116 check_dsp(ctx);
13117 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13118 break;
13119 case OPC_MAQ_S_W_QHRR:
13120 check_dsp(ctx);
13121 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13122 break;
13123 case OPC_MAQ_SA_W_QHRR:
13124 check_dsp(ctx);
13125 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13126 break;
13127 case OPC_MULSAQ_S_L_PW:
13128 check_dsp(ctx);
13129 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13130 break;
13131 case OPC_MULSAQ_S_W_QH:
13132 check_dsp(ctx);
13133 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13134 break;
13135 }
13136 }
13137 break;
13138#endif
13139 case OPC_ADDU_QB_DSP:
13140 switch (op2) {
13141 case OPC_MULEU_S_PH_QBL:
13142 check_dsp(ctx);
13143 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13144 break;
13145 case OPC_MULEU_S_PH_QBR:
13146 check_dsp(ctx);
13147 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13148 break;
13149 case OPC_MULQ_RS_PH:
13150 check_dsp(ctx);
13151 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152 break;
13153 case OPC_MULEQ_S_W_PHL:
13154 check_dsp(ctx);
13155 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13156 break;
13157 case OPC_MULEQ_S_W_PHR:
13158 check_dsp(ctx);
13159 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13160 break;
13161 case OPC_MULQ_S_PH:
13162 check_dsp_r2(ctx);
13163 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13164 break;
13165 }
13166 break;
13167#ifdef TARGET_MIPS64
13168 case OPC_ADDU_OB_DSP:
13169 switch (op2) {
13170 case OPC_MULEQ_S_PW_QHL:
13171 check_dsp(ctx);
13172 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13173 break;
13174 case OPC_MULEQ_S_PW_QHR:
13175 check_dsp(ctx);
13176 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13177 break;
13178 case OPC_MULEU_S_QH_OBL:
13179 check_dsp(ctx);
13180 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13181 break;
13182 case OPC_MULEU_S_QH_OBR:
13183 check_dsp(ctx);
13184 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13185 break;
13186 case OPC_MULQ_RS_QH:
13187 check_dsp(ctx);
13188 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13189 break;
13190 }
13191 break;
13192#endif
13193 }
13194
13195 tcg_temp_free_i32(t0);
13196 tcg_temp_free(v1_t);
13197 tcg_temp_free(v2_t);
13198}
13199
13200static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13201 int ret, int val)
13202{
13203 int16_t imm;
13204 TCGv t0;
13205 TCGv val_t;
13206
13207 if (ret == 0) {
13208
13209 return;
13210 }
13211
13212 t0 = tcg_temp_new();
13213 val_t = tcg_temp_new();
13214 gen_load_gpr(val_t, val);
13215
13216 switch (op1) {
13217 case OPC_ABSQ_S_PH_DSP:
13218 switch (op2) {
13219 case OPC_BITREV:
13220 check_dsp(ctx);
13221 gen_helper_bitrev(cpu_gpr[ret], val_t);
13222 break;
13223 case OPC_REPL_QB:
13224 check_dsp(ctx);
13225 {
13226 target_long result;
13227 imm = (ctx->opcode >> 16) & 0xFF;
13228 result = (uint32_t)imm << 24 |
13229 (uint32_t)imm << 16 |
13230 (uint32_t)imm << 8 |
13231 (uint32_t)imm;
13232 result = (int32_t)result;
13233 tcg_gen_movi_tl(cpu_gpr[ret], result);
13234 }
13235 break;
13236 case OPC_REPLV_QB:
13237 check_dsp(ctx);
13238 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13239 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13240 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13241 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13242 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13243 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13244 break;
13245 case OPC_REPL_PH:
13246 check_dsp(ctx);
13247 {
13248 imm = (ctx->opcode >> 16) & 0x03FF;
13249 imm = (int16_t)(imm << 6) >> 6;
13250 tcg_gen_movi_tl(cpu_gpr[ret], \
13251 (target_long)((int32_t)imm << 16 | \
13252 (uint16_t)imm));
13253 }
13254 break;
13255 case OPC_REPLV_PH:
13256 check_dsp(ctx);
13257 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13258 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13259 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13260 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13261 break;
13262 }
13263 break;
13264#ifdef TARGET_MIPS64
13265 case OPC_ABSQ_S_QH_DSP:
13266 switch (op2) {
13267 case OPC_REPL_OB:
13268 check_dsp(ctx);
13269 {
13270 target_long temp;
13271
13272 imm = (ctx->opcode >> 16) & 0xFF;
13273 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13274 temp = (temp << 16) | temp;
13275 temp = (temp << 32) | temp;
13276 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13277 break;
13278 }
13279 case OPC_REPL_PW:
13280 check_dsp(ctx);
13281 {
13282 target_long temp;
13283
13284 imm = (ctx->opcode >> 16) & 0x03FF;
13285 imm = (int16_t)(imm << 6) >> 6;
13286 temp = ((target_long)imm << 32) \
13287 | ((target_long)imm & 0xFFFFFFFF);
13288 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13289 break;
13290 }
13291 case OPC_REPL_QH:
13292 check_dsp(ctx);
13293 {
13294 target_long temp;
13295
13296 imm = (ctx->opcode >> 16) & 0x03FF;
13297 imm = (int16_t)(imm << 6) >> 6;
13298
13299 temp = ((uint64_t)(uint16_t)imm << 48) |
13300 ((uint64_t)(uint16_t)imm << 32) |
13301 ((uint64_t)(uint16_t)imm << 16) |
13302 (uint64_t)(uint16_t)imm;
13303 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13304 break;
13305 }
13306 case OPC_REPLV_OB:
13307 check_dsp(ctx);
13308 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13309 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13310 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13311 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13312 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13313 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13314 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13315 break;
13316 case OPC_REPLV_PW:
13317 check_dsp(ctx);
13318 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13319 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13320 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13321 break;
13322 case OPC_REPLV_QH:
13323 check_dsp(ctx);
13324 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13325 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13326 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13327 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13328 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13329 break;
13330 }
13331 break;
13332#endif
13333 }
13334 tcg_temp_free(t0);
13335 tcg_temp_free(val_t);
13336}
13337
13338static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13339 uint32_t op1, uint32_t op2,
13340 int ret, int v1, int v2, int check_ret)
13341{
13342 TCGv t1;
13343 TCGv v1_t;
13344 TCGv v2_t;
13345
13346 if ((ret == 0) && (check_ret == 1)) {
13347
13348 return;
13349 }
13350
13351 t1 = tcg_temp_new();
13352 v1_t = tcg_temp_new();
13353 v2_t = tcg_temp_new();
13354
13355 gen_load_gpr(v1_t, v1);
13356 gen_load_gpr(v2_t, v2);
13357
13358 switch (op1) {
13359 case OPC_CMPU_EQ_QB_DSP:
13360 switch (op2) {
13361 case OPC_CMPU_EQ_QB:
13362 check_dsp(ctx);
13363 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13364 break;
13365 case OPC_CMPU_LT_QB:
13366 check_dsp(ctx);
13367 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13368 break;
13369 case OPC_CMPU_LE_QB:
13370 check_dsp(ctx);
13371 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13372 break;
13373 case OPC_CMPGU_EQ_QB:
13374 check_dsp(ctx);
13375 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13376 break;
13377 case OPC_CMPGU_LT_QB:
13378 check_dsp(ctx);
13379 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13380 break;
13381 case OPC_CMPGU_LE_QB:
13382 check_dsp(ctx);
13383 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13384 break;
13385 case OPC_CMPGDU_EQ_QB:
13386 check_dsp_r2(ctx);
13387 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13388 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13389 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13390 tcg_gen_shli_tl(t1, t1, 24);
13391 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13392 break;
13393 case OPC_CMPGDU_LT_QB:
13394 check_dsp_r2(ctx);
13395 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13396 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13397 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13398 tcg_gen_shli_tl(t1, t1, 24);
13399 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13400 break;
13401 case OPC_CMPGDU_LE_QB:
13402 check_dsp_r2(ctx);
13403 gen_helper_cmpgu_le_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_CMP_EQ_PH:
13410 check_dsp(ctx);
13411 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13412 break;
13413 case OPC_CMP_LT_PH:
13414 check_dsp(ctx);
13415 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13416 break;
13417 case OPC_CMP_LE_PH:
13418 check_dsp(ctx);
13419 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13420 break;
13421 case OPC_PICK_QB:
13422 check_dsp(ctx);
13423 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13424 break;
13425 case OPC_PICK_PH:
13426 check_dsp(ctx);
13427 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13428 break;
13429 case OPC_PACKRL_PH:
13430 check_dsp(ctx);
13431 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13432 break;
13433 }
13434 break;
13435#ifdef TARGET_MIPS64
13436 case OPC_CMPU_EQ_OB_DSP:
13437 switch (op2) {
13438 case OPC_CMP_EQ_PW:
13439 check_dsp(ctx);
13440 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13441 break;
13442 case OPC_CMP_LT_PW:
13443 check_dsp(ctx);
13444 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13445 break;
13446 case OPC_CMP_LE_PW:
13447 check_dsp(ctx);
13448 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13449 break;
13450 case OPC_CMP_EQ_QH:
13451 check_dsp(ctx);
13452 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13453 break;
13454 case OPC_CMP_LT_QH:
13455 check_dsp(ctx);
13456 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13457 break;
13458 case OPC_CMP_LE_QH:
13459 check_dsp(ctx);
13460 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13461 break;
13462 case OPC_CMPGDU_EQ_OB:
13463 check_dsp_r2(ctx);
13464 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13465 break;
13466 case OPC_CMPGDU_LT_OB:
13467 check_dsp_r2(ctx);
13468 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13469 break;
13470 case OPC_CMPGDU_LE_OB:
13471 check_dsp_r2(ctx);
13472 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13473 break;
13474 case OPC_CMPGU_EQ_OB:
13475 check_dsp(ctx);
13476 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13477 break;
13478 case OPC_CMPGU_LT_OB:
13479 check_dsp(ctx);
13480 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13481 break;
13482 case OPC_CMPGU_LE_OB:
13483 check_dsp(ctx);
13484 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13485 break;
13486 case OPC_CMPU_EQ_OB:
13487 check_dsp(ctx);
13488 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13489 break;
13490 case OPC_CMPU_LT_OB:
13491 check_dsp(ctx);
13492 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13493 break;
13494 case OPC_CMPU_LE_OB:
13495 check_dsp(ctx);
13496 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13497 break;
13498 case OPC_PACKRL_PW:
13499 check_dsp(ctx);
13500 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13501 break;
13502 case OPC_PICK_OB:
13503 check_dsp(ctx);
13504 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13505 break;
13506 case OPC_PICK_PW:
13507 check_dsp(ctx);
13508 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13509 break;
13510 case OPC_PICK_QH:
13511 check_dsp(ctx);
13512 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13513 break;
13514 }
13515 break;
13516#endif
13517 }
13518
13519 tcg_temp_free(t1);
13520 tcg_temp_free(v1_t);
13521 tcg_temp_free(v2_t);
13522}
13523
13524static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13525 uint32_t op1, int rt, int rs, int sa)
13526{
13527 TCGv t0;
13528
13529 check_dsp_r2(ctx);
13530
13531 if (rt == 0) {
13532
13533 return;
13534 }
13535
13536 t0 = tcg_temp_new();
13537 gen_load_gpr(t0, rs);
13538
13539 switch (op1) {
13540 case OPC_APPEND_DSP:
13541 switch (MASK_APPEND(ctx->opcode)) {
13542 case OPC_APPEND:
13543 if (sa != 0) {
13544 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13545 }
13546 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13547 break;
13548 case OPC_PREPEND:
13549 if (sa != 0) {
13550 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13551 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13552 tcg_gen_shli_tl(t0, t0, 32 - sa);
13553 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13554 }
13555 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13556 break;
13557 case OPC_BALIGN:
13558 sa &= 3;
13559 if (sa != 0 && sa != 2) {
13560 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13561 tcg_gen_ext32u_tl(t0, t0);
13562 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13563 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13564 }
13565 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13566 break;
13567 default:
13568 MIPS_INVAL("MASK APPEND");
13569 gen_reserved_instruction(ctx);
13570 break;
13571 }
13572 break;
13573#ifdef TARGET_MIPS64
13574 case OPC_DAPPEND_DSP:
13575 switch (MASK_DAPPEND(ctx->opcode)) {
13576 case OPC_DAPPEND:
13577 if (sa != 0) {
13578 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13579 }
13580 break;
13581 case OPC_PREPENDD:
13582 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13583 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13584 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13585 break;
13586 case OPC_PREPENDW:
13587 if (sa != 0) {
13588 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13589 tcg_gen_shli_tl(t0, t0, 64 - sa);
13590 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13591 }
13592 break;
13593 case OPC_DBALIGN:
13594 sa &= 7;
13595 if (sa != 0 && sa != 2 && sa != 4) {
13596 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13597 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13598 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13599 }
13600 break;
13601 default:
13602 MIPS_INVAL("MASK DAPPEND");
13603 gen_reserved_instruction(ctx);
13604 break;
13605 }
13606 break;
13607#endif
13608 }
13609 tcg_temp_free(t0);
13610}
13611
13612static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13613 int ret, int v1, int v2, int check_ret)
13614
13615{
13616 TCGv t0;
13617 TCGv t1;
13618 TCGv v1_t;
13619 int16_t imm;
13620
13621 if ((ret == 0) && (check_ret == 1)) {
13622
13623 return;
13624 }
13625
13626 t0 = tcg_temp_new();
13627 t1 = tcg_temp_new();
13628 v1_t = tcg_temp_new();
13629
13630 gen_load_gpr(v1_t, v1);
13631
13632 switch (op1) {
13633 case OPC_EXTR_W_DSP:
13634 check_dsp(ctx);
13635 switch (op2) {
13636 case OPC_EXTR_W:
13637 tcg_gen_movi_tl(t0, v2);
13638 tcg_gen_movi_tl(t1, v1);
13639 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13640 break;
13641 case OPC_EXTR_R_W:
13642 tcg_gen_movi_tl(t0, v2);
13643 tcg_gen_movi_tl(t1, v1);
13644 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13645 break;
13646 case OPC_EXTR_RS_W:
13647 tcg_gen_movi_tl(t0, v2);
13648 tcg_gen_movi_tl(t1, v1);
13649 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13650 break;
13651 case OPC_EXTR_S_H:
13652 tcg_gen_movi_tl(t0, v2);
13653 tcg_gen_movi_tl(t1, v1);
13654 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13655 break;
13656 case OPC_EXTRV_S_H:
13657 tcg_gen_movi_tl(t0, v2);
13658 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13659 break;
13660 case OPC_EXTRV_W:
13661 tcg_gen_movi_tl(t0, v2);
13662 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13663 break;
13664 case OPC_EXTRV_R_W:
13665 tcg_gen_movi_tl(t0, v2);
13666 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13667 break;
13668 case OPC_EXTRV_RS_W:
13669 tcg_gen_movi_tl(t0, v2);
13670 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13671 break;
13672 case OPC_EXTP:
13673 tcg_gen_movi_tl(t0, v2);
13674 tcg_gen_movi_tl(t1, v1);
13675 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13676 break;
13677 case OPC_EXTPV:
13678 tcg_gen_movi_tl(t0, v2);
13679 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13680 break;
13681 case OPC_EXTPDP:
13682 tcg_gen_movi_tl(t0, v2);
13683 tcg_gen_movi_tl(t1, v1);
13684 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13685 break;
13686 case OPC_EXTPDPV:
13687 tcg_gen_movi_tl(t0, v2);
13688 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13689 break;
13690 case OPC_SHILO:
13691 imm = (ctx->opcode >> 20) & 0x3F;
13692 tcg_gen_movi_tl(t0, ret);
13693 tcg_gen_movi_tl(t1, imm);
13694 gen_helper_shilo(t0, t1, cpu_env);
13695 break;
13696 case OPC_SHILOV:
13697 tcg_gen_movi_tl(t0, ret);
13698 gen_helper_shilo(t0, v1_t, cpu_env);
13699 break;
13700 case OPC_MTHLIP:
13701 tcg_gen_movi_tl(t0, ret);
13702 gen_helper_mthlip(t0, v1_t, cpu_env);
13703 break;
13704 case OPC_WRDSP:
13705 imm = (ctx->opcode >> 11) & 0x3FF;
13706 tcg_gen_movi_tl(t0, imm);
13707 gen_helper_wrdsp(v1_t, t0, cpu_env);
13708 break;
13709 case OPC_RDDSP:
13710 imm = (ctx->opcode >> 16) & 0x03FF;
13711 tcg_gen_movi_tl(t0, imm);
13712 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13713 break;
13714 }
13715 break;
13716#ifdef TARGET_MIPS64
13717 case OPC_DEXTR_W_DSP:
13718 check_dsp(ctx);
13719 switch (op2) {
13720 case OPC_DMTHLIP:
13721 tcg_gen_movi_tl(t0, ret);
13722 gen_helper_dmthlip(v1_t, t0, cpu_env);
13723 break;
13724 case OPC_DSHILO:
13725 {
13726 int shift = (ctx->opcode >> 19) & 0x7F;
13727 int ac = (ctx->opcode >> 11) & 0x03;
13728 tcg_gen_movi_tl(t0, shift);
13729 tcg_gen_movi_tl(t1, ac);
13730 gen_helper_dshilo(t0, t1, cpu_env);
13731 break;
13732 }
13733 case OPC_DSHILOV:
13734 {
13735 int ac = (ctx->opcode >> 11) & 0x03;
13736 tcg_gen_movi_tl(t0, ac);
13737 gen_helper_dshilo(v1_t, t0, cpu_env);
13738 break;
13739 }
13740 case OPC_DEXTP:
13741 tcg_gen_movi_tl(t0, v2);
13742 tcg_gen_movi_tl(t1, v1);
13743
13744 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13745 break;
13746 case OPC_DEXTPV:
13747 tcg_gen_movi_tl(t0, v2);
13748 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13749 break;
13750 case OPC_DEXTPDP:
13751 tcg_gen_movi_tl(t0, v2);
13752 tcg_gen_movi_tl(t1, v1);
13753 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13754 break;
13755 case OPC_DEXTPDPV:
13756 tcg_gen_movi_tl(t0, v2);
13757 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13758 break;
13759 case OPC_DEXTR_L:
13760 tcg_gen_movi_tl(t0, v2);
13761 tcg_gen_movi_tl(t1, v1);
13762 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13763 break;
13764 case OPC_DEXTR_R_L:
13765 tcg_gen_movi_tl(t0, v2);
13766 tcg_gen_movi_tl(t1, v1);
13767 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13768 break;
13769 case OPC_DEXTR_RS_L:
13770 tcg_gen_movi_tl(t0, v2);
13771 tcg_gen_movi_tl(t1, v1);
13772 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13773 break;
13774 case OPC_DEXTR_W:
13775 tcg_gen_movi_tl(t0, v2);
13776 tcg_gen_movi_tl(t1, v1);
13777 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13778 break;
13779 case OPC_DEXTR_R_W:
13780 tcg_gen_movi_tl(t0, v2);
13781 tcg_gen_movi_tl(t1, v1);
13782 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13783 break;
13784 case OPC_DEXTR_RS_W:
13785 tcg_gen_movi_tl(t0, v2);
13786 tcg_gen_movi_tl(t1, v1);
13787 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13788 break;
13789 case OPC_DEXTR_S_H:
13790 tcg_gen_movi_tl(t0, v2);
13791 tcg_gen_movi_tl(t1, v1);
13792 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13793 break;
13794 case OPC_DEXTRV_S_H:
13795 tcg_gen_movi_tl(t0, v2);
13796 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13797 break;
13798 case OPC_DEXTRV_L:
13799 tcg_gen_movi_tl(t0, v2);
13800 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13801 break;
13802 case OPC_DEXTRV_R_L:
13803 tcg_gen_movi_tl(t0, v2);
13804 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13805 break;
13806 case OPC_DEXTRV_RS_L:
13807 tcg_gen_movi_tl(t0, v2);
13808 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13809 break;
13810 case OPC_DEXTRV_W:
13811 tcg_gen_movi_tl(t0, v2);
13812 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13813 break;
13814 case OPC_DEXTRV_R_W:
13815 tcg_gen_movi_tl(t0, v2);
13816 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13817 break;
13818 case OPC_DEXTRV_RS_W:
13819 tcg_gen_movi_tl(t0, v2);
13820 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13821 break;
13822 }
13823 break;
13824#endif
13825 }
13826
13827 tcg_temp_free(t0);
13828 tcg_temp_free(t1);
13829 tcg_temp_free(v1_t);
13830}
13831
13832
13833
13834static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13835{
13836 int rs, rt, rd, sa;
13837 uint32_t op1, op2;
13838
13839 rs = (ctx->opcode >> 21) & 0x1f;
13840 rt = (ctx->opcode >> 16) & 0x1f;
13841 rd = (ctx->opcode >> 11) & 0x1f;
13842 sa = (ctx->opcode >> 6) & 0x1f;
13843
13844 op1 = MASK_SPECIAL(ctx->opcode);
13845 switch (op1) {
13846 case OPC_MULT:
13847 case OPC_MULTU:
13848 case OPC_DIV:
13849 case OPC_DIVU:
13850 op2 = MASK_R6_MULDIV(ctx->opcode);
13851 switch (op2) {
13852 case R6_OPC_MUL:
13853 case R6_OPC_MUH:
13854 case R6_OPC_MULU:
13855 case R6_OPC_MUHU:
13856 case R6_OPC_DIV:
13857 case R6_OPC_MOD:
13858 case R6_OPC_DIVU:
13859 case R6_OPC_MODU:
13860 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13861 break;
13862 default:
13863 MIPS_INVAL("special_r6 muldiv");
13864 gen_reserved_instruction(ctx);
13865 break;
13866 }
13867 break;
13868 case OPC_SELEQZ:
13869 case OPC_SELNEZ:
13870 gen_cond_move(ctx, op1, rd, rs, rt);
13871 break;
13872 case R6_OPC_CLO:
13873 case R6_OPC_CLZ:
13874 if (rt == 0 && sa == 1) {
13875
13876
13877
13878
13879 gen_cl(ctx, op1, rd, rs);
13880 } else {
13881 gen_reserved_instruction(ctx);
13882 }
13883 break;
13884 case R6_OPC_SDBBP:
13885 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
13886 gen_helper_do_semihosting(cpu_env);
13887 } else {
13888 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13889 gen_reserved_instruction(ctx);
13890 } else {
13891 generate_exception_end(ctx, EXCP_DBp);
13892 }
13893 }
13894 break;
13895#if defined(TARGET_MIPS64)
13896 case R6_OPC_DCLO:
13897 case R6_OPC_DCLZ:
13898 if (rt == 0 && sa == 1) {
13899
13900
13901
13902
13903 check_mips_64(ctx);
13904 gen_cl(ctx, op1, rd, rs);
13905 } else {
13906 gen_reserved_instruction(ctx);
13907 }
13908 break;
13909 case OPC_DMULT:
13910 case OPC_DMULTU:
13911 case OPC_DDIV:
13912 case OPC_DDIVU:
13913
13914 op2 = MASK_R6_MULDIV(ctx->opcode);
13915 switch (op2) {
13916 case R6_OPC_DMUL:
13917 case R6_OPC_DMUH:
13918 case R6_OPC_DMULU:
13919 case R6_OPC_DMUHU:
13920 case R6_OPC_DDIV:
13921 case R6_OPC_DMOD:
13922 case R6_OPC_DDIVU:
13923 case R6_OPC_DMODU:
13924 check_mips_64(ctx);
13925 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13926 break;
13927 default:
13928 MIPS_INVAL("special_r6 muldiv");
13929 gen_reserved_instruction(ctx);
13930 break;
13931 }
13932 break;
13933#endif
13934 default:
13935 MIPS_INVAL("special_r6");
13936 gen_reserved_instruction(ctx);
13937 break;
13938 }
13939}
13940
13941static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13942{
13943 int rs = extract32(ctx->opcode, 21, 5);
13944 int rt = extract32(ctx->opcode, 16, 5);
13945 int rd = extract32(ctx->opcode, 11, 5);
13946 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13947
13948 switch (op1) {
13949 case OPC_MOVN:
13950 case OPC_MOVZ:
13951 gen_cond_move(ctx, op1, rd, rs, rt);
13952 break;
13953 case OPC_MFHI:
13954 case OPC_MFLO:
13955 gen_HILO(ctx, op1, 0, rd);
13956 break;
13957 case OPC_MTHI:
13958 case OPC_MTLO:
13959 gen_HILO(ctx, op1, 0, rs);
13960 break;
13961 case OPC_MULT:
13962 case OPC_MULTU:
13963 gen_mul_txx9(ctx, op1, rd, rs, rt);
13964 break;
13965 case OPC_DIV:
13966 case OPC_DIVU:
13967 gen_muldiv(ctx, op1, 0, rs, rt);
13968 break;
13969#if defined(TARGET_MIPS64)
13970 case OPC_DMULT:
13971 case OPC_DMULTU:
13972 case OPC_DDIV:
13973 case OPC_DDIVU:
13974 check_insn_opc_user_only(ctx, INSN_R5900);
13975 gen_muldiv(ctx, op1, 0, rs, rt);
13976 break;
13977#endif
13978 case OPC_JR:
13979 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13980 break;
13981 default:
13982 MIPS_INVAL("special_tx79");
13983 gen_reserved_instruction(ctx);
13984 break;
13985 }
13986}
13987
13988static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13989{
13990 int rs, rt, rd;
13991 uint32_t op1;
13992
13993 rs = (ctx->opcode >> 21) & 0x1f;
13994 rt = (ctx->opcode >> 16) & 0x1f;
13995 rd = (ctx->opcode >> 11) & 0x1f;
13996
13997 op1 = MASK_SPECIAL(ctx->opcode);
13998 switch (op1) {
13999 case OPC_MOVN:
14000 case OPC_MOVZ:
14001 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
14002 INSN_LOONGSON2E | INSN_LOONGSON2F);
14003 gen_cond_move(ctx, op1, rd, rs, rt);
14004 break;
14005 case OPC_MFHI:
14006 case OPC_MFLO:
14007 gen_HILO(ctx, op1, rs & 3, rd);
14008 break;
14009 case OPC_MTHI:
14010 case OPC_MTLO:
14011 gen_HILO(ctx, op1, rd & 3, rs);
14012 break;
14013 case OPC_MOVCI:
14014 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
14015 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14016 check_cp1_enabled(ctx);
14017 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14018 (ctx->opcode >> 16) & 1);
14019 } else {
14020 generate_exception_err(ctx, EXCP_CpU, 1);
14021 }
14022 break;
14023 case OPC_MULT:
14024 case OPC_MULTU:
14025 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14026 break;
14027 case OPC_DIV:
14028 case OPC_DIVU:
14029 gen_muldiv(ctx, op1, 0, rs, rt);
14030 break;
14031#if defined(TARGET_MIPS64)
14032 case OPC_DMULT:
14033 case OPC_DMULTU:
14034 case OPC_DDIV:
14035 case OPC_DDIVU:
14036 check_insn(ctx, ISA_MIPS3);
14037 check_mips_64(ctx);
14038 gen_muldiv(ctx, op1, 0, rs, rt);
14039 break;
14040#endif
14041 case OPC_JR:
14042 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14043 break;
14044 case OPC_SPIM:
14045#ifdef MIPS_STRICT_STANDARD
14046 MIPS_INVAL("SPIM");
14047 gen_reserved_instruction(ctx);
14048#else
14049
14050 MIPS_INVAL("spim (unofficial)");
14051 gen_reserved_instruction(ctx);
14052#endif
14053 break;
14054 default:
14055 MIPS_INVAL("special_legacy");
14056 gen_reserved_instruction(ctx);
14057 break;
14058 }
14059}
14060
14061static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
14062{
14063 int rs, rt, rd, sa;
14064 uint32_t op1;
14065
14066 rs = (ctx->opcode >> 21) & 0x1f;
14067 rt = (ctx->opcode >> 16) & 0x1f;
14068 rd = (ctx->opcode >> 11) & 0x1f;
14069 sa = (ctx->opcode >> 6) & 0x1f;
14070
14071 op1 = MASK_SPECIAL(ctx->opcode);
14072 switch (op1) {
14073 case OPC_SLL:
14074 if (sa == 5 && rd == 0 &&
14075 rs == 0 && rt == 0) {
14076 if ((ctx->insn_flags & ISA_MIPS_R6) &&
14077 (ctx->hflags & MIPS_HFLAG_BMASK)) {
14078 gen_reserved_instruction(ctx);
14079 break;
14080 }
14081 }
14082
14083 case OPC_SRA:
14084 gen_shift_imm(ctx, op1, rd, rt, sa);
14085 break;
14086 case OPC_SRL:
14087 switch ((ctx->opcode >> 21) & 0x1f) {
14088 case 1:
14089
14090 if (ctx->insn_flags & ISA_MIPS_R2) {
14091 op1 = OPC_ROTR;
14092 }
14093
14094 case 0:
14095 gen_shift_imm(ctx, op1, rd, rt, sa);
14096 break;
14097 default:
14098 gen_reserved_instruction(ctx);
14099 break;
14100 }
14101 break;
14102 case OPC_ADD:
14103 case OPC_ADDU:
14104 case OPC_SUB:
14105 case OPC_SUBU:
14106 gen_arith(ctx, op1, rd, rs, rt);
14107 break;
14108 case OPC_SLLV:
14109 case OPC_SRAV:
14110 gen_shift(ctx, op1, rd, rs, rt);
14111 break;
14112 case OPC_SRLV:
14113 switch ((ctx->opcode >> 6) & 0x1f) {
14114 case 1:
14115
14116 if (ctx->insn_flags & ISA_MIPS_R2) {
14117 op1 = OPC_ROTRV;
14118 }
14119
14120 case 0:
14121 gen_shift(ctx, op1, rd, rs, rt);
14122 break;
14123 default:
14124 gen_reserved_instruction(ctx);
14125 break;
14126 }
14127 break;
14128 case OPC_SLT:
14129 case OPC_SLTU:
14130 gen_slt(ctx, op1, rd, rs, rt);
14131 break;
14132 case OPC_AND:
14133 case OPC_OR:
14134 case OPC_NOR:
14135 case OPC_XOR:
14136 gen_logic(ctx, op1, rd, rs, rt);
14137 break;
14138 case OPC_JALR:
14139 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14140 break;
14141 case OPC_TGE:
14142 case OPC_TGEU:
14143 case OPC_TLT:
14144 case OPC_TLTU:
14145 case OPC_TEQ:
14146 case OPC_TNE:
14147 check_insn(ctx, ISA_MIPS2);
14148 gen_trap(ctx, op1, rs, rt, -1);
14149 break;
14150 case OPC_PMON:
14151
14152#ifdef MIPS_STRICT_STANDARD
14153 MIPS_INVAL("PMON / selsl");
14154 gen_reserved_instruction(ctx);
14155#else
14156 gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
14157#endif
14158 break;
14159 case OPC_SYSCALL:
14160 generate_exception_end(ctx, EXCP_SYSCALL);
14161 break;
14162 case OPC_BREAK:
14163 generate_exception_end(ctx, EXCP_BREAK);
14164 break;
14165 case OPC_SYNC:
14166 check_insn(ctx, ISA_MIPS2);
14167 gen_sync(extract32(ctx->opcode, 6, 5));
14168 break;
14169
14170#if defined(TARGET_MIPS64)
14171
14172 case OPC_DSLL:
14173 case OPC_DSRA:
14174 case OPC_DSLL32:
14175 case OPC_DSRA32:
14176 check_insn(ctx, ISA_MIPS3);
14177 check_mips_64(ctx);
14178 gen_shift_imm(ctx, op1, rd, rt, sa);
14179 break;
14180 case OPC_DSRL:
14181 switch ((ctx->opcode >> 21) & 0x1f) {
14182 case 1:
14183
14184 if (ctx->insn_flags & ISA_MIPS_R2) {
14185 op1 = OPC_DROTR;
14186 }
14187
14188 case 0:
14189 check_insn(ctx, ISA_MIPS3);
14190 check_mips_64(ctx);
14191 gen_shift_imm(ctx, op1, rd, rt, sa);
14192 break;
14193 default:
14194 gen_reserved_instruction(ctx);
14195 break;
14196 }
14197 break;
14198 case OPC_DSRL32:
14199 switch ((ctx->opcode >> 21) & 0x1f) {
14200 case 1:
14201
14202 if (ctx->insn_flags & ISA_MIPS_R2) {
14203 op1 = OPC_DROTR32;
14204 }
14205
14206 case 0:
14207 check_insn(ctx, ISA_MIPS3);
14208 check_mips_64(ctx);
14209 gen_shift_imm(ctx, op1, rd, rt, sa);
14210 break;
14211 default:
14212 gen_reserved_instruction(ctx);
14213 break;
14214 }
14215 break;
14216 case OPC_DADD:
14217 case OPC_DADDU:
14218 case OPC_DSUB:
14219 case OPC_DSUBU:
14220 check_insn(ctx, ISA_MIPS3);
14221 check_mips_64(ctx);
14222 gen_arith(ctx, op1, rd, rs, rt);
14223 break;
14224 case OPC_DSLLV:
14225 case OPC_DSRAV:
14226 check_insn(ctx, ISA_MIPS3);
14227 check_mips_64(ctx);
14228 gen_shift(ctx, op1, rd, rs, rt);
14229 break;
14230 case OPC_DSRLV:
14231 switch ((ctx->opcode >> 6) & 0x1f) {
14232 case 1:
14233
14234 if (ctx->insn_flags & ISA_MIPS_R2) {
14235 op1 = OPC_DROTRV;
14236 }
14237
14238 case 0:
14239 check_insn(ctx, ISA_MIPS3);
14240 check_mips_64(ctx);
14241 gen_shift(ctx, op1, rd, rs, rt);
14242 break;
14243 default:
14244 gen_reserved_instruction(ctx);
14245 break;
14246 }
14247 break;
14248#endif
14249 default:
14250 if (ctx->insn_flags & ISA_MIPS_R6) {
14251 decode_opc_special_r6(env, ctx);
14252 } else if (ctx->insn_flags & INSN_R5900) {
14253 decode_opc_special_tx79(env, ctx);
14254 } else {
14255 decode_opc_special_legacy(env, ctx);
14256 }
14257 }
14258}
14259
14260
14261static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
14262{
14263 int rs, rt, rd;
14264 uint32_t op1;
14265
14266 rs = (ctx->opcode >> 21) & 0x1f;
14267 rt = (ctx->opcode >> 16) & 0x1f;
14268 rd = (ctx->opcode >> 11) & 0x1f;
14269
14270 op1 = MASK_SPECIAL2(ctx->opcode);
14271 switch (op1) {
14272 case OPC_MADD:
14273 case OPC_MADDU:
14274 case OPC_MSUB:
14275 case OPC_MSUBU:
14276 check_insn(ctx, ISA_MIPS_R1);
14277 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14278 break;
14279 case OPC_MUL:
14280 gen_arith(ctx, op1, rd, rs, rt);
14281 break;
14282 case OPC_DIV_G_2F:
14283 case OPC_DIVU_G_2F:
14284 case OPC_MULT_G_2F:
14285 case OPC_MULTU_G_2F:
14286 case OPC_MOD_G_2F:
14287 case OPC_MODU_G_2F:
14288 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14289 gen_loongson_integer(ctx, op1, rd, rs, rt);
14290 break;
14291 case OPC_CLO:
14292 case OPC_CLZ:
14293 check_insn(ctx, ISA_MIPS_R1);
14294 gen_cl(ctx, op1, rd, rs);
14295 break;
14296 case OPC_SDBBP:
14297 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14298 gen_helper_do_semihosting(cpu_env);
14299 } else {
14300
14301
14302
14303
14304 check_insn(ctx, ISA_MIPS_R1);
14305 generate_exception_end(ctx, EXCP_DBp);
14306 }
14307 break;
14308#if defined(TARGET_MIPS64)
14309 case OPC_DCLO:
14310 case OPC_DCLZ:
14311 check_insn(ctx, ISA_MIPS_R1);
14312 check_mips_64(ctx);
14313 gen_cl(ctx, op1, rd, rs);
14314 break;
14315 case OPC_DMULT_G_2F:
14316 case OPC_DMULTU_G_2F:
14317 case OPC_DDIV_G_2F:
14318 case OPC_DDIVU_G_2F:
14319 case OPC_DMOD_G_2F:
14320 case OPC_DMODU_G_2F:
14321 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14322 gen_loongson_integer(ctx, op1, rd, rs, rt);
14323 break;
14324#endif
14325 default:
14326 MIPS_INVAL("special2_legacy");
14327 gen_reserved_instruction(ctx);
14328 break;
14329 }
14330}
14331
14332static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14333{
14334 int rs, rt, rd, sa;
14335 uint32_t op1, op2;
14336 int16_t imm;
14337
14338 rs = (ctx->opcode >> 21) & 0x1f;
14339 rt = (ctx->opcode >> 16) & 0x1f;
14340 rd = (ctx->opcode >> 11) & 0x1f;
14341 sa = (ctx->opcode >> 6) & 0x1f;
14342 imm = (int16_t)ctx->opcode >> 7;
14343
14344 op1 = MASK_SPECIAL3(ctx->opcode);
14345 switch (op1) {
14346 case R6_OPC_PREF:
14347 if (rt >= 24) {
14348
14349 gen_reserved_instruction(ctx);
14350 }
14351
14352 break;
14353 case R6_OPC_CACHE:
14354 check_cp0_enabled(ctx);
14355 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14356 gen_cache_operation(ctx, rt, rs, imm);
14357 }
14358 break;
14359 case R6_OPC_SC:
14360 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14361 break;
14362 case R6_OPC_LL:
14363 gen_ld(ctx, op1, rt, rs, imm);
14364 break;
14365 case OPC_BSHFL:
14366 {
14367 if (rd == 0) {
14368
14369 break;
14370 }
14371 op2 = MASK_BSHFL(ctx->opcode);
14372 switch (op2) {
14373 case OPC_ALIGN:
14374 case OPC_ALIGN_1:
14375 case OPC_ALIGN_2:
14376 case OPC_ALIGN_3:
14377 gen_align(ctx, 32, rd, rs, rt, sa & 3);
14378 break;
14379 case OPC_BITSWAP:
14380 gen_bitswap(ctx, op2, rd, rt);
14381 break;
14382 }
14383 }
14384 break;
14385#ifndef CONFIG_USER_ONLY
14386 case OPC_GINV:
14387 if (unlikely(ctx->gi <= 1)) {
14388 gen_reserved_instruction(ctx);
14389 }
14390 check_cp0_enabled(ctx);
14391 switch ((ctx->opcode >> 6) & 3) {
14392 case 0:
14393
14394 break;
14395 case 2:
14396 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14397 break;
14398 default:
14399 gen_reserved_instruction(ctx);
14400 break;
14401 }
14402 break;
14403#endif
14404#if defined(TARGET_MIPS64)
14405 case R6_OPC_SCD:
14406 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
14407 break;
14408 case R6_OPC_LLD:
14409 gen_ld(ctx, op1, rt, rs, imm);
14410 break;
14411 case OPC_DBSHFL:
14412 check_mips_64(ctx);
14413 {
14414 if (rd == 0) {
14415
14416 break;
14417 }
14418 op2 = MASK_DBSHFL(ctx->opcode);
14419 switch (op2) {
14420 case OPC_DALIGN:
14421 case OPC_DALIGN_1:
14422 case OPC_DALIGN_2:
14423 case OPC_DALIGN_3:
14424 case OPC_DALIGN_4:
14425 case OPC_DALIGN_5:
14426 case OPC_DALIGN_6:
14427 case OPC_DALIGN_7:
14428 gen_align(ctx, 64, rd, rs, rt, sa & 7);
14429 break;
14430 case OPC_DBITSWAP:
14431 gen_bitswap(ctx, op2, rd, rt);
14432 break;
14433 }
14434
14435 }
14436 break;
14437#endif
14438 default:
14439 MIPS_INVAL("special3_r6");
14440 gen_reserved_instruction(ctx);
14441 break;
14442 }
14443}
14444
14445static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14446{
14447 int rs, rt, rd;
14448 uint32_t op1, op2;
14449
14450 rs = (ctx->opcode >> 21) & 0x1f;
14451 rt = (ctx->opcode >> 16) & 0x1f;
14452 rd = (ctx->opcode >> 11) & 0x1f;
14453
14454 op1 = MASK_SPECIAL3(ctx->opcode);
14455 switch (op1) {
14456 case OPC_DIV_G_2E:
14457 case OPC_DIVU_G_2E:
14458 case OPC_MOD_G_2E:
14459 case OPC_MODU_G_2E:
14460 case OPC_MULT_G_2E:
14461 case OPC_MULTU_G_2E:
14462
14463
14464
14465
14466 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
14467 op2 = MASK_ADDUH_QB(ctx->opcode);
14468 switch (op2) {
14469 case OPC_ADDUH_QB:
14470 case OPC_ADDUH_R_QB:
14471 case OPC_ADDQH_PH:
14472 case OPC_ADDQH_R_PH:
14473 case OPC_ADDQH_W:
14474 case OPC_ADDQH_R_W:
14475 case OPC_SUBUH_QB:
14476 case OPC_SUBUH_R_QB:
14477 case OPC_SUBQH_PH:
14478 case OPC_SUBQH_R_PH:
14479 case OPC_SUBQH_W:
14480 case OPC_SUBQH_R_W:
14481 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14482 break;
14483 case OPC_MUL_PH:
14484 case OPC_MUL_S_PH:
14485 case OPC_MULQ_S_W:
14486 case OPC_MULQ_RS_W:
14487 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14488 break;
14489 default:
14490 MIPS_INVAL("MASK ADDUH.QB");
14491 gen_reserved_instruction(ctx);
14492 break;
14493 }
14494 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14495 gen_loongson_integer(ctx, op1, rd, rs, rt);
14496 } else {
14497 gen_reserved_instruction(ctx);
14498 }
14499 break;
14500 case OPC_LX_DSP:
14501 op2 = MASK_LX(ctx->opcode);
14502 switch (op2) {
14503#if defined(TARGET_MIPS64)
14504 case OPC_LDX:
14505#endif
14506 case OPC_LBUX:
14507 case OPC_LHX:
14508 case OPC_LWX:
14509 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14510 break;
14511 default:
14512 MIPS_INVAL("MASK LX");
14513 gen_reserved_instruction(ctx);
14514 break;
14515 }
14516 break;
14517 case OPC_ABSQ_S_PH_DSP:
14518 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14519 switch (op2) {
14520 case OPC_ABSQ_S_QB:
14521 case OPC_ABSQ_S_PH:
14522 case OPC_ABSQ_S_W:
14523 case OPC_PRECEQ_W_PHL:
14524 case OPC_PRECEQ_W_PHR:
14525 case OPC_PRECEQU_PH_QBL:
14526 case OPC_PRECEQU_PH_QBR:
14527 case OPC_PRECEQU_PH_QBLA:
14528 case OPC_PRECEQU_PH_QBRA:
14529 case OPC_PRECEU_PH_QBL:
14530 case OPC_PRECEU_PH_QBR:
14531 case OPC_PRECEU_PH_QBLA:
14532 case OPC_PRECEU_PH_QBRA:
14533 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14534 break;
14535 case OPC_BITREV:
14536 case OPC_REPL_QB:
14537 case OPC_REPLV_QB:
14538 case OPC_REPL_PH:
14539 case OPC_REPLV_PH:
14540 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14541 break;
14542 default:
14543 MIPS_INVAL("MASK ABSQ_S.PH");
14544 gen_reserved_instruction(ctx);
14545 break;
14546 }
14547 break;
14548 case OPC_ADDU_QB_DSP:
14549 op2 = MASK_ADDU_QB(ctx->opcode);
14550 switch (op2) {
14551 case OPC_ADDQ_PH:
14552 case OPC_ADDQ_S_PH:
14553 case OPC_ADDQ_S_W:
14554 case OPC_ADDU_QB:
14555 case OPC_ADDU_S_QB:
14556 case OPC_ADDU_PH:
14557 case OPC_ADDU_S_PH:
14558 case OPC_SUBQ_PH:
14559 case OPC_SUBQ_S_PH:
14560 case OPC_SUBQ_S_W:
14561 case OPC_SUBU_QB:
14562 case OPC_SUBU_S_QB:
14563 case OPC_SUBU_PH:
14564 case OPC_SUBU_S_PH:
14565 case OPC_ADDSC:
14566 case OPC_ADDWC:
14567 case OPC_MODSUB:
14568 case OPC_RADDU_W_QB:
14569 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14570 break;
14571 case OPC_MULEU_S_PH_QBL:
14572 case OPC_MULEU_S_PH_QBR:
14573 case OPC_MULQ_RS_PH:
14574 case OPC_MULEQ_S_W_PHL:
14575 case OPC_MULEQ_S_W_PHR:
14576 case OPC_MULQ_S_PH:
14577 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14578 break;
14579 default:
14580 MIPS_INVAL("MASK ADDU.QB");
14581 gen_reserved_instruction(ctx);
14582 break;
14583
14584 }
14585 break;
14586 case OPC_CMPU_EQ_QB_DSP:
14587 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14588 switch (op2) {
14589 case OPC_PRECR_SRA_PH_W:
14590 case OPC_PRECR_SRA_R_PH_W:
14591 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14592 break;
14593 case OPC_PRECR_QB_PH:
14594 case OPC_PRECRQ_QB_PH:
14595 case OPC_PRECRQ_PH_W:
14596 case OPC_PRECRQ_RS_PH_W:
14597 case OPC_PRECRQU_S_QB_PH:
14598 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14599 break;
14600 case OPC_CMPU_EQ_QB:
14601 case OPC_CMPU_LT_QB:
14602 case OPC_CMPU_LE_QB:
14603 case OPC_CMP_EQ_PH:
14604 case OPC_CMP_LT_PH:
14605 case OPC_CMP_LE_PH:
14606 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14607 break;
14608 case OPC_CMPGU_EQ_QB:
14609 case OPC_CMPGU_LT_QB:
14610 case OPC_CMPGU_LE_QB:
14611 case OPC_CMPGDU_EQ_QB:
14612 case OPC_CMPGDU_LT_QB:
14613 case OPC_CMPGDU_LE_QB:
14614 case OPC_PICK_QB:
14615 case OPC_PICK_PH:
14616 case OPC_PACKRL_PH:
14617 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14618 break;
14619 default:
14620 MIPS_INVAL("MASK CMPU.EQ.QB");
14621 gen_reserved_instruction(ctx);
14622 break;
14623 }
14624 break;
14625 case OPC_SHLL_QB_DSP:
14626 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14627 break;
14628 case OPC_DPA_W_PH_DSP:
14629 op2 = MASK_DPA_W_PH(ctx->opcode);
14630 switch (op2) {
14631 case OPC_DPAU_H_QBL:
14632 case OPC_DPAU_H_QBR:
14633 case OPC_DPSU_H_QBL:
14634 case OPC_DPSU_H_QBR:
14635 case OPC_DPA_W_PH:
14636 case OPC_DPAX_W_PH:
14637 case OPC_DPAQ_S_W_PH:
14638 case OPC_DPAQX_S_W_PH:
14639 case OPC_DPAQX_SA_W_PH:
14640 case OPC_DPS_W_PH:
14641 case OPC_DPSX_W_PH:
14642 case OPC_DPSQ_S_W_PH:
14643 case OPC_DPSQX_S_W_PH:
14644 case OPC_DPSQX_SA_W_PH:
14645 case OPC_MULSAQ_S_W_PH:
14646 case OPC_DPAQ_SA_L_W:
14647 case OPC_DPSQ_SA_L_W:
14648 case OPC_MAQ_S_W_PHL:
14649 case OPC_MAQ_S_W_PHR:
14650 case OPC_MAQ_SA_W_PHL:
14651 case OPC_MAQ_SA_W_PHR:
14652 case OPC_MULSA_W_PH:
14653 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14654 break;
14655 default:
14656 MIPS_INVAL("MASK DPAW.PH");
14657 gen_reserved_instruction(ctx);
14658 break;
14659 }
14660 break;
14661 case OPC_INSV_DSP:
14662 op2 = MASK_INSV(ctx->opcode);
14663 switch (op2) {
14664 case OPC_INSV:
14665 check_dsp(ctx);
14666 {
14667 TCGv t0, t1;
14668
14669 if (rt == 0) {
14670 break;
14671 }
14672
14673 t0 = tcg_temp_new();
14674 t1 = tcg_temp_new();
14675
14676 gen_load_gpr(t0, rt);
14677 gen_load_gpr(t1, rs);
14678
14679 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14680
14681 tcg_temp_free(t0);
14682 tcg_temp_free(t1);
14683 break;
14684 }
14685 default:
14686 MIPS_INVAL("MASK INSV");
14687 gen_reserved_instruction(ctx);
14688 break;
14689 }
14690 break;
14691 case OPC_APPEND_DSP:
14692 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14693 break;
14694 case OPC_EXTR_W_DSP:
14695 op2 = MASK_EXTR_W(ctx->opcode);
14696 switch (op2) {
14697 case OPC_EXTR_W:
14698 case OPC_EXTR_R_W:
14699 case OPC_EXTR_RS_W:
14700 case OPC_EXTR_S_H:
14701 case OPC_EXTRV_S_H:
14702 case OPC_EXTRV_W:
14703 case OPC_EXTRV_R_W:
14704 case OPC_EXTRV_RS_W:
14705 case OPC_EXTP:
14706 case OPC_EXTPV:
14707 case OPC_EXTPDP:
14708 case OPC_EXTPDPV:
14709 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14710 break;
14711 case OPC_RDDSP:
14712 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14713 break;
14714 case OPC_SHILO:
14715 case OPC_SHILOV:
14716 case OPC_MTHLIP:
14717 case OPC_WRDSP:
14718 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14719 break;
14720 default:
14721 MIPS_INVAL("MASK EXTR.W");
14722 gen_reserved_instruction(ctx);
14723 break;
14724 }
14725 break;
14726#if defined(TARGET_MIPS64)
14727 case OPC_DDIV_G_2E:
14728 case OPC_DDIVU_G_2E:
14729 case OPC_DMULT_G_2E:
14730 case OPC_DMULTU_G_2E:
14731 case OPC_DMOD_G_2E:
14732 case OPC_DMODU_G_2E:
14733 check_insn(ctx, INSN_LOONGSON2E);
14734 gen_loongson_integer(ctx, op1, rd, rs, rt);
14735 break;
14736 case OPC_ABSQ_S_QH_DSP:
14737 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14738 switch (op2) {
14739 case OPC_PRECEQ_L_PWL:
14740 case OPC_PRECEQ_L_PWR:
14741 case OPC_PRECEQ_PW_QHL:
14742 case OPC_PRECEQ_PW_QHR:
14743 case OPC_PRECEQ_PW_QHLA:
14744 case OPC_PRECEQ_PW_QHRA:
14745 case OPC_PRECEQU_QH_OBL:
14746 case OPC_PRECEQU_QH_OBR:
14747 case OPC_PRECEQU_QH_OBLA:
14748 case OPC_PRECEQU_QH_OBRA:
14749 case OPC_PRECEU_QH_OBL:
14750 case OPC_PRECEU_QH_OBR:
14751 case OPC_PRECEU_QH_OBLA:
14752 case OPC_PRECEU_QH_OBRA:
14753 case OPC_ABSQ_S_OB:
14754 case OPC_ABSQ_S_PW:
14755 case OPC_ABSQ_S_QH:
14756 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14757 break;
14758 case OPC_REPL_OB:
14759 case OPC_REPL_PW:
14760 case OPC_REPL_QH:
14761 case OPC_REPLV_OB:
14762 case OPC_REPLV_PW:
14763 case OPC_REPLV_QH:
14764 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14765 break;
14766 default:
14767 MIPS_INVAL("MASK ABSQ_S.QH");
14768 gen_reserved_instruction(ctx);
14769 break;
14770 }
14771 break;
14772 case OPC_ADDU_OB_DSP:
14773 op2 = MASK_ADDU_OB(ctx->opcode);
14774 switch (op2) {
14775 case OPC_RADDU_L_OB:
14776 case OPC_SUBQ_PW:
14777 case OPC_SUBQ_S_PW:
14778 case OPC_SUBQ_QH:
14779 case OPC_SUBQ_S_QH:
14780 case OPC_SUBU_OB:
14781 case OPC_SUBU_S_OB:
14782 case OPC_SUBU_QH:
14783 case OPC_SUBU_S_QH:
14784 case OPC_SUBUH_OB:
14785 case OPC_SUBUH_R_OB:
14786 case OPC_ADDQ_PW:
14787 case OPC_ADDQ_S_PW:
14788 case OPC_ADDQ_QH:
14789 case OPC_ADDQ_S_QH:
14790 case OPC_ADDU_OB:
14791 case OPC_ADDU_S_OB:
14792 case OPC_ADDU_QH:
14793 case OPC_ADDU_S_QH:
14794 case OPC_ADDUH_OB:
14795 case OPC_ADDUH_R_OB:
14796 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14797 break;
14798 case OPC_MULEQ_S_PW_QHL:
14799 case OPC_MULEQ_S_PW_QHR:
14800 case OPC_MULEU_S_QH_OBL:
14801 case OPC_MULEU_S_QH_OBR:
14802 case OPC_MULQ_RS_QH:
14803 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14804 break;
14805 default:
14806 MIPS_INVAL("MASK ADDU.OB");
14807 gen_reserved_instruction(ctx);
14808 break;
14809 }
14810 break;
14811 case OPC_CMPU_EQ_OB_DSP:
14812 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14813 switch (op2) {
14814 case OPC_PRECR_SRA_QH_PW:
14815 case OPC_PRECR_SRA_R_QH_PW:
14816
14817 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14818 break;
14819 case OPC_PRECR_OB_QH:
14820 case OPC_PRECRQ_OB_QH:
14821 case OPC_PRECRQ_PW_L:
14822 case OPC_PRECRQ_QH_PW:
14823 case OPC_PRECRQ_RS_QH_PW:
14824 case OPC_PRECRQU_S_OB_QH:
14825 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14826 break;
14827 case OPC_CMPU_EQ_OB:
14828 case OPC_CMPU_LT_OB:
14829 case OPC_CMPU_LE_OB:
14830 case OPC_CMP_EQ_QH:
14831 case OPC_CMP_LT_QH:
14832 case OPC_CMP_LE_QH:
14833 case OPC_CMP_EQ_PW:
14834 case OPC_CMP_LT_PW:
14835 case OPC_CMP_LE_PW:
14836 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14837 break;
14838 case OPC_CMPGDU_EQ_OB:
14839 case OPC_CMPGDU_LT_OB:
14840 case OPC_CMPGDU_LE_OB:
14841 case OPC_CMPGU_EQ_OB:
14842 case OPC_CMPGU_LT_OB:
14843 case OPC_CMPGU_LE_OB:
14844 case OPC_PACKRL_PW:
14845 case OPC_PICK_OB:
14846 case OPC_PICK_PW:
14847 case OPC_PICK_QH:
14848 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14849 break;
14850 default:
14851 MIPS_INVAL("MASK CMPU_EQ.OB");
14852 gen_reserved_instruction(ctx);
14853 break;
14854 }
14855 break;
14856 case OPC_DAPPEND_DSP:
14857 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14858 break;
14859 case OPC_DEXTR_W_DSP:
14860 op2 = MASK_DEXTR_W(ctx->opcode);
14861 switch (op2) {
14862 case OPC_DEXTP:
14863 case OPC_DEXTPDP:
14864 case OPC_DEXTPDPV:
14865 case OPC_DEXTPV:
14866 case OPC_DEXTR_L:
14867 case OPC_DEXTR_R_L:
14868 case OPC_DEXTR_RS_L:
14869 case OPC_DEXTR_W:
14870 case OPC_DEXTR_R_W:
14871 case OPC_DEXTR_RS_W:
14872 case OPC_DEXTR_S_H:
14873 case OPC_DEXTRV_L:
14874 case OPC_DEXTRV_R_L:
14875 case OPC_DEXTRV_RS_L:
14876 case OPC_DEXTRV_S_H:
14877 case OPC_DEXTRV_W:
14878 case OPC_DEXTRV_R_W:
14879 case OPC_DEXTRV_RS_W:
14880 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14881 break;
14882 case OPC_DMTHLIP:
14883 case OPC_DSHILO:
14884 case OPC_DSHILOV:
14885 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14886 break;
14887 default:
14888 MIPS_INVAL("MASK EXTR.W");
14889 gen_reserved_instruction(ctx);
14890 break;
14891 }
14892 break;
14893 case OPC_DPAQ_W_QH_DSP:
14894 op2 = MASK_DPAQ_W_QH(ctx->opcode);
14895 switch (op2) {
14896 case OPC_DPAU_H_OBL:
14897 case OPC_DPAU_H_OBR:
14898 case OPC_DPSU_H_OBL:
14899 case OPC_DPSU_H_OBR:
14900 case OPC_DPA_W_QH:
14901 case OPC_DPAQ_S_W_QH:
14902 case OPC_DPS_W_QH:
14903 case OPC_DPSQ_S_W_QH:
14904 case OPC_MULSAQ_S_W_QH:
14905 case OPC_DPAQ_SA_L_PW:
14906 case OPC_DPSQ_SA_L_PW:
14907 case OPC_MULSAQ_S_L_PW:
14908 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14909 break;
14910 case OPC_MAQ_S_W_QHLL:
14911 case OPC_MAQ_S_W_QHLR:
14912 case OPC_MAQ_S_W_QHRL:
14913 case OPC_MAQ_S_W_QHRR:
14914 case OPC_MAQ_SA_W_QHLL:
14915 case OPC_MAQ_SA_W_QHLR:
14916 case OPC_MAQ_SA_W_QHRL:
14917 case OPC_MAQ_SA_W_QHRR:
14918 case OPC_MAQ_S_L_PWL:
14919 case OPC_MAQ_S_L_PWR:
14920 case OPC_DMADD:
14921 case OPC_DMADDU:
14922 case OPC_DMSUB:
14923 case OPC_DMSUBU:
14924 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14925 break;
14926 default:
14927 MIPS_INVAL("MASK DPAQ.W.QH");
14928 gen_reserved_instruction(ctx);
14929 break;
14930 }
14931 break;
14932 case OPC_DINSV_DSP:
14933 op2 = MASK_INSV(ctx->opcode);
14934 switch (op2) {
14935 case OPC_DINSV:
14936 {
14937 TCGv t0, t1;
14938
14939 check_dsp(ctx);
14940
14941 if (rt == 0) {
14942 break;
14943 }
14944
14945 t0 = tcg_temp_new();
14946 t1 = tcg_temp_new();
14947
14948 gen_load_gpr(t0, rt);
14949 gen_load_gpr(t1, rs);
14950
14951 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14952
14953 tcg_temp_free(t0);
14954 tcg_temp_free(t1);
14955 break;
14956 }
14957 default:
14958 MIPS_INVAL("MASK DINSV");
14959 gen_reserved_instruction(ctx);
14960 break;
14961 }
14962 break;
14963 case OPC_SHLL_OB_DSP:
14964 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14965 break;
14966#endif
14967 default:
14968 MIPS_INVAL("special3_legacy");
14969 gen_reserved_instruction(ctx);
14970 break;
14971 }
14972}
14973
14974
14975#if defined(TARGET_MIPS64)
14976
14977static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14978{
14979 uint32_t opc = MASK_MMI(ctx->opcode);
14980 int rs = extract32(ctx->opcode, 21, 5);
14981 int rt = extract32(ctx->opcode, 16, 5);
14982 int rd = extract32(ctx->opcode, 11, 5);
14983
14984 switch (opc) {
14985 case MMI_OPC_MULT1:
14986 case MMI_OPC_MULTU1:
14987 case MMI_OPC_MADD:
14988 case MMI_OPC_MADDU:
14989 case MMI_OPC_MADD1:
14990 case MMI_OPC_MADDU1:
14991 gen_mul_txx9(ctx, opc, rd, rs, rt);
14992 break;
14993 case MMI_OPC_DIV1:
14994 case MMI_OPC_DIVU1:
14995 gen_div1_tx79(ctx, opc, rs, rt);
14996 break;
14997 default:
14998 MIPS_INVAL("TX79 MMI class");
14999 gen_reserved_instruction(ctx);
15000 break;
15001 }
15002}
15003
15004static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
15005{
15006 gen_reserved_instruction(ctx);
15007}
15008
15009
15010
15011
15012
15013
15014
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
15031{
15032 int base = extract32(ctx->opcode, 21, 5);
15033 int rt = extract32(ctx->opcode, 16, 5);
15034 int offset = extract32(ctx->opcode, 0, 16);
15035
15036#ifdef CONFIG_USER_ONLY
15037 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15038 uint32_t op2 = extract32(ctx->opcode, 6, 5);
15039
15040 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15041 int rd = extract32(ctx->opcode, 11, 5);
15042
15043 gen_rdhwr(ctx, rt, rd, 0);
15044 return;
15045 }
15046#endif
15047
15048 gen_mmi_sq(ctx, base, rt, offset);
15049}
15050
15051#endif
15052
15053static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15054{
15055 int rs, rt, rd, sa;
15056 uint32_t op1, op2;
15057 int16_t imm;
15058
15059 rs = (ctx->opcode >> 21) & 0x1f;
15060 rt = (ctx->opcode >> 16) & 0x1f;
15061 rd = (ctx->opcode >> 11) & 0x1f;
15062 sa = (ctx->opcode >> 6) & 0x1f;
15063 imm = sextract32(ctx->opcode, 7, 9);
15064
15065 op1 = MASK_SPECIAL3(ctx->opcode);
15066
15067
15068
15069
15070
15071
15072 if (ctx->eva) {
15073 switch (op1) {
15074 case OPC_LWLE:
15075 case OPC_LWRE:
15076 case OPC_LBUE:
15077 case OPC_LHUE:
15078 case OPC_LBE:
15079 case OPC_LHE:
15080 case OPC_LLE:
15081 case OPC_LWE:
15082 check_cp0_enabled(ctx);
15083 gen_ld(ctx, op1, rt, rs, imm);
15084 return;
15085 case OPC_SWLE:
15086 case OPC_SWRE:
15087 case OPC_SBE:
15088 case OPC_SHE:
15089 case OPC_SWE:
15090 check_cp0_enabled(ctx);
15091 gen_st(ctx, op1, rt, rs, imm);
15092 return;
15093 case OPC_SCE:
15094 check_cp0_enabled(ctx);
15095 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
15096 return;
15097 case OPC_CACHEE:
15098 check_eva(ctx);
15099 check_cp0_enabled(ctx);
15100 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15101 gen_cache_operation(ctx, rt, rs, imm);
15102 }
15103 return;
15104 case OPC_PREFE:
15105 check_cp0_enabled(ctx);
15106
15107 return;
15108 }
15109 }
15110
15111 switch (op1) {
15112 case OPC_EXT:
15113 case OPC_INS:
15114 check_insn(ctx, ISA_MIPS_R2);
15115 gen_bitops(ctx, op1, rt, rs, sa, rd);
15116 break;
15117 case OPC_BSHFL:
15118 op2 = MASK_BSHFL(ctx->opcode);
15119 switch (op2) {
15120 case OPC_ALIGN:
15121 case OPC_ALIGN_1:
15122 case OPC_ALIGN_2:
15123 case OPC_ALIGN_3:
15124 case OPC_BITSWAP:
15125 check_insn(ctx, ISA_MIPS_R6);
15126 decode_opc_special3_r6(env, ctx);
15127 break;
15128 default:
15129 check_insn(ctx, ISA_MIPS_R2);
15130 gen_bshfl(ctx, op2, rt, rd);
15131 break;
15132 }
15133 break;
15134#if defined(TARGET_MIPS64)
15135 case OPC_DEXTM:
15136 case OPC_DEXTU:
15137 case OPC_DEXT:
15138 case OPC_DINSM:
15139 case OPC_DINSU:
15140 case OPC_DINS:
15141 check_insn(ctx, ISA_MIPS_R2);
15142 check_mips_64(ctx);
15143 gen_bitops(ctx, op1, rt, rs, sa, rd);
15144 break;
15145 case OPC_DBSHFL:
15146 op2 = MASK_DBSHFL(ctx->opcode);
15147 switch (op2) {
15148 case OPC_DALIGN:
15149 case OPC_DALIGN_1:
15150 case OPC_DALIGN_2:
15151 case OPC_DALIGN_3:
15152 case OPC_DALIGN_4:
15153 case OPC_DALIGN_5:
15154 case OPC_DALIGN_6:
15155 case OPC_DALIGN_7:
15156 case OPC_DBITSWAP:
15157 check_insn(ctx, ISA_MIPS_R6);
15158 decode_opc_special3_r6(env, ctx);
15159 break;
15160 default:
15161 check_insn(ctx, ISA_MIPS_R2);
15162 check_mips_64(ctx);
15163 op2 = MASK_DBSHFL(ctx->opcode);
15164 gen_bshfl(ctx, op2, rt, rd);
15165 break;
15166 }
15167 break;
15168#endif
15169 case OPC_RDHWR:
15170 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
15171 break;
15172 case OPC_FORK:
15173 check_mt(ctx);
15174 {
15175 TCGv t0 = tcg_temp_new();
15176 TCGv t1 = tcg_temp_new();
15177
15178 gen_load_gpr(t0, rt);
15179 gen_load_gpr(t1, rs);
15180 gen_helper_fork(t0, t1);
15181 tcg_temp_free(t0);
15182 tcg_temp_free(t1);
15183 }
15184 break;
15185 case OPC_YIELD:
15186 check_mt(ctx);
15187 {
15188 TCGv t0 = tcg_temp_new();
15189
15190 gen_load_gpr(t0, rs);
15191 gen_helper_yield(t0, cpu_env, t0);
15192 gen_store_gpr(t0, rd);
15193 tcg_temp_free(t0);
15194 }
15195 break;
15196 default:
15197 if (ctx->insn_flags & ISA_MIPS_R6) {
15198 decode_opc_special3_r6(env, ctx);
15199 } else {
15200 decode_opc_special3_legacy(env, ctx);
15201 }
15202 }
15203}
15204
15205static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
15206{
15207 int32_t offset;
15208 int rs, rt, rd, sa;
15209 uint32_t op, op1;
15210 int16_t imm;
15211
15212 op = MASK_OP_MAJOR(ctx->opcode);
15213 rs = (ctx->opcode >> 21) & 0x1f;
15214 rt = (ctx->opcode >> 16) & 0x1f;
15215 rd = (ctx->opcode >> 11) & 0x1f;
15216 sa = (ctx->opcode >> 6) & 0x1f;
15217 imm = (int16_t)ctx->opcode;
15218 switch (op) {
15219 case OPC_SPECIAL:
15220 decode_opc_special(env, ctx);
15221 break;
15222 case OPC_SPECIAL2:
15223#if defined(TARGET_MIPS64)
15224 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15225 decode_mmi(env, ctx);
15226 break;
15227 }
15228#endif
15229 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
15230 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15231 gen_arith(ctx, OPC_MUL, rd, rs, rt);
15232 } else {
15233 decode_ase_mxu(ctx, ctx->opcode);
15234 }
15235 break;
15236 }
15237 decode_opc_special2_legacy(env, ctx);
15238 break;
15239 case OPC_SPECIAL3:
15240#if defined(TARGET_MIPS64)
15241 if (ctx->insn_flags & INSN_R5900) {
15242 decode_mmi_sq(env, ctx);
15243 } else {
15244 decode_opc_special3(env, ctx);
15245 }
15246#else
15247 decode_opc_special3(env, ctx);
15248#endif
15249 break;
15250 case OPC_REGIMM:
15251 op1 = MASK_REGIMM(ctx->opcode);
15252 switch (op1) {
15253 case OPC_BLTZL:
15254 case OPC_BGEZL:
15255 case OPC_BLTZALL:
15256 case OPC_BGEZALL:
15257 check_insn(ctx, ISA_MIPS2);
15258 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15259
15260 case OPC_BLTZ:
15261 case OPC_BGEZ:
15262 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15263 break;
15264 case OPC_BLTZAL:
15265 case OPC_BGEZAL:
15266 if (ctx->insn_flags & ISA_MIPS_R6) {
15267 if (rs == 0) {
15268
15269 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15270 } else {
15271 gen_reserved_instruction(ctx);
15272 }
15273 } else {
15274 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15275 }
15276 break;
15277 case OPC_TGEI:
15278 case OPC_TGEIU:
15279 case OPC_TLTI:
15280 case OPC_TLTIU:
15281 case OPC_TEQI:
15282
15283 case OPC_TNEI:
15284 check_insn(ctx, ISA_MIPS2);
15285 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15286 gen_trap(ctx, op1, rs, -1, imm);
15287 break;
15288 case OPC_SIGRIE:
15289 check_insn(ctx, ISA_MIPS_R6);
15290 gen_reserved_instruction(ctx);
15291 break;
15292 case OPC_SYNCI:
15293 check_insn(ctx, ISA_MIPS_R2);
15294
15295
15296
15297
15298 ctx->base.is_jmp = DISAS_STOP;
15299 break;
15300 case OPC_BPOSGE32:
15301#if defined(TARGET_MIPS64)
15302 case OPC_BPOSGE64:
15303#endif
15304 check_dsp(ctx);
15305 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
15306 break;
15307#if defined(TARGET_MIPS64)
15308 case OPC_DAHI:
15309 check_insn(ctx, ISA_MIPS_R6);
15310 check_mips_64(ctx);
15311 if (rs != 0) {
15312 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15313 }
15314 break;
15315 case OPC_DATI:
15316 check_insn(ctx, ISA_MIPS_R6);
15317 check_mips_64(ctx);
15318 if (rs != 0) {
15319 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15320 }
15321 break;
15322#endif
15323 default:
15324 MIPS_INVAL("regimm");
15325 gen_reserved_instruction(ctx);
15326 break;
15327 }
15328 break;
15329 case OPC_CP0:
15330 check_cp0_enabled(ctx);
15331 op1 = MASK_CP0(ctx->opcode);
15332 switch (op1) {
15333 case OPC_MFC0:
15334 case OPC_MTC0:
15335 case OPC_MFTR:
15336 case OPC_MTTR:
15337 case OPC_MFHC0:
15338 case OPC_MTHC0:
15339#if defined(TARGET_MIPS64)
15340 case OPC_DMFC0:
15341 case OPC_DMTC0:
15342#endif
15343#ifndef CONFIG_USER_ONLY
15344 gen_cp0(env, ctx, op1, rt, rd);
15345#endif
15346 break;
15347 case OPC_C0:
15348 case OPC_C0_1:
15349 case OPC_C0_2:
15350 case OPC_C0_3:
15351 case OPC_C0_4:
15352 case OPC_C0_5:
15353 case OPC_C0_6:
15354 case OPC_C0_7:
15355 case OPC_C0_8:
15356 case OPC_C0_9:
15357 case OPC_C0_A:
15358 case OPC_C0_B:
15359 case OPC_C0_C:
15360 case OPC_C0_D:
15361 case OPC_C0_E:
15362 case OPC_C0_F:
15363#ifndef CONFIG_USER_ONLY
15364 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15365#endif
15366 break;
15367 case OPC_MFMC0:
15368#ifndef CONFIG_USER_ONLY
15369 {
15370 uint32_t op2;
15371 TCGv t0 = tcg_temp_new();
15372
15373 op2 = MASK_MFMC0(ctx->opcode);
15374 switch (op2) {
15375 case OPC_DMT:
15376 check_cp0_mt(ctx);
15377 gen_helper_dmt(t0);
15378 gen_store_gpr(t0, rt);
15379 break;
15380 case OPC_EMT:
15381 check_cp0_mt(ctx);
15382 gen_helper_emt(t0);
15383 gen_store_gpr(t0, rt);
15384 break;
15385 case OPC_DVPE:
15386 check_cp0_mt(ctx);
15387 gen_helper_dvpe(t0, cpu_env);
15388 gen_store_gpr(t0, rt);
15389 break;
15390 case OPC_EVPE:
15391 check_cp0_mt(ctx);
15392 gen_helper_evpe(t0, cpu_env);
15393 gen_store_gpr(t0, rt);
15394 break;
15395 case OPC_DVP:
15396 check_insn(ctx, ISA_MIPS_R6);
15397 if (ctx->vp) {
15398 gen_helper_dvp(t0, cpu_env);
15399 gen_store_gpr(t0, rt);
15400 }
15401 break;
15402 case OPC_EVP:
15403 check_insn(ctx, ISA_MIPS_R6);
15404 if (ctx->vp) {
15405 gen_helper_evp(t0, cpu_env);
15406 gen_store_gpr(t0, rt);
15407 }
15408 break;
15409 case OPC_DI:
15410 check_insn(ctx, ISA_MIPS_R2);
15411 save_cpu_state(ctx, 1);
15412 gen_helper_di(t0, cpu_env);
15413 gen_store_gpr(t0, rt);
15414
15415
15416
15417
15418 ctx->base.is_jmp = DISAS_STOP;
15419 break;
15420 case OPC_EI:
15421 check_insn(ctx, ISA_MIPS_R2);
15422 save_cpu_state(ctx, 1);
15423 gen_helper_ei(t0, cpu_env);
15424 gen_store_gpr(t0, rt);
15425
15426
15427
15428
15429 gen_save_pc(ctx->base.pc_next + 4);
15430 ctx->base.is_jmp = DISAS_EXIT;
15431 break;
15432 default:
15433 MIPS_INVAL("mfmc0");
15434 gen_reserved_instruction(ctx);
15435 break;
15436 }
15437 tcg_temp_free(t0);
15438 }
15439#endif
15440 break;
15441 case OPC_RDPGPR:
15442 check_insn(ctx, ISA_MIPS_R2);
15443 gen_load_srsgpr(rt, rd);
15444 break;
15445 case OPC_WRPGPR:
15446 check_insn(ctx, ISA_MIPS_R2);
15447 gen_store_srsgpr(rt, rd);
15448 break;
15449 default:
15450 MIPS_INVAL("cp0");
15451 gen_reserved_instruction(ctx);
15452 break;
15453 }
15454 break;
15455 case OPC_BOVC:
15456 if (ctx->insn_flags & ISA_MIPS_R6) {
15457
15458 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15459 } else {
15460
15461
15462 gen_arith_imm(ctx, op, rt, rs, imm);
15463 }
15464 break;
15465 case OPC_ADDIU:
15466 gen_arith_imm(ctx, op, rt, rs, imm);
15467 break;
15468 case OPC_SLTI:
15469 case OPC_SLTIU:
15470 gen_slt_imm(ctx, op, rt, rs, imm);
15471 break;
15472 case OPC_ANDI:
15473 case OPC_LUI:
15474 case OPC_ORI:
15475 case OPC_XORI:
15476 gen_logic_imm(ctx, op, rt, rs, imm);
15477 break;
15478 case OPC_J:
15479 case OPC_JAL:
15480 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15481 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15482 break;
15483
15484 case OPC_BLEZC:
15485 if (ctx->insn_flags & ISA_MIPS_R6) {
15486 if (rt == 0) {
15487 gen_reserved_instruction(ctx);
15488 break;
15489 }
15490
15491 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15492 } else {
15493
15494 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15495 }
15496 break;
15497 case OPC_BGTZC:
15498 if (ctx->insn_flags & ISA_MIPS_R6) {
15499 if (rt == 0) {
15500 gen_reserved_instruction(ctx);
15501 break;
15502 }
15503
15504 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15505 } else {
15506
15507 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15508 }
15509 break;
15510 case OPC_BLEZALC:
15511 if (rt == 0) {
15512
15513 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15514 } else {
15515 check_insn(ctx, ISA_MIPS_R6);
15516
15517 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15518 }
15519 break;
15520 case OPC_BGTZALC:
15521 if (rt == 0) {
15522
15523 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15524 } else {
15525 check_insn(ctx, ISA_MIPS_R6);
15526
15527 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15528 }
15529 break;
15530 case OPC_BEQL:
15531 case OPC_BNEL:
15532 check_insn(ctx, ISA_MIPS2);
15533 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15534
15535 case OPC_BEQ:
15536 case OPC_BNE:
15537 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15538 break;
15539 case OPC_LL:
15540 check_insn(ctx, ISA_MIPS2);
15541 if (ctx->insn_flags & INSN_R5900) {
15542 check_insn_opc_user_only(ctx, INSN_R5900);
15543 }
15544
15545 case OPC_LWL:
15546 case OPC_LWR:
15547 case OPC_LB:
15548 case OPC_LH:
15549 case OPC_LW:
15550 case OPC_LWPC:
15551 case OPC_LBU:
15552 case OPC_LHU:
15553 gen_ld(ctx, op, rt, rs, imm);
15554 break;
15555 case OPC_SWL:
15556 case OPC_SWR:
15557 case OPC_SB:
15558 case OPC_SH:
15559 case OPC_SW:
15560 gen_st(ctx, op, rt, rs, imm);
15561 break;
15562 case OPC_SC:
15563 check_insn(ctx, ISA_MIPS2);
15564 if (ctx->insn_flags & INSN_R5900) {
15565 check_insn_opc_user_only(ctx, INSN_R5900);
15566 }
15567 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15568 break;
15569 case OPC_CACHE:
15570 check_cp0_enabled(ctx);
15571 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
15572 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15573 gen_cache_operation(ctx, rt, rs, imm);
15574 }
15575
15576 break;
15577 case OPC_PREF:
15578 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15579
15580 break;
15581
15582
15583 case OPC_LWC1:
15584 case OPC_LDC1:
15585 case OPC_SWC1:
15586 case OPC_SDC1:
15587 gen_cop1_ldst(ctx, op, rt, rs, imm);
15588 break;
15589
15590 case OPC_CP1:
15591 op1 = MASK_CP1(ctx->opcode);
15592
15593 switch (op1) {
15594 case OPC_MFHC1:
15595 case OPC_MTHC1:
15596 check_cp1_enabled(ctx);
15597 check_insn(ctx, ISA_MIPS_R2);
15598
15599 case OPC_MFC1:
15600 case OPC_CFC1:
15601 case OPC_MTC1:
15602 case OPC_CTC1:
15603 check_cp1_enabled(ctx);
15604 gen_cp1(ctx, op1, rt, rd);
15605 break;
15606#if defined(TARGET_MIPS64)
15607 case OPC_DMFC1:
15608 case OPC_DMTC1:
15609 check_cp1_enabled(ctx);
15610 check_insn(ctx, ISA_MIPS3);
15611 check_mips_64(ctx);
15612 gen_cp1(ctx, op1, rt, rd);
15613 break;
15614#endif
15615 case OPC_BC1EQZ:
15616 check_cp1_enabled(ctx);
15617 if (ctx->insn_flags & ISA_MIPS_R6) {
15618
15619 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15620 rt, imm << 2, 4);
15621 } else {
15622
15623 check_cop1x(ctx);
15624 check_insn(ctx, ASE_MIPS3D);
15625 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15626 (rt >> 2) & 0x7, imm << 2);
15627 }
15628 break;
15629 case OPC_BC1NEZ:
15630 check_cp1_enabled(ctx);
15631 check_insn(ctx, ISA_MIPS_R6);
15632 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15633 rt, imm << 2, 4);
15634 break;
15635 case OPC_BC1ANY4:
15636 check_cp1_enabled(ctx);
15637 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15638 check_cop1x(ctx);
15639 check_insn(ctx, ASE_MIPS3D);
15640
15641 case OPC_BC1:
15642 check_cp1_enabled(ctx);
15643 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15644 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15645 (rt >> 2) & 0x7, imm << 2);
15646 break;
15647 case OPC_PS_FMT:
15648 check_ps(ctx);
15649
15650 case OPC_S_FMT:
15651 case OPC_D_FMT:
15652 check_cp1_enabled(ctx);
15653 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15654 (imm >> 8) & 0x7);
15655 break;
15656 case OPC_W_FMT:
15657 case OPC_L_FMT:
15658 {
15659 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15660 check_cp1_enabled(ctx);
15661 if (ctx->insn_flags & ISA_MIPS_R6) {
15662 switch (r6_op) {
15663 case R6_OPC_CMP_AF_S:
15664 case R6_OPC_CMP_UN_S:
15665 case R6_OPC_CMP_EQ_S:
15666 case R6_OPC_CMP_UEQ_S:
15667 case R6_OPC_CMP_LT_S:
15668 case R6_OPC_CMP_ULT_S:
15669 case R6_OPC_CMP_LE_S:
15670 case R6_OPC_CMP_ULE_S:
15671 case R6_OPC_CMP_SAF_S:
15672 case R6_OPC_CMP_SUN_S:
15673 case R6_OPC_CMP_SEQ_S:
15674 case R6_OPC_CMP_SEUQ_S:
15675 case R6_OPC_CMP_SLT_S:
15676 case R6_OPC_CMP_SULT_S:
15677 case R6_OPC_CMP_SLE_S:
15678 case R6_OPC_CMP_SULE_S:
15679 case R6_OPC_CMP_OR_S:
15680 case R6_OPC_CMP_UNE_S:
15681 case R6_OPC_CMP_NE_S:
15682 case R6_OPC_CMP_SOR_S:
15683 case R6_OPC_CMP_SUNE_S:
15684 case R6_OPC_CMP_SNE_S:
15685 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15686 break;
15687 case R6_OPC_CMP_AF_D:
15688 case R6_OPC_CMP_UN_D:
15689 case R6_OPC_CMP_EQ_D:
15690 case R6_OPC_CMP_UEQ_D:
15691 case R6_OPC_CMP_LT_D:
15692 case R6_OPC_CMP_ULT_D:
15693 case R6_OPC_CMP_LE_D:
15694 case R6_OPC_CMP_ULE_D:
15695 case R6_OPC_CMP_SAF_D:
15696 case R6_OPC_CMP_SUN_D:
15697 case R6_OPC_CMP_SEQ_D:
15698 case R6_OPC_CMP_SEUQ_D:
15699 case R6_OPC_CMP_SLT_D:
15700 case R6_OPC_CMP_SULT_D:
15701 case R6_OPC_CMP_SLE_D:
15702 case R6_OPC_CMP_SULE_D:
15703 case R6_OPC_CMP_OR_D:
15704 case R6_OPC_CMP_UNE_D:
15705 case R6_OPC_CMP_NE_D:
15706 case R6_OPC_CMP_SOR_D:
15707 case R6_OPC_CMP_SUNE_D:
15708 case R6_OPC_CMP_SNE_D:
15709 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15710 break;
15711 default:
15712 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15713 rt, rd, sa, (imm >> 8) & 0x7);
15714
15715 break;
15716 }
15717 } else {
15718 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15719 (imm >> 8) & 0x7);
15720 }
15721 break;
15722 }
15723 default:
15724 MIPS_INVAL("cp1");
15725 gen_reserved_instruction(ctx);
15726 break;
15727 }
15728 break;
15729
15730
15731 case OPC_BC:
15732 case OPC_BALC:
15733 if (ctx->insn_flags & ISA_MIPS_R6) {
15734
15735 gen_compute_compact_branch(ctx, op, 0, 0,
15736 sextract32(ctx->opcode << 2, 0, 28));
15737 } else if (ctx->insn_flags & ASE_LEXT) {
15738 gen_loongson_lswc2(ctx, rt, rs, rd);
15739 } else {
15740
15741
15742 generate_exception_err(ctx, EXCP_CpU, 2);
15743 }
15744 break;
15745 case OPC_BEQZC:
15746 case OPC_BNEZC:
15747 if (ctx->insn_flags & ISA_MIPS_R6) {
15748 if (rs != 0) {
15749
15750 gen_compute_compact_branch(ctx, op, rs, 0,
15751 sextract32(ctx->opcode << 2, 0, 23));
15752 } else {
15753
15754 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15755 }
15756 } else if (ctx->insn_flags & ASE_LEXT) {
15757 gen_loongson_lsdc2(ctx, rt, rs, rd);
15758 } else {
15759
15760
15761 generate_exception_err(ctx, EXCP_CpU, 2);
15762 }
15763 break;
15764 case OPC_CP2:
15765 check_insn(ctx, ASE_LMMI);
15766
15767 gen_loongson_multimedia(ctx, sa, rd, rt);
15768 break;
15769
15770 case OPC_CP3:
15771 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15772 check_cp1_enabled(ctx);
15773 op1 = MASK_CP3(ctx->opcode);
15774 switch (op1) {
15775 case OPC_LUXC1:
15776 case OPC_SUXC1:
15777 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15778
15779 case OPC_LWXC1:
15780 case OPC_LDXC1:
15781 case OPC_SWXC1:
15782 case OPC_SDXC1:
15783 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15784 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15785 break;
15786 case OPC_PREFX:
15787 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15788
15789 break;
15790 case OPC_ALNV_PS:
15791 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15792
15793 case OPC_MADD_S:
15794 case OPC_MADD_D:
15795 case OPC_MADD_PS:
15796 case OPC_MSUB_S:
15797 case OPC_MSUB_D:
15798 case OPC_MSUB_PS:
15799 case OPC_NMADD_S:
15800 case OPC_NMADD_D:
15801 case OPC_NMADD_PS:
15802 case OPC_NMSUB_S:
15803 case OPC_NMSUB_D:
15804 case OPC_NMSUB_PS:
15805 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15806 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15807 break;
15808 default:
15809 MIPS_INVAL("cp3");
15810 gen_reserved_instruction(ctx);
15811 break;
15812 }
15813 } else {
15814 generate_exception_err(ctx, EXCP_CpU, 1);
15815 }
15816 break;
15817
15818#if defined(TARGET_MIPS64)
15819
15820 case OPC_LLD:
15821 if (ctx->insn_flags & INSN_R5900) {
15822 check_insn_opc_user_only(ctx, INSN_R5900);
15823 }
15824
15825 case OPC_LDL:
15826 case OPC_LDR:
15827 case OPC_LWU:
15828 case OPC_LD:
15829 check_insn(ctx, ISA_MIPS3);
15830 check_mips_64(ctx);
15831 gen_ld(ctx, op, rt, rs, imm);
15832 break;
15833 case OPC_SDL:
15834 case OPC_SDR:
15835 case OPC_SD:
15836 check_insn(ctx, ISA_MIPS3);
15837 check_mips_64(ctx);
15838 gen_st(ctx, op, rt, rs, imm);
15839 break;
15840 case OPC_SCD:
15841 check_insn(ctx, ISA_MIPS3);
15842 if (ctx->insn_flags & INSN_R5900) {
15843 check_insn_opc_user_only(ctx, INSN_R5900);
15844 }
15845 check_mips_64(ctx);
15846 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
15847 break;
15848 case OPC_BNVC:
15849 if (ctx->insn_flags & ISA_MIPS_R6) {
15850
15851 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15852 } else {
15853
15854 check_insn(ctx, ISA_MIPS3);
15855 check_mips_64(ctx);
15856 gen_arith_imm(ctx, op, rt, rs, imm);
15857 }
15858 break;
15859 case OPC_DADDIU:
15860 check_insn(ctx, ISA_MIPS3);
15861 check_mips_64(ctx);
15862 gen_arith_imm(ctx, op, rt, rs, imm);
15863 break;
15864#else
15865 case OPC_BNVC:
15866 if (ctx->insn_flags & ISA_MIPS_R6) {
15867 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15868 } else {
15869 MIPS_INVAL("major opcode");
15870 gen_reserved_instruction(ctx);
15871 }
15872 break;
15873#endif
15874 case OPC_DAUI:
15875 if (ctx->insn_flags & ISA_MIPS_R6) {
15876#if defined(TARGET_MIPS64)
15877
15878 check_mips_64(ctx);
15879 if (rs == 0) {
15880 generate_exception(ctx, EXCP_RI);
15881 } else if (rt != 0) {
15882 TCGv t0 = tcg_temp_new();
15883 gen_load_gpr(t0, rs);
15884 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15885 tcg_temp_free(t0);
15886 }
15887#else
15888 gen_reserved_instruction(ctx);
15889 MIPS_INVAL("major opcode");
15890#endif
15891 } else {
15892
15893 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15894 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15895 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15896 }
15897 break;
15898 case OPC_MDMX:
15899
15900 break;
15901 case OPC_PCREL:
15902 check_insn(ctx, ISA_MIPS_R6);
15903 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15904 break;
15905 default:
15906 MIPS_INVAL("major opcode");
15907 return false;
15908 }
15909 return true;
15910}
15911
15912static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15913{
15914
15915 if (ctx->base.pc_next & 0x3) {
15916 env->CP0_BadVAddr = ctx->base.pc_next;
15917 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15918 return;
15919 }
15920
15921
15922 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15923 TCGLabel *l1 = gen_new_label();
15924
15925 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15926 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15927 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15928 gen_set_label(l1);
15929 }
15930
15931
15932
15933
15934 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15935 return;
15936 }
15937 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15938 return;
15939 }
15940
15941
15942 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15943 return;
15944 }
15945
15946
15947 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15948 return;
15949 }
15950
15951 if (decode_opc_legacy(env, ctx)) {
15952 return;
15953 }
15954
15955 gen_reserved_instruction(ctx);
15956}
15957
15958static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15959{
15960 DisasContext *ctx = container_of(dcbase, DisasContext, base);
15961 CPUMIPSState *env = cs->env_ptr;
15962
15963 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15964 ctx->saved_pc = -1;
15965 ctx->insn_flags = env->insn_flags;
15966 ctx->CP0_Config0 = env->CP0_Config0;
15967 ctx->CP0_Config1 = env->CP0_Config1;
15968 ctx->CP0_Config2 = env->CP0_Config2;
15969 ctx->CP0_Config3 = env->CP0_Config3;
15970 ctx->CP0_Config5 = env->CP0_Config5;
15971 ctx->btarget = 0;
15972 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15973 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15974 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15975 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15976 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15977 ctx->PAMask = env->PAMask;
15978 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15979 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15980 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15981 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15982 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15983
15984 ctx->hflags = (uint32_t)ctx->base.tb->flags;
15985 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15986 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15987 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15988 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15989 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15990 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15991 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15992 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15993 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15994 restore_cpu_state(env, ctx);
15995#ifdef CONFIG_USER_ONLY
15996 ctx->mem_idx = MIPS_HFLAG_UM;
15997#else
15998 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15999#endif
16000 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
16001 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
16002
16003
16004
16005
16006
16007
16008
16009 if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
16010 ctx->base.max_insns = 2;
16011 }
16012
16013 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16014 ctx->hflags);
16015}
16016
16017static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16018{
16019}
16020
16021static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16022{
16023 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16024
16025 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16026 ctx->btarget);
16027}
16028
16029static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16030{
16031 CPUMIPSState *env = cs->env_ptr;
16032 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16033 int insn_bytes;
16034 int is_slot;
16035
16036 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
16037 if (ctx->insn_flags & ISA_NANOMIPS32) {
16038 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16039 insn_bytes = decode_isa_nanomips(env, ctx);
16040 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
16041 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
16042 insn_bytes = 4;
16043 decode_opc(env, ctx);
16044 } else if (ctx->insn_flags & ASE_MICROMIPS) {
16045 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16046 insn_bytes = decode_isa_micromips(env, ctx);
16047 } else if (ctx->insn_flags & ASE_MIPS16) {
16048 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16049 insn_bytes = decode_ase_mips16e(env, ctx);
16050 } else {
16051 gen_reserved_instruction(ctx);
16052 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16053 return;
16054 }
16055
16056 if (ctx->hflags & MIPS_HFLAG_BMASK) {
16057 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16058 MIPS_HFLAG_FBNSLOT))) {
16059
16060
16061
16062
16063 is_slot = 1;
16064 }
16065 if ((ctx->hflags & MIPS_HFLAG_M16) &&
16066 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
16067
16068
16069
16070
16071 is_slot = 1;
16072 }
16073 }
16074 if (is_slot) {
16075 gen_branch(ctx, insn_bytes);
16076 }
16077 ctx->base.pc_next += insn_bytes;
16078
16079 if (ctx->base.is_jmp != DISAS_NEXT) {
16080 return;
16081 }
16082
16083
16084
16085
16086
16087
16088 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
16089 && !ctx->base.singlestep_enabled) {
16090 ctx->base.is_jmp = DISAS_TOO_MANY;
16091 }
16092}
16093
16094static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16095{
16096 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16097
16098 switch (ctx->base.is_jmp) {
16099 case DISAS_STOP:
16100 gen_save_pc(ctx->base.pc_next);
16101 tcg_gen_lookup_and_goto_ptr();
16102 break;
16103 case DISAS_NEXT:
16104 case DISAS_TOO_MANY:
16105 save_cpu_state(ctx, 0);
16106 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16107 break;
16108 case DISAS_EXIT:
16109 tcg_gen_exit_tb(NULL, 0);
16110 break;
16111 case DISAS_NORETURN:
16112 break;
16113 default:
16114 g_assert_not_reached();
16115 }
16116}
16117
16118static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
16119{
16120 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
16121 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
16122}
16123
16124static const TranslatorOps mips_tr_ops = {
16125 .init_disas_context = mips_tr_init_disas_context,
16126 .tb_start = mips_tr_tb_start,
16127 .insn_start = mips_tr_insn_start,
16128 .translate_insn = mips_tr_translate_insn,
16129 .tb_stop = mips_tr_tb_stop,
16130 .disas_log = mips_tr_disas_log,
16131};
16132
16133void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
16134{
16135 DisasContext ctx;
16136
16137 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
16138}
16139
16140void mips_tcg_init(void)
16141{
16142 int i;
16143
16144 cpu_gpr[0] = NULL;
16145 for (i = 1; i < 32; i++)
16146 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16147 offsetof(CPUMIPSState,
16148 active_tc.gpr[i]),
16149 regnames[i]);
16150#if defined(TARGET_MIPS64)
16151 cpu_gpr_hi[0] = NULL;
16152
16153 for (unsigned i = 1; i < 32; i++) {
16154 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16155
16156 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16157 offsetof(CPUMIPSState,
16158 active_tc.gpr_hi[i]),
16159 rname);
16160 }
16161#endif
16162 for (i = 0; i < 32; i++) {
16163 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
16164
16165 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16166 }
16167 msa_translate_init();
16168 cpu_PC = tcg_global_mem_new(cpu_env,
16169 offsetof(CPUMIPSState, active_tc.PC), "PC");
16170 for (i = 0; i < MIPS_DSP_ACC; i++) {
16171 cpu_HI[i] = tcg_global_mem_new(cpu_env,
16172 offsetof(CPUMIPSState, active_tc.HI[i]),
16173 regnames_HI[i]);
16174 cpu_LO[i] = tcg_global_mem_new(cpu_env,
16175 offsetof(CPUMIPSState, active_tc.LO[i]),
16176 regnames_LO[i]);
16177 }
16178 cpu_dspctrl = tcg_global_mem_new(cpu_env,
16179 offsetof(CPUMIPSState,
16180 active_tc.DSPControl),
16181 "DSPControl");
16182 bcond = tcg_global_mem_new(cpu_env,
16183 offsetof(CPUMIPSState, bcond), "bcond");
16184 btarget = tcg_global_mem_new(cpu_env,
16185 offsetof(CPUMIPSState, btarget), "btarget");
16186 hflags = tcg_global_mem_new_i32(cpu_env,
16187 offsetof(CPUMIPSState, hflags), "hflags");
16188
16189 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
16190 offsetof(CPUMIPSState, active_fpu.fcr0),
16191 "fcr0");
16192 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
16193 offsetof(CPUMIPSState, active_fpu.fcr31),
16194 "fcr31");
16195 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16196 "lladdr");
16197 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16198 "llval");
16199
16200 if (TARGET_LONG_BITS == 32) {
16201 mxu_translate_init();
16202 }
16203}
16204
16205void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16206 target_ulong *data)
16207{
16208 env->active_tc.PC = data[0];
16209 env->hflags &= ~MIPS_HFLAG_BMASK;
16210 env->hflags |= data[1];
16211 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16212 case MIPS_HFLAG_BR:
16213 break;
16214 case MIPS_HFLAG_BC:
16215 case MIPS_HFLAG_BL:
16216 case MIPS_HFLAG_B:
16217 env->btarget = data[2];
16218 break;
16219 }
16220}
16221