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_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
299
300enum {
301 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
302 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
303 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
304 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
305 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
306 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
307 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
308 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
309 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
310 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
311 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
312 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
313 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
314 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
315};
316
317
318#define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
319
320enum {
321 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
322 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
323 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
324 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
325 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
326 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
327 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
328 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
329 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
330 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
331 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
332 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
333 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
334 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
335 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
336 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
337
338 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
339 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
340};
341
342
343#define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
344
345enum {
346
347 OPC_MADD = 0x00 | OPC_SPECIAL2,
348 OPC_MADDU = 0x01 | OPC_SPECIAL2,
349 OPC_MUL = 0x02 | OPC_SPECIAL2,
350 OPC_MSUB = 0x04 | OPC_SPECIAL2,
351 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
352
353 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
354 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
355 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
356 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
357 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
358 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
359 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
360 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
361 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
362 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
363 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
364 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
365
366 OPC_CLZ = 0x20 | OPC_SPECIAL2,
367 OPC_CLO = 0x21 | OPC_SPECIAL2,
368 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
369 OPC_DCLO = 0x25 | OPC_SPECIAL2,
370
371 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
372};
373
374
375#define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
376
377enum {
378 OPC_EXT = 0x00 | OPC_SPECIAL3,
379 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
380 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
381 OPC_DEXT = 0x03 | OPC_SPECIAL3,
382 OPC_INS = 0x04 | OPC_SPECIAL3,
383 OPC_DINSM = 0x05 | OPC_SPECIAL3,
384 OPC_DINSU = 0x06 | OPC_SPECIAL3,
385 OPC_DINS = 0x07 | OPC_SPECIAL3,
386 OPC_FORK = 0x08 | OPC_SPECIAL3,
387 OPC_YIELD = 0x09 | OPC_SPECIAL3,
388 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
389 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
390 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
391 OPC_GINV = 0x3D | OPC_SPECIAL3,
392
393
394 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
395 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
396 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
397 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
398 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
399 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
400 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
401 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
402 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
403 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
404 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
405 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
406
407
408 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
409
410 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
411 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
412 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
413 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
414
415
416 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
417 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
418
419 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
420 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
421
422
423
424 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
425 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
426
427 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
428 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
429
430 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
431 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
432
433 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
434 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
435
436
437 OPC_LWLE = 0x19 | OPC_SPECIAL3,
438 OPC_LWRE = 0x1A | OPC_SPECIAL3,
439 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
440 OPC_SBE = 0x1C | OPC_SPECIAL3,
441 OPC_SHE = 0x1D | OPC_SPECIAL3,
442 OPC_SCE = 0x1E | OPC_SPECIAL3,
443 OPC_SWE = 0x1F | OPC_SPECIAL3,
444 OPC_SWLE = 0x21 | OPC_SPECIAL3,
445 OPC_SWRE = 0x22 | OPC_SPECIAL3,
446 OPC_PREFE = 0x23 | OPC_SPECIAL3,
447 OPC_LBUE = 0x28 | OPC_SPECIAL3,
448 OPC_LHUE = 0x29 | OPC_SPECIAL3,
449 OPC_LBE = 0x2C | OPC_SPECIAL3,
450 OPC_LHE = 0x2D | OPC_SPECIAL3,
451 OPC_LLE = 0x2E | OPC_SPECIAL3,
452 OPC_LWE = 0x2F | OPC_SPECIAL3,
453
454
455 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
456 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
457 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
458 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
459 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
460 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
461};
462
463
464#define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
465enum {
466 OPC_GSLQ = 0x0020 | OPC_LWC2,
467 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
468 OPC_GSSHFL = OPC_LWC2,
469 OPC_GSSQ = 0x0020 | OPC_SWC2,
470 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
471 OPC_GSSHFS = OPC_SWC2,
472};
473
474
475#define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
476enum {
477 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
478 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
479 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
480 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
481 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
482 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
483 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
484 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
485};
486
487
488#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
489
490enum {
491 OPC_GSLBX = 0x0 | OPC_LDC2,
492 OPC_GSLHX = 0x1 | OPC_LDC2,
493 OPC_GSLWX = 0x2 | OPC_LDC2,
494 OPC_GSLDX = 0x3 | OPC_LDC2,
495 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
496 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
497 OPC_GSSBX = 0x0 | OPC_SDC2,
498 OPC_GSSHX = 0x1 | OPC_SDC2,
499 OPC_GSSWX = 0x2 | OPC_SDC2,
500 OPC_GSSDX = 0x3 | OPC_SDC2,
501 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
502 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
503};
504
505
506#define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507
508enum {
509 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
510 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
511 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
512 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL,
513 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
514 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
515 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
516 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL
517};
518
519
520#define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
521
522enum {
523 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
524 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
525 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL,
526 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
527 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
528 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
529 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
530 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
531 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
532 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
533 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL,
534};
535
536
537enum {
538 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
539 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
540};
541
542#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
543
544enum {
545 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
546 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
547 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
548 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
549};
550
551#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552enum {
553
554 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
555 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
556 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
557 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
558 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
559 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
560 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
561 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
562 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
563 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
564 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
565 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
566 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
567 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
568 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
569 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
570 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
571 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
572
573 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
574 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
575 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
576 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
577 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
578 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
579};
580
581#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
582#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583enum {
584
585 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
586 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
587 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
588 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
589 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
590 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
591 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
592 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
593 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
594 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
595 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
596 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
597
598 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
599 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
600 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
601 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
602};
603
604#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605enum {
606
607 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
608 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
609 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
610 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
611 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
612 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
613 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
614 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
615 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
616 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
617 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
618 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
619 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
620
621 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
622 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
623 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
624 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
625 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
626};
627
628#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
629enum {
630
631 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
633 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
634 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
635 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
636 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
637 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
638
639 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
640 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
641 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
642 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
643 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
644 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
645 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
646 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
647 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
648 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
649 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
650 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
651 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
652 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
653 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
654};
655
656#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
657enum {
658
659 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
660 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
661 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
662 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
663 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
664 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
665 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
666 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
667 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
668 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
669 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
670 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
671 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
672 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
673 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
674 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
675 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
676 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
677 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
678 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
679 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
680 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
681};
682
683#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
684enum {
685
686 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
687 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
688 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
689 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
690 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
691 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
692 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
693 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
694 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
695 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
696 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
697 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
698 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
699 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
700 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
701 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
702 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
703 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
704 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
705 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
706 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
707 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
708};
709
710#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711enum {
712
713 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
714};
715
716#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
717enum {
718
719 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
720 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
721 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
722};
723
724#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
725enum {
726
727 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
728 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
729 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
730 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
731 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
732 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
733 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
734 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
735 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
736 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
737 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
738 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
739 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
740 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
741 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
742 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
743 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
744};
745
746#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
747enum {
748
749 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
752 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
753 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
754 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
755 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
756 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
757 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
758 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
759 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
760 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
761 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
762 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
763 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
764 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
765 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
766
767 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
768 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
769 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
770 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
771 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
772 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
773};
774
775#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776enum {
777
778 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
779 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
780 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
781 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
782 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
783
784 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
785 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
786 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
787 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
788 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
789 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
790 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
791 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
792 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
793 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
794 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
795 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
796 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
797 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
798 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
799 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
800 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
801 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
802 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
803 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
804 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
805};
806
807#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808enum {
809
810 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
817 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
818 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
819 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
820 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
821 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
822 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
823 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
824 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
825 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
826 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
827 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
828 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
829
830 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
831 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
832 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
833 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
834 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
835 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
836 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
837 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
838};
839
840#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
841enum {
842
843 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
844 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
845 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
846 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
847};
848
849#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
850enum {
851
852 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
853 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
854 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
855 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
856 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
857 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
858 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
859 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
860 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
861 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
862 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
863 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
864 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
865 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
866 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
867 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
868 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
869 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
870 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
871 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
872 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
873};
874
875#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
876enum {
877
878 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
879};
880
881#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
882enum {
883
884 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
889 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
890 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
891 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
892 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
893 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
894 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
895 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
896 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
897 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
898 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
899 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
900 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
901 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
902 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
903 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
904 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
905 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
906 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
907 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
908 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
909 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
910};
911
912#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
913enum {
914
915 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
920 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
921 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
922 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
923 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
924 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
925 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
926 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
927 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
928 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
929 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
930 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
931 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
932 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
933 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
934 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
935 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
936 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
937 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
938 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
939 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
940 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
941};
942
943
944#define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
945
946enum {
947 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
948 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
949 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
950 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
951 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
952 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
953 OPC_MFTR = (0x08 << 21) | OPC_CP0,
954 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
955 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
956 OPC_MTTR = (0x0C << 21) | OPC_CP0,
957 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
958 OPC_C0 = (0x10 << 21) | OPC_CP0,
959 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
960 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
961 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
962 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
963 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
964 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
965 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
966 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
967 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
968 OPC_C0_A = (0x1A << 21) | OPC_CP0,
969 OPC_C0_B = (0x1B << 21) | OPC_CP0,
970 OPC_C0_C = (0x1C << 21) | OPC_CP0,
971 OPC_C0_D = (0x1D << 21) | OPC_CP0,
972 OPC_C0_E = (0x1E << 21) | OPC_CP0,
973 OPC_C0_F = (0x1F << 21) | OPC_CP0,
974};
975
976
977#define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
978
979enum {
980 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
981 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
982 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
983 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
984 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
985 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
986 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
987 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
988};
989
990
991#define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
992
993enum {
994 OPC_TLBR = 0x01 | OPC_C0,
995 OPC_TLBWI = 0x02 | OPC_C0,
996 OPC_TLBINV = 0x03 | OPC_C0,
997 OPC_TLBINVF = 0x04 | OPC_C0,
998 OPC_TLBWR = 0x06 | OPC_C0,
999 OPC_TLBP = 0x08 | OPC_C0,
1000 OPC_RFE = 0x10 | OPC_C0,
1001 OPC_ERET = 0x18 | OPC_C0,
1002 OPC_DERET = 0x1F | OPC_C0,
1003 OPC_WAIT = 0x20 | OPC_C0,
1004};
1005
1006#define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1007
1008enum {
1009 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1010 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1011 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1012 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1013 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1014 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1015 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1016 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1017 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1018 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1019 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1020};
1021
1022#define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1023
1024enum {
1025 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1026 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1027 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1028 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1029 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1030 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1031 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1032 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1033
1034 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1035 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1036 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1037 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1038 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1039 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1040 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1041 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1042
1043 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1044 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1045 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1046 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1047 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1048 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1049 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1050 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1051
1052 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1053 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1054 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1055 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1056 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1057 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1058 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1059 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1060
1061 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1062 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1063 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1064 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1065 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1066 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1067
1068 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1069 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1070 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1071 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1072 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1073 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1074
1075 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1076 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1077 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1078 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1079 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1080 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1081
1082 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1083 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1084 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1085 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1086 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1087 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1088
1089 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1090 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1091 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1092 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1093 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1094 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1095
1096 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1097 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1098 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1099 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1100 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1101 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1102
1103 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1104 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1105 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1106 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1107 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1108 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1109
1110 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1111 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1112 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1113 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1114 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1115 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1116};
1117
1118
1119#define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1120
1121enum {
1122 OPC_LWXC1 = 0x00 | OPC_CP3,
1123 OPC_LDXC1 = 0x01 | OPC_CP3,
1124 OPC_LUXC1 = 0x05 | OPC_CP3,
1125 OPC_SWXC1 = 0x08 | OPC_CP3,
1126 OPC_SDXC1 = 0x09 | OPC_CP3,
1127 OPC_SUXC1 = 0x0D | OPC_CP3,
1128 OPC_PREFX = 0x0F | OPC_CP3,
1129 OPC_ALNV_PS = 0x1E | OPC_CP3,
1130 OPC_MADD_S = 0x20 | OPC_CP3,
1131 OPC_MADD_D = 0x21 | OPC_CP3,
1132 OPC_MADD_PS = 0x26 | OPC_CP3,
1133 OPC_MSUB_S = 0x28 | OPC_CP3,
1134 OPC_MSUB_D = 0x29 | OPC_CP3,
1135 OPC_MSUB_PS = 0x2E | OPC_CP3,
1136 OPC_NMADD_S = 0x30 | OPC_CP3,
1137 OPC_NMADD_D = 0x31 | OPC_CP3,
1138 OPC_NMADD_PS = 0x36 | OPC_CP3,
1139 OPC_NMSUB_S = 0x38 | OPC_CP3,
1140 OPC_NMSUB_D = 0x39 | OPC_CP3,
1141 OPC_NMSUB_PS = 0x3E | OPC_CP3,
1142};
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180enum {
1181 MMI_OPC_CLASS_MMI = 0x1C << 26,
1182 MMI_OPC_SQ = 0x1F << 26,
1183};
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1208enum {
1209 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI,
1210 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI,
1211 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI,
1212 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI,
1213 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI,
1214 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI,
1215 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1216 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1217};
1218
1219
1220TCGv cpu_gpr[32], cpu_PC;
1221
1222
1223
1224
1225TCGv_i64 cpu_gpr_hi[32];
1226TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1227static TCGv cpu_dspctrl, btarget;
1228TCGv bcond;
1229static TCGv cpu_lladdr, cpu_llval;
1230static TCGv_i32 hflags;
1231TCGv_i32 fpu_fcr0, fpu_fcr31;
1232TCGv_i64 fpu_f64[32];
1233
1234#include "exec/gen-icount.h"
1235
1236#define gen_helper_0e0i(name, arg) do { \
1237 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1238 gen_helper_##name(cpu_env, helper_tmp); \
1239 tcg_temp_free_i32(helper_tmp); \
1240 } while (0)
1241
1242#define gen_helper_0e1i(name, arg1, arg2) do { \
1243 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1244 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1245 tcg_temp_free_i32(helper_tmp); \
1246 } while (0)
1247
1248#define gen_helper_1e0i(name, ret, arg1) do { \
1249 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1250 gen_helper_##name(ret, cpu_env, helper_tmp); \
1251 tcg_temp_free_i32(helper_tmp); \
1252 } while (0)
1253
1254#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1255 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1256 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1257 tcg_temp_free_i32(helper_tmp); \
1258 } while (0)
1259
1260#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1261 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1262 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1263 tcg_temp_free_i32(helper_tmp); \
1264 } while (0)
1265
1266#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1267 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1268 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1269 tcg_temp_free_i32(helper_tmp); \
1270 } while (0)
1271
1272#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1273 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1274 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1275 tcg_temp_free_i32(helper_tmp); \
1276 } while (0)
1277
1278#define DISAS_STOP DISAS_TARGET_0
1279#define DISAS_EXIT DISAS_TARGET_1
1280
1281static const char regnames_HI[][4] = {
1282 "HI0", "HI1", "HI2", "HI3",
1283};
1284
1285static const char regnames_LO[][4] = {
1286 "LO0", "LO1", "LO2", "LO3",
1287};
1288
1289
1290void gen_load_gpr(TCGv t, int reg)
1291{
1292 if (reg == 0) {
1293 tcg_gen_movi_tl(t, 0);
1294 } else {
1295 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1296 }
1297}
1298
1299void gen_store_gpr(TCGv t, int reg)
1300{
1301 if (reg != 0) {
1302 tcg_gen_mov_tl(cpu_gpr[reg], t);
1303 }
1304}
1305
1306#if defined(TARGET_MIPS64)
1307void gen_load_gpr_hi(TCGv_i64 t, int reg)
1308{
1309 if (reg == 0) {
1310 tcg_gen_movi_i64(t, 0);
1311 } else {
1312 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1313 }
1314}
1315
1316void gen_store_gpr_hi(TCGv_i64 t, int reg)
1317{
1318 if (reg != 0) {
1319 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1320 }
1321}
1322#endif
1323
1324
1325static inline void gen_load_srsgpr(int from, int to)
1326{
1327 TCGv t0 = tcg_temp_new();
1328
1329 if (from == 0) {
1330 tcg_gen_movi_tl(t0, 0);
1331 } else {
1332 TCGv_i32 t2 = tcg_temp_new_i32();
1333 TCGv_ptr addr = tcg_temp_new_ptr();
1334
1335 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1336 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1337 tcg_gen_andi_i32(t2, t2, 0xf);
1338 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1339 tcg_gen_ext_i32_ptr(addr, t2);
1340 tcg_gen_add_ptr(addr, cpu_env, addr);
1341
1342 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1343 tcg_temp_free_ptr(addr);
1344 tcg_temp_free_i32(t2);
1345 }
1346 gen_store_gpr(t0, to);
1347 tcg_temp_free(t0);
1348}
1349
1350static inline void gen_store_srsgpr(int from, int to)
1351{
1352 if (to != 0) {
1353 TCGv t0 = tcg_temp_new();
1354 TCGv_i32 t2 = tcg_temp_new_i32();
1355 TCGv_ptr addr = tcg_temp_new_ptr();
1356
1357 gen_load_gpr(t0, from);
1358 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1359 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1360 tcg_gen_andi_i32(t2, t2, 0xf);
1361 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1362 tcg_gen_ext_i32_ptr(addr, t2);
1363 tcg_gen_add_ptr(addr, cpu_env, addr);
1364
1365 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1366 tcg_temp_free_ptr(addr);
1367 tcg_temp_free_i32(t2);
1368 tcg_temp_free(t0);
1369 }
1370}
1371
1372
1373static inline void gen_save_pc(target_ulong pc)
1374{
1375 tcg_gen_movi_tl(cpu_PC, pc);
1376}
1377
1378static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1379{
1380 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1381 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1382 gen_save_pc(ctx->base.pc_next);
1383 ctx->saved_pc = ctx->base.pc_next;
1384 }
1385 if (ctx->hflags != ctx->saved_hflags) {
1386 tcg_gen_movi_i32(hflags, ctx->hflags);
1387 ctx->saved_hflags = ctx->hflags;
1388 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1389 case MIPS_HFLAG_BR:
1390 break;
1391 case MIPS_HFLAG_BC:
1392 case MIPS_HFLAG_BL:
1393 case MIPS_HFLAG_B:
1394 tcg_gen_movi_tl(btarget, ctx->btarget);
1395 break;
1396 }
1397 }
1398}
1399
1400static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1401{
1402 ctx->saved_hflags = ctx->hflags;
1403 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1404 case MIPS_HFLAG_BR:
1405 break;
1406 case MIPS_HFLAG_BC:
1407 case MIPS_HFLAG_BL:
1408 case MIPS_HFLAG_B:
1409 ctx->btarget = env->btarget;
1410 break;
1411 }
1412}
1413
1414void generate_exception_err(DisasContext *ctx, int excp, int err)
1415{
1416 TCGv_i32 texcp = tcg_const_i32(excp);
1417 TCGv_i32 terr = tcg_const_i32(err);
1418 save_cpu_state(ctx, 1);
1419 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1420 tcg_temp_free_i32(terr);
1421 tcg_temp_free_i32(texcp);
1422 ctx->base.is_jmp = DISAS_NORETURN;
1423}
1424
1425void generate_exception(DisasContext *ctx, int excp)
1426{
1427 gen_helper_0e0i(raise_exception, excp);
1428}
1429
1430void generate_exception_end(DisasContext *ctx, int excp)
1431{
1432 generate_exception_err(ctx, excp, 0);
1433}
1434
1435void gen_reserved_instruction(DisasContext *ctx)
1436{
1437 generate_exception_end(ctx, EXCP_RI);
1438}
1439
1440
1441void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1442{
1443 if (ctx->hflags & MIPS_HFLAG_FRE) {
1444 generate_exception(ctx, EXCP_RI);
1445 }
1446 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1447}
1448
1449void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1450{
1451 TCGv_i64 t64;
1452 if (ctx->hflags & MIPS_HFLAG_FRE) {
1453 generate_exception(ctx, EXCP_RI);
1454 }
1455 t64 = tcg_temp_new_i64();
1456 tcg_gen_extu_i32_i64(t64, t);
1457 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1458 tcg_temp_free_i64(t64);
1459}
1460
1461static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1462{
1463 if (ctx->hflags & MIPS_HFLAG_F64) {
1464 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1465 } else {
1466 gen_load_fpr32(ctx, t, reg | 1);
1467 }
1468}
1469
1470static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1471{
1472 if (ctx->hflags & MIPS_HFLAG_F64) {
1473 TCGv_i64 t64 = tcg_temp_new_i64();
1474 tcg_gen_extu_i32_i64(t64, t);
1475 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1476 tcg_temp_free_i64(t64);
1477 } else {
1478 gen_store_fpr32(ctx, t, reg | 1);
1479 }
1480}
1481
1482void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1483{
1484 if (ctx->hflags & MIPS_HFLAG_F64) {
1485 tcg_gen_mov_i64(t, fpu_f64[reg]);
1486 } else {
1487 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1488 }
1489}
1490
1491void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1492{
1493 if (ctx->hflags & MIPS_HFLAG_F64) {
1494 tcg_gen_mov_i64(fpu_f64[reg], t);
1495 } else {
1496 TCGv_i64 t0;
1497 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1498 t0 = tcg_temp_new_i64();
1499 tcg_gen_shri_i64(t0, t, 32);
1500 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1501 tcg_temp_free_i64(t0);
1502 }
1503}
1504
1505int get_fp_bit(int cc)
1506{
1507 if (cc) {
1508 return 24 + cc;
1509 } else {
1510 return 23;
1511 }
1512}
1513
1514
1515void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1516{
1517 tcg_gen_add_tl(ret, arg0, arg1);
1518
1519#if defined(TARGET_MIPS64)
1520 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1521 tcg_gen_ext32s_i64(ret, ret);
1522 }
1523#endif
1524}
1525
1526static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1527 target_long ofs)
1528{
1529 tcg_gen_addi_tl(ret, base, ofs);
1530
1531#if defined(TARGET_MIPS64)
1532 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1533 tcg_gen_ext32s_i64(ret, ret);
1534 }
1535#endif
1536}
1537
1538
1539static target_long addr_add(DisasContext *ctx, target_long base,
1540 target_long offset)
1541{
1542 target_long sum = base + offset;
1543
1544#if defined(TARGET_MIPS64)
1545 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1546 sum = (int32_t)sum;
1547 }
1548#endif
1549 return sum;
1550}
1551
1552
1553void gen_move_low32(TCGv ret, TCGv_i64 arg)
1554{
1555#if defined(TARGET_MIPS64)
1556 tcg_gen_ext32s_i64(ret, arg);
1557#else
1558 tcg_gen_extrl_i64_i32(ret, arg);
1559#endif
1560}
1561
1562
1563void gen_move_high32(TCGv ret, TCGv_i64 arg)
1564{
1565#if defined(TARGET_MIPS64)
1566 tcg_gen_sari_i64(ret, arg, 32);
1567#else
1568 tcg_gen_extrh_i64_i32(ret, arg);
1569#endif
1570}
1571
1572bool check_cp0_enabled(DisasContext *ctx)
1573{
1574 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1575 generate_exception_end(ctx, EXCP_CpU);
1576 return false;
1577 }
1578 return true;
1579}
1580
1581void check_cp1_enabled(DisasContext *ctx)
1582{
1583 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1584 generate_exception_err(ctx, EXCP_CpU, 1);
1585 }
1586}
1587
1588
1589
1590
1591
1592
1593void check_cop1x(DisasContext *ctx)
1594{
1595 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1596 gen_reserved_instruction(ctx);
1597 }
1598}
1599
1600
1601
1602
1603
1604void check_cp1_64bitmode(DisasContext *ctx)
1605{
1606 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1607 gen_reserved_instruction(ctx);
1608 }
1609}
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622void check_cp1_registers(DisasContext *ctx, int regs)
1623{
1624 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1625 gen_reserved_instruction(ctx);
1626 }
1627}
1628
1629
1630
1631
1632
1633static inline void check_dsp(DisasContext *ctx)
1634{
1635 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1636 if (ctx->insn_flags & ASE_DSP) {
1637 generate_exception_end(ctx, EXCP_DSPDIS);
1638 } else {
1639 gen_reserved_instruction(ctx);
1640 }
1641 }
1642}
1643
1644static inline void check_dsp_r2(DisasContext *ctx)
1645{
1646 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1647 if (ctx->insn_flags & ASE_DSP) {
1648 generate_exception_end(ctx, EXCP_DSPDIS);
1649 } else {
1650 gen_reserved_instruction(ctx);
1651 }
1652 }
1653}
1654
1655static inline void check_dsp_r3(DisasContext *ctx)
1656{
1657 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1658 if (ctx->insn_flags & ASE_DSP) {
1659 generate_exception_end(ctx, EXCP_DSPDIS);
1660 } else {
1661 gen_reserved_instruction(ctx);
1662 }
1663 }
1664}
1665
1666
1667
1668
1669
1670void check_insn(DisasContext *ctx, uint64_t flags)
1671{
1672 if (unlikely(!(ctx->insn_flags & flags))) {
1673 gen_reserved_instruction(ctx);
1674 }
1675}
1676
1677
1678
1679
1680
1681
1682static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1683{
1684 if (unlikely(ctx->insn_flags & flags)) {
1685 gen_reserved_instruction(ctx);
1686 }
1687}
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1698{
1699#ifndef CONFIG_USER_ONLY
1700 check_insn_opc_removed(ctx, flags);
1701#endif
1702}
1703
1704
1705
1706
1707
1708static inline void check_ps(DisasContext *ctx)
1709{
1710 if (unlikely(!ctx->ps)) {
1711 generate_exception(ctx, EXCP_RI);
1712 }
1713 check_cp1_64bitmode(ctx);
1714}
1715
1716
1717
1718
1719
1720void check_mips_64(DisasContext *ctx)
1721{
1722 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1723 gen_reserved_instruction(ctx);
1724 }
1725}
1726
1727#ifndef CONFIG_USER_ONLY
1728static inline void check_mvh(DisasContext *ctx)
1729{
1730 if (unlikely(!ctx->mvh)) {
1731 generate_exception(ctx, EXCP_RI);
1732 }
1733}
1734#endif
1735
1736
1737
1738
1739
1740static inline void check_xnp(DisasContext *ctx)
1741{
1742 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1743 gen_reserved_instruction(ctx);
1744 }
1745}
1746
1747#ifndef CONFIG_USER_ONLY
1748
1749
1750
1751
1752static inline void check_pw(DisasContext *ctx)
1753{
1754 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1755 gen_reserved_instruction(ctx);
1756 }
1757}
1758#endif
1759
1760
1761
1762
1763
1764static inline void check_mt(DisasContext *ctx)
1765{
1766 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1767 gen_reserved_instruction(ctx);
1768 }
1769}
1770
1771#ifndef CONFIG_USER_ONLY
1772
1773
1774
1775
1776
1777
1778static inline void check_cp0_mt(DisasContext *ctx)
1779{
1780 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1781 generate_exception_end(ctx, EXCP_CpU);
1782 } else {
1783 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1784 gen_reserved_instruction(ctx);
1785 }
1786 }
1787}
1788#endif
1789
1790
1791
1792
1793
1794static inline void check_nms(DisasContext *ctx)
1795{
1796 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1797 gen_reserved_instruction(ctx);
1798 }
1799}
1800
1801
1802
1803
1804
1805
1806static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1807{
1808 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1809 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1810 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1811 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1812 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1813 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1814 gen_reserved_instruction(ctx);
1815 }
1816}
1817
1818
1819
1820
1821
1822static inline void check_eva(DisasContext *ctx)
1823{
1824 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1825 gen_reserved_instruction(ctx);
1826 }
1827}
1828
1829
1830
1831
1832
1833
1834
1835
1836#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1837#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1838#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1839static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1840 int ft, int fs, int cc) \
1841{ \
1842 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1843 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1844 switch (ifmt) { \
1845 case FMT_PS: \
1846 check_ps(ctx); \
1847 break; \
1848 case FMT_D: \
1849 if (abs) { \
1850 check_cop1x(ctx); \
1851 } \
1852 check_cp1_registers(ctx, fs | ft); \
1853 break; \
1854 case FMT_S: \
1855 if (abs) { \
1856 check_cop1x(ctx); \
1857 } \
1858 break; \
1859 } \
1860 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1861 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1862 switch (n) { \
1863 case 0: \
1864 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1865 break; \
1866 case 1: \
1867 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1868 break; \
1869 case 2: \
1870 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1871 break; \
1872 case 3: \
1873 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1874 break; \
1875 case 4: \
1876 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1877 break; \
1878 case 5: \
1879 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1880 break; \
1881 case 6: \
1882 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1883 break; \
1884 case 7: \
1885 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1886 break; \
1887 case 8: \
1888 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1889 break; \
1890 case 9: \
1891 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1892 break; \
1893 case 10: \
1894 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1895 break; \
1896 case 11: \
1897 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1898 break; \
1899 case 12: \
1900 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1901 break; \
1902 case 13: \
1903 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1904 break; \
1905 case 14: \
1906 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1907 break; \
1908 case 15: \
1909 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1910 break; \
1911 default: \
1912 abort(); \
1913 } \
1914 tcg_temp_free_i##bits(fp0); \
1915 tcg_temp_free_i##bits(fp1); \
1916}
1917
1918FOP_CONDS(, 0, d, FMT_D, 64)
1919FOP_CONDS(abs, 1, d, FMT_D, 64)
1920FOP_CONDS(, 0, s, FMT_S, 32)
1921FOP_CONDS(abs, 1, s, FMT_S, 32)
1922FOP_CONDS(, 0, ps, FMT_PS, 64)
1923FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1924#undef FOP_CONDS
1925
1926#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1927static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1928 int ft, int fs, int fd) \
1929{ \
1930 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1931 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1932 if (ifmt == FMT_D) { \
1933 check_cp1_registers(ctx, fs | ft | fd); \
1934 } \
1935 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1936 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1937 switch (n) { \
1938 case 0: \
1939 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1940 break; \
1941 case 1: \
1942 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1943 break; \
1944 case 2: \
1945 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1946 break; \
1947 case 3: \
1948 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1949 break; \
1950 case 4: \
1951 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1952 break; \
1953 case 5: \
1954 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1955 break; \
1956 case 6: \
1957 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1958 break; \
1959 case 7: \
1960 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1961 break; \
1962 case 8: \
1963 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1964 break; \
1965 case 9: \
1966 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1967 break; \
1968 case 10: \
1969 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1970 break; \
1971 case 11: \
1972 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1973 break; \
1974 case 12: \
1975 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1976 break; \
1977 case 13: \
1978 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1979 break; \
1980 case 14: \
1981 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1982 break; \
1983 case 15: \
1984 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1985 break; \
1986 case 17: \
1987 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1988 break; \
1989 case 18: \
1990 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1991 break; \
1992 case 19: \
1993 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1994 break; \
1995 case 25: \
1996 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1997 break; \
1998 case 26: \
1999 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2000 break; \
2001 case 27: \
2002 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2003 break; \
2004 default: \
2005 abort(); \
2006 } \
2007 STORE; \
2008 tcg_temp_free_i ## bits(fp0); \
2009 tcg_temp_free_i ## bits(fp1); \
2010}
2011
2012FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2013FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2014#undef FOP_CONDNS
2015#undef gen_ldcmp_fpr32
2016#undef gen_ldcmp_fpr64
2017
2018
2019#ifdef CONFIG_USER_ONLY
2020#define OP_LD_ATOMIC(insn, fname) \
2021static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2022 DisasContext *ctx) \
2023{ \
2024 TCGv t0 = tcg_temp_new(); \
2025 tcg_gen_mov_tl(t0, arg1); \
2026 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2027 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2028 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2029 tcg_temp_free(t0); \
2030}
2031#else
2032#define OP_LD_ATOMIC(insn, fname) \
2033static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2034 DisasContext *ctx) \
2035{ \
2036 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2037}
2038#endif
2039OP_LD_ATOMIC(ll, ld32s);
2040#if defined(TARGET_MIPS64)
2041OP_LD_ATOMIC(lld, ld64);
2042#endif
2043#undef OP_LD_ATOMIC
2044
2045void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
2046{
2047 if (base == 0) {
2048 tcg_gen_movi_tl(addr, offset);
2049 } else if (offset == 0) {
2050 gen_load_gpr(addr, base);
2051 } else {
2052 tcg_gen_movi_tl(addr, offset);
2053 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2054 }
2055}
2056
2057static target_ulong pc_relative_pc(DisasContext *ctx)
2058{
2059 target_ulong pc = ctx->base.pc_next;
2060
2061 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2062 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2063
2064 pc -= branch_bytes;
2065 }
2066
2067 pc &= ~(target_ulong)3;
2068 return pc;
2069}
2070
2071
2072static void gen_ld(DisasContext *ctx, uint32_t opc,
2073 int rt, int base, int offset)
2074{
2075 TCGv t0, t1, t2;
2076 int mem_idx = ctx->mem_idx;
2077
2078 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2079 INSN_LOONGSON3A)) {
2080
2081
2082
2083
2084
2085 return;
2086 }
2087
2088 t0 = tcg_temp_new();
2089 gen_base_offset_addr(ctx, t0, base, offset);
2090
2091 switch (opc) {
2092#if defined(TARGET_MIPS64)
2093 case OPC_LWU:
2094 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2095 ctx->default_tcg_memop_mask);
2096 gen_store_gpr(t0, rt);
2097 break;
2098 case OPC_LD:
2099 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2100 ctx->default_tcg_memop_mask);
2101 gen_store_gpr(t0, rt);
2102 break;
2103 case OPC_LLD:
2104 case R6_OPC_LLD:
2105 op_ld_lld(t0, t0, mem_idx, ctx);
2106 gen_store_gpr(t0, rt);
2107 break;
2108 case OPC_LDL:
2109 t1 = tcg_temp_new();
2110
2111
2112
2113
2114 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2115 tcg_gen_andi_tl(t1, t0, 7);
2116#ifndef TARGET_WORDS_BIGENDIAN
2117 tcg_gen_xori_tl(t1, t1, 7);
2118#endif
2119 tcg_gen_shli_tl(t1, t1, 3);
2120 tcg_gen_andi_tl(t0, t0, ~7);
2121 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2122 tcg_gen_shl_tl(t0, t0, t1);
2123 t2 = tcg_const_tl(-1);
2124 tcg_gen_shl_tl(t2, t2, t1);
2125 gen_load_gpr(t1, rt);
2126 tcg_gen_andc_tl(t1, t1, t2);
2127 tcg_temp_free(t2);
2128 tcg_gen_or_tl(t0, t0, t1);
2129 tcg_temp_free(t1);
2130 gen_store_gpr(t0, rt);
2131 break;
2132 case OPC_LDR:
2133 t1 = tcg_temp_new();
2134
2135
2136
2137
2138 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2139 tcg_gen_andi_tl(t1, t0, 7);
2140#ifdef TARGET_WORDS_BIGENDIAN
2141 tcg_gen_xori_tl(t1, t1, 7);
2142#endif
2143 tcg_gen_shli_tl(t1, t1, 3);
2144 tcg_gen_andi_tl(t0, t0, ~7);
2145 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2146 tcg_gen_shr_tl(t0, t0, t1);
2147 tcg_gen_xori_tl(t1, t1, 63);
2148 t2 = tcg_const_tl(0xfffffffffffffffeull);
2149 tcg_gen_shl_tl(t2, t2, t1);
2150 gen_load_gpr(t1, rt);
2151 tcg_gen_and_tl(t1, t1, t2);
2152 tcg_temp_free(t2);
2153 tcg_gen_or_tl(t0, t0, t1);
2154 tcg_temp_free(t1);
2155 gen_store_gpr(t0, rt);
2156 break;
2157 case OPC_LDPC:
2158 t1 = tcg_const_tl(pc_relative_pc(ctx));
2159 gen_op_addr_add(ctx, t0, t0, t1);
2160 tcg_temp_free(t1);
2161 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2162 gen_store_gpr(t0, rt);
2163 break;
2164#endif
2165 case OPC_LWPC:
2166 t1 = tcg_const_tl(pc_relative_pc(ctx));
2167 gen_op_addr_add(ctx, t0, t0, t1);
2168 tcg_temp_free(t1);
2169 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2170 gen_store_gpr(t0, rt);
2171 break;
2172 case OPC_LWE:
2173 mem_idx = MIPS_HFLAG_UM;
2174
2175 case OPC_LW:
2176 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2177 ctx->default_tcg_memop_mask);
2178 gen_store_gpr(t0, rt);
2179 break;
2180 case OPC_LHE:
2181 mem_idx = MIPS_HFLAG_UM;
2182
2183 case OPC_LH:
2184 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2185 ctx->default_tcg_memop_mask);
2186 gen_store_gpr(t0, rt);
2187 break;
2188 case OPC_LHUE:
2189 mem_idx = MIPS_HFLAG_UM;
2190
2191 case OPC_LHU:
2192 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2193 ctx->default_tcg_memop_mask);
2194 gen_store_gpr(t0, rt);
2195 break;
2196 case OPC_LBE:
2197 mem_idx = MIPS_HFLAG_UM;
2198
2199 case OPC_LB:
2200 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2201 gen_store_gpr(t0, rt);
2202 break;
2203 case OPC_LBUE:
2204 mem_idx = MIPS_HFLAG_UM;
2205
2206 case OPC_LBU:
2207 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2208 gen_store_gpr(t0, rt);
2209 break;
2210 case OPC_LWLE:
2211 mem_idx = MIPS_HFLAG_UM;
2212
2213 case OPC_LWL:
2214 t1 = tcg_temp_new();
2215
2216
2217
2218
2219 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2220 tcg_gen_andi_tl(t1, t0, 3);
2221#ifndef TARGET_WORDS_BIGENDIAN
2222 tcg_gen_xori_tl(t1, t1, 3);
2223#endif
2224 tcg_gen_shli_tl(t1, t1, 3);
2225 tcg_gen_andi_tl(t0, t0, ~3);
2226 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2227 tcg_gen_shl_tl(t0, t0, t1);
2228 t2 = tcg_const_tl(-1);
2229 tcg_gen_shl_tl(t2, t2, t1);
2230 gen_load_gpr(t1, rt);
2231 tcg_gen_andc_tl(t1, t1, t2);
2232 tcg_temp_free(t2);
2233 tcg_gen_or_tl(t0, t0, t1);
2234 tcg_temp_free(t1);
2235 tcg_gen_ext32s_tl(t0, t0);
2236 gen_store_gpr(t0, rt);
2237 break;
2238 case OPC_LWRE:
2239 mem_idx = MIPS_HFLAG_UM;
2240
2241 case OPC_LWR:
2242 t1 = tcg_temp_new();
2243
2244
2245
2246
2247 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2248 tcg_gen_andi_tl(t1, t0, 3);
2249#ifdef TARGET_WORDS_BIGENDIAN
2250 tcg_gen_xori_tl(t1, t1, 3);
2251#endif
2252 tcg_gen_shli_tl(t1, t1, 3);
2253 tcg_gen_andi_tl(t0, t0, ~3);
2254 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2255 tcg_gen_shr_tl(t0, t0, t1);
2256 tcg_gen_xori_tl(t1, t1, 31);
2257 t2 = tcg_const_tl(0xfffffffeull);
2258 tcg_gen_shl_tl(t2, t2, t1);
2259 gen_load_gpr(t1, rt);
2260 tcg_gen_and_tl(t1, t1, t2);
2261 tcg_temp_free(t2);
2262 tcg_gen_or_tl(t0, t0, t1);
2263 tcg_temp_free(t1);
2264 tcg_gen_ext32s_tl(t0, t0);
2265 gen_store_gpr(t0, rt);
2266 break;
2267 case OPC_LLE:
2268 mem_idx = MIPS_HFLAG_UM;
2269
2270 case OPC_LL:
2271 case R6_OPC_LL:
2272 op_ld_ll(t0, t0, mem_idx, ctx);
2273 gen_store_gpr(t0, rt);
2274 break;
2275 }
2276 tcg_temp_free(t0);
2277}
2278
2279
2280static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2281 int base, int offset)
2282{
2283 TCGv t0 = tcg_temp_new();
2284 TCGv t1 = tcg_temp_new();
2285 int mem_idx = ctx->mem_idx;
2286
2287 gen_base_offset_addr(ctx, t0, base, offset);
2288 gen_load_gpr(t1, rt);
2289 switch (opc) {
2290#if defined(TARGET_MIPS64)
2291 case OPC_SD:
2292 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
2293 ctx->default_tcg_memop_mask);
2294 break;
2295 case OPC_SDL:
2296 gen_helper_0e2i(sdl, t1, t0, mem_idx);
2297 break;
2298 case OPC_SDR:
2299 gen_helper_0e2i(sdr, t1, t0, mem_idx);
2300 break;
2301#endif
2302 case OPC_SWE:
2303 mem_idx = MIPS_HFLAG_UM;
2304
2305 case OPC_SW:
2306 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2307 ctx->default_tcg_memop_mask);
2308 break;
2309 case OPC_SHE:
2310 mem_idx = MIPS_HFLAG_UM;
2311
2312 case OPC_SH:
2313 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2314 ctx->default_tcg_memop_mask);
2315 break;
2316 case OPC_SBE:
2317 mem_idx = MIPS_HFLAG_UM;
2318
2319 case OPC_SB:
2320 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2321 break;
2322 case OPC_SWLE:
2323 mem_idx = MIPS_HFLAG_UM;
2324
2325 case OPC_SWL:
2326 gen_helper_0e2i(swl, t1, t0, mem_idx);
2327 break;
2328 case OPC_SWRE:
2329 mem_idx = MIPS_HFLAG_UM;
2330
2331 case OPC_SWR:
2332 gen_helper_0e2i(swr, t1, t0, mem_idx);
2333 break;
2334 }
2335 tcg_temp_free(t0);
2336 tcg_temp_free(t1);
2337}
2338
2339
2340
2341static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2342 MemOp tcg_mo, bool eva)
2343{
2344 TCGv addr, t0, val;
2345 TCGLabel *l1 = gen_new_label();
2346 TCGLabel *done = gen_new_label();
2347
2348 t0 = tcg_temp_new();
2349 addr = tcg_temp_new();
2350
2351 gen_base_offset_addr(ctx, addr, base, offset);
2352 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2353 tcg_temp_free(addr);
2354 tcg_gen_movi_tl(t0, 0);
2355 gen_store_gpr(t0, rt);
2356 tcg_gen_br(done);
2357
2358 gen_set_label(l1);
2359
2360 val = tcg_temp_new();
2361 gen_load_gpr(val, rt);
2362 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2363 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2364 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2365 gen_store_gpr(t0, rt);
2366 tcg_temp_free(val);
2367
2368 gen_set_label(done);
2369 tcg_temp_free(t0);
2370}
2371
2372
2373static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2374 TCGv t0)
2375{
2376
2377
2378
2379
2380 switch (opc) {
2381 case OPC_LWC1:
2382 {
2383 TCGv_i32 fp0 = tcg_temp_new_i32();
2384 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2385 ctx->default_tcg_memop_mask);
2386 gen_store_fpr32(ctx, fp0, ft);
2387 tcg_temp_free_i32(fp0);
2388 }
2389 break;
2390 case OPC_SWC1:
2391 {
2392 TCGv_i32 fp0 = tcg_temp_new_i32();
2393 gen_load_fpr32(ctx, fp0, ft);
2394 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2395 ctx->default_tcg_memop_mask);
2396 tcg_temp_free_i32(fp0);
2397 }
2398 break;
2399 case OPC_LDC1:
2400 {
2401 TCGv_i64 fp0 = tcg_temp_new_i64();
2402 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2403 ctx->default_tcg_memop_mask);
2404 gen_store_fpr64(ctx, fp0, ft);
2405 tcg_temp_free_i64(fp0);
2406 }
2407 break;
2408 case OPC_SDC1:
2409 {
2410 TCGv_i64 fp0 = tcg_temp_new_i64();
2411 gen_load_fpr64(ctx, fp0, ft);
2412 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2413 ctx->default_tcg_memop_mask);
2414 tcg_temp_free_i64(fp0);
2415 }
2416 break;
2417 default:
2418 MIPS_INVAL("flt_ldst");
2419 gen_reserved_instruction(ctx);
2420 break;
2421 }
2422}
2423
2424static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2425 int rs, int16_t imm)
2426{
2427 TCGv t0 = tcg_temp_new();
2428
2429 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2430 check_cp1_enabled(ctx);
2431 switch (op) {
2432 case OPC_LDC1:
2433 case OPC_SDC1:
2434 check_insn(ctx, ISA_MIPS2);
2435
2436 default:
2437 gen_base_offset_addr(ctx, t0, rs, imm);
2438 gen_flt_ldst(ctx, op, rt, t0);
2439 }
2440 } else {
2441 generate_exception_err(ctx, EXCP_CpU, 1);
2442 }
2443 tcg_temp_free(t0);
2444}
2445
2446
2447static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2448 int rt, int rs, int imm)
2449{
2450 target_ulong uimm = (target_long)imm;
2451
2452 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2453
2454
2455
2456
2457 return;
2458 }
2459 switch (opc) {
2460 case OPC_ADDI:
2461 {
2462 TCGv t0 = tcg_temp_local_new();
2463 TCGv t1 = tcg_temp_new();
2464 TCGv t2 = tcg_temp_new();
2465 TCGLabel *l1 = gen_new_label();
2466
2467 gen_load_gpr(t1, rs);
2468 tcg_gen_addi_tl(t0, t1, uimm);
2469 tcg_gen_ext32s_tl(t0, t0);
2470
2471 tcg_gen_xori_tl(t1, t1, ~uimm);
2472 tcg_gen_xori_tl(t2, t0, uimm);
2473 tcg_gen_and_tl(t1, t1, t2);
2474 tcg_temp_free(t2);
2475 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2476 tcg_temp_free(t1);
2477
2478 generate_exception(ctx, EXCP_OVERFLOW);
2479 gen_set_label(l1);
2480 tcg_gen_ext32s_tl(t0, t0);
2481 gen_store_gpr(t0, rt);
2482 tcg_temp_free(t0);
2483 }
2484 break;
2485 case OPC_ADDIU:
2486 if (rs != 0) {
2487 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2488 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2489 } else {
2490 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2491 }
2492 break;
2493#if defined(TARGET_MIPS64)
2494 case OPC_DADDI:
2495 {
2496 TCGv t0 = tcg_temp_local_new();
2497 TCGv t1 = tcg_temp_new();
2498 TCGv t2 = tcg_temp_new();
2499 TCGLabel *l1 = gen_new_label();
2500
2501 gen_load_gpr(t1, rs);
2502 tcg_gen_addi_tl(t0, t1, uimm);
2503
2504 tcg_gen_xori_tl(t1, t1, ~uimm);
2505 tcg_gen_xori_tl(t2, t0, uimm);
2506 tcg_gen_and_tl(t1, t1, t2);
2507 tcg_temp_free(t2);
2508 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2509 tcg_temp_free(t1);
2510
2511 generate_exception(ctx, EXCP_OVERFLOW);
2512 gen_set_label(l1);
2513 gen_store_gpr(t0, rt);
2514 tcg_temp_free(t0);
2515 }
2516 break;
2517 case OPC_DADDIU:
2518 if (rs != 0) {
2519 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2520 } else {
2521 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2522 }
2523 break;
2524#endif
2525 }
2526}
2527
2528
2529static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2530 int rt, int rs, int16_t imm)
2531{
2532 target_ulong uimm;
2533
2534 if (rt == 0) {
2535
2536 return;
2537 }
2538 uimm = (uint16_t)imm;
2539 switch (opc) {
2540 case OPC_ANDI:
2541 if (likely(rs != 0)) {
2542 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2543 } else {
2544 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2545 }
2546 break;
2547 case OPC_ORI:
2548 if (rs != 0) {
2549 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2550 } else {
2551 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2552 }
2553 break;
2554 case OPC_XORI:
2555 if (likely(rs != 0)) {
2556 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2557 } else {
2558 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2559 }
2560 break;
2561 case OPC_LUI:
2562 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2563
2564 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2565 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2566 } else {
2567 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2568 }
2569 break;
2570
2571 default:
2572 break;
2573 }
2574}
2575
2576
2577static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2578 int rt, int rs, int16_t imm)
2579{
2580 target_ulong uimm = (target_long)imm;
2581 TCGv t0;
2582
2583 if (rt == 0) {
2584
2585 return;
2586 }
2587 t0 = tcg_temp_new();
2588 gen_load_gpr(t0, rs);
2589 switch (opc) {
2590 case OPC_SLTI:
2591 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2592 break;
2593 case OPC_SLTIU:
2594 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2595 break;
2596 }
2597 tcg_temp_free(t0);
2598}
2599
2600
2601static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2602 int rt, int rs, int16_t imm)
2603{
2604 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2605 TCGv t0;
2606
2607 if (rt == 0) {
2608
2609 return;
2610 }
2611
2612 t0 = tcg_temp_new();
2613 gen_load_gpr(t0, rs);
2614 switch (opc) {
2615 case OPC_SLL:
2616 tcg_gen_shli_tl(t0, t0, uimm);
2617 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2618 break;
2619 case OPC_SRA:
2620 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2621 break;
2622 case OPC_SRL:
2623 if (uimm != 0) {
2624 tcg_gen_ext32u_tl(t0, t0);
2625 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2626 } else {
2627 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2628 }
2629 break;
2630 case OPC_ROTR:
2631 if (uimm != 0) {
2632 TCGv_i32 t1 = tcg_temp_new_i32();
2633
2634 tcg_gen_trunc_tl_i32(t1, t0);
2635 tcg_gen_rotri_i32(t1, t1, uimm);
2636 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2637 tcg_temp_free_i32(t1);
2638 } else {
2639 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2640 }
2641 break;
2642#if defined(TARGET_MIPS64)
2643 case OPC_DSLL:
2644 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2645 break;
2646 case OPC_DSRA:
2647 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2648 break;
2649 case OPC_DSRL:
2650 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2651 break;
2652 case OPC_DROTR:
2653 if (uimm != 0) {
2654 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2655 } else {
2656 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2657 }
2658 break;
2659 case OPC_DSLL32:
2660 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2661 break;
2662 case OPC_DSRA32:
2663 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2664 break;
2665 case OPC_DSRL32:
2666 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2667 break;
2668 case OPC_DROTR32:
2669 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2670 break;
2671#endif
2672 }
2673 tcg_temp_free(t0);
2674}
2675
2676
2677static void gen_arith(DisasContext *ctx, uint32_t opc,
2678 int rd, int rs, int rt)
2679{
2680 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2681 && opc != OPC_DADD && opc != OPC_DSUB) {
2682
2683
2684
2685
2686 return;
2687 }
2688
2689 switch (opc) {
2690 case OPC_ADD:
2691 {
2692 TCGv t0 = tcg_temp_local_new();
2693 TCGv t1 = tcg_temp_new();
2694 TCGv t2 = tcg_temp_new();
2695 TCGLabel *l1 = gen_new_label();
2696
2697 gen_load_gpr(t1, rs);
2698 gen_load_gpr(t2, rt);
2699 tcg_gen_add_tl(t0, t1, t2);
2700 tcg_gen_ext32s_tl(t0, t0);
2701 tcg_gen_xor_tl(t1, t1, t2);
2702 tcg_gen_xor_tl(t2, t0, t2);
2703 tcg_gen_andc_tl(t1, t2, t1);
2704 tcg_temp_free(t2);
2705 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2706 tcg_temp_free(t1);
2707
2708 generate_exception(ctx, EXCP_OVERFLOW);
2709 gen_set_label(l1);
2710 gen_store_gpr(t0, rd);
2711 tcg_temp_free(t0);
2712 }
2713 break;
2714 case OPC_ADDU:
2715 if (rs != 0 && rt != 0) {
2716 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2717 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2718 } else if (rs == 0 && rt != 0) {
2719 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2720 } else if (rs != 0 && rt == 0) {
2721 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2722 } else {
2723 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2724 }
2725 break;
2726 case OPC_SUB:
2727 {
2728 TCGv t0 = tcg_temp_local_new();
2729 TCGv t1 = tcg_temp_new();
2730 TCGv t2 = tcg_temp_new();
2731 TCGLabel *l1 = gen_new_label();
2732
2733 gen_load_gpr(t1, rs);
2734 gen_load_gpr(t2, rt);
2735 tcg_gen_sub_tl(t0, t1, t2);
2736 tcg_gen_ext32s_tl(t0, t0);
2737 tcg_gen_xor_tl(t2, t1, t2);
2738 tcg_gen_xor_tl(t1, t0, t1);
2739 tcg_gen_and_tl(t1, t1, t2);
2740 tcg_temp_free(t2);
2741 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2742 tcg_temp_free(t1);
2743
2744
2745
2746
2747 generate_exception(ctx, EXCP_OVERFLOW);
2748 gen_set_label(l1);
2749 gen_store_gpr(t0, rd);
2750 tcg_temp_free(t0);
2751 }
2752 break;
2753 case OPC_SUBU:
2754 if (rs != 0 && rt != 0) {
2755 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2756 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2757 } else if (rs == 0 && rt != 0) {
2758 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2759 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2760 } else if (rs != 0 && rt == 0) {
2761 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2762 } else {
2763 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2764 }
2765 break;
2766#if defined(TARGET_MIPS64)
2767 case OPC_DADD:
2768 {
2769 TCGv t0 = tcg_temp_local_new();
2770 TCGv t1 = tcg_temp_new();
2771 TCGv t2 = tcg_temp_new();
2772 TCGLabel *l1 = gen_new_label();
2773
2774 gen_load_gpr(t1, rs);
2775 gen_load_gpr(t2, rt);
2776 tcg_gen_add_tl(t0, t1, t2);
2777 tcg_gen_xor_tl(t1, t1, t2);
2778 tcg_gen_xor_tl(t2, t0, t2);
2779 tcg_gen_andc_tl(t1, t2, t1);
2780 tcg_temp_free(t2);
2781 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2782 tcg_temp_free(t1);
2783
2784 generate_exception(ctx, EXCP_OVERFLOW);
2785 gen_set_label(l1);
2786 gen_store_gpr(t0, rd);
2787 tcg_temp_free(t0);
2788 }
2789 break;
2790 case OPC_DADDU:
2791 if (rs != 0 && rt != 0) {
2792 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2793 } else if (rs == 0 && rt != 0) {
2794 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2795 } else if (rs != 0 && rt == 0) {
2796 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2797 } else {
2798 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2799 }
2800 break;
2801 case OPC_DSUB:
2802 {
2803 TCGv t0 = tcg_temp_local_new();
2804 TCGv t1 = tcg_temp_new();
2805 TCGv t2 = tcg_temp_new();
2806 TCGLabel *l1 = gen_new_label();
2807
2808 gen_load_gpr(t1, rs);
2809 gen_load_gpr(t2, rt);
2810 tcg_gen_sub_tl(t0, t1, t2);
2811 tcg_gen_xor_tl(t2, t1, t2);
2812 tcg_gen_xor_tl(t1, t0, t1);
2813 tcg_gen_and_tl(t1, t1, t2);
2814 tcg_temp_free(t2);
2815 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2816 tcg_temp_free(t1);
2817
2818
2819
2820
2821 generate_exception(ctx, EXCP_OVERFLOW);
2822 gen_set_label(l1);
2823 gen_store_gpr(t0, rd);
2824 tcg_temp_free(t0);
2825 }
2826 break;
2827 case OPC_DSUBU:
2828 if (rs != 0 && rt != 0) {
2829 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2830 } else if (rs == 0 && rt != 0) {
2831 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2832 } else if (rs != 0 && rt == 0) {
2833 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2834 } else {
2835 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2836 }
2837 break;
2838#endif
2839 case OPC_MUL:
2840 if (likely(rs != 0 && rt != 0)) {
2841 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2842 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2843 } else {
2844 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2845 }
2846 break;
2847 }
2848}
2849
2850
2851static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2852 int rd, int rs, int rt)
2853{
2854 TCGv t0, t1, t2;
2855
2856 if (rd == 0) {
2857
2858 return;
2859 }
2860
2861 t0 = tcg_temp_new();
2862 gen_load_gpr(t0, rt);
2863 t1 = tcg_const_tl(0);
2864 t2 = tcg_temp_new();
2865 gen_load_gpr(t2, rs);
2866 switch (opc) {
2867 case OPC_MOVN:
2868 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2869 break;
2870 case OPC_MOVZ:
2871 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2872 break;
2873 case OPC_SELNEZ:
2874 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2875 break;
2876 case OPC_SELEQZ:
2877 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2878 break;
2879 }
2880 tcg_temp_free(t2);
2881 tcg_temp_free(t1);
2882 tcg_temp_free(t0);
2883}
2884
2885
2886static void gen_logic(DisasContext *ctx, uint32_t opc,
2887 int rd, int rs, int rt)
2888{
2889 if (rd == 0) {
2890
2891 return;
2892 }
2893
2894 switch (opc) {
2895 case OPC_AND:
2896 if (likely(rs != 0 && rt != 0)) {
2897 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2898 } else {
2899 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2900 }
2901 break;
2902 case OPC_NOR:
2903 if (rs != 0 && rt != 0) {
2904 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2905 } else if (rs == 0 && rt != 0) {
2906 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2907 } else if (rs != 0 && rt == 0) {
2908 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2909 } else {
2910 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2911 }
2912 break;
2913 case OPC_OR:
2914 if (likely(rs != 0 && rt != 0)) {
2915 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2916 } else if (rs == 0 && rt != 0) {
2917 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2918 } else if (rs != 0 && rt == 0) {
2919 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2920 } else {
2921 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2922 }
2923 break;
2924 case OPC_XOR:
2925 if (likely(rs != 0 && rt != 0)) {
2926 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2927 } else if (rs == 0 && rt != 0) {
2928 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2929 } else if (rs != 0 && rt == 0) {
2930 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2931 } else {
2932 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2933 }
2934 break;
2935 }
2936}
2937
2938
2939static void gen_slt(DisasContext *ctx, uint32_t opc,
2940 int rd, int rs, int rt)
2941{
2942 TCGv t0, t1;
2943
2944 if (rd == 0) {
2945
2946 return;
2947 }
2948
2949 t0 = tcg_temp_new();
2950 t1 = tcg_temp_new();
2951 gen_load_gpr(t0, rs);
2952 gen_load_gpr(t1, rt);
2953 switch (opc) {
2954 case OPC_SLT:
2955 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2956 break;
2957 case OPC_SLTU:
2958 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2959 break;
2960 }
2961 tcg_temp_free(t0);
2962 tcg_temp_free(t1);
2963}
2964
2965
2966static void gen_shift(DisasContext *ctx, uint32_t opc,
2967 int rd, int rs, int rt)
2968{
2969 TCGv t0, t1;
2970
2971 if (rd == 0) {
2972
2973
2974
2975
2976 return;
2977 }
2978
2979 t0 = tcg_temp_new();
2980 t1 = tcg_temp_new();
2981 gen_load_gpr(t0, rs);
2982 gen_load_gpr(t1, rt);
2983 switch (opc) {
2984 case OPC_SLLV:
2985 tcg_gen_andi_tl(t0, t0, 0x1f);
2986 tcg_gen_shl_tl(t0, t1, t0);
2987 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2988 break;
2989 case OPC_SRAV:
2990 tcg_gen_andi_tl(t0, t0, 0x1f);
2991 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2992 break;
2993 case OPC_SRLV:
2994 tcg_gen_ext32u_tl(t1, t1);
2995 tcg_gen_andi_tl(t0, t0, 0x1f);
2996 tcg_gen_shr_tl(t0, t1, t0);
2997 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2998 break;
2999 case OPC_ROTRV:
3000 {
3001 TCGv_i32 t2 = tcg_temp_new_i32();
3002 TCGv_i32 t3 = tcg_temp_new_i32();
3003
3004 tcg_gen_trunc_tl_i32(t2, t0);
3005 tcg_gen_trunc_tl_i32(t3, t1);
3006 tcg_gen_andi_i32(t2, t2, 0x1f);
3007 tcg_gen_rotr_i32(t2, t3, t2);
3008 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3009 tcg_temp_free_i32(t2);
3010 tcg_temp_free_i32(t3);
3011 }
3012 break;
3013#if defined(TARGET_MIPS64)
3014 case OPC_DSLLV:
3015 tcg_gen_andi_tl(t0, t0, 0x3f);
3016 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3017 break;
3018 case OPC_DSRAV:
3019 tcg_gen_andi_tl(t0, t0, 0x3f);
3020 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3021 break;
3022 case OPC_DSRLV:
3023 tcg_gen_andi_tl(t0, t0, 0x3f);
3024 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3025 break;
3026 case OPC_DROTRV:
3027 tcg_gen_andi_tl(t0, t0, 0x3f);
3028 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3029 break;
3030#endif
3031 }
3032 tcg_temp_free(t0);
3033 tcg_temp_free(t1);
3034}
3035
3036
3037static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3038{
3039 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3040
3041 return;
3042 }
3043
3044 if (acc != 0) {
3045 check_dsp(ctx);
3046 }
3047
3048 switch (opc) {
3049 case OPC_MFHI:
3050#if defined(TARGET_MIPS64)
3051 if (acc != 0) {
3052 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3053 } else
3054#endif
3055 {
3056 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3057 }
3058 break;
3059 case OPC_MFLO:
3060#if defined(TARGET_MIPS64)
3061 if (acc != 0) {
3062 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3063 } else
3064#endif
3065 {
3066 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3067 }
3068 break;
3069 case OPC_MTHI:
3070 if (reg != 0) {
3071#if defined(TARGET_MIPS64)
3072 if (acc != 0) {
3073 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3074 } else
3075#endif
3076 {
3077 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3078 }
3079 } else {
3080 tcg_gen_movi_tl(cpu_HI[acc], 0);
3081 }
3082 break;
3083 case OPC_MTLO:
3084 if (reg != 0) {
3085#if defined(TARGET_MIPS64)
3086 if (acc != 0) {
3087 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3088 } else
3089#endif
3090 {
3091 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3092 }
3093 } else {
3094 tcg_gen_movi_tl(cpu_LO[acc], 0);
3095 }
3096 break;
3097 }
3098}
3099
3100static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3101 MemOp memop)
3102{
3103 TCGv t0 = tcg_const_tl(addr);
3104 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3105 gen_store_gpr(t0, reg);
3106 tcg_temp_free(t0);
3107}
3108
3109static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3110 int rs)
3111{
3112 target_long offset;
3113 target_long addr;
3114
3115 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3116 case OPC_ADDIUPC:
3117 if (rs != 0) {
3118 offset = sextract32(ctx->opcode << 2, 0, 21);
3119 addr = addr_add(ctx, pc, offset);
3120 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3121 }
3122 break;
3123 case R6_OPC_LWPC:
3124 offset = sextract32(ctx->opcode << 2, 0, 21);
3125 addr = addr_add(ctx, pc, offset);
3126 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3127 break;
3128#if defined(TARGET_MIPS64)
3129 case OPC_LWUPC:
3130 check_mips_64(ctx);
3131 offset = sextract32(ctx->opcode << 2, 0, 21);
3132 addr = addr_add(ctx, pc, offset);
3133 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3134 break;
3135#endif
3136 default:
3137 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3138 case OPC_AUIPC:
3139 if (rs != 0) {
3140 offset = sextract32(ctx->opcode, 0, 16) << 16;
3141 addr = addr_add(ctx, pc, offset);
3142 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3143 }
3144 break;
3145 case OPC_ALUIPC:
3146 if (rs != 0) {
3147 offset = sextract32(ctx->opcode, 0, 16) << 16;
3148 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3149 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3150 }
3151 break;
3152#if defined(TARGET_MIPS64)
3153 case R6_OPC_LDPC:
3154 case R6_OPC_LDPC + (1 << 16):
3155 case R6_OPC_LDPC + (2 << 16):
3156 case R6_OPC_LDPC + (3 << 16):
3157 check_mips_64(ctx);
3158 offset = sextract32(ctx->opcode << 3, 0, 21);
3159 addr = addr_add(ctx, (pc & ~0x7), offset);
3160 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3161 break;
3162#endif
3163 default:
3164 MIPS_INVAL("OPC_PCREL");
3165 gen_reserved_instruction(ctx);
3166 break;
3167 }
3168 break;
3169 }
3170}
3171
3172static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3173{
3174 TCGv t0, t1;
3175
3176 if (rd == 0) {
3177
3178 return;
3179 }
3180
3181 t0 = tcg_temp_new();
3182 t1 = tcg_temp_new();
3183
3184 gen_load_gpr(t0, rs);
3185 gen_load_gpr(t1, rt);
3186
3187 switch (opc) {
3188 case R6_OPC_DIV:
3189 {
3190 TCGv t2 = tcg_temp_new();
3191 TCGv t3 = tcg_temp_new();
3192 tcg_gen_ext32s_tl(t0, t0);
3193 tcg_gen_ext32s_tl(t1, t1);
3194 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3195 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3196 tcg_gen_and_tl(t2, t2, t3);
3197 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3198 tcg_gen_or_tl(t2, t2, t3);
3199 tcg_gen_movi_tl(t3, 0);
3200 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3201 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3202 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3203 tcg_temp_free(t3);
3204 tcg_temp_free(t2);
3205 }
3206 break;
3207 case R6_OPC_MOD:
3208 {
3209 TCGv t2 = tcg_temp_new();
3210 TCGv t3 = tcg_temp_new();
3211 tcg_gen_ext32s_tl(t0, t0);
3212 tcg_gen_ext32s_tl(t1, t1);
3213 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3214 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3215 tcg_gen_and_tl(t2, t2, t3);
3216 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3217 tcg_gen_or_tl(t2, t2, t3);
3218 tcg_gen_movi_tl(t3, 0);
3219 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3220 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3221 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3222 tcg_temp_free(t3);
3223 tcg_temp_free(t2);
3224 }
3225 break;
3226 case R6_OPC_DIVU:
3227 {
3228 TCGv t2 = tcg_const_tl(0);
3229 TCGv t3 = tcg_const_tl(1);
3230 tcg_gen_ext32u_tl(t0, t0);
3231 tcg_gen_ext32u_tl(t1, t1);
3232 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3233 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3234 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3235 tcg_temp_free(t3);
3236 tcg_temp_free(t2);
3237 }
3238 break;
3239 case R6_OPC_MODU:
3240 {
3241 TCGv t2 = tcg_const_tl(0);
3242 TCGv t3 = tcg_const_tl(1);
3243 tcg_gen_ext32u_tl(t0, t0);
3244 tcg_gen_ext32u_tl(t1, t1);
3245 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3246 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3247 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3248 tcg_temp_free(t3);
3249 tcg_temp_free(t2);
3250 }
3251 break;
3252 case R6_OPC_MUL:
3253 {
3254 TCGv_i32 t2 = tcg_temp_new_i32();
3255 TCGv_i32 t3 = tcg_temp_new_i32();
3256 tcg_gen_trunc_tl_i32(t2, t0);
3257 tcg_gen_trunc_tl_i32(t3, t1);
3258 tcg_gen_mul_i32(t2, t2, t3);
3259 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3260 tcg_temp_free_i32(t2);
3261 tcg_temp_free_i32(t3);
3262 }
3263 break;
3264 case R6_OPC_MUH:
3265 {
3266 TCGv_i32 t2 = tcg_temp_new_i32();
3267 TCGv_i32 t3 = tcg_temp_new_i32();
3268 tcg_gen_trunc_tl_i32(t2, t0);
3269 tcg_gen_trunc_tl_i32(t3, t1);
3270 tcg_gen_muls2_i32(t2, t3, t2, t3);
3271 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3272 tcg_temp_free_i32(t2);
3273 tcg_temp_free_i32(t3);
3274 }
3275 break;
3276 case R6_OPC_MULU:
3277 {
3278 TCGv_i32 t2 = tcg_temp_new_i32();
3279 TCGv_i32 t3 = tcg_temp_new_i32();
3280 tcg_gen_trunc_tl_i32(t2, t0);
3281 tcg_gen_trunc_tl_i32(t3, t1);
3282 tcg_gen_mul_i32(t2, t2, t3);
3283 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3284 tcg_temp_free_i32(t2);
3285 tcg_temp_free_i32(t3);
3286 }
3287 break;
3288 case R6_OPC_MUHU:
3289 {
3290 TCGv_i32 t2 = tcg_temp_new_i32();
3291 TCGv_i32 t3 = tcg_temp_new_i32();
3292 tcg_gen_trunc_tl_i32(t2, t0);
3293 tcg_gen_trunc_tl_i32(t3, t1);
3294 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3295 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3296 tcg_temp_free_i32(t2);
3297 tcg_temp_free_i32(t3);
3298 }
3299 break;
3300#if defined(TARGET_MIPS64)
3301 case R6_OPC_DDIV:
3302 {
3303 TCGv t2 = tcg_temp_new();
3304 TCGv t3 = tcg_temp_new();
3305 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3306 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3307 tcg_gen_and_tl(t2, t2, t3);
3308 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3309 tcg_gen_or_tl(t2, t2, t3);
3310 tcg_gen_movi_tl(t3, 0);
3311 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3312 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3313 tcg_temp_free(t3);
3314 tcg_temp_free(t2);
3315 }
3316 break;
3317 case R6_OPC_DMOD:
3318 {
3319 TCGv t2 = tcg_temp_new();
3320 TCGv t3 = tcg_temp_new();
3321 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3322 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3323 tcg_gen_and_tl(t2, t2, t3);
3324 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3325 tcg_gen_or_tl(t2, t2, t3);
3326 tcg_gen_movi_tl(t3, 0);
3327 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3328 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3329 tcg_temp_free(t3);
3330 tcg_temp_free(t2);
3331 }
3332 break;
3333 case R6_OPC_DDIVU:
3334 {
3335 TCGv t2 = tcg_const_tl(0);
3336 TCGv t3 = tcg_const_tl(1);
3337 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3338 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3339 tcg_temp_free(t3);
3340 tcg_temp_free(t2);
3341 }
3342 break;
3343 case R6_OPC_DMODU:
3344 {
3345 TCGv t2 = tcg_const_tl(0);
3346 TCGv t3 = tcg_const_tl(1);
3347 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3348 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3349 tcg_temp_free(t3);
3350 tcg_temp_free(t2);
3351 }
3352 break;
3353 case R6_OPC_DMUL:
3354 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3355 break;
3356 case R6_OPC_DMUH:
3357 {
3358 TCGv t2 = tcg_temp_new();
3359 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3360 tcg_temp_free(t2);
3361 }
3362 break;
3363 case R6_OPC_DMULU:
3364 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3365 break;
3366 case R6_OPC_DMUHU:
3367 {
3368 TCGv t2 = tcg_temp_new();
3369 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3370 tcg_temp_free(t2);
3371 }
3372 break;
3373#endif
3374 default:
3375 MIPS_INVAL("r6 mul/div");
3376 gen_reserved_instruction(ctx);
3377 goto out;
3378 }
3379 out:
3380 tcg_temp_free(t0);
3381 tcg_temp_free(t1);
3382}
3383
3384#if defined(TARGET_MIPS64)
3385static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3386{
3387 TCGv t0, t1;
3388
3389 t0 = tcg_temp_new();
3390 t1 = tcg_temp_new();
3391
3392 gen_load_gpr(t0, rs);
3393 gen_load_gpr(t1, rt);
3394
3395 switch (opc) {
3396 case MMI_OPC_DIV1:
3397 {
3398 TCGv t2 = tcg_temp_new();
3399 TCGv t3 = tcg_temp_new();
3400 tcg_gen_ext32s_tl(t0, t0);
3401 tcg_gen_ext32s_tl(t1, t1);
3402 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3403 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3404 tcg_gen_and_tl(t2, t2, t3);
3405 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3406 tcg_gen_or_tl(t2, t2, t3);
3407 tcg_gen_movi_tl(t3, 0);
3408 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3409 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3410 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3411 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3412 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3413 tcg_temp_free(t3);
3414 tcg_temp_free(t2);
3415 }
3416 break;
3417 case MMI_OPC_DIVU1:
3418 {
3419 TCGv t2 = tcg_const_tl(0);
3420 TCGv t3 = tcg_const_tl(1);
3421 tcg_gen_ext32u_tl(t0, t0);
3422 tcg_gen_ext32u_tl(t1, t1);
3423 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3424 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3425 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3426 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3427 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3428 tcg_temp_free(t3);
3429 tcg_temp_free(t2);
3430 }
3431 break;
3432 default:
3433 MIPS_INVAL("div1 TX79");
3434 gen_reserved_instruction(ctx);
3435 goto out;
3436 }
3437 out:
3438 tcg_temp_free(t0);
3439 tcg_temp_free(t1);
3440}
3441#endif
3442
3443static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3444 int acc, int rs, int rt)
3445{
3446 TCGv t0, t1;
3447
3448 t0 = tcg_temp_new();
3449 t1 = tcg_temp_new();
3450
3451 gen_load_gpr(t0, rs);
3452 gen_load_gpr(t1, rt);
3453
3454 if (acc != 0) {
3455 check_dsp(ctx);
3456 }
3457
3458 switch (opc) {
3459 case OPC_DIV:
3460 {
3461 TCGv t2 = tcg_temp_new();
3462 TCGv t3 = tcg_temp_new();
3463 tcg_gen_ext32s_tl(t0, t0);
3464 tcg_gen_ext32s_tl(t1, t1);
3465 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3466 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3467 tcg_gen_and_tl(t2, t2, t3);
3468 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3469 tcg_gen_or_tl(t2, t2, t3);
3470 tcg_gen_movi_tl(t3, 0);
3471 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3472 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3473 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3474 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3475 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3476 tcg_temp_free(t3);
3477 tcg_temp_free(t2);
3478 }
3479 break;
3480 case OPC_DIVU:
3481 {
3482 TCGv t2 = tcg_const_tl(0);
3483 TCGv t3 = tcg_const_tl(1);
3484 tcg_gen_ext32u_tl(t0, t0);
3485 tcg_gen_ext32u_tl(t1, t1);
3486 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3487 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3488 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3489 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3490 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3491 tcg_temp_free(t3);
3492 tcg_temp_free(t2);
3493 }
3494 break;
3495 case OPC_MULT:
3496 {
3497 TCGv_i32 t2 = tcg_temp_new_i32();
3498 TCGv_i32 t3 = tcg_temp_new_i32();
3499 tcg_gen_trunc_tl_i32(t2, t0);
3500 tcg_gen_trunc_tl_i32(t3, t1);
3501 tcg_gen_muls2_i32(t2, t3, t2, t3);
3502 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3503 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3504 tcg_temp_free_i32(t2);
3505 tcg_temp_free_i32(t3);
3506 }
3507 break;
3508 case OPC_MULTU:
3509 {
3510 TCGv_i32 t2 = tcg_temp_new_i32();
3511 TCGv_i32 t3 = tcg_temp_new_i32();
3512 tcg_gen_trunc_tl_i32(t2, t0);
3513 tcg_gen_trunc_tl_i32(t3, t1);
3514 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3515 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3516 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3517 tcg_temp_free_i32(t2);
3518 tcg_temp_free_i32(t3);
3519 }
3520 break;
3521#if defined(TARGET_MIPS64)
3522 case OPC_DDIV:
3523 {
3524 TCGv t2 = tcg_temp_new();
3525 TCGv t3 = tcg_temp_new();
3526 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3527 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3528 tcg_gen_and_tl(t2, t2, t3);
3529 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3530 tcg_gen_or_tl(t2, t2, t3);
3531 tcg_gen_movi_tl(t3, 0);
3532 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3533 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3534 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3535 tcg_temp_free(t3);
3536 tcg_temp_free(t2);
3537 }
3538 break;
3539 case OPC_DDIVU:
3540 {
3541 TCGv t2 = tcg_const_tl(0);
3542 TCGv t3 = tcg_const_tl(1);
3543 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3544 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3545 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3546 tcg_temp_free(t3);
3547 tcg_temp_free(t2);
3548 }
3549 break;
3550 case OPC_DMULT:
3551 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3552 break;
3553 case OPC_DMULTU:
3554 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3555 break;
3556#endif
3557 case OPC_MADD:
3558 {
3559 TCGv_i64 t2 = tcg_temp_new_i64();
3560 TCGv_i64 t3 = tcg_temp_new_i64();
3561
3562 tcg_gen_ext_tl_i64(t2, t0);
3563 tcg_gen_ext_tl_i64(t3, t1);
3564 tcg_gen_mul_i64(t2, t2, t3);
3565 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3566 tcg_gen_add_i64(t2, t2, t3);
3567 tcg_temp_free_i64(t3);
3568 gen_move_low32(cpu_LO[acc], t2);
3569 gen_move_high32(cpu_HI[acc], t2);
3570 tcg_temp_free_i64(t2);
3571 }
3572 break;
3573 case OPC_MADDU:
3574 {
3575 TCGv_i64 t2 = tcg_temp_new_i64();
3576 TCGv_i64 t3 = tcg_temp_new_i64();
3577
3578 tcg_gen_ext32u_tl(t0, t0);
3579 tcg_gen_ext32u_tl(t1, t1);
3580 tcg_gen_extu_tl_i64(t2, t0);
3581 tcg_gen_extu_tl_i64(t3, t1);
3582 tcg_gen_mul_i64(t2, t2, t3);
3583 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3584 tcg_gen_add_i64(t2, t2, t3);
3585 tcg_temp_free_i64(t3);
3586 gen_move_low32(cpu_LO[acc], t2);
3587 gen_move_high32(cpu_HI[acc], t2);
3588 tcg_temp_free_i64(t2);
3589 }
3590 break;
3591 case OPC_MSUB:
3592 {
3593 TCGv_i64 t2 = tcg_temp_new_i64();
3594 TCGv_i64 t3 = tcg_temp_new_i64();
3595
3596 tcg_gen_ext_tl_i64(t2, t0);
3597 tcg_gen_ext_tl_i64(t3, t1);
3598 tcg_gen_mul_i64(t2, t2, t3);
3599 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3600 tcg_gen_sub_i64(t2, t3, t2);
3601 tcg_temp_free_i64(t3);
3602 gen_move_low32(cpu_LO[acc], t2);
3603 gen_move_high32(cpu_HI[acc], t2);
3604 tcg_temp_free_i64(t2);
3605 }
3606 break;
3607 case OPC_MSUBU:
3608 {
3609 TCGv_i64 t2 = tcg_temp_new_i64();
3610 TCGv_i64 t3 = tcg_temp_new_i64();
3611
3612 tcg_gen_ext32u_tl(t0, t0);
3613 tcg_gen_ext32u_tl(t1, t1);
3614 tcg_gen_extu_tl_i64(t2, t0);
3615 tcg_gen_extu_tl_i64(t3, t1);
3616 tcg_gen_mul_i64(t2, t2, t3);
3617 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3618 tcg_gen_sub_i64(t2, t3, t2);
3619 tcg_temp_free_i64(t3);
3620 gen_move_low32(cpu_LO[acc], t2);
3621 gen_move_high32(cpu_HI[acc], t2);
3622 tcg_temp_free_i64(t2);
3623 }
3624 break;
3625 default:
3626 MIPS_INVAL("mul/div");
3627 gen_reserved_instruction(ctx);
3628 goto out;
3629 }
3630 out:
3631 tcg_temp_free(t0);
3632 tcg_temp_free(t1);
3633}
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3662 int rd, int rs, int rt)
3663{
3664 TCGv t0 = tcg_temp_new();
3665 TCGv t1 = tcg_temp_new();
3666 int acc = 0;
3667
3668 gen_load_gpr(t0, rs);
3669 gen_load_gpr(t1, rt);
3670
3671 switch (opc) {
3672 case MMI_OPC_MULT1:
3673 acc = 1;
3674
3675 case OPC_MULT:
3676 {
3677 TCGv_i32 t2 = tcg_temp_new_i32();
3678 TCGv_i32 t3 = tcg_temp_new_i32();
3679 tcg_gen_trunc_tl_i32(t2, t0);
3680 tcg_gen_trunc_tl_i32(t3, t1);
3681 tcg_gen_muls2_i32(t2, t3, t2, t3);
3682 if (rd) {
3683 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3684 }
3685 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3686 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3687 tcg_temp_free_i32(t2);
3688 tcg_temp_free_i32(t3);
3689 }
3690 break;
3691 case MMI_OPC_MULTU1:
3692 acc = 1;
3693
3694 case OPC_MULTU:
3695 {
3696 TCGv_i32 t2 = tcg_temp_new_i32();
3697 TCGv_i32 t3 = tcg_temp_new_i32();
3698 tcg_gen_trunc_tl_i32(t2, t0);
3699 tcg_gen_trunc_tl_i32(t3, t1);
3700 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3701 if (rd) {
3702 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3703 }
3704 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3705 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3706 tcg_temp_free_i32(t2);
3707 tcg_temp_free_i32(t3);
3708 }
3709 break;
3710 case MMI_OPC_MADD1:
3711 acc = 1;
3712
3713 case MMI_OPC_MADD:
3714 {
3715 TCGv_i64 t2 = tcg_temp_new_i64();
3716 TCGv_i64 t3 = tcg_temp_new_i64();
3717
3718 tcg_gen_ext_tl_i64(t2, t0);
3719 tcg_gen_ext_tl_i64(t3, t1);
3720 tcg_gen_mul_i64(t2, t2, t3);
3721 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3722 tcg_gen_add_i64(t2, t2, t3);
3723 tcg_temp_free_i64(t3);
3724 gen_move_low32(cpu_LO[acc], t2);
3725 gen_move_high32(cpu_HI[acc], t2);
3726 if (rd) {
3727 gen_move_low32(cpu_gpr[rd], t2);
3728 }
3729 tcg_temp_free_i64(t2);
3730 }
3731 break;
3732 case MMI_OPC_MADDU1:
3733 acc = 1;
3734
3735 case MMI_OPC_MADDU:
3736 {
3737 TCGv_i64 t2 = tcg_temp_new_i64();
3738 TCGv_i64 t3 = tcg_temp_new_i64();
3739
3740 tcg_gen_ext32u_tl(t0, t0);
3741 tcg_gen_ext32u_tl(t1, t1);
3742 tcg_gen_extu_tl_i64(t2, t0);
3743 tcg_gen_extu_tl_i64(t3, t1);
3744 tcg_gen_mul_i64(t2, t2, t3);
3745 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3746 tcg_gen_add_i64(t2, t2, t3);
3747 tcg_temp_free_i64(t3);
3748 gen_move_low32(cpu_LO[acc], t2);
3749 gen_move_high32(cpu_HI[acc], t2);
3750 if (rd) {
3751 gen_move_low32(cpu_gpr[rd], t2);
3752 }
3753 tcg_temp_free_i64(t2);
3754 }
3755 break;
3756 default:
3757 MIPS_INVAL("mul/madd TXx9");
3758 gen_reserved_instruction(ctx);
3759 goto out;
3760 }
3761
3762 out:
3763 tcg_temp_free(t0);
3764 tcg_temp_free(t1);
3765}
3766
3767static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
3768 int rd, int rs, int rt)
3769{
3770 TCGv t0 = tcg_temp_new();
3771 TCGv t1 = tcg_temp_new();
3772
3773 gen_load_gpr(t0, rs);
3774 gen_load_gpr(t1, rt);
3775
3776 switch (opc) {
3777 case OPC_VR54XX_MULS:
3778 gen_helper_muls(t0, cpu_env, t0, t1);
3779 break;
3780 case OPC_VR54XX_MULSU:
3781 gen_helper_mulsu(t0, cpu_env, t0, t1);
3782 break;
3783 case OPC_VR54XX_MACC:
3784 gen_helper_macc(t0, cpu_env, t0, t1);
3785 break;
3786 case OPC_VR54XX_MACCU:
3787 gen_helper_maccu(t0, cpu_env, t0, t1);
3788 break;
3789 case OPC_VR54XX_MSAC:
3790 gen_helper_msac(t0, cpu_env, t0, t1);
3791 break;
3792 case OPC_VR54XX_MSACU:
3793 gen_helper_msacu(t0, cpu_env, t0, t1);
3794 break;
3795 case OPC_VR54XX_MULHI:
3796 gen_helper_mulhi(t0, cpu_env, t0, t1);
3797 break;
3798 case OPC_VR54XX_MULHIU:
3799 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3800 break;
3801 case OPC_VR54XX_MULSHI:
3802 gen_helper_mulshi(t0, cpu_env, t0, t1);
3803 break;
3804 case OPC_VR54XX_MULSHIU:
3805 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3806 break;
3807 case OPC_VR54XX_MACCHI:
3808 gen_helper_macchi(t0, cpu_env, t0, t1);
3809 break;
3810 case OPC_VR54XX_MACCHIU:
3811 gen_helper_macchiu(t0, cpu_env, t0, t1);
3812 break;
3813 case OPC_VR54XX_MSACHI:
3814 gen_helper_msachi(t0, cpu_env, t0, t1);
3815 break;
3816 case OPC_VR54XX_MSACHIU:
3817 gen_helper_msachiu(t0, cpu_env, t0, t1);
3818 break;
3819 default:
3820 MIPS_INVAL("mul vr54xx");
3821 gen_reserved_instruction(ctx);
3822 goto out;
3823 }
3824 gen_store_gpr(t0, rd);
3825
3826 out:
3827 tcg_temp_free(t0);
3828 tcg_temp_free(t1);
3829}
3830
3831static void gen_cl(DisasContext *ctx, uint32_t opc,
3832 int rd, int rs)
3833{
3834 TCGv t0;
3835
3836 if (rd == 0) {
3837
3838 return;
3839 }
3840 t0 = cpu_gpr[rd];
3841 gen_load_gpr(t0, rs);
3842
3843 switch (opc) {
3844 case OPC_CLO:
3845 case R6_OPC_CLO:
3846#if defined(TARGET_MIPS64)
3847 case OPC_DCLO:
3848 case R6_OPC_DCLO:
3849#endif
3850 tcg_gen_not_tl(t0, t0);
3851 break;
3852 }
3853
3854 switch (opc) {
3855 case OPC_CLO:
3856 case R6_OPC_CLO:
3857 case OPC_CLZ:
3858 case R6_OPC_CLZ:
3859 tcg_gen_ext32u_tl(t0, t0);
3860 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3861 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3862 break;
3863#if defined(TARGET_MIPS64)
3864 case OPC_DCLO:
3865 case R6_OPC_DCLO:
3866 case OPC_DCLZ:
3867 case R6_OPC_DCLZ:
3868 tcg_gen_clzi_i64(t0, t0, 64);
3869 break;
3870#endif
3871 }
3872}
3873
3874
3875static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3876 int rd, int rs, int rt)
3877{
3878 TCGv t0, t1;
3879
3880 if (rd == 0) {
3881
3882 return;
3883 }
3884
3885 switch (opc) {
3886 case OPC_MULT_G_2E:
3887 case OPC_MULT_G_2F:
3888 case OPC_MULTU_G_2E:
3889 case OPC_MULTU_G_2F:
3890#if defined(TARGET_MIPS64)
3891 case OPC_DMULT_G_2E:
3892 case OPC_DMULT_G_2F:
3893 case OPC_DMULTU_G_2E:
3894 case OPC_DMULTU_G_2F:
3895#endif
3896 t0 = tcg_temp_new();
3897 t1 = tcg_temp_new();
3898 break;
3899 default:
3900 t0 = tcg_temp_local_new();
3901 t1 = tcg_temp_local_new();
3902 break;
3903 }
3904
3905 gen_load_gpr(t0, rs);
3906 gen_load_gpr(t1, rt);
3907
3908 switch (opc) {
3909 case OPC_MULT_G_2E:
3910 case OPC_MULT_G_2F:
3911 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3912 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3913 break;
3914 case OPC_MULTU_G_2E:
3915 case OPC_MULTU_G_2F:
3916 tcg_gen_ext32u_tl(t0, t0);
3917 tcg_gen_ext32u_tl(t1, t1);
3918 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3919 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3920 break;
3921 case OPC_DIV_G_2E:
3922 case OPC_DIV_G_2F:
3923 {
3924 TCGLabel *l1 = gen_new_label();
3925 TCGLabel *l2 = gen_new_label();
3926 TCGLabel *l3 = gen_new_label();
3927 tcg_gen_ext32s_tl(t0, t0);
3928 tcg_gen_ext32s_tl(t1, t1);
3929 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3930 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3931 tcg_gen_br(l3);
3932 gen_set_label(l1);
3933 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3934 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3935 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3936 tcg_gen_br(l3);
3937 gen_set_label(l2);
3938 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3939 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3940 gen_set_label(l3);
3941 }
3942 break;
3943 case OPC_DIVU_G_2E:
3944 case OPC_DIVU_G_2F:
3945 {
3946 TCGLabel *l1 = gen_new_label();
3947 TCGLabel *l2 = gen_new_label();
3948 tcg_gen_ext32u_tl(t0, t0);
3949 tcg_gen_ext32u_tl(t1, t1);
3950 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3951 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3952 tcg_gen_br(l2);
3953 gen_set_label(l1);
3954 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3955 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3956 gen_set_label(l2);
3957 }
3958 break;
3959 case OPC_MOD_G_2E:
3960 case OPC_MOD_G_2F:
3961 {
3962 TCGLabel *l1 = gen_new_label();
3963 TCGLabel *l2 = gen_new_label();
3964 TCGLabel *l3 = gen_new_label();
3965 tcg_gen_ext32u_tl(t0, t0);
3966 tcg_gen_ext32u_tl(t1, t1);
3967 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3968 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3969 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3970 gen_set_label(l1);
3971 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3972 tcg_gen_br(l3);
3973 gen_set_label(l2);
3974 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3975 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3976 gen_set_label(l3);
3977 }
3978 break;
3979 case OPC_MODU_G_2E:
3980 case OPC_MODU_G_2F:
3981 {
3982 TCGLabel *l1 = gen_new_label();
3983 TCGLabel *l2 = gen_new_label();
3984 tcg_gen_ext32u_tl(t0, t0);
3985 tcg_gen_ext32u_tl(t1, t1);
3986 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3987 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3988 tcg_gen_br(l2);
3989 gen_set_label(l1);
3990 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3991 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3992 gen_set_label(l2);
3993 }
3994 break;
3995#if defined(TARGET_MIPS64)
3996 case OPC_DMULT_G_2E:
3997 case OPC_DMULT_G_2F:
3998 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3999 break;
4000 case OPC_DMULTU_G_2E:
4001 case OPC_DMULTU_G_2F:
4002 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4003 break;
4004 case OPC_DDIV_G_2E:
4005 case OPC_DDIV_G_2F:
4006 {
4007 TCGLabel *l1 = gen_new_label();
4008 TCGLabel *l2 = gen_new_label();
4009 TCGLabel *l3 = gen_new_label();
4010 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4011 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4012 tcg_gen_br(l3);
4013 gen_set_label(l1);
4014 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4015 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4016 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4017 tcg_gen_br(l3);
4018 gen_set_label(l2);
4019 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4020 gen_set_label(l3);
4021 }
4022 break;
4023 case OPC_DDIVU_G_2E:
4024 case OPC_DDIVU_G_2F:
4025 {
4026 TCGLabel *l1 = gen_new_label();
4027 TCGLabel *l2 = gen_new_label();
4028 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4029 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4030 tcg_gen_br(l2);
4031 gen_set_label(l1);
4032 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4033 gen_set_label(l2);
4034 }
4035 break;
4036 case OPC_DMOD_G_2E:
4037 case OPC_DMOD_G_2F:
4038 {
4039 TCGLabel *l1 = gen_new_label();
4040 TCGLabel *l2 = gen_new_label();
4041 TCGLabel *l3 = gen_new_label();
4042 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4043 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4044 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4045 gen_set_label(l1);
4046 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4047 tcg_gen_br(l3);
4048 gen_set_label(l2);
4049 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4050 gen_set_label(l3);
4051 }
4052 break;
4053 case OPC_DMODU_G_2E:
4054 case OPC_DMODU_G_2F:
4055 {
4056 TCGLabel *l1 = gen_new_label();
4057 TCGLabel *l2 = gen_new_label();
4058 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4059 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4060 tcg_gen_br(l2);
4061 gen_set_label(l1);
4062 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4063 gen_set_label(l2);
4064 }
4065 break;
4066#endif
4067 }
4068
4069 tcg_temp_free(t0);
4070 tcg_temp_free(t1);
4071}
4072
4073
4074static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4075{
4076 uint32_t opc, shift_max;
4077 TCGv_i64 t0, t1;
4078 TCGCond cond;
4079
4080 opc = MASK_LMMI(ctx->opcode);
4081 switch (opc) {
4082 case OPC_ADD_CP2:
4083 case OPC_SUB_CP2:
4084 case OPC_DADD_CP2:
4085 case OPC_DSUB_CP2:
4086 t0 = tcg_temp_local_new_i64();
4087 t1 = tcg_temp_local_new_i64();
4088 break;
4089 default:
4090 t0 = tcg_temp_new_i64();
4091 t1 = tcg_temp_new_i64();
4092 break;
4093 }
4094
4095 check_cp1_enabled(ctx);
4096 gen_load_fpr64(ctx, t0, rs);
4097 gen_load_fpr64(ctx, t1, rt);
4098
4099 switch (opc) {
4100 case OPC_PADDSH:
4101 gen_helper_paddsh(t0, t0, t1);
4102 break;
4103 case OPC_PADDUSH:
4104 gen_helper_paddush(t0, t0, t1);
4105 break;
4106 case OPC_PADDH:
4107 gen_helper_paddh(t0, t0, t1);
4108 break;
4109 case OPC_PADDW:
4110 gen_helper_paddw(t0, t0, t1);
4111 break;
4112 case OPC_PADDSB:
4113 gen_helper_paddsb(t0, t0, t1);
4114 break;
4115 case OPC_PADDUSB:
4116 gen_helper_paddusb(t0, t0, t1);
4117 break;
4118 case OPC_PADDB:
4119 gen_helper_paddb(t0, t0, t1);
4120 break;
4121
4122 case OPC_PSUBSH:
4123 gen_helper_psubsh(t0, t0, t1);
4124 break;
4125 case OPC_PSUBUSH:
4126 gen_helper_psubush(t0, t0, t1);
4127 break;
4128 case OPC_PSUBH:
4129 gen_helper_psubh(t0, t0, t1);
4130 break;
4131 case OPC_PSUBW:
4132 gen_helper_psubw(t0, t0, t1);
4133 break;
4134 case OPC_PSUBSB:
4135 gen_helper_psubsb(t0, t0, t1);
4136 break;
4137 case OPC_PSUBUSB:
4138 gen_helper_psubusb(t0, t0, t1);
4139 break;
4140 case OPC_PSUBB:
4141 gen_helper_psubb(t0, t0, t1);
4142 break;
4143
4144 case OPC_PSHUFH:
4145 gen_helper_pshufh(t0, t0, t1);
4146 break;
4147 case OPC_PACKSSWH:
4148 gen_helper_packsswh(t0, t0, t1);
4149 break;
4150 case OPC_PACKSSHB:
4151 gen_helper_packsshb(t0, t0, t1);
4152 break;
4153 case OPC_PACKUSHB:
4154 gen_helper_packushb(t0, t0, t1);
4155 break;
4156
4157 case OPC_PUNPCKLHW:
4158 gen_helper_punpcklhw(t0, t0, t1);
4159 break;
4160 case OPC_PUNPCKHHW:
4161 gen_helper_punpckhhw(t0, t0, t1);
4162 break;
4163 case OPC_PUNPCKLBH:
4164 gen_helper_punpcklbh(t0, t0, t1);
4165 break;
4166 case OPC_PUNPCKHBH:
4167 gen_helper_punpckhbh(t0, t0, t1);
4168 break;
4169 case OPC_PUNPCKLWD:
4170 gen_helper_punpcklwd(t0, t0, t1);
4171 break;
4172 case OPC_PUNPCKHWD:
4173 gen_helper_punpckhwd(t0, t0, t1);
4174 break;
4175
4176 case OPC_PAVGH:
4177 gen_helper_pavgh(t0, t0, t1);
4178 break;
4179 case OPC_PAVGB:
4180 gen_helper_pavgb(t0, t0, t1);
4181 break;
4182 case OPC_PMAXSH:
4183 gen_helper_pmaxsh(t0, t0, t1);
4184 break;
4185 case OPC_PMINSH:
4186 gen_helper_pminsh(t0, t0, t1);
4187 break;
4188 case OPC_PMAXUB:
4189 gen_helper_pmaxub(t0, t0, t1);
4190 break;
4191 case OPC_PMINUB:
4192 gen_helper_pminub(t0, t0, t1);
4193 break;
4194
4195 case OPC_PCMPEQW:
4196 gen_helper_pcmpeqw(t0, t0, t1);
4197 break;
4198 case OPC_PCMPGTW:
4199 gen_helper_pcmpgtw(t0, t0, t1);
4200 break;
4201 case OPC_PCMPEQH:
4202 gen_helper_pcmpeqh(t0, t0, t1);
4203 break;
4204 case OPC_PCMPGTH:
4205 gen_helper_pcmpgth(t0, t0, t1);
4206 break;
4207 case OPC_PCMPEQB:
4208 gen_helper_pcmpeqb(t0, t0, t1);
4209 break;
4210 case OPC_PCMPGTB:
4211 gen_helper_pcmpgtb(t0, t0, t1);
4212 break;
4213
4214 case OPC_PSLLW:
4215 gen_helper_psllw(t0, t0, t1);
4216 break;
4217 case OPC_PSLLH:
4218 gen_helper_psllh(t0, t0, t1);
4219 break;
4220 case OPC_PSRLW:
4221 gen_helper_psrlw(t0, t0, t1);
4222 break;
4223 case OPC_PSRLH:
4224 gen_helper_psrlh(t0, t0, t1);
4225 break;
4226 case OPC_PSRAW:
4227 gen_helper_psraw(t0, t0, t1);
4228 break;
4229 case OPC_PSRAH:
4230 gen_helper_psrah(t0, t0, t1);
4231 break;
4232
4233 case OPC_PMULLH:
4234 gen_helper_pmullh(t0, t0, t1);
4235 break;
4236 case OPC_PMULHH:
4237 gen_helper_pmulhh(t0, t0, t1);
4238 break;
4239 case OPC_PMULHUH:
4240 gen_helper_pmulhuh(t0, t0, t1);
4241 break;
4242 case OPC_PMADDHW:
4243 gen_helper_pmaddhw(t0, t0, t1);
4244 break;
4245
4246 case OPC_PASUBUB:
4247 gen_helper_pasubub(t0, t0, t1);
4248 break;
4249 case OPC_BIADD:
4250 gen_helper_biadd(t0, t0);
4251 break;
4252 case OPC_PMOVMSKB:
4253 gen_helper_pmovmskb(t0, t0);
4254 break;
4255
4256 case OPC_PADDD:
4257 tcg_gen_add_i64(t0, t0, t1);
4258 break;
4259 case OPC_PSUBD:
4260 tcg_gen_sub_i64(t0, t0, t1);
4261 break;
4262 case OPC_XOR_CP2:
4263 tcg_gen_xor_i64(t0, t0, t1);
4264 break;
4265 case OPC_NOR_CP2:
4266 tcg_gen_nor_i64(t0, t0, t1);
4267 break;
4268 case OPC_AND_CP2:
4269 tcg_gen_and_i64(t0, t0, t1);
4270 break;
4271 case OPC_OR_CP2:
4272 tcg_gen_or_i64(t0, t0, t1);
4273 break;
4274
4275 case OPC_PANDN:
4276 tcg_gen_andc_i64(t0, t1, t0);
4277 break;
4278
4279 case OPC_PINSRH_0:
4280 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4281 break;
4282 case OPC_PINSRH_1:
4283 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4284 break;
4285 case OPC_PINSRH_2:
4286 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4287 break;
4288 case OPC_PINSRH_3:
4289 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4290 break;
4291
4292 case OPC_PEXTRH:
4293 tcg_gen_andi_i64(t1, t1, 3);
4294 tcg_gen_shli_i64(t1, t1, 4);
4295 tcg_gen_shr_i64(t0, t0, t1);
4296 tcg_gen_ext16u_i64(t0, t0);
4297 break;
4298
4299 case OPC_ADDU_CP2:
4300 tcg_gen_add_i64(t0, t0, t1);
4301 tcg_gen_ext32s_i64(t0, t0);
4302 break;
4303 case OPC_SUBU_CP2:
4304 tcg_gen_sub_i64(t0, t0, t1);
4305 tcg_gen_ext32s_i64(t0, t0);
4306 break;
4307
4308 case OPC_SLL_CP2:
4309 shift_max = 32;
4310 goto do_shift;
4311 case OPC_SRL_CP2:
4312 shift_max = 32;
4313 goto do_shift;
4314 case OPC_SRA_CP2:
4315 shift_max = 32;
4316 goto do_shift;
4317 case OPC_DSLL_CP2:
4318 shift_max = 64;
4319 goto do_shift;
4320 case OPC_DSRL_CP2:
4321 shift_max = 64;
4322 goto do_shift;
4323 case OPC_DSRA_CP2:
4324 shift_max = 64;
4325 goto do_shift;
4326 do_shift:
4327
4328 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4329
4330 switch (opc) {
4331 case OPC_SLL_CP2:
4332 case OPC_DSLL_CP2:
4333 tcg_gen_shl_i64(t0, t0, t1);
4334 break;
4335 case OPC_SRA_CP2:
4336 case OPC_DSRA_CP2:
4337
4338
4339
4340
4341 tcg_gen_sar_i64(t0, t0, t1);
4342 break;
4343 case OPC_SRL_CP2:
4344
4345 tcg_gen_ext32u_i64(t0, t0);
4346
4347 case OPC_DSRL_CP2:
4348 tcg_gen_shr_i64(t0, t0, t1);
4349 break;
4350 }
4351
4352 if (shift_max == 32) {
4353 tcg_gen_ext32s_i64(t0, t0);
4354 }
4355
4356
4357 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4358 tcg_gen_neg_i64(t1, t1);
4359 tcg_gen_and_i64(t0, t0, t1);
4360 break;
4361
4362 case OPC_ADD_CP2:
4363 case OPC_DADD_CP2:
4364 {
4365 TCGv_i64 t2 = tcg_temp_new_i64();
4366 TCGLabel *lab = gen_new_label();
4367
4368 tcg_gen_mov_i64(t2, t0);
4369 tcg_gen_add_i64(t0, t1, t2);
4370 if (opc == OPC_ADD_CP2) {
4371 tcg_gen_ext32s_i64(t0, t0);
4372 }
4373 tcg_gen_xor_i64(t1, t1, t2);
4374 tcg_gen_xor_i64(t2, t2, t0);
4375 tcg_gen_andc_i64(t1, t2, t1);
4376 tcg_temp_free_i64(t2);
4377 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4378 generate_exception(ctx, EXCP_OVERFLOW);
4379 gen_set_label(lab);
4380 break;
4381 }
4382
4383 case OPC_SUB_CP2:
4384 case OPC_DSUB_CP2:
4385 {
4386 TCGv_i64 t2 = tcg_temp_new_i64();
4387 TCGLabel *lab = gen_new_label();
4388
4389 tcg_gen_mov_i64(t2, t0);
4390 tcg_gen_sub_i64(t0, t1, t2);
4391 if (opc == OPC_SUB_CP2) {
4392 tcg_gen_ext32s_i64(t0, t0);
4393 }
4394 tcg_gen_xor_i64(t1, t1, t2);
4395 tcg_gen_xor_i64(t2, t2, t0);
4396 tcg_gen_and_i64(t1, t1, t2);
4397 tcg_temp_free_i64(t2);
4398 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4399 generate_exception(ctx, EXCP_OVERFLOW);
4400 gen_set_label(lab);
4401 break;
4402 }
4403
4404 case OPC_PMULUW:
4405 tcg_gen_ext32u_i64(t0, t0);
4406 tcg_gen_ext32u_i64(t1, t1);
4407 tcg_gen_mul_i64(t0, t0, t1);
4408 break;
4409
4410 case OPC_SEQU_CP2:
4411 case OPC_SEQ_CP2:
4412 cond = TCG_COND_EQ;
4413 goto do_cc_cond;
4414 break;
4415 case OPC_SLTU_CP2:
4416 cond = TCG_COND_LTU;
4417 goto do_cc_cond;
4418 break;
4419 case OPC_SLT_CP2:
4420 cond = TCG_COND_LT;
4421 goto do_cc_cond;
4422 break;
4423 case OPC_SLEU_CP2:
4424 cond = TCG_COND_LEU;
4425 goto do_cc_cond;
4426 break;
4427 case OPC_SLE_CP2:
4428 cond = TCG_COND_LE;
4429 do_cc_cond:
4430 {
4431 int cc = (ctx->opcode >> 8) & 0x7;
4432 TCGv_i64 t64 = tcg_temp_new_i64();
4433 TCGv_i32 t32 = tcg_temp_new_i32();
4434
4435 tcg_gen_setcond_i64(cond, t64, t0, t1);
4436 tcg_gen_extrl_i64_i32(t32, t64);
4437 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4438 get_fp_bit(cc), 1);
4439
4440 tcg_temp_free_i32(t32);
4441 tcg_temp_free_i64(t64);
4442 }
4443 goto no_rd;
4444 break;
4445 default:
4446 MIPS_INVAL("loongson_cp2");
4447 gen_reserved_instruction(ctx);
4448 return;
4449 }
4450
4451 gen_store_fpr64(ctx, t0, rd);
4452
4453no_rd:
4454 tcg_temp_free_i64(t0);
4455 tcg_temp_free_i64(t1);
4456}
4457
4458static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4459 int rs, int rd)
4460{
4461 TCGv t0, t1, t2;
4462 TCGv_i32 fp0;
4463#if defined(TARGET_MIPS64)
4464 int lsq_rt1 = ctx->opcode & 0x1f;
4465 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4466#endif
4467 int shf_offset = sextract32(ctx->opcode, 6, 8);
4468
4469 t0 = tcg_temp_new();
4470
4471 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4472#if defined(TARGET_MIPS64)
4473 case OPC_GSLQ:
4474 t1 = tcg_temp_new();
4475 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4476 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4477 ctx->default_tcg_memop_mask);
4478 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4479 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4480 ctx->default_tcg_memop_mask);
4481 gen_store_gpr(t1, rt);
4482 gen_store_gpr(t0, lsq_rt1);
4483 tcg_temp_free(t1);
4484 break;
4485 case OPC_GSLQC1:
4486 check_cp1_enabled(ctx);
4487 t1 = tcg_temp_new();
4488 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4489 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4490 ctx->default_tcg_memop_mask);
4491 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4492 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4493 ctx->default_tcg_memop_mask);
4494 gen_store_fpr64(ctx, t1, rt);
4495 gen_store_fpr64(ctx, t0, lsq_rt1);
4496 tcg_temp_free(t1);
4497 break;
4498 case OPC_GSSQ:
4499 t1 = tcg_temp_new();
4500 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4501 gen_load_gpr(t1, rt);
4502 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4503 ctx->default_tcg_memop_mask);
4504 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4505 gen_load_gpr(t1, lsq_rt1);
4506 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4507 ctx->default_tcg_memop_mask);
4508 tcg_temp_free(t1);
4509 break;
4510 case OPC_GSSQC1:
4511 check_cp1_enabled(ctx);
4512 t1 = tcg_temp_new();
4513 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4514 gen_load_fpr64(ctx, t1, rt);
4515 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4516 ctx->default_tcg_memop_mask);
4517 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4518 gen_load_fpr64(ctx, t1, lsq_rt1);
4519 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4520 ctx->default_tcg_memop_mask);
4521 tcg_temp_free(t1);
4522 break;
4523#endif
4524 case OPC_GSSHFL:
4525 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4526 case OPC_GSLWLC1:
4527 check_cp1_enabled(ctx);
4528 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4529 t1 = tcg_temp_new();
4530 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4531 tcg_gen_andi_tl(t1, t0, 3);
4532#ifndef TARGET_WORDS_BIGENDIAN
4533 tcg_gen_xori_tl(t1, t1, 3);
4534#endif
4535 tcg_gen_shli_tl(t1, t1, 3);
4536 tcg_gen_andi_tl(t0, t0, ~3);
4537 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4538 tcg_gen_shl_tl(t0, t0, t1);
4539 t2 = tcg_const_tl(-1);
4540 tcg_gen_shl_tl(t2, t2, t1);
4541 fp0 = tcg_temp_new_i32();
4542 gen_load_fpr32(ctx, fp0, rt);
4543 tcg_gen_ext_i32_tl(t1, fp0);
4544 tcg_gen_andc_tl(t1, t1, t2);
4545 tcg_temp_free(t2);
4546 tcg_gen_or_tl(t0, t0, t1);
4547 tcg_temp_free(t1);
4548#if defined(TARGET_MIPS64)
4549 tcg_gen_extrl_i64_i32(fp0, t0);
4550#else
4551 tcg_gen_ext32s_tl(fp0, t0);
4552#endif
4553 gen_store_fpr32(ctx, fp0, rt);
4554 tcg_temp_free_i32(fp0);
4555 break;
4556 case OPC_GSLWRC1:
4557 check_cp1_enabled(ctx);
4558 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4559 t1 = tcg_temp_new();
4560 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4561 tcg_gen_andi_tl(t1, t0, 3);
4562#ifdef TARGET_WORDS_BIGENDIAN
4563 tcg_gen_xori_tl(t1, t1, 3);
4564#endif
4565 tcg_gen_shli_tl(t1, t1, 3);
4566 tcg_gen_andi_tl(t0, t0, ~3);
4567 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4568 tcg_gen_shr_tl(t0, t0, t1);
4569 tcg_gen_xori_tl(t1, t1, 31);
4570 t2 = tcg_const_tl(0xfffffffeull);
4571 tcg_gen_shl_tl(t2, t2, t1);
4572 fp0 = tcg_temp_new_i32();
4573 gen_load_fpr32(ctx, fp0, rt);
4574 tcg_gen_ext_i32_tl(t1, fp0);
4575 tcg_gen_and_tl(t1, t1, t2);
4576 tcg_temp_free(t2);
4577 tcg_gen_or_tl(t0, t0, t1);
4578 tcg_temp_free(t1);
4579#if defined(TARGET_MIPS64)
4580 tcg_gen_extrl_i64_i32(fp0, t0);
4581#else
4582 tcg_gen_ext32s_tl(fp0, t0);
4583#endif
4584 gen_store_fpr32(ctx, fp0, rt);
4585 tcg_temp_free_i32(fp0);
4586 break;
4587#if defined(TARGET_MIPS64)
4588 case OPC_GSLDLC1:
4589 check_cp1_enabled(ctx);
4590 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4591 t1 = tcg_temp_new();
4592 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4593 tcg_gen_andi_tl(t1, t0, 7);
4594#ifndef TARGET_WORDS_BIGENDIAN
4595 tcg_gen_xori_tl(t1, t1, 7);
4596#endif
4597 tcg_gen_shli_tl(t1, t1, 3);
4598 tcg_gen_andi_tl(t0, t0, ~7);
4599 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4600 tcg_gen_shl_tl(t0, t0, t1);
4601 t2 = tcg_const_tl(-1);
4602 tcg_gen_shl_tl(t2, t2, t1);
4603 gen_load_fpr64(ctx, t1, rt);
4604 tcg_gen_andc_tl(t1, t1, t2);
4605 tcg_temp_free(t2);
4606 tcg_gen_or_tl(t0, t0, t1);
4607 tcg_temp_free(t1);
4608 gen_store_fpr64(ctx, t0, rt);
4609 break;
4610 case OPC_GSLDRC1:
4611 check_cp1_enabled(ctx);
4612 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4613 t1 = tcg_temp_new();
4614 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4615 tcg_gen_andi_tl(t1, t0, 7);
4616#ifdef TARGET_WORDS_BIGENDIAN
4617 tcg_gen_xori_tl(t1, t1, 7);
4618#endif
4619 tcg_gen_shli_tl(t1, t1, 3);
4620 tcg_gen_andi_tl(t0, t0, ~7);
4621 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4622 tcg_gen_shr_tl(t0, t0, t1);
4623 tcg_gen_xori_tl(t1, t1, 63);
4624 t2 = tcg_const_tl(0xfffffffffffffffeull);
4625 tcg_gen_shl_tl(t2, t2, t1);
4626 gen_load_fpr64(ctx, t1, rt);
4627 tcg_gen_and_tl(t1, t1, t2);
4628 tcg_temp_free(t2);
4629 tcg_gen_or_tl(t0, t0, t1);
4630 tcg_temp_free(t1);
4631 gen_store_fpr64(ctx, t0, rt);
4632 break;
4633#endif
4634 default:
4635 MIPS_INVAL("loongson_gsshfl");
4636 gen_reserved_instruction(ctx);
4637 break;
4638 }
4639 break;
4640 case OPC_GSSHFS:
4641 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4642 case OPC_GSSWLC1:
4643 check_cp1_enabled(ctx);
4644 t1 = tcg_temp_new();
4645 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4646 fp0 = tcg_temp_new_i32();
4647 gen_load_fpr32(ctx, fp0, rt);
4648 tcg_gen_ext_i32_tl(t1, fp0);
4649 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4650 tcg_temp_free_i32(fp0);
4651 tcg_temp_free(t1);
4652 break;
4653 case OPC_GSSWRC1:
4654 check_cp1_enabled(ctx);
4655 t1 = tcg_temp_new();
4656 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4657 fp0 = tcg_temp_new_i32();
4658 gen_load_fpr32(ctx, fp0, rt);
4659 tcg_gen_ext_i32_tl(t1, fp0);
4660 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4661 tcg_temp_free_i32(fp0);
4662 tcg_temp_free(t1);
4663 break;
4664#if defined(TARGET_MIPS64)
4665 case OPC_GSSDLC1:
4666 check_cp1_enabled(ctx);
4667 t1 = tcg_temp_new();
4668 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4669 gen_load_fpr64(ctx, t1, rt);
4670 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4671 tcg_temp_free(t1);
4672 break;
4673 case OPC_GSSDRC1:
4674 check_cp1_enabled(ctx);
4675 t1 = tcg_temp_new();
4676 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4677 gen_load_fpr64(ctx, t1, rt);
4678 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4679 tcg_temp_free(t1);
4680 break;
4681#endif
4682 default:
4683 MIPS_INVAL("loongson_gsshfs");
4684 gen_reserved_instruction(ctx);
4685 break;
4686 }
4687 break;
4688 default:
4689 MIPS_INVAL("loongson_gslsq");
4690 gen_reserved_instruction(ctx);
4691 break;
4692 }
4693 tcg_temp_free(t0);
4694}
4695
4696
4697static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4698 int rs, int rd)
4699{
4700 int offset = sextract32(ctx->opcode, 3, 8);
4701 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4702 TCGv t0, t1;
4703 TCGv_i32 fp0;
4704
4705
4706 switch (opc) {
4707 case OPC_GSLBX:
4708 case OPC_GSLHX:
4709 case OPC_GSLWX:
4710 case OPC_GSLDX:
4711
4712 if (rt == 0) {
4713 return;
4714 }
4715 break;
4716 case OPC_GSSBX:
4717 case OPC_GSSHX:
4718 case OPC_GSSWX:
4719 case OPC_GSSDX:
4720 break;
4721 case OPC_GSLWXC1:
4722#if defined(TARGET_MIPS64)
4723 case OPC_GSLDXC1:
4724#endif
4725 check_cp1_enabled(ctx);
4726
4727 if (rt == 0) {
4728 return;
4729 }
4730 break;
4731 case OPC_GSSWXC1:
4732#if defined(TARGET_MIPS64)
4733 case OPC_GSSDXC1:
4734#endif
4735 check_cp1_enabled(ctx);
4736 break;
4737 default:
4738 MIPS_INVAL("loongson_lsdc2");
4739 gen_reserved_instruction(ctx);
4740 return;
4741 break;
4742 }
4743
4744 t0 = tcg_temp_new();
4745
4746 gen_base_offset_addr(ctx, t0, rs, offset);
4747 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4748
4749 switch (opc) {
4750 case OPC_GSLBX:
4751 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4752 gen_store_gpr(t0, rt);
4753 break;
4754 case OPC_GSLHX:
4755 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4756 ctx->default_tcg_memop_mask);
4757 gen_store_gpr(t0, rt);
4758 break;
4759 case OPC_GSLWX:
4760 gen_base_offset_addr(ctx, t0, rs, offset);
4761 if (rd) {
4762 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4763 }
4764 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4765 ctx->default_tcg_memop_mask);
4766 gen_store_gpr(t0, rt);
4767 break;
4768#if defined(TARGET_MIPS64)
4769 case OPC_GSLDX:
4770 gen_base_offset_addr(ctx, t0, rs, offset);
4771 if (rd) {
4772 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4773 }
4774 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4775 ctx->default_tcg_memop_mask);
4776 gen_store_gpr(t0, rt);
4777 break;
4778#endif
4779 case OPC_GSLWXC1:
4780 check_cp1_enabled(ctx);
4781 gen_base_offset_addr(ctx, t0, rs, offset);
4782 if (rd) {
4783 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4784 }
4785 fp0 = tcg_temp_new_i32();
4786 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4787 ctx->default_tcg_memop_mask);
4788 gen_store_fpr32(ctx, fp0, rt);
4789 tcg_temp_free_i32(fp0);
4790 break;
4791#if defined(TARGET_MIPS64)
4792 case OPC_GSLDXC1:
4793 check_cp1_enabled(ctx);
4794 gen_base_offset_addr(ctx, t0, rs, offset);
4795 if (rd) {
4796 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4797 }
4798 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4799 ctx->default_tcg_memop_mask);
4800 gen_store_fpr64(ctx, t0, rt);
4801 break;
4802#endif
4803 case OPC_GSSBX:
4804 t1 = tcg_temp_new();
4805 gen_load_gpr(t1, rt);
4806 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4807 tcg_temp_free(t1);
4808 break;
4809 case OPC_GSSHX:
4810 t1 = tcg_temp_new();
4811 gen_load_gpr(t1, rt);
4812 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4813 ctx->default_tcg_memop_mask);
4814 tcg_temp_free(t1);
4815 break;
4816 case OPC_GSSWX:
4817 t1 = tcg_temp_new();
4818 gen_load_gpr(t1, rt);
4819 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4820 ctx->default_tcg_memop_mask);
4821 tcg_temp_free(t1);
4822 break;
4823#if defined(TARGET_MIPS64)
4824 case OPC_GSSDX:
4825 t1 = tcg_temp_new();
4826 gen_load_gpr(t1, rt);
4827 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4828 ctx->default_tcg_memop_mask);
4829 tcg_temp_free(t1);
4830 break;
4831#endif
4832 case OPC_GSSWXC1:
4833 fp0 = tcg_temp_new_i32();
4834 gen_load_fpr32(ctx, fp0, rt);
4835 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4836 ctx->default_tcg_memop_mask);
4837 tcg_temp_free_i32(fp0);
4838 break;
4839#if defined(TARGET_MIPS64)
4840 case OPC_GSSDXC1:
4841 t1 = tcg_temp_new();
4842 gen_load_fpr64(ctx, t1, rt);
4843 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
4844 ctx->default_tcg_memop_mask);
4845 tcg_temp_free(t1);
4846 break;
4847#endif
4848 default:
4849 break;
4850 }
4851
4852 tcg_temp_free(t0);
4853}
4854
4855
4856static void gen_trap(DisasContext *ctx, uint32_t opc,
4857 int rs, int rt, int16_t imm)
4858{
4859 int cond;
4860 TCGv t0 = tcg_temp_new();
4861 TCGv t1 = tcg_temp_new();
4862
4863 cond = 0;
4864
4865 switch (opc) {
4866 case OPC_TEQ:
4867 case OPC_TGE:
4868 case OPC_TGEU:
4869 case OPC_TLT:
4870 case OPC_TLTU:
4871 case OPC_TNE:
4872
4873 if (rs != rt) {
4874 gen_load_gpr(t0, rs);
4875 gen_load_gpr(t1, rt);
4876 cond = 1;
4877 }
4878 break;
4879 case OPC_TEQI:
4880 case OPC_TGEI:
4881 case OPC_TGEIU:
4882 case OPC_TLTI:
4883 case OPC_TLTIU:
4884 case OPC_TNEI:
4885
4886 if (rs != 0 || imm != 0) {
4887 gen_load_gpr(t0, rs);
4888 tcg_gen_movi_tl(t1, (int32_t)imm);
4889 cond = 1;
4890 }
4891 break;
4892 }
4893 if (cond == 0) {
4894 switch (opc) {
4895 case OPC_TEQ:
4896 case OPC_TEQI:
4897 case OPC_TGE:
4898 case OPC_TGEI:
4899 case OPC_TGEU:
4900 case OPC_TGEIU:
4901
4902 generate_exception_end(ctx, EXCP_TRAP);
4903 break;
4904 case OPC_TLT:
4905 case OPC_TLTI:
4906 case OPC_TLTU:
4907 case OPC_TLTIU:
4908 case OPC_TNE:
4909 case OPC_TNEI:
4910
4911 break;
4912 }
4913 } else {
4914 TCGLabel *l1 = gen_new_label();
4915
4916 switch (opc) {
4917 case OPC_TEQ:
4918 case OPC_TEQI:
4919 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4920 break;
4921 case OPC_TGE:
4922 case OPC_TGEI:
4923 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4924 break;
4925 case OPC_TGEU:
4926 case OPC_TGEIU:
4927 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4928 break;
4929 case OPC_TLT:
4930 case OPC_TLTI:
4931 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4932 break;
4933 case OPC_TLTU:
4934 case OPC_TLTIU:
4935 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4936 break;
4937 case OPC_TNE:
4938 case OPC_TNEI:
4939 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4940 break;
4941 }
4942 generate_exception(ctx, EXCP_TRAP);
4943 gen_set_label(l1);
4944 }
4945 tcg_temp_free(t0);
4946 tcg_temp_free(t1);
4947}
4948
4949static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4950{
4951 if (translator_use_goto_tb(&ctx->base, dest)) {
4952 tcg_gen_goto_tb(n);
4953 gen_save_pc(dest);
4954 tcg_gen_exit_tb(ctx->base.tb, n);
4955 } else {
4956 gen_save_pc(dest);
4957 if (ctx->base.singlestep_enabled) {
4958 save_cpu_state(ctx, 0);
4959 gen_helper_raise_exception_debug(cpu_env);
4960 } else {
4961 tcg_gen_lookup_and_goto_ptr();
4962 }
4963 }
4964}
4965
4966
4967static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4968 int insn_bytes,
4969 int rs, int rt, int32_t offset,
4970 int delayslot_size)
4971{
4972 target_ulong btgt = -1;
4973 int blink = 0;
4974 int bcond_compute = 0;
4975 TCGv t0 = tcg_temp_new();
4976 TCGv t1 = tcg_temp_new();
4977
4978 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4979#ifdef MIPS_DEBUG_DISAS
4980 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4981 TARGET_FMT_lx "\n", ctx->base.pc_next);
4982#endif
4983 gen_reserved_instruction(ctx);
4984 goto out;
4985 }
4986
4987
4988 switch (opc) {
4989 case OPC_BEQ:
4990 case OPC_BEQL:
4991 case OPC_BNE:
4992 case OPC_BNEL:
4993
4994 if (rs != rt) {
4995 gen_load_gpr(t0, rs);
4996 gen_load_gpr(t1, rt);
4997 bcond_compute = 1;
4998 }
4999 btgt = ctx->base.pc_next + insn_bytes + offset;
5000 break;
5001 case OPC_BGEZ:
5002 case OPC_BGEZAL:
5003 case OPC_BGEZALL:
5004 case OPC_BGEZL:
5005 case OPC_BGTZ:
5006 case OPC_BGTZL:
5007 case OPC_BLEZ:
5008 case OPC_BLEZL:
5009 case OPC_BLTZ:
5010 case OPC_BLTZAL:
5011 case OPC_BLTZALL:
5012 case OPC_BLTZL:
5013
5014 if (rs != 0) {
5015 gen_load_gpr(t0, rs);
5016 bcond_compute = 1;
5017 }
5018 btgt = ctx->base.pc_next + insn_bytes + offset;
5019 break;
5020 case OPC_BPOSGE32:
5021#if defined(TARGET_MIPS64)
5022 case OPC_BPOSGE64:
5023 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5024#else
5025 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5026#endif
5027 bcond_compute = 1;
5028 btgt = ctx->base.pc_next + insn_bytes + offset;
5029 break;
5030 case OPC_J:
5031 case OPC_JAL:
5032 case OPC_JALX:
5033
5034 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5035 (uint32_t)offset;
5036 break;
5037 case OPC_JR:
5038 case OPC_JALR:
5039
5040 if (offset != 0 && offset != 16) {
5041
5042
5043
5044
5045 MIPS_INVAL("jump hint");
5046 gen_reserved_instruction(ctx);
5047 goto out;
5048 }
5049 gen_load_gpr(btarget, rs);
5050 break;
5051 default:
5052 MIPS_INVAL("branch/jump");
5053 gen_reserved_instruction(ctx);
5054 goto out;
5055 }
5056 if (bcond_compute == 0) {
5057
5058 switch (opc) {
5059 case OPC_BEQ:
5060 case OPC_BEQL:
5061 case OPC_BGEZ:
5062 case OPC_BGEZL:
5063 case OPC_BLEZ:
5064 case OPC_BLEZL:
5065
5066 ctx->hflags |= MIPS_HFLAG_B;
5067 break;
5068 case OPC_BGEZAL:
5069 case OPC_BGEZALL:
5070
5071 blink = 31;
5072 ctx->hflags |= MIPS_HFLAG_B;
5073 break;
5074 case OPC_BNE:
5075 case OPC_BGTZ:
5076 case OPC_BLTZ:
5077
5078 goto out;
5079 case OPC_BLTZAL:
5080
5081
5082
5083
5084 blink = 31;
5085 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5086 ctx->hflags |= MIPS_HFLAG_B;
5087 break;
5088 case OPC_BLTZALL:
5089 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5090
5091 ctx->base.pc_next += 4;
5092 goto out;
5093 case OPC_BNEL:
5094 case OPC_BGTZL:
5095 case OPC_BLTZL:
5096
5097 ctx->base.pc_next += 4;
5098 goto out;
5099 case OPC_J:
5100 ctx->hflags |= MIPS_HFLAG_B;
5101 break;
5102 case OPC_JALX:
5103 ctx->hflags |= MIPS_HFLAG_BX;
5104
5105 case OPC_JAL:
5106 blink = 31;
5107 ctx->hflags |= MIPS_HFLAG_B;
5108 break;
5109 case OPC_JR:
5110 ctx->hflags |= MIPS_HFLAG_BR;
5111 break;
5112 case OPC_JALR:
5113 blink = rt;
5114 ctx->hflags |= MIPS_HFLAG_BR;
5115 break;
5116 default:
5117 MIPS_INVAL("branch/jump");
5118 gen_reserved_instruction(ctx);
5119 goto out;
5120 }
5121 } else {
5122 switch (opc) {
5123 case OPC_BEQ:
5124 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5125 goto not_likely;
5126 case OPC_BEQL:
5127 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5128 goto likely;
5129 case OPC_BNE:
5130 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5131 goto not_likely;
5132 case OPC_BNEL:
5133 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5134 goto likely;
5135 case OPC_BGEZ:
5136 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5137 goto not_likely;
5138 case OPC_BGEZL:
5139 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5140 goto likely;
5141 case OPC_BGEZAL:
5142 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5143 blink = 31;
5144 goto not_likely;
5145 case OPC_BGEZALL:
5146 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5147 blink = 31;
5148 goto likely;
5149 case OPC_BGTZ:
5150 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5151 goto not_likely;
5152 case OPC_BGTZL:
5153 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5154 goto likely;
5155 case OPC_BLEZ:
5156 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5157 goto not_likely;
5158 case OPC_BLEZL:
5159 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5160 goto likely;
5161 case OPC_BLTZ:
5162 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5163 goto not_likely;
5164 case OPC_BLTZL:
5165 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5166 goto likely;
5167 case OPC_BPOSGE32:
5168 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5169 goto not_likely;
5170#if defined(TARGET_MIPS64)
5171 case OPC_BPOSGE64:
5172 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5173 goto not_likely;
5174#endif
5175 case OPC_BLTZAL:
5176 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5177 blink = 31;
5178 not_likely:
5179 ctx->hflags |= MIPS_HFLAG_BC;
5180 break;
5181 case OPC_BLTZALL:
5182 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5183 blink = 31;
5184 likely:
5185 ctx->hflags |= MIPS_HFLAG_BL;
5186 break;
5187 default:
5188 MIPS_INVAL("conditional branch/jump");
5189 gen_reserved_instruction(ctx);
5190 goto out;
5191 }
5192 }
5193
5194 ctx->btarget = btgt;
5195
5196 switch (delayslot_size) {
5197 case 2:
5198 ctx->hflags |= MIPS_HFLAG_BDS16;
5199 break;
5200 case 4:
5201 ctx->hflags |= MIPS_HFLAG_BDS32;
5202 break;
5203 }
5204
5205 if (blink > 0) {
5206 int post_delay = insn_bytes + delayslot_size;
5207 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5208
5209 tcg_gen_movi_tl(cpu_gpr[blink],
5210 ctx->base.pc_next + post_delay + lowbit);
5211 }
5212
5213 out:
5214 if (insn_bytes == 2) {
5215 ctx->hflags |= MIPS_HFLAG_B16;
5216 }
5217 tcg_temp_free(t0);
5218 tcg_temp_free(t1);
5219}
5220
5221
5222
5223static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5224 int rs, int lsb, int msb)
5225{
5226 TCGv t0 = tcg_temp_new();
5227 TCGv t1 = tcg_temp_new();
5228
5229 gen_load_gpr(t1, rs);
5230 switch (opc) {
5231 case OPC_EXT:
5232 if (lsb + msb > 31) {
5233 goto fail;
5234 }
5235 if (msb != 31) {
5236 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5237 } else {
5238
5239
5240
5241
5242 tcg_gen_ext32s_tl(t0, t1);
5243 }
5244 break;
5245#if defined(TARGET_MIPS64)
5246 case OPC_DEXTU:
5247 lsb += 32;
5248 goto do_dext;
5249 case OPC_DEXTM:
5250 msb += 32;
5251 goto do_dext;
5252 case OPC_DEXT:
5253 do_dext:
5254 if (lsb + msb > 63) {
5255 goto fail;
5256 }
5257 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5258 break;
5259#endif
5260 case OPC_INS:
5261 if (lsb > msb) {
5262 goto fail;
5263 }
5264 gen_load_gpr(t0, rt);
5265 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5266 tcg_gen_ext32s_tl(t0, t0);
5267 break;
5268#if defined(TARGET_MIPS64)
5269 case OPC_DINSU:
5270 lsb += 32;
5271
5272 case OPC_DINSM:
5273 msb += 32;
5274
5275 case OPC_DINS:
5276 if (lsb > msb) {
5277 goto fail;
5278 }
5279 gen_load_gpr(t0, rt);
5280 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5281 break;
5282#endif
5283 default:
5284fail:
5285 MIPS_INVAL("bitops");
5286 gen_reserved_instruction(ctx);
5287 tcg_temp_free(t0);
5288 tcg_temp_free(t1);
5289 return;
5290 }
5291 gen_store_gpr(t0, rt);
5292 tcg_temp_free(t0);
5293 tcg_temp_free(t1);
5294}
5295
5296static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5297{
5298 TCGv t0;
5299
5300 if (rd == 0) {
5301
5302 return;
5303 }
5304
5305 t0 = tcg_temp_new();
5306 gen_load_gpr(t0, rt);
5307 switch (op2) {
5308 case OPC_WSBH:
5309 {
5310 TCGv t1 = tcg_temp_new();
5311 TCGv t2 = tcg_const_tl(0x00FF00FF);
5312
5313 tcg_gen_shri_tl(t1, t0, 8);
5314 tcg_gen_and_tl(t1, t1, t2);
5315 tcg_gen_and_tl(t0, t0, t2);
5316 tcg_gen_shli_tl(t0, t0, 8);
5317 tcg_gen_or_tl(t0, t0, t1);
5318 tcg_temp_free(t2);
5319 tcg_temp_free(t1);
5320 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5321 }
5322 break;
5323 case OPC_SEB:
5324 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5325 break;
5326 case OPC_SEH:
5327 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5328 break;
5329#if defined(TARGET_MIPS64)
5330 case OPC_DSBH:
5331 {
5332 TCGv t1 = tcg_temp_new();
5333 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5334
5335 tcg_gen_shri_tl(t1, t0, 8);
5336 tcg_gen_and_tl(t1, t1, t2);
5337 tcg_gen_and_tl(t0, t0, t2);
5338 tcg_gen_shli_tl(t0, t0, 8);
5339 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5340 tcg_temp_free(t2);
5341 tcg_temp_free(t1);
5342 }
5343 break;
5344 case OPC_DSHD:
5345 {
5346 TCGv t1 = tcg_temp_new();
5347 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5348
5349 tcg_gen_shri_tl(t1, t0, 16);
5350 tcg_gen_and_tl(t1, t1, t2);
5351 tcg_gen_and_tl(t0, t0, t2);
5352 tcg_gen_shli_tl(t0, t0, 16);
5353 tcg_gen_or_tl(t0, t0, t1);
5354 tcg_gen_shri_tl(t1, t0, 32);
5355 tcg_gen_shli_tl(t0, t0, 32);
5356 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5357 tcg_temp_free(t2);
5358 tcg_temp_free(t1);
5359 }
5360 break;
5361#endif
5362 default:
5363 MIPS_INVAL("bsfhl");
5364 gen_reserved_instruction(ctx);
5365 tcg_temp_free(t0);
5366 return;
5367 }
5368 tcg_temp_free(t0);
5369}
5370
5371static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5372 int rt, int bits)
5373{
5374 TCGv t0;
5375 if (rd == 0) {
5376
5377 return;
5378 }
5379 t0 = tcg_temp_new();
5380 if (bits == 0 || bits == wordsz) {
5381 if (bits == 0) {
5382 gen_load_gpr(t0, rt);
5383 } else {
5384 gen_load_gpr(t0, rs);
5385 }
5386 switch (wordsz) {
5387 case 32:
5388 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5389 break;
5390#if defined(TARGET_MIPS64)
5391 case 64:
5392 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5393 break;
5394#endif
5395 }
5396 } else {
5397 TCGv t1 = tcg_temp_new();
5398 gen_load_gpr(t0, rt);
5399 gen_load_gpr(t1, rs);
5400 switch (wordsz) {
5401 case 32:
5402 {
5403 TCGv_i64 t2 = tcg_temp_new_i64();
5404 tcg_gen_concat_tl_i64(t2, t1, t0);
5405 tcg_gen_shri_i64(t2, t2, 32 - bits);
5406 gen_move_low32(cpu_gpr[rd], t2);
5407 tcg_temp_free_i64(t2);
5408 }
5409 break;
5410#if defined(TARGET_MIPS64)
5411 case 64:
5412 tcg_gen_shli_tl(t0, t0, bits);
5413 tcg_gen_shri_tl(t1, t1, 64 - bits);
5414 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5415 break;
5416#endif
5417 }
5418 tcg_temp_free(t1);
5419 }
5420
5421 tcg_temp_free(t0);
5422}
5423
5424void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5425{
5426 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5427}
5428
5429static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5430{
5431 TCGv t0;
5432 if (rd == 0) {
5433
5434 return;
5435 }
5436 t0 = tcg_temp_new();
5437 gen_load_gpr(t0, rt);
5438 switch (opc) {
5439 case OPC_BITSWAP:
5440 gen_helper_bitswap(cpu_gpr[rd], t0);
5441 break;
5442#if defined(TARGET_MIPS64)
5443 case OPC_DBITSWAP:
5444 gen_helper_dbitswap(cpu_gpr[rd], t0);
5445 break;
5446#endif
5447 }
5448 tcg_temp_free(t0);
5449}
5450
5451#ifndef CONFIG_USER_ONLY
5452
5453static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5454{
5455 TCGv_i64 t0 = tcg_temp_new_i64();
5456 TCGv_i64 t1 = tcg_temp_new_i64();
5457
5458 tcg_gen_ext_tl_i64(t0, arg);
5459 tcg_gen_ld_i64(t1, cpu_env, off);
5460#if defined(TARGET_MIPS64)
5461 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5462#else
5463 tcg_gen_concat32_i64(t1, t1, t0);
5464#endif
5465 tcg_gen_st_i64(t1, cpu_env, off);
5466 tcg_temp_free_i64(t1);
5467 tcg_temp_free_i64(t0);
5468}
5469
5470static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5471{
5472 TCGv_i64 t0 = tcg_temp_new_i64();
5473 TCGv_i64 t1 = tcg_temp_new_i64();
5474
5475 tcg_gen_ext_tl_i64(t0, arg);
5476 tcg_gen_ld_i64(t1, cpu_env, off);
5477 tcg_gen_concat32_i64(t1, t1, t0);
5478 tcg_gen_st_i64(t1, cpu_env, off);
5479 tcg_temp_free_i64(t1);
5480 tcg_temp_free_i64(t0);
5481}
5482
5483static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5484{
5485 TCGv_i64 t0 = tcg_temp_new_i64();
5486
5487 tcg_gen_ld_i64(t0, cpu_env, off);
5488#if defined(TARGET_MIPS64)
5489 tcg_gen_shri_i64(t0, t0, 30);
5490#else
5491 tcg_gen_shri_i64(t0, t0, 32);
5492#endif
5493 gen_move_low32(arg, t0);
5494 tcg_temp_free_i64(t0);
5495}
5496
5497static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5498{
5499 TCGv_i64 t0 = tcg_temp_new_i64();
5500
5501 tcg_gen_ld_i64(t0, cpu_env, off);
5502 tcg_gen_shri_i64(t0, t0, 32 + shift);
5503 gen_move_low32(arg, t0);
5504 tcg_temp_free_i64(t0);
5505}
5506
5507static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5508{
5509 TCGv_i32 t0 = tcg_temp_new_i32();
5510
5511 tcg_gen_ld_i32(t0, cpu_env, off);
5512 tcg_gen_ext_i32_tl(arg, t0);
5513 tcg_temp_free_i32(t0);
5514}
5515
5516static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5517{
5518 tcg_gen_ld_tl(arg, cpu_env, off);
5519 tcg_gen_ext32s_tl(arg, arg);
5520}
5521
5522static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5523{
5524 TCGv_i32 t0 = tcg_temp_new_i32();
5525
5526 tcg_gen_trunc_tl_i32(t0, arg);
5527 tcg_gen_st_i32(t0, cpu_env, off);
5528 tcg_temp_free_i32(t0);
5529}
5530
5531#define CP0_CHECK(c) \
5532 do { \
5533 if (!(c)) { \
5534 goto cp0_unimplemented; \
5535 } \
5536 } while (0)
5537
5538static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5539{
5540 const char *register_name = "invalid";
5541
5542 switch (reg) {
5543 case CP0_REGISTER_02:
5544 switch (sel) {
5545 case 0:
5546 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5547 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5548 register_name = "EntryLo0";
5549 break;
5550 default:
5551 goto cp0_unimplemented;
5552 }
5553 break;
5554 case CP0_REGISTER_03:
5555 switch (sel) {
5556 case CP0_REG03__ENTRYLO1:
5557 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5558 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5559 register_name = "EntryLo1";
5560 break;
5561 default:
5562 goto cp0_unimplemented;
5563 }
5564 break;
5565 case CP0_REGISTER_09:
5566 switch (sel) {
5567 case CP0_REG09__SAAR:
5568 CP0_CHECK(ctx->saar);
5569 gen_helper_mfhc0_saar(arg, cpu_env);
5570 register_name = "SAAR";
5571 break;
5572 default:
5573 goto cp0_unimplemented;
5574 }
5575 break;
5576 case CP0_REGISTER_17:
5577 switch (sel) {
5578 case CP0_REG17__LLADDR:
5579 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5580 ctx->CP0_LLAddr_shift);
5581 register_name = "LLAddr";
5582 break;
5583 case CP0_REG17__MAAR:
5584 CP0_CHECK(ctx->mrp);
5585 gen_helper_mfhc0_maar(arg, cpu_env);
5586 register_name = "MAAR";
5587 break;
5588 default:
5589 goto cp0_unimplemented;
5590 }
5591 break;
5592 case CP0_REGISTER_19:
5593 switch (sel) {
5594 case CP0_REG19__WATCHHI0:
5595 case CP0_REG19__WATCHHI1:
5596 case CP0_REG19__WATCHHI2:
5597 case CP0_REG19__WATCHHI3:
5598 case CP0_REG19__WATCHHI4:
5599 case CP0_REG19__WATCHHI5:
5600 case CP0_REG19__WATCHHI6:
5601 case CP0_REG19__WATCHHI7:
5602
5603 CP0_CHECK(ctx->mi);
5604 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5605 register_name = "WatchHi";
5606 break;
5607 default:
5608 goto cp0_unimplemented;
5609 }
5610 break;
5611 case CP0_REGISTER_28:
5612 switch (sel) {
5613 case 0:
5614 case 2:
5615 case 4:
5616 case 6:
5617 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5618 register_name = "TagLo";
5619 break;
5620 default:
5621 goto cp0_unimplemented;
5622 }
5623 break;
5624 default:
5625 goto cp0_unimplemented;
5626 }
5627 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5628 return;
5629
5630cp0_unimplemented:
5631 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5632 register_name, reg, sel);
5633 tcg_gen_movi_tl(arg, 0);
5634}
5635
5636static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5637{
5638 const char *register_name = "invalid";
5639 uint64_t mask = ctx->PAMask >> 36;
5640
5641 switch (reg) {
5642 case CP0_REGISTER_02:
5643 switch (sel) {
5644 case 0:
5645 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5646 tcg_gen_andi_tl(arg, arg, mask);
5647 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5648 register_name = "EntryLo0";
5649 break;
5650 default:
5651 goto cp0_unimplemented;
5652 }
5653 break;
5654 case CP0_REGISTER_03:
5655 switch (sel) {
5656 case CP0_REG03__ENTRYLO1:
5657 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5658 tcg_gen_andi_tl(arg, arg, mask);
5659 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5660 register_name = "EntryLo1";
5661 break;
5662 default:
5663 goto cp0_unimplemented;
5664 }
5665 break;
5666 case CP0_REGISTER_09:
5667 switch (sel) {
5668 case CP0_REG09__SAAR:
5669 CP0_CHECK(ctx->saar);
5670 gen_helper_mthc0_saar(cpu_env, arg);
5671 register_name = "SAAR";
5672 break;
5673 default:
5674 goto cp0_unimplemented;
5675 }
5676 break;
5677 case CP0_REGISTER_17:
5678 switch (sel) {
5679 case CP0_REG17__LLADDR:
5680
5681
5682
5683
5684
5685
5686 register_name = "LLAddr";
5687 break;
5688 case CP0_REG17__MAAR:
5689 CP0_CHECK(ctx->mrp);
5690 gen_helper_mthc0_maar(cpu_env, arg);
5691 register_name = "MAAR";
5692 break;
5693 default:
5694 goto cp0_unimplemented;
5695 }
5696 break;
5697 case CP0_REGISTER_19:
5698 switch (sel) {
5699 case CP0_REG19__WATCHHI0:
5700 case CP0_REG19__WATCHHI1:
5701 case CP0_REG19__WATCHHI2:
5702 case CP0_REG19__WATCHHI3:
5703 case CP0_REG19__WATCHHI4:
5704 case CP0_REG19__WATCHHI5:
5705 case CP0_REG19__WATCHHI6:
5706 case CP0_REG19__WATCHHI7:
5707
5708 CP0_CHECK(ctx->mi);
5709 gen_helper_0e1i(mthc0_watchhi, arg, sel);
5710 register_name = "WatchHi";
5711 break;
5712 default:
5713 goto cp0_unimplemented;
5714 }
5715 break;
5716 case CP0_REGISTER_28:
5717 switch (sel) {
5718 case 0:
5719 case 2:
5720 case 4:
5721 case 6:
5722 tcg_gen_andi_tl(arg, arg, mask);
5723 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5724 register_name = "TagLo";
5725 break;
5726 default:
5727 goto cp0_unimplemented;
5728 }
5729 break;
5730 default:
5731 goto cp0_unimplemented;
5732 }
5733 trace_mips_translate_c0("mthc0", register_name, reg, sel);
5734 return;
5735
5736cp0_unimplemented:
5737 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5738 register_name, reg, sel);
5739}
5740
5741static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5742{
5743 if (ctx->insn_flags & ISA_MIPS_R6) {
5744 tcg_gen_movi_tl(arg, 0);
5745 } else {
5746 tcg_gen_movi_tl(arg, ~0);
5747 }
5748}
5749
5750static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5751{
5752 const char *register_name = "invalid";
5753
5754 if (sel != 0) {
5755 check_insn(ctx, ISA_MIPS_R1);
5756 }
5757
5758 switch (reg) {
5759 case CP0_REGISTER_00:
5760 switch (sel) {
5761 case CP0_REG00__INDEX:
5762 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5763 register_name = "Index";
5764 break;
5765 case CP0_REG00__MVPCONTROL:
5766 CP0_CHECK(ctx->insn_flags & ASE_MT);
5767 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5768 register_name = "MVPControl";
5769 break;
5770 case CP0_REG00__MVPCONF0:
5771 CP0_CHECK(ctx->insn_flags & ASE_MT);
5772 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5773 register_name = "MVPConf0";
5774 break;
5775 case CP0_REG00__MVPCONF1:
5776 CP0_CHECK(ctx->insn_flags & ASE_MT);
5777 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5778 register_name = "MVPConf1";
5779 break;
5780 case CP0_REG00__VPCONTROL:
5781 CP0_CHECK(ctx->vp);
5782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5783 register_name = "VPControl";
5784 break;
5785 default:
5786 goto cp0_unimplemented;
5787 }
5788 break;
5789 case CP0_REGISTER_01:
5790 switch (sel) {
5791 case CP0_REG01__RANDOM:
5792 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5793 gen_helper_mfc0_random(arg, cpu_env);
5794 register_name = "Random";
5795 break;
5796 case CP0_REG01__VPECONTROL:
5797 CP0_CHECK(ctx->insn_flags & ASE_MT);
5798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5799 register_name = "VPEControl";
5800 break;
5801 case CP0_REG01__VPECONF0:
5802 CP0_CHECK(ctx->insn_flags & ASE_MT);
5803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5804 register_name = "VPEConf0";
5805 break;
5806 case CP0_REG01__VPECONF1:
5807 CP0_CHECK(ctx->insn_flags & ASE_MT);
5808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5809 register_name = "VPEConf1";
5810 break;
5811 case CP0_REG01__YQMASK:
5812 CP0_CHECK(ctx->insn_flags & ASE_MT);
5813 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5814 register_name = "YQMask";
5815 break;
5816 case CP0_REG01__VPESCHEDULE:
5817 CP0_CHECK(ctx->insn_flags & ASE_MT);
5818 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5819 register_name = "VPESchedule";
5820 break;
5821 case CP0_REG01__VPESCHEFBACK:
5822 CP0_CHECK(ctx->insn_flags & ASE_MT);
5823 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5824 register_name = "VPEScheFBack";
5825 break;
5826 case CP0_REG01__VPEOPT:
5827 CP0_CHECK(ctx->insn_flags & ASE_MT);
5828 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5829 register_name = "VPEOpt";
5830 break;
5831 default:
5832 goto cp0_unimplemented;
5833 }
5834 break;
5835 case CP0_REGISTER_02:
5836 switch (sel) {
5837 case CP0_REG02__ENTRYLO0:
5838 {
5839 TCGv_i64 tmp = tcg_temp_new_i64();
5840 tcg_gen_ld_i64(tmp, cpu_env,
5841 offsetof(CPUMIPSState, CP0_EntryLo0));
5842#if defined(TARGET_MIPS64)
5843 if (ctx->rxi) {
5844
5845 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5846 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5847 }
5848#endif
5849 gen_move_low32(arg, tmp);
5850 tcg_temp_free_i64(tmp);
5851 }
5852 register_name = "EntryLo0";
5853 break;
5854 case CP0_REG02__TCSTATUS:
5855 CP0_CHECK(ctx->insn_flags & ASE_MT);
5856 gen_helper_mfc0_tcstatus(arg, cpu_env);
5857 register_name = "TCStatus";
5858 break;
5859 case CP0_REG02__TCBIND:
5860 CP0_CHECK(ctx->insn_flags & ASE_MT);
5861 gen_helper_mfc0_tcbind(arg, cpu_env);
5862 register_name = "TCBind";
5863 break;
5864 case CP0_REG02__TCRESTART:
5865 CP0_CHECK(ctx->insn_flags & ASE_MT);
5866 gen_helper_mfc0_tcrestart(arg, cpu_env);
5867 register_name = "TCRestart";
5868 break;
5869 case CP0_REG02__TCHALT:
5870 CP0_CHECK(ctx->insn_flags & ASE_MT);
5871 gen_helper_mfc0_tchalt(arg, cpu_env);
5872 register_name = "TCHalt";
5873 break;
5874 case CP0_REG02__TCCONTEXT:
5875 CP0_CHECK(ctx->insn_flags & ASE_MT);
5876 gen_helper_mfc0_tccontext(arg, cpu_env);
5877 register_name = "TCContext";
5878 break;
5879 case CP0_REG02__TCSCHEDULE:
5880 CP0_CHECK(ctx->insn_flags & ASE_MT);
5881 gen_helper_mfc0_tcschedule(arg, cpu_env);
5882 register_name = "TCSchedule";
5883 break;
5884 case CP0_REG02__TCSCHEFBACK:
5885 CP0_CHECK(ctx->insn_flags & ASE_MT);
5886 gen_helper_mfc0_tcschefback(arg, cpu_env);
5887 register_name = "TCScheFBack";
5888 break;
5889 default:
5890 goto cp0_unimplemented;
5891 }
5892 break;
5893 case CP0_REGISTER_03:
5894 switch (sel) {
5895 case CP0_REG03__ENTRYLO1:
5896 {
5897 TCGv_i64 tmp = tcg_temp_new_i64();
5898 tcg_gen_ld_i64(tmp, cpu_env,
5899 offsetof(CPUMIPSState, CP0_EntryLo1));
5900#if defined(TARGET_MIPS64)
5901 if (ctx->rxi) {
5902
5903 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5904 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5905 }
5906#endif
5907 gen_move_low32(arg, tmp);
5908 tcg_temp_free_i64(tmp);
5909 }
5910 register_name = "EntryLo1";
5911 break;
5912 case CP0_REG03__GLOBALNUM:
5913 CP0_CHECK(ctx->vp);
5914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5915 register_name = "GlobalNumber";
5916 break;
5917 default:
5918 goto cp0_unimplemented;
5919 }
5920 break;
5921 case CP0_REGISTER_04:
5922 switch (sel) {
5923 case CP0_REG04__CONTEXT:
5924 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5925 tcg_gen_ext32s_tl(arg, arg);
5926 register_name = "Context";
5927 break;
5928 case CP0_REG04__CONTEXTCONFIG:
5929
5930
5931 register_name = "ContextConfig";
5932 goto cp0_unimplemented;
5933 case CP0_REG04__USERLOCAL:
5934 CP0_CHECK(ctx->ulri);
5935 tcg_gen_ld_tl(arg, cpu_env,
5936 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5937 tcg_gen_ext32s_tl(arg, arg);
5938 register_name = "UserLocal";
5939 break;
5940 case CP0_REG04__MMID:
5941 CP0_CHECK(ctx->mi);
5942 gen_helper_mtc0_memorymapid(cpu_env, arg);
5943 register_name = "MMID";
5944 break;
5945 default:
5946 goto cp0_unimplemented;
5947 }
5948 break;
5949 case CP0_REGISTER_05:
5950 switch (sel) {
5951 case CP0_REG05__PAGEMASK:
5952 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5953 register_name = "PageMask";
5954 break;
5955 case CP0_REG05__PAGEGRAIN:
5956 check_insn(ctx, ISA_MIPS_R2);
5957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5958 register_name = "PageGrain";
5959 break;
5960 case CP0_REG05__SEGCTL0:
5961 CP0_CHECK(ctx->sc);
5962 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5963 tcg_gen_ext32s_tl(arg, arg);
5964 register_name = "SegCtl0";
5965 break;
5966 case CP0_REG05__SEGCTL1:
5967 CP0_CHECK(ctx->sc);
5968 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5969 tcg_gen_ext32s_tl(arg, arg);
5970 register_name = "SegCtl1";
5971 break;
5972 case CP0_REG05__SEGCTL2:
5973 CP0_CHECK(ctx->sc);
5974 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5975 tcg_gen_ext32s_tl(arg, arg);
5976 register_name = "SegCtl2";
5977 break;
5978 case CP0_REG05__PWBASE:
5979 check_pw(ctx);
5980 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5981 register_name = "PWBase";
5982 break;
5983 case CP0_REG05__PWFIELD:
5984 check_pw(ctx);
5985 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5986 register_name = "PWField";
5987 break;
5988 case CP0_REG05__PWSIZE:
5989 check_pw(ctx);
5990 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5991 register_name = "PWSize";
5992 break;
5993 default:
5994 goto cp0_unimplemented;
5995 }
5996 break;
5997 case CP0_REGISTER_06:
5998 switch (sel) {
5999 case CP0_REG06__WIRED:
6000 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6001 register_name = "Wired";
6002 break;
6003 case CP0_REG06__SRSCONF0:
6004 check_insn(ctx, ISA_MIPS_R2);
6005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6006 register_name = "SRSConf0";
6007 break;
6008 case CP0_REG06__SRSCONF1:
6009 check_insn(ctx, ISA_MIPS_R2);
6010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6011 register_name = "SRSConf1";
6012 break;
6013 case CP0_REG06__SRSCONF2:
6014 check_insn(ctx, ISA_MIPS_R2);
6015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6016 register_name = "SRSConf2";
6017 break;
6018 case CP0_REG06__SRSCONF3:
6019 check_insn(ctx, ISA_MIPS_R2);
6020 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6021 register_name = "SRSConf3";
6022 break;
6023 case CP0_REG06__SRSCONF4:
6024 check_insn(ctx, ISA_MIPS_R2);
6025 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6026 register_name = "SRSConf4";
6027 break;
6028 case CP0_REG06__PWCTL:
6029 check_pw(ctx);
6030 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6031 register_name = "PWCtl";
6032 break;
6033 default:
6034 goto cp0_unimplemented;
6035 }
6036 break;
6037 case CP0_REGISTER_07:
6038 switch (sel) {
6039 case CP0_REG07__HWRENA:
6040 check_insn(ctx, ISA_MIPS_R2);
6041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6042 register_name = "HWREna";
6043 break;
6044 default:
6045 goto cp0_unimplemented;
6046 }
6047 break;
6048 case CP0_REGISTER_08:
6049 switch (sel) {
6050 case CP0_REG08__BADVADDR:
6051 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6052 tcg_gen_ext32s_tl(arg, arg);
6053 register_name = "BadVAddr";
6054 break;
6055 case CP0_REG08__BADINSTR:
6056 CP0_CHECK(ctx->bi);
6057 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6058 register_name = "BadInstr";
6059 break;
6060 case CP0_REG08__BADINSTRP:
6061 CP0_CHECK(ctx->bp);
6062 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6063 register_name = "BadInstrP";
6064 break;
6065 case CP0_REG08__BADINSTRX:
6066 CP0_CHECK(ctx->bi);
6067 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6068 tcg_gen_andi_tl(arg, arg, ~0xffff);
6069 register_name = "BadInstrX";
6070 break;
6071 default:
6072 goto cp0_unimplemented;
6073 }
6074 break;
6075 case CP0_REGISTER_09:
6076 switch (sel) {
6077 case CP0_REG09__COUNT:
6078
6079 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6080 gen_io_start();
6081 }
6082 gen_helper_mfc0_count(arg, cpu_env);
6083
6084
6085
6086
6087
6088 gen_save_pc(ctx->base.pc_next + 4);
6089 ctx->base.is_jmp = DISAS_EXIT;
6090 register_name = "Count";
6091 break;
6092 case CP0_REG09__SAARI:
6093 CP0_CHECK(ctx->saar);
6094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
6095 register_name = "SAARI";
6096 break;
6097 case CP0_REG09__SAAR:
6098 CP0_CHECK(ctx->saar);
6099 gen_helper_mfc0_saar(arg, cpu_env);
6100 register_name = "SAAR";
6101 break;
6102 default:
6103 goto cp0_unimplemented;
6104 }
6105 break;
6106 case CP0_REGISTER_10:
6107 switch (sel) {
6108 case CP0_REG10__ENTRYHI:
6109 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6110 tcg_gen_ext32s_tl(arg, arg);
6111 register_name = "EntryHi";
6112 break;
6113 default:
6114 goto cp0_unimplemented;
6115 }
6116 break;
6117 case CP0_REGISTER_11:
6118 switch (sel) {
6119 case CP0_REG11__COMPARE:
6120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6121 register_name = "Compare";
6122 break;
6123
6124 default:
6125 goto cp0_unimplemented;
6126 }
6127 break;
6128 case CP0_REGISTER_12:
6129 switch (sel) {
6130 case CP0_REG12__STATUS:
6131 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6132 register_name = "Status";
6133 break;
6134 case CP0_REG12__INTCTL:
6135 check_insn(ctx, ISA_MIPS_R2);
6136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6137 register_name = "IntCtl";
6138 break;
6139 case CP0_REG12__SRSCTL:
6140 check_insn(ctx, ISA_MIPS_R2);
6141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6142 register_name = "SRSCtl";
6143 break;
6144 case CP0_REG12__SRSMAP:
6145 check_insn(ctx, ISA_MIPS_R2);
6146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6147 register_name = "SRSMap";
6148 break;
6149 default:
6150 goto cp0_unimplemented;
6151 }
6152 break;
6153 case CP0_REGISTER_13:
6154 switch (sel) {
6155 case CP0_REG13__CAUSE:
6156 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6157 register_name = "Cause";
6158 break;
6159 default:
6160 goto cp0_unimplemented;
6161 }
6162 break;
6163 case CP0_REGISTER_14:
6164 switch (sel) {
6165 case CP0_REG14__EPC:
6166 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6167 tcg_gen_ext32s_tl(arg, arg);
6168 register_name = "EPC";
6169 break;
6170 default:
6171 goto cp0_unimplemented;
6172 }
6173 break;
6174 case CP0_REGISTER_15:
6175 switch (sel) {
6176 case CP0_REG15__PRID:
6177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6178 register_name = "PRid";
6179 break;
6180 case CP0_REG15__EBASE:
6181 check_insn(ctx, ISA_MIPS_R2);
6182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6183 tcg_gen_ext32s_tl(arg, arg);
6184 register_name = "EBase";
6185 break;
6186 case CP0_REG15__CMGCRBASE:
6187 check_insn(ctx, ISA_MIPS_R2);
6188 CP0_CHECK(ctx->cmgcr);
6189 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6190 tcg_gen_ext32s_tl(arg, arg);
6191 register_name = "CMGCRBase";
6192 break;
6193 default:
6194 goto cp0_unimplemented;
6195 }
6196 break;
6197 case CP0_REGISTER_16:
6198 switch (sel) {
6199 case CP0_REG16__CONFIG:
6200 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6201 register_name = "Config";
6202 break;
6203 case CP0_REG16__CONFIG1:
6204 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6205 register_name = "Config1";
6206 break;
6207 case CP0_REG16__CONFIG2:
6208 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6209 register_name = "Config2";
6210 break;
6211 case CP0_REG16__CONFIG3:
6212 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6213 register_name = "Config3";
6214 break;
6215 case CP0_REG16__CONFIG4:
6216 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6217 register_name = "Config4";
6218 break;
6219 case CP0_REG16__CONFIG5:
6220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6221 register_name = "Config5";
6222 break;
6223
6224 case CP0_REG16__CONFIG6:
6225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6226 register_name = "Config6";
6227 break;
6228 case CP0_REG16__CONFIG7:
6229 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6230 register_name = "Config7";
6231 break;
6232 default:
6233 goto cp0_unimplemented;
6234 }
6235 break;
6236 case CP0_REGISTER_17:
6237 switch (sel) {
6238 case CP0_REG17__LLADDR:
6239 gen_helper_mfc0_lladdr(arg, cpu_env);
6240 register_name = "LLAddr";
6241 break;
6242 case CP0_REG17__MAAR:
6243 CP0_CHECK(ctx->mrp);
6244 gen_helper_mfc0_maar(arg, cpu_env);
6245 register_name = "MAAR";
6246 break;
6247 case CP0_REG17__MAARI:
6248 CP0_CHECK(ctx->mrp);
6249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6250 register_name = "MAARI";
6251 break;
6252 default:
6253 goto cp0_unimplemented;
6254 }
6255 break;
6256 case CP0_REGISTER_18:
6257 switch (sel) {
6258 case CP0_REG18__WATCHLO0:
6259 case CP0_REG18__WATCHLO1:
6260 case CP0_REG18__WATCHLO2:
6261 case CP0_REG18__WATCHLO3:
6262 case CP0_REG18__WATCHLO4:
6263 case CP0_REG18__WATCHLO5:
6264 case CP0_REG18__WATCHLO6:
6265 case CP0_REG18__WATCHLO7:
6266 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6267 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6268 register_name = "WatchLo";
6269 break;
6270 default:
6271 goto cp0_unimplemented;
6272 }
6273 break;
6274 case CP0_REGISTER_19:
6275 switch (sel) {
6276 case CP0_REG19__WATCHHI0:
6277 case CP0_REG19__WATCHHI1:
6278 case CP0_REG19__WATCHHI2:
6279 case CP0_REG19__WATCHHI3:
6280 case CP0_REG19__WATCHHI4:
6281 case CP0_REG19__WATCHHI5:
6282 case CP0_REG19__WATCHHI6:
6283 case CP0_REG19__WATCHHI7:
6284 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6285 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6286 register_name = "WatchHi";
6287 break;
6288 default:
6289 goto cp0_unimplemented;
6290 }
6291 break;
6292 case CP0_REGISTER_20:
6293 switch (sel) {
6294 case CP0_REG20__XCONTEXT:
6295#if defined(TARGET_MIPS64)
6296 check_insn(ctx, ISA_MIPS3);
6297 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6298 tcg_gen_ext32s_tl(arg, arg);
6299 register_name = "XContext";
6300 break;
6301#endif
6302 default:
6303 goto cp0_unimplemented;
6304 }
6305 break;
6306 case CP0_REGISTER_21:
6307
6308 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6309 switch (sel) {
6310 case 0:
6311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6312 register_name = "Framemask";
6313 break;
6314 default:
6315 goto cp0_unimplemented;
6316 }
6317 break;
6318 case CP0_REGISTER_22:
6319 tcg_gen_movi_tl(arg, 0);
6320 register_name = "'Diagnostic";
6321 break;
6322 case CP0_REGISTER_23:
6323 switch (sel) {
6324 case CP0_REG23__DEBUG:
6325 gen_helper_mfc0_debug(arg, cpu_env);
6326 register_name = "Debug";
6327 break;
6328 case CP0_REG23__TRACECONTROL:
6329
6330
6331 register_name = "TraceControl";
6332 goto cp0_unimplemented;
6333 case CP0_REG23__TRACECONTROL2:
6334
6335
6336 register_name = "TraceControl2";
6337 goto cp0_unimplemented;
6338 case CP0_REG23__USERTRACEDATA1:
6339
6340
6341 register_name = "UserTraceData1";
6342 goto cp0_unimplemented;
6343 case CP0_REG23__TRACEIBPC:
6344
6345
6346 register_name = "TraceIBPC";
6347 goto cp0_unimplemented;
6348 case CP0_REG23__TRACEDBPC:
6349
6350
6351 register_name = "TraceDBPC";
6352 goto cp0_unimplemented;
6353 default:
6354 goto cp0_unimplemented;
6355 }
6356 break;
6357 case CP0_REGISTER_24:
6358 switch (sel) {
6359 case CP0_REG24__DEPC:
6360
6361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6362 tcg_gen_ext32s_tl(arg, arg);
6363 register_name = "DEPC";
6364 break;
6365 default:
6366 goto cp0_unimplemented;
6367 }
6368 break;
6369 case CP0_REGISTER_25:
6370 switch (sel) {
6371 case CP0_REG25__PERFCTL0:
6372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6373 register_name = "Performance0";
6374 break;
6375 case CP0_REG25__PERFCNT0:
6376
6377 register_name = "Performance1";
6378 goto cp0_unimplemented;
6379 case CP0_REG25__PERFCTL1:
6380
6381 register_name = "Performance2";
6382 goto cp0_unimplemented;
6383 case CP0_REG25__PERFCNT1:
6384
6385 register_name = "Performance3";
6386 goto cp0_unimplemented;
6387 case CP0_REG25__PERFCTL2:
6388
6389 register_name = "Performance4";
6390 goto cp0_unimplemented;
6391 case CP0_REG25__PERFCNT2:
6392
6393 register_name = "Performance5";
6394 goto cp0_unimplemented;
6395 case CP0_REG25__PERFCTL3:
6396
6397 register_name = "Performance6";
6398 goto cp0_unimplemented;
6399 case CP0_REG25__PERFCNT3:
6400
6401 register_name = "Performance7";
6402 goto cp0_unimplemented;
6403 default:
6404 goto cp0_unimplemented;
6405 }
6406 break;
6407 case CP0_REGISTER_26:
6408 switch (sel) {
6409 case CP0_REG26__ERRCTL:
6410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6411 register_name = "ErrCtl";
6412 break;
6413 default:
6414 goto cp0_unimplemented;
6415 }
6416 break;
6417 case CP0_REGISTER_27:
6418 switch (sel) {
6419 case CP0_REG27__CACHERR:
6420 tcg_gen_movi_tl(arg, 0);
6421 register_name = "CacheErr";
6422 break;
6423 default:
6424 goto cp0_unimplemented;
6425 }
6426 break;
6427 case CP0_REGISTER_28:
6428 switch (sel) {
6429 case CP0_REG28__TAGLO:
6430 case CP0_REG28__TAGLO1:
6431 case CP0_REG28__TAGLO2:
6432 case CP0_REG28__TAGLO3:
6433 {
6434 TCGv_i64 tmp = tcg_temp_new_i64();
6435 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6436 gen_move_low32(arg, tmp);
6437 tcg_temp_free_i64(tmp);
6438 }
6439 register_name = "TagLo";
6440 break;
6441 case CP0_REG28__DATALO:
6442 case CP0_REG28__DATALO1:
6443 case CP0_REG28__DATALO2:
6444 case CP0_REG28__DATALO3:
6445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6446 register_name = "DataLo";
6447 break;
6448 default:
6449 goto cp0_unimplemented;
6450 }
6451 break;
6452 case CP0_REGISTER_29:
6453 switch (sel) {
6454 case CP0_REG29__TAGHI:
6455 case CP0_REG29__TAGHI1:
6456 case CP0_REG29__TAGHI2:
6457 case CP0_REG29__TAGHI3:
6458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6459 register_name = "TagHi";
6460 break;
6461 case CP0_REG29__DATAHI:
6462 case CP0_REG29__DATAHI1:
6463 case CP0_REG29__DATAHI2:
6464 case CP0_REG29__DATAHI3:
6465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6466 register_name = "DataHi";
6467 break;
6468 default:
6469 goto cp0_unimplemented;
6470 }
6471 break;
6472 case CP0_REGISTER_30:
6473 switch (sel) {
6474 case CP0_REG30__ERROREPC:
6475 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6476 tcg_gen_ext32s_tl(arg, arg);
6477 register_name = "ErrorEPC";
6478 break;
6479 default:
6480 goto cp0_unimplemented;
6481 }
6482 break;
6483 case CP0_REGISTER_31:
6484 switch (sel) {
6485 case CP0_REG31__DESAVE:
6486
6487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6488 register_name = "DESAVE";
6489 break;
6490 case CP0_REG31__KSCRATCH1:
6491 case CP0_REG31__KSCRATCH2:
6492 case CP0_REG31__KSCRATCH3:
6493 case CP0_REG31__KSCRATCH4:
6494 case CP0_REG31__KSCRATCH5:
6495 case CP0_REG31__KSCRATCH6:
6496 CP0_CHECK(ctx->kscrexist & (1 << sel));
6497 tcg_gen_ld_tl(arg, cpu_env,
6498 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6499 tcg_gen_ext32s_tl(arg, arg);
6500 register_name = "KScratch";
6501 break;
6502 default:
6503 goto cp0_unimplemented;
6504 }
6505 break;
6506 default:
6507 goto cp0_unimplemented;
6508 }
6509 trace_mips_translate_c0("mfc0", register_name, reg, sel);
6510 return;
6511
6512cp0_unimplemented:
6513 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6514 register_name, reg, sel);
6515 gen_mfc0_unimplemented(ctx, arg);
6516}
6517
6518static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6519{
6520 const char *register_name = "invalid";
6521
6522 if (sel != 0) {
6523 check_insn(ctx, ISA_MIPS_R1);
6524 }
6525
6526 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6527 gen_io_start();
6528 }
6529
6530 switch (reg) {
6531 case CP0_REGISTER_00:
6532 switch (sel) {
6533 case CP0_REG00__INDEX:
6534 gen_helper_mtc0_index(cpu_env, arg);
6535 register_name = "Index";
6536 break;
6537 case CP0_REG00__MVPCONTROL:
6538 CP0_CHECK(ctx->insn_flags & ASE_MT);
6539 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6540 register_name = "MVPControl";
6541 break;
6542 case CP0_REG00__MVPCONF0:
6543 CP0_CHECK(ctx->insn_flags & ASE_MT);
6544
6545 register_name = "MVPConf0";
6546 break;
6547 case CP0_REG00__MVPCONF1:
6548 CP0_CHECK(ctx->insn_flags & ASE_MT);
6549
6550 register_name = "MVPConf1";
6551 break;
6552 case CP0_REG00__VPCONTROL:
6553 CP0_CHECK(ctx->vp);
6554
6555 register_name = "VPControl";
6556 break;
6557 default:
6558 goto cp0_unimplemented;
6559 }
6560 break;
6561 case CP0_REGISTER_01:
6562 switch (sel) {
6563 case CP0_REG01__RANDOM:
6564
6565 register_name = "Random";
6566 break;
6567 case CP0_REG01__VPECONTROL:
6568 CP0_CHECK(ctx->insn_flags & ASE_MT);
6569 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6570 register_name = "VPEControl";
6571 break;
6572 case CP0_REG01__VPECONF0:
6573 CP0_CHECK(ctx->insn_flags & ASE_MT);
6574 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6575 register_name = "VPEConf0";
6576 break;
6577 case CP0_REG01__VPECONF1:
6578 CP0_CHECK(ctx->insn_flags & ASE_MT);
6579 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6580 register_name = "VPEConf1";
6581 break;
6582 case CP0_REG01__YQMASK:
6583 CP0_CHECK(ctx->insn_flags & ASE_MT);
6584 gen_helper_mtc0_yqmask(cpu_env, arg);
6585 register_name = "YQMask";
6586 break;
6587 case CP0_REG01__VPESCHEDULE:
6588 CP0_CHECK(ctx->insn_flags & ASE_MT);
6589 tcg_gen_st_tl(arg, cpu_env,
6590 offsetof(CPUMIPSState, CP0_VPESchedule));
6591 register_name = "VPESchedule";
6592 break;
6593 case CP0_REG01__VPESCHEFBACK:
6594 CP0_CHECK(ctx->insn_flags & ASE_MT);
6595 tcg_gen_st_tl(arg, cpu_env,
6596 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6597 register_name = "VPEScheFBack";
6598 break;
6599 case CP0_REG01__VPEOPT:
6600 CP0_CHECK(ctx->insn_flags & ASE_MT);
6601 gen_helper_mtc0_vpeopt(cpu_env, arg);
6602 register_name = "VPEOpt";
6603 break;
6604 default:
6605 goto cp0_unimplemented;
6606 }
6607 break;
6608 case CP0_REGISTER_02:
6609 switch (sel) {
6610 case CP0_REG02__ENTRYLO0:
6611 gen_helper_mtc0_entrylo0(cpu_env, arg);
6612 register_name = "EntryLo0";
6613 break;
6614 case CP0_REG02__TCSTATUS:
6615 CP0_CHECK(ctx->insn_flags & ASE_MT);
6616 gen_helper_mtc0_tcstatus(cpu_env, arg);
6617 register_name = "TCStatus";
6618 break;
6619 case CP0_REG02__TCBIND:
6620 CP0_CHECK(ctx->insn_flags & ASE_MT);
6621 gen_helper_mtc0_tcbind(cpu_env, arg);
6622 register_name = "TCBind";
6623 break;
6624 case CP0_REG02__TCRESTART:
6625 CP0_CHECK(ctx->insn_flags & ASE_MT);
6626 gen_helper_mtc0_tcrestart(cpu_env, arg);
6627 register_name = "TCRestart";
6628 break;
6629 case CP0_REG02__TCHALT:
6630 CP0_CHECK(ctx->insn_flags & ASE_MT);
6631 gen_helper_mtc0_tchalt(cpu_env, arg);
6632 register_name = "TCHalt";
6633 break;
6634 case CP0_REG02__TCCONTEXT:
6635 CP0_CHECK(ctx->insn_flags & ASE_MT);
6636 gen_helper_mtc0_tccontext(cpu_env, arg);
6637 register_name = "TCContext";
6638 break;
6639 case CP0_REG02__TCSCHEDULE:
6640 CP0_CHECK(ctx->insn_flags & ASE_MT);
6641 gen_helper_mtc0_tcschedule(cpu_env, arg);
6642 register_name = "TCSchedule";
6643 break;
6644 case CP0_REG02__TCSCHEFBACK:
6645 CP0_CHECK(ctx->insn_flags & ASE_MT);
6646 gen_helper_mtc0_tcschefback(cpu_env, arg);
6647 register_name = "TCScheFBack";
6648 break;
6649 default:
6650 goto cp0_unimplemented;
6651 }
6652 break;
6653 case CP0_REGISTER_03:
6654 switch (sel) {
6655 case CP0_REG03__ENTRYLO1:
6656 gen_helper_mtc0_entrylo1(cpu_env, arg);
6657 register_name = "EntryLo1";
6658 break;
6659 case CP0_REG03__GLOBALNUM:
6660 CP0_CHECK(ctx->vp);
6661
6662 register_name = "GlobalNumber";
6663 break;
6664 default:
6665 goto cp0_unimplemented;
6666 }
6667 break;
6668 case CP0_REGISTER_04:
6669 switch (sel) {
6670 case CP0_REG04__CONTEXT:
6671 gen_helper_mtc0_context(cpu_env, arg);
6672 register_name = "Context";
6673 break;
6674 case CP0_REG04__CONTEXTCONFIG:
6675
6676
6677 register_name = "ContextConfig";
6678 goto cp0_unimplemented;
6679 case CP0_REG04__USERLOCAL:
6680 CP0_CHECK(ctx->ulri);
6681 tcg_gen_st_tl(arg, cpu_env,
6682 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6683 register_name = "UserLocal";
6684 break;
6685 case CP0_REG04__MMID:
6686 CP0_CHECK(ctx->mi);
6687 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6688 register_name = "MMID";
6689 break;
6690 default:
6691 goto cp0_unimplemented;
6692 }
6693 break;
6694 case CP0_REGISTER_05:
6695 switch (sel) {
6696 case CP0_REG05__PAGEMASK:
6697 gen_helper_mtc0_pagemask(cpu_env, arg);
6698 register_name = "PageMask";
6699 break;
6700 case CP0_REG05__PAGEGRAIN:
6701 check_insn(ctx, ISA_MIPS_R2);
6702 gen_helper_mtc0_pagegrain(cpu_env, arg);
6703 register_name = "PageGrain";
6704 ctx->base.is_jmp = DISAS_STOP;
6705 break;
6706 case CP0_REG05__SEGCTL0:
6707 CP0_CHECK(ctx->sc);
6708 gen_helper_mtc0_segctl0(cpu_env, arg);
6709 register_name = "SegCtl0";
6710 break;
6711 case CP0_REG05__SEGCTL1:
6712 CP0_CHECK(ctx->sc);
6713 gen_helper_mtc0_segctl1(cpu_env, arg);
6714 register_name = "SegCtl1";
6715 break;
6716 case CP0_REG05__SEGCTL2:
6717 CP0_CHECK(ctx->sc);
6718 gen_helper_mtc0_segctl2(cpu_env, arg);
6719 register_name = "SegCtl2";
6720 break;
6721 case CP0_REG05__PWBASE:
6722 check_pw(ctx);
6723 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6724 register_name = "PWBase";
6725 break;
6726 case CP0_REG05__PWFIELD:
6727 check_pw(ctx);
6728 gen_helper_mtc0_pwfield(cpu_env, arg);
6729 register_name = "PWField";
6730 break;
6731 case CP0_REG05__PWSIZE:
6732 check_pw(ctx);
6733 gen_helper_mtc0_pwsize(cpu_env, arg);
6734 register_name = "PWSize";
6735 break;
6736 default:
6737 goto cp0_unimplemented;
6738 }
6739 break;
6740 case CP0_REGISTER_06:
6741 switch (sel) {
6742 case CP0_REG06__WIRED:
6743 gen_helper_mtc0_wired(cpu_env, arg);
6744 register_name = "Wired";
6745 break;
6746 case CP0_REG06__SRSCONF0:
6747 check_insn(ctx, ISA_MIPS_R2);
6748 gen_helper_mtc0_srsconf0(cpu_env, arg);
6749 register_name = "SRSConf0";
6750 break;
6751 case CP0_REG06__SRSCONF1:
6752 check_insn(ctx, ISA_MIPS_R2);
6753 gen_helper_mtc0_srsconf1(cpu_env, arg);
6754 register_name = "SRSConf1";
6755 break;
6756 case CP0_REG06__SRSCONF2:
6757 check_insn(ctx, ISA_MIPS_R2);
6758 gen_helper_mtc0_srsconf2(cpu_env, arg);
6759 register_name = "SRSConf2";
6760 break;
6761 case CP0_REG06__SRSCONF3:
6762 check_insn(ctx, ISA_MIPS_R2);
6763 gen_helper_mtc0_srsconf3(cpu_env, arg);
6764 register_name = "SRSConf3";
6765 break;
6766 case CP0_REG06__SRSCONF4:
6767 check_insn(ctx, ISA_MIPS_R2);
6768 gen_helper_mtc0_srsconf4(cpu_env, arg);
6769 register_name = "SRSConf4";
6770 break;
6771 case CP0_REG06__PWCTL:
6772 check_pw(ctx);
6773 gen_helper_mtc0_pwctl(cpu_env, arg);
6774 register_name = "PWCtl";
6775 break;
6776 default:
6777 goto cp0_unimplemented;
6778 }
6779 break;
6780 case CP0_REGISTER_07:
6781 switch (sel) {
6782 case CP0_REG07__HWRENA:
6783 check_insn(ctx, ISA_MIPS_R2);
6784 gen_helper_mtc0_hwrena(cpu_env, arg);
6785 ctx->base.is_jmp = DISAS_STOP;
6786 register_name = "HWREna";
6787 break;
6788 default:
6789 goto cp0_unimplemented;
6790 }
6791 break;
6792 case CP0_REGISTER_08:
6793 switch (sel) {
6794 case CP0_REG08__BADVADDR:
6795
6796 register_name = "BadVAddr";
6797 break;
6798 case CP0_REG08__BADINSTR:
6799
6800 register_name = "BadInstr";
6801 break;
6802 case CP0_REG08__BADINSTRP:
6803
6804 register_name = "BadInstrP";
6805 break;
6806 case CP0_REG08__BADINSTRX:
6807
6808 register_name = "BadInstrX";
6809 break;
6810 default:
6811 goto cp0_unimplemented;
6812 }
6813 break;
6814 case CP0_REGISTER_09:
6815 switch (sel) {
6816 case CP0_REG09__COUNT:
6817 gen_helper_mtc0_count(cpu_env, arg);
6818 register_name = "Count";
6819 break;
6820 case CP0_REG09__SAARI:
6821 CP0_CHECK(ctx->saar);
6822 gen_helper_mtc0_saari(cpu_env, arg);
6823 register_name = "SAARI";
6824 break;
6825 case CP0_REG09__SAAR:
6826 CP0_CHECK(ctx->saar);
6827 gen_helper_mtc0_saar(cpu_env, arg);
6828 register_name = "SAAR";
6829 break;
6830 default:
6831 goto cp0_unimplemented;
6832 }
6833 break;
6834 case CP0_REGISTER_10:
6835 switch (sel) {
6836 case CP0_REG10__ENTRYHI:
6837 gen_helper_mtc0_entryhi(cpu_env, arg);
6838 register_name = "EntryHi";
6839 break;
6840 default:
6841 goto cp0_unimplemented;
6842 }
6843 break;
6844 case CP0_REGISTER_11:
6845 switch (sel) {
6846 case CP0_REG11__COMPARE:
6847 gen_helper_mtc0_compare(cpu_env, arg);
6848 register_name = "Compare";
6849 break;
6850
6851 default:
6852 goto cp0_unimplemented;
6853 }
6854 break;
6855 case CP0_REGISTER_12:
6856 switch (sel) {
6857 case CP0_REG12__STATUS:
6858 save_cpu_state(ctx, 1);
6859 gen_helper_mtc0_status(cpu_env, arg);
6860
6861 gen_save_pc(ctx->base.pc_next + 4);
6862 ctx->base.is_jmp = DISAS_EXIT;
6863 register_name = "Status";
6864 break;
6865 case CP0_REG12__INTCTL:
6866 check_insn(ctx, ISA_MIPS_R2);
6867 gen_helper_mtc0_intctl(cpu_env, arg);
6868
6869 ctx->base.is_jmp = DISAS_STOP;
6870 register_name = "IntCtl";
6871 break;
6872 case CP0_REG12__SRSCTL:
6873 check_insn(ctx, ISA_MIPS_R2);
6874 gen_helper_mtc0_srsctl(cpu_env, arg);
6875
6876 ctx->base.is_jmp = DISAS_STOP;
6877 register_name = "SRSCtl";
6878 break;
6879 case CP0_REG12__SRSMAP:
6880 check_insn(ctx, ISA_MIPS_R2);
6881 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6882
6883 ctx->base.is_jmp = DISAS_STOP;
6884 register_name = "SRSMap";
6885 break;
6886 default:
6887 goto cp0_unimplemented;
6888 }
6889 break;
6890 case CP0_REGISTER_13:
6891 switch (sel) {
6892 case CP0_REG13__CAUSE:
6893 save_cpu_state(ctx, 1);
6894 gen_helper_mtc0_cause(cpu_env, arg);
6895
6896
6897
6898
6899
6900 gen_save_pc(ctx->base.pc_next + 4);
6901 ctx->base.is_jmp = DISAS_EXIT;
6902 register_name = "Cause";
6903 break;
6904 default:
6905 goto cp0_unimplemented;
6906 }
6907 break;
6908 case CP0_REGISTER_14:
6909 switch (sel) {
6910 case CP0_REG14__EPC:
6911 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6912 register_name = "EPC";
6913 break;
6914 default:
6915 goto cp0_unimplemented;
6916 }
6917 break;
6918 case CP0_REGISTER_15:
6919 switch (sel) {
6920 case CP0_REG15__PRID:
6921
6922 register_name = "PRid";
6923 break;
6924 case CP0_REG15__EBASE:
6925 check_insn(ctx, ISA_MIPS_R2);
6926 gen_helper_mtc0_ebase(cpu_env, arg);
6927 register_name = "EBase";
6928 break;
6929 default:
6930 goto cp0_unimplemented;
6931 }
6932 break;
6933 case CP0_REGISTER_16:
6934 switch (sel) {
6935 case CP0_REG16__CONFIG:
6936 gen_helper_mtc0_config0(cpu_env, arg);
6937 register_name = "Config";
6938
6939 ctx->base.is_jmp = DISAS_STOP;
6940 break;
6941 case CP0_REG16__CONFIG1:
6942
6943 register_name = "Config1";
6944 break;
6945 case CP0_REG16__CONFIG2:
6946 gen_helper_mtc0_config2(cpu_env, arg);
6947 register_name = "Config2";
6948
6949 ctx->base.is_jmp = DISAS_STOP;
6950 break;
6951 case CP0_REG16__CONFIG3:
6952 gen_helper_mtc0_config3(cpu_env, arg);
6953 register_name = "Config3";
6954
6955 ctx->base.is_jmp = DISAS_STOP;
6956 break;
6957 case CP0_REG16__CONFIG4:
6958 gen_helper_mtc0_config4(cpu_env, arg);
6959 register_name = "Config4";
6960 ctx->base.is_jmp = DISAS_STOP;
6961 break;
6962 case CP0_REG16__CONFIG5:
6963 gen_helper_mtc0_config5(cpu_env, arg);
6964 register_name = "Config5";
6965
6966 ctx->base.is_jmp = DISAS_STOP;
6967 break;
6968
6969 case CP0_REG16__CONFIG6:
6970
6971 register_name = "Config6";
6972 break;
6973 case CP0_REG16__CONFIG7:
6974
6975 register_name = "Config7";
6976 break;
6977 default:
6978 register_name = "Invalid config selector";
6979 goto cp0_unimplemented;
6980 }
6981 break;
6982 case CP0_REGISTER_17:
6983 switch (sel) {
6984 case CP0_REG17__LLADDR:
6985 gen_helper_mtc0_lladdr(cpu_env, arg);
6986 register_name = "LLAddr";
6987 break;
6988 case CP0_REG17__MAAR:
6989 CP0_CHECK(ctx->mrp);
6990 gen_helper_mtc0_maar(cpu_env, arg);
6991 register_name = "MAAR";
6992 break;
6993 case CP0_REG17__MAARI:
6994 CP0_CHECK(ctx->mrp);
6995 gen_helper_mtc0_maari(cpu_env, arg);
6996 register_name = "MAARI";
6997 break;
6998 default:
6999 goto cp0_unimplemented;
7000 }
7001 break;
7002 case CP0_REGISTER_18:
7003 switch (sel) {
7004 case CP0_REG18__WATCHLO0:
7005 case CP0_REG18__WATCHLO1:
7006 case CP0_REG18__WATCHLO2:
7007 case CP0_REG18__WATCHLO3:
7008 case CP0_REG18__WATCHLO4:
7009 case CP0_REG18__WATCHLO5:
7010 case CP0_REG18__WATCHLO6:
7011 case CP0_REG18__WATCHLO7:
7012 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7013 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7014 register_name = "WatchLo";
7015 break;
7016 default:
7017 goto cp0_unimplemented;
7018 }
7019 break;
7020 case CP0_REGISTER_19:
7021 switch (sel) {
7022 case CP0_REG19__WATCHHI0:
7023 case CP0_REG19__WATCHHI1:
7024 case CP0_REG19__WATCHHI2:
7025 case CP0_REG19__WATCHHI3:
7026 case CP0_REG19__WATCHHI4:
7027 case CP0_REG19__WATCHHI5:
7028 case CP0_REG19__WATCHHI6:
7029 case CP0_REG19__WATCHHI7:
7030 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7031 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7032 register_name = "WatchHi";
7033 break;
7034 default:
7035 goto cp0_unimplemented;
7036 }
7037 break;
7038 case CP0_REGISTER_20:
7039 switch (sel) {
7040 case CP0_REG20__XCONTEXT:
7041#if defined(TARGET_MIPS64)
7042 check_insn(ctx, ISA_MIPS3);
7043 gen_helper_mtc0_xcontext(cpu_env, arg);
7044 register_name = "XContext";
7045 break;
7046#endif
7047 default:
7048 goto cp0_unimplemented;
7049 }
7050 break;
7051 case CP0_REGISTER_21:
7052
7053 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7054 switch (sel) {
7055 case 0:
7056 gen_helper_mtc0_framemask(cpu_env, arg);
7057 register_name = "Framemask";
7058 break;
7059 default:
7060 goto cp0_unimplemented;
7061 }
7062 break;
7063 case CP0_REGISTER_22:
7064
7065 register_name = "Diagnostic";
7066 break;
7067 case CP0_REGISTER_23:
7068 switch (sel) {
7069 case CP0_REG23__DEBUG:
7070 gen_helper_mtc0_debug(cpu_env, arg);
7071
7072 gen_save_pc(ctx->base.pc_next + 4);
7073 ctx->base.is_jmp = DISAS_EXIT;
7074 register_name = "Debug";
7075 break;
7076 case CP0_REG23__TRACECONTROL:
7077
7078
7079 register_name = "TraceControl";
7080
7081 ctx->base.is_jmp = DISAS_STOP;
7082 goto cp0_unimplemented;
7083 case CP0_REG23__TRACECONTROL2:
7084
7085
7086 register_name = "TraceControl2";
7087
7088 ctx->base.is_jmp = DISAS_STOP;
7089 goto cp0_unimplemented;
7090 case CP0_REG23__USERTRACEDATA1:
7091
7092 ctx->base.is_jmp = DISAS_STOP;
7093
7094
7095 register_name = "UserTraceData";
7096
7097 ctx->base.is_jmp = DISAS_STOP;
7098 goto cp0_unimplemented;
7099 case CP0_REG23__TRACEIBPC:
7100
7101
7102
7103 ctx->base.is_jmp = DISAS_STOP;
7104 register_name = "TraceIBPC";
7105 goto cp0_unimplemented;
7106 case CP0_REG23__TRACEDBPC:
7107
7108
7109
7110 ctx->base.is_jmp = DISAS_STOP;
7111 register_name = "TraceDBPC";
7112 goto cp0_unimplemented;
7113 default:
7114 goto cp0_unimplemented;
7115 }
7116 break;
7117 case CP0_REGISTER_24:
7118 switch (sel) {
7119 case CP0_REG24__DEPC:
7120
7121 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7122 register_name = "DEPC";
7123 break;
7124 default:
7125 goto cp0_unimplemented;
7126 }
7127 break;
7128 case CP0_REGISTER_25:
7129 switch (sel) {
7130 case CP0_REG25__PERFCTL0:
7131 gen_helper_mtc0_performance0(cpu_env, arg);
7132 register_name = "Performance0";
7133 break;
7134 case CP0_REG25__PERFCNT0:
7135
7136 register_name = "Performance1";
7137 goto cp0_unimplemented;
7138 case CP0_REG25__PERFCTL1:
7139
7140 register_name = "Performance2";
7141 goto cp0_unimplemented;
7142 case CP0_REG25__PERFCNT1:
7143
7144 register_name = "Performance3";
7145 goto cp0_unimplemented;
7146 case CP0_REG25__PERFCTL2:
7147
7148 register_name = "Performance4";
7149 goto cp0_unimplemented;
7150 case CP0_REG25__PERFCNT2:
7151
7152 register_name = "Performance5";
7153 goto cp0_unimplemented;
7154 case CP0_REG25__PERFCTL3:
7155
7156 register_name = "Performance6";
7157 goto cp0_unimplemented;
7158 case CP0_REG25__PERFCNT3:
7159
7160 register_name = "Performance7";
7161 goto cp0_unimplemented;
7162 default:
7163 goto cp0_unimplemented;
7164 }
7165 break;
7166 case CP0_REGISTER_26:
7167 switch (sel) {
7168 case CP0_REG26__ERRCTL:
7169 gen_helper_mtc0_errctl(cpu_env, arg);
7170 ctx->base.is_jmp = DISAS_STOP;
7171 register_name = "ErrCtl";
7172 break;
7173 default:
7174 goto cp0_unimplemented;
7175 }
7176 break;
7177 case CP0_REGISTER_27:
7178 switch (sel) {
7179 case CP0_REG27__CACHERR:
7180
7181 register_name = "CacheErr";
7182 break;
7183 default:
7184 goto cp0_unimplemented;
7185 }
7186 break;
7187 case CP0_REGISTER_28:
7188 switch (sel) {
7189 case CP0_REG28__TAGLO:
7190 case CP0_REG28__TAGLO1:
7191 case CP0_REG28__TAGLO2:
7192 case CP0_REG28__TAGLO3:
7193 gen_helper_mtc0_taglo(cpu_env, arg);
7194 register_name = "TagLo";
7195 break;
7196 case CP0_REG28__DATALO:
7197 case CP0_REG28__DATALO1:
7198 case CP0_REG28__DATALO2:
7199 case CP0_REG28__DATALO3:
7200 gen_helper_mtc0_datalo(cpu_env, arg);
7201 register_name = "DataLo";
7202 break;
7203 default:
7204 goto cp0_unimplemented;
7205 }
7206 break;
7207 case CP0_REGISTER_29:
7208 switch (sel) {
7209 case CP0_REG29__TAGHI:
7210 case CP0_REG29__TAGHI1:
7211 case CP0_REG29__TAGHI2:
7212 case CP0_REG29__TAGHI3:
7213 gen_helper_mtc0_taghi(cpu_env, arg);
7214 register_name = "TagHi";
7215 break;
7216 case CP0_REG29__DATAHI:
7217 case CP0_REG29__DATAHI1:
7218 case CP0_REG29__DATAHI2:
7219 case CP0_REG29__DATAHI3:
7220 gen_helper_mtc0_datahi(cpu_env, arg);
7221 register_name = "DataHi";
7222 break;
7223 default:
7224 register_name = "invalid sel";
7225 goto cp0_unimplemented;
7226 }
7227 break;
7228 case CP0_REGISTER_30:
7229 switch (sel) {
7230 case CP0_REG30__ERROREPC:
7231 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7232 register_name = "ErrorEPC";
7233 break;
7234 default:
7235 goto cp0_unimplemented;
7236 }
7237 break;
7238 case CP0_REGISTER_31:
7239 switch (sel) {
7240 case CP0_REG31__DESAVE:
7241
7242 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7243 register_name = "DESAVE";
7244 break;
7245 case CP0_REG31__KSCRATCH1:
7246 case CP0_REG31__KSCRATCH2:
7247 case CP0_REG31__KSCRATCH3:
7248 case CP0_REG31__KSCRATCH4:
7249 case CP0_REG31__KSCRATCH5:
7250 case CP0_REG31__KSCRATCH6:
7251 CP0_CHECK(ctx->kscrexist & (1 << sel));
7252 tcg_gen_st_tl(arg, cpu_env,
7253 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7254 register_name = "KScratch";
7255 break;
7256 default:
7257 goto cp0_unimplemented;
7258 }
7259 break;
7260 default:
7261 goto cp0_unimplemented;
7262 }
7263 trace_mips_translate_c0("mtc0", register_name, reg, sel);
7264
7265
7266 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7267
7268
7269
7270
7271 gen_save_pc(ctx->base.pc_next + 4);
7272 ctx->base.is_jmp = DISAS_EXIT;
7273 }
7274 return;
7275
7276cp0_unimplemented:
7277 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7278 register_name, reg, sel);
7279}
7280
7281#if defined(TARGET_MIPS64)
7282static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7283{
7284 const char *register_name = "invalid";
7285
7286 if (sel != 0) {
7287 check_insn(ctx, ISA_MIPS_R1);
7288 }
7289
7290 switch (reg) {
7291 case CP0_REGISTER_00:
7292 switch (sel) {
7293 case CP0_REG00__INDEX:
7294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7295 register_name = "Index";
7296 break;
7297 case CP0_REG00__MVPCONTROL:
7298 CP0_CHECK(ctx->insn_flags & ASE_MT);
7299 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7300 register_name = "MVPControl";
7301 break;
7302 case CP0_REG00__MVPCONF0:
7303 CP0_CHECK(ctx->insn_flags & ASE_MT);
7304 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7305 register_name = "MVPConf0";
7306 break;
7307 case CP0_REG00__MVPCONF1:
7308 CP0_CHECK(ctx->insn_flags & ASE_MT);
7309 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7310 register_name = "MVPConf1";
7311 break;
7312 case CP0_REG00__VPCONTROL:
7313 CP0_CHECK(ctx->vp);
7314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7315 register_name = "VPControl";
7316 break;
7317 default:
7318 goto cp0_unimplemented;
7319 }
7320 break;
7321 case CP0_REGISTER_01:
7322 switch (sel) {
7323 case CP0_REG01__RANDOM:
7324 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7325 gen_helper_mfc0_random(arg, cpu_env);
7326 register_name = "Random";
7327 break;
7328 case CP0_REG01__VPECONTROL:
7329 CP0_CHECK(ctx->insn_flags & ASE_MT);
7330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7331 register_name = "VPEControl";
7332 break;
7333 case CP0_REG01__VPECONF0:
7334 CP0_CHECK(ctx->insn_flags & ASE_MT);
7335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7336 register_name = "VPEConf0";
7337 break;
7338 case CP0_REG01__VPECONF1:
7339 CP0_CHECK(ctx->insn_flags & ASE_MT);
7340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7341 register_name = "VPEConf1";
7342 break;
7343 case CP0_REG01__YQMASK:
7344 CP0_CHECK(ctx->insn_flags & ASE_MT);
7345 tcg_gen_ld_tl(arg, cpu_env,
7346 offsetof(CPUMIPSState, CP0_YQMask));
7347 register_name = "YQMask";
7348 break;
7349 case CP0_REG01__VPESCHEDULE:
7350 CP0_CHECK(ctx->insn_flags & ASE_MT);
7351 tcg_gen_ld_tl(arg, cpu_env,
7352 offsetof(CPUMIPSState, CP0_VPESchedule));
7353 register_name = "VPESchedule";
7354 break;
7355 case CP0_REG01__VPESCHEFBACK:
7356 CP0_CHECK(ctx->insn_flags & ASE_MT);
7357 tcg_gen_ld_tl(arg, cpu_env,
7358 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7359 register_name = "VPEScheFBack";
7360 break;
7361 case CP0_REG01__VPEOPT:
7362 CP0_CHECK(ctx->insn_flags & ASE_MT);
7363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7364 register_name = "VPEOpt";
7365 break;
7366 default:
7367 goto cp0_unimplemented;
7368 }
7369 break;
7370 case CP0_REGISTER_02:
7371 switch (sel) {
7372 case CP0_REG02__ENTRYLO0:
7373 tcg_gen_ld_tl(arg, cpu_env,
7374 offsetof(CPUMIPSState, CP0_EntryLo0));
7375 register_name = "EntryLo0";
7376 break;
7377 case CP0_REG02__TCSTATUS:
7378 CP0_CHECK(ctx->insn_flags & ASE_MT);
7379 gen_helper_mfc0_tcstatus(arg, cpu_env);
7380 register_name = "TCStatus";
7381 break;
7382 case CP0_REG02__TCBIND:
7383 CP0_CHECK(ctx->insn_flags & ASE_MT);
7384 gen_helper_mfc0_tcbind(arg, cpu_env);
7385 register_name = "TCBind";
7386 break;
7387 case CP0_REG02__TCRESTART:
7388 CP0_CHECK(ctx->insn_flags & ASE_MT);
7389 gen_helper_dmfc0_tcrestart(arg, cpu_env);
7390 register_name = "TCRestart";
7391 break;
7392 case CP0_REG02__TCHALT:
7393 CP0_CHECK(ctx->insn_flags & ASE_MT);
7394 gen_helper_dmfc0_tchalt(arg, cpu_env);
7395 register_name = "TCHalt";
7396 break;
7397 case CP0_REG02__TCCONTEXT:
7398 CP0_CHECK(ctx->insn_flags & ASE_MT);
7399 gen_helper_dmfc0_tccontext(arg, cpu_env);
7400 register_name = "TCContext";
7401 break;
7402 case CP0_REG02__TCSCHEDULE:
7403 CP0_CHECK(ctx->insn_flags & ASE_MT);
7404 gen_helper_dmfc0_tcschedule(arg, cpu_env);
7405 register_name = "TCSchedule";
7406 break;
7407 case CP0_REG02__TCSCHEFBACK:
7408 CP0_CHECK(ctx->insn_flags & ASE_MT);
7409 gen_helper_dmfc0_tcschefback(arg, cpu_env);
7410 register_name = "TCScheFBack";
7411 break;
7412 default:
7413 goto cp0_unimplemented;
7414 }
7415 break;
7416 case CP0_REGISTER_03:
7417 switch (sel) {
7418 case CP0_REG03__ENTRYLO1:
7419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7420 register_name = "EntryLo1";
7421 break;
7422 case CP0_REG03__GLOBALNUM:
7423 CP0_CHECK(ctx->vp);
7424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7425 register_name = "GlobalNumber";
7426 break;
7427 default:
7428 goto cp0_unimplemented;
7429 }
7430 break;
7431 case CP0_REGISTER_04:
7432 switch (sel) {
7433 case CP0_REG04__CONTEXT:
7434 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7435 register_name = "Context";
7436 break;
7437 case CP0_REG04__CONTEXTCONFIG:
7438
7439
7440 register_name = "ContextConfig";
7441 goto cp0_unimplemented;
7442 case CP0_REG04__USERLOCAL:
7443 CP0_CHECK(ctx->ulri);
7444 tcg_gen_ld_tl(arg, cpu_env,
7445 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7446 register_name = "UserLocal";
7447 break;
7448 case CP0_REG04__MMID:
7449 CP0_CHECK(ctx->mi);
7450 gen_helper_mtc0_memorymapid(cpu_env, arg);
7451 register_name = "MMID";
7452 break;
7453 default:
7454 goto cp0_unimplemented;
7455 }
7456 break;
7457 case CP0_REGISTER_05:
7458 switch (sel) {
7459 case CP0_REG05__PAGEMASK:
7460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7461 register_name = "PageMask";
7462 break;
7463 case CP0_REG05__PAGEGRAIN:
7464 check_insn(ctx, ISA_MIPS_R2);
7465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7466 register_name = "PageGrain";
7467 break;
7468 case CP0_REG05__SEGCTL0:
7469 CP0_CHECK(ctx->sc);
7470 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7471 register_name = "SegCtl0";
7472 break;
7473 case CP0_REG05__SEGCTL1:
7474 CP0_CHECK(ctx->sc);
7475 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7476 register_name = "SegCtl1";
7477 break;
7478 case CP0_REG05__SEGCTL2:
7479 CP0_CHECK(ctx->sc);
7480 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7481 register_name = "SegCtl2";
7482 break;
7483 case CP0_REG05__PWBASE:
7484 check_pw(ctx);
7485 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7486 register_name = "PWBase";
7487 break;
7488 case CP0_REG05__PWFIELD:
7489 check_pw(ctx);
7490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7491 register_name = "PWField";
7492 break;
7493 case CP0_REG05__PWSIZE:
7494 check_pw(ctx);
7495 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7496 register_name = "PWSize";
7497 break;
7498 default:
7499 goto cp0_unimplemented;
7500 }
7501 break;
7502 case CP0_REGISTER_06:
7503 switch (sel) {
7504 case CP0_REG06__WIRED:
7505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7506 register_name = "Wired";
7507 break;
7508 case CP0_REG06__SRSCONF0:
7509 check_insn(ctx, ISA_MIPS_R2);
7510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7511 register_name = "SRSConf0";
7512 break;
7513 case CP0_REG06__SRSCONF1:
7514 check_insn(ctx, ISA_MIPS_R2);
7515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7516 register_name = "SRSConf1";
7517 break;
7518 case CP0_REG06__SRSCONF2:
7519 check_insn(ctx, ISA_MIPS_R2);
7520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7521 register_name = "SRSConf2";
7522 break;
7523 case CP0_REG06__SRSCONF3:
7524 check_insn(ctx, ISA_MIPS_R2);
7525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7526 register_name = "SRSConf3";
7527 break;
7528 case CP0_REG06__SRSCONF4:
7529 check_insn(ctx, ISA_MIPS_R2);
7530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7531 register_name = "SRSConf4";
7532 break;
7533 case CP0_REG06__PWCTL:
7534 check_pw(ctx);
7535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7536 register_name = "PWCtl";
7537 break;
7538 default:
7539 goto cp0_unimplemented;
7540 }
7541 break;
7542 case CP0_REGISTER_07:
7543 switch (sel) {
7544 case CP0_REG07__HWRENA:
7545 check_insn(ctx, ISA_MIPS_R2);
7546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7547 register_name = "HWREna";
7548 break;
7549 default:
7550 goto cp0_unimplemented;
7551 }
7552 break;
7553 case CP0_REGISTER_08:
7554 switch (sel) {
7555 case CP0_REG08__BADVADDR:
7556 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7557 register_name = "BadVAddr";
7558 break;
7559 case CP0_REG08__BADINSTR:
7560 CP0_CHECK(ctx->bi);
7561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7562 register_name = "BadInstr";
7563 break;
7564 case CP0_REG08__BADINSTRP:
7565 CP0_CHECK(ctx->bp);
7566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7567 register_name = "BadInstrP";
7568 break;
7569 case CP0_REG08__BADINSTRX:
7570 CP0_CHECK(ctx->bi);
7571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7572 tcg_gen_andi_tl(arg, arg, ~0xffff);
7573 register_name = "BadInstrX";
7574 break;
7575 default:
7576 goto cp0_unimplemented;
7577 }
7578 break;
7579 case CP0_REGISTER_09:
7580 switch (sel) {
7581 case CP0_REG09__COUNT:
7582
7583 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7584 gen_io_start();
7585 }
7586 gen_helper_mfc0_count(arg, cpu_env);
7587
7588
7589
7590
7591
7592 gen_save_pc(ctx->base.pc_next + 4);
7593 ctx->base.is_jmp = DISAS_EXIT;
7594 register_name = "Count";
7595 break;
7596 case CP0_REG09__SAARI:
7597 CP0_CHECK(ctx->saar);
7598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7599 register_name = "SAARI";
7600 break;
7601 case CP0_REG09__SAAR:
7602 CP0_CHECK(ctx->saar);
7603 gen_helper_dmfc0_saar(arg, cpu_env);
7604 register_name = "SAAR";
7605 break;
7606 default:
7607 goto cp0_unimplemented;
7608 }
7609 break;
7610 case CP0_REGISTER_10:
7611 switch (sel) {
7612 case CP0_REG10__ENTRYHI:
7613 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7614 register_name = "EntryHi";
7615 break;
7616 default:
7617 goto cp0_unimplemented;
7618 }
7619 break;
7620 case CP0_REGISTER_11:
7621 switch (sel) {
7622 case CP0_REG11__COMPARE:
7623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7624 register_name = "Compare";
7625 break;
7626
7627 default:
7628 goto cp0_unimplemented;
7629 }
7630 break;
7631 case CP0_REGISTER_12:
7632 switch (sel) {
7633 case CP0_REG12__STATUS:
7634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7635 register_name = "Status";
7636 break;
7637 case CP0_REG12__INTCTL:
7638 check_insn(ctx, ISA_MIPS_R2);
7639 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7640 register_name = "IntCtl";
7641 break;
7642 case CP0_REG12__SRSCTL:
7643 check_insn(ctx, ISA_MIPS_R2);
7644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7645 register_name = "SRSCtl";
7646 break;
7647 case CP0_REG12__SRSMAP:
7648 check_insn(ctx, ISA_MIPS_R2);
7649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7650 register_name = "SRSMap";
7651 break;
7652 default:
7653 goto cp0_unimplemented;
7654 }
7655 break;
7656 case CP0_REGISTER_13:
7657 switch (sel) {
7658 case CP0_REG13__CAUSE:
7659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7660 register_name = "Cause";
7661 break;
7662 default:
7663 goto cp0_unimplemented;
7664 }
7665 break;
7666 case CP0_REGISTER_14:
7667 switch (sel) {
7668 case CP0_REG14__EPC:
7669 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7670 register_name = "EPC";
7671 break;
7672 default:
7673 goto cp0_unimplemented;
7674 }
7675 break;
7676 case CP0_REGISTER_15:
7677 switch (sel) {
7678 case CP0_REG15__PRID:
7679 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7680 register_name = "PRid";
7681 break;
7682 case CP0_REG15__EBASE:
7683 check_insn(ctx, ISA_MIPS_R2);
7684 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7685 register_name = "EBase";
7686 break;
7687 case CP0_REG15__CMGCRBASE:
7688 check_insn(ctx, ISA_MIPS_R2);
7689 CP0_CHECK(ctx->cmgcr);
7690 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7691 register_name = "CMGCRBase";
7692 break;
7693 default:
7694 goto cp0_unimplemented;
7695 }
7696 break;
7697 case CP0_REGISTER_16:
7698 switch (sel) {
7699 case CP0_REG16__CONFIG:
7700 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7701 register_name = "Config";
7702 break;
7703 case CP0_REG16__CONFIG1:
7704 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7705 register_name = "Config1";
7706 break;
7707 case CP0_REG16__CONFIG2:
7708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7709 register_name = "Config2";
7710 break;
7711 case CP0_REG16__CONFIG3:
7712 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7713 register_name = "Config3";
7714 break;
7715 case CP0_REG16__CONFIG4:
7716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7717 register_name = "Config4";
7718 break;
7719 case CP0_REG16__CONFIG5:
7720 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7721 register_name = "Config5";
7722 break;
7723
7724 case CP0_REG16__CONFIG6:
7725 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7726 register_name = "Config6";
7727 break;
7728 case CP0_REG16__CONFIG7:
7729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7730 register_name = "Config7";
7731 break;
7732 default:
7733 goto cp0_unimplemented;
7734 }
7735 break;
7736 case CP0_REGISTER_17:
7737 switch (sel) {
7738 case CP0_REG17__LLADDR:
7739 gen_helper_dmfc0_lladdr(arg, cpu_env);
7740 register_name = "LLAddr";
7741 break;
7742 case CP0_REG17__MAAR:
7743 CP0_CHECK(ctx->mrp);
7744 gen_helper_dmfc0_maar(arg, cpu_env);
7745 register_name = "MAAR";
7746 break;
7747 case CP0_REG17__MAARI:
7748 CP0_CHECK(ctx->mrp);
7749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7750 register_name = "MAARI";
7751 break;
7752 default:
7753 goto cp0_unimplemented;
7754 }
7755 break;
7756 case CP0_REGISTER_18:
7757 switch (sel) {
7758 case CP0_REG18__WATCHLO0:
7759 case CP0_REG18__WATCHLO1:
7760 case CP0_REG18__WATCHLO2:
7761 case CP0_REG18__WATCHLO3:
7762 case CP0_REG18__WATCHLO4:
7763 case CP0_REG18__WATCHLO5:
7764 case CP0_REG18__WATCHLO6:
7765 case CP0_REG18__WATCHLO7:
7766 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7767 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7768 register_name = "WatchLo";
7769 break;
7770 default:
7771 goto cp0_unimplemented;
7772 }
7773 break;
7774 case CP0_REGISTER_19:
7775 switch (sel) {
7776 case CP0_REG19__WATCHHI0:
7777 case CP0_REG19__WATCHHI1:
7778 case CP0_REG19__WATCHHI2:
7779 case CP0_REG19__WATCHHI3:
7780 case CP0_REG19__WATCHHI4:
7781 case CP0_REG19__WATCHHI5:
7782 case CP0_REG19__WATCHHI6:
7783 case CP0_REG19__WATCHHI7:
7784 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7785 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7786 register_name = "WatchHi";
7787 break;
7788 default:
7789 goto cp0_unimplemented;
7790 }
7791 break;
7792 case CP0_REGISTER_20:
7793 switch (sel) {
7794 case CP0_REG20__XCONTEXT:
7795 check_insn(ctx, ISA_MIPS3);
7796 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7797 register_name = "XContext";
7798 break;
7799 default:
7800 goto cp0_unimplemented;
7801 }
7802 break;
7803 case CP0_REGISTER_21:
7804
7805 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7806 switch (sel) {
7807 case 0:
7808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7809 register_name = "Framemask";
7810 break;
7811 default:
7812 goto cp0_unimplemented;
7813 }
7814 break;
7815 case CP0_REGISTER_22:
7816 tcg_gen_movi_tl(arg, 0);
7817 register_name = "'Diagnostic";
7818 break;
7819 case CP0_REGISTER_23:
7820 switch (sel) {
7821 case CP0_REG23__DEBUG:
7822 gen_helper_mfc0_debug(arg, cpu_env);
7823 register_name = "Debug";
7824 break;
7825 case CP0_REG23__TRACECONTROL:
7826
7827
7828 register_name = "TraceControl";
7829 goto cp0_unimplemented;
7830 case CP0_REG23__TRACECONTROL2:
7831
7832
7833 register_name = "TraceControl2";
7834 goto cp0_unimplemented;
7835 case CP0_REG23__USERTRACEDATA1:
7836
7837
7838 register_name = "UserTraceData1";
7839 goto cp0_unimplemented;
7840 case CP0_REG23__TRACEIBPC:
7841
7842
7843 register_name = "TraceIBPC";
7844 goto cp0_unimplemented;
7845 case CP0_REG23__TRACEDBPC:
7846
7847
7848 register_name = "TraceDBPC";
7849 goto cp0_unimplemented;
7850 default:
7851 goto cp0_unimplemented;
7852 }
7853 break;
7854 case CP0_REGISTER_24:
7855 switch (sel) {
7856 case CP0_REG24__DEPC:
7857
7858 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7859 register_name = "DEPC";
7860 break;
7861 default:
7862 goto cp0_unimplemented;
7863 }
7864 break;
7865 case CP0_REGISTER_25:
7866 switch (sel) {
7867 case CP0_REG25__PERFCTL0:
7868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7869 register_name = "Performance0";
7870 break;
7871 case CP0_REG25__PERFCNT0:
7872
7873 register_name = "Performance1";
7874 goto cp0_unimplemented;
7875 case CP0_REG25__PERFCTL1:
7876
7877 register_name = "Performance2";
7878 goto cp0_unimplemented;
7879 case CP0_REG25__PERFCNT1:
7880
7881 register_name = "Performance3";
7882 goto cp0_unimplemented;
7883 case CP0_REG25__PERFCTL2:
7884
7885 register_name = "Performance4";
7886 goto cp0_unimplemented;
7887 case CP0_REG25__PERFCNT2:
7888
7889 register_name = "Performance5";
7890 goto cp0_unimplemented;
7891 case CP0_REG25__PERFCTL3:
7892
7893 register_name = "Performance6";
7894 goto cp0_unimplemented;
7895 case CP0_REG25__PERFCNT3:
7896
7897 register_name = "Performance7";
7898 goto cp0_unimplemented;
7899 default:
7900 goto cp0_unimplemented;
7901 }
7902 break;
7903 case CP0_REGISTER_26:
7904 switch (sel) {
7905 case CP0_REG26__ERRCTL:
7906 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7907 register_name = "ErrCtl";
7908 break;
7909 default:
7910 goto cp0_unimplemented;
7911 }
7912 break;
7913 case CP0_REGISTER_27:
7914 switch (sel) {
7915
7916 case CP0_REG27__CACHERR:
7917 tcg_gen_movi_tl(arg, 0);
7918 register_name = "CacheErr";
7919 break;
7920 default:
7921 goto cp0_unimplemented;
7922 }
7923 break;
7924 case CP0_REGISTER_28:
7925 switch (sel) {
7926 case CP0_REG28__TAGLO:
7927 case CP0_REG28__TAGLO1:
7928 case CP0_REG28__TAGLO2:
7929 case CP0_REG28__TAGLO3:
7930 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7931 register_name = "TagLo";
7932 break;
7933 case CP0_REG28__DATALO:
7934 case CP0_REG28__DATALO1:
7935 case CP0_REG28__DATALO2:
7936 case CP0_REG28__DATALO3:
7937 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7938 register_name = "DataLo";
7939 break;
7940 default:
7941 goto cp0_unimplemented;
7942 }
7943 break;
7944 case CP0_REGISTER_29:
7945 switch (sel) {
7946 case CP0_REG29__TAGHI:
7947 case CP0_REG29__TAGHI1:
7948 case CP0_REG29__TAGHI2:
7949 case CP0_REG29__TAGHI3:
7950 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7951 register_name = "TagHi";
7952 break;
7953 case CP0_REG29__DATAHI:
7954 case CP0_REG29__DATAHI1:
7955 case CP0_REG29__DATAHI2:
7956 case CP0_REG29__DATAHI3:
7957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7958 register_name = "DataHi";
7959 break;
7960 default:
7961 goto cp0_unimplemented;
7962 }
7963 break;
7964 case CP0_REGISTER_30:
7965 switch (sel) {
7966 case CP0_REG30__ERROREPC:
7967 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7968 register_name = "ErrorEPC";
7969 break;
7970 default:
7971 goto cp0_unimplemented;
7972 }
7973 break;
7974 case CP0_REGISTER_31:
7975 switch (sel) {
7976 case CP0_REG31__DESAVE:
7977
7978 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7979 register_name = "DESAVE";
7980 break;
7981 case CP0_REG31__KSCRATCH1:
7982 case CP0_REG31__KSCRATCH2:
7983 case CP0_REG31__KSCRATCH3:
7984 case CP0_REG31__KSCRATCH4:
7985 case CP0_REG31__KSCRATCH5:
7986 case CP0_REG31__KSCRATCH6:
7987 CP0_CHECK(ctx->kscrexist & (1 << sel));
7988 tcg_gen_ld_tl(arg, cpu_env,
7989 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7990 register_name = "KScratch";
7991 break;
7992 default:
7993 goto cp0_unimplemented;
7994 }
7995 break;
7996 default:
7997 goto cp0_unimplemented;
7998 }
7999 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8000 return;
8001
8002cp0_unimplemented:
8003 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8004 register_name, reg, sel);
8005 gen_mfc0_unimplemented(ctx, arg);
8006}
8007
8008static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8009{
8010 const char *register_name = "invalid";
8011
8012 if (sel != 0) {
8013 check_insn(ctx, ISA_MIPS_R1);
8014 }
8015
8016 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8017 gen_io_start();
8018 }
8019
8020 switch (reg) {
8021 case CP0_REGISTER_00:
8022 switch (sel) {
8023 case CP0_REG00__INDEX:
8024 gen_helper_mtc0_index(cpu_env, arg);
8025 register_name = "Index";
8026 break;
8027 case CP0_REG00__MVPCONTROL:
8028 CP0_CHECK(ctx->insn_flags & ASE_MT);
8029 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8030 register_name = "MVPControl";
8031 break;
8032 case CP0_REG00__MVPCONF0:
8033 CP0_CHECK(ctx->insn_flags & ASE_MT);
8034
8035 register_name = "MVPConf0";
8036 break;
8037 case CP0_REG00__MVPCONF1:
8038 CP0_CHECK(ctx->insn_flags & ASE_MT);
8039
8040 register_name = "MVPConf1";
8041 break;
8042 case CP0_REG00__VPCONTROL:
8043 CP0_CHECK(ctx->vp);
8044
8045 register_name = "VPControl";
8046 break;
8047 default:
8048 goto cp0_unimplemented;
8049 }
8050 break;
8051 case CP0_REGISTER_01:
8052 switch (sel) {
8053 case CP0_REG01__RANDOM:
8054
8055 register_name = "Random";
8056 break;
8057 case CP0_REG01__VPECONTROL:
8058 CP0_CHECK(ctx->insn_flags & ASE_MT);
8059 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8060 register_name = "VPEControl";
8061 break;
8062 case CP0_REG01__VPECONF0:
8063 CP0_CHECK(ctx->insn_flags & ASE_MT);
8064 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8065 register_name = "VPEConf0";
8066 break;
8067 case CP0_REG01__VPECONF1:
8068 CP0_CHECK(ctx->insn_flags & ASE_MT);
8069 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8070 register_name = "VPEConf1";
8071 break;
8072 case CP0_REG01__YQMASK:
8073 CP0_CHECK(ctx->insn_flags & ASE_MT);
8074 gen_helper_mtc0_yqmask(cpu_env, arg);
8075 register_name = "YQMask";
8076 break;
8077 case CP0_REG01__VPESCHEDULE:
8078 CP0_CHECK(ctx->insn_flags & ASE_MT);
8079 tcg_gen_st_tl(arg, cpu_env,
8080 offsetof(CPUMIPSState, CP0_VPESchedule));
8081 register_name = "VPESchedule";
8082 break;
8083 case CP0_REG01__VPESCHEFBACK:
8084 CP0_CHECK(ctx->insn_flags & ASE_MT);
8085 tcg_gen_st_tl(arg, cpu_env,
8086 offsetof(CPUMIPSState, CP0_VPEScheFBack));
8087 register_name = "VPEScheFBack";
8088 break;
8089 case CP0_REG01__VPEOPT:
8090 CP0_CHECK(ctx->insn_flags & ASE_MT);
8091 gen_helper_mtc0_vpeopt(cpu_env, arg);
8092 register_name = "VPEOpt";
8093 break;
8094 default:
8095 goto cp0_unimplemented;
8096 }
8097 break;
8098 case CP0_REGISTER_02:
8099 switch (sel) {
8100 case CP0_REG02__ENTRYLO0:
8101 gen_helper_dmtc0_entrylo0(cpu_env, arg);
8102 register_name = "EntryLo0";
8103 break;
8104 case CP0_REG02__TCSTATUS:
8105 CP0_CHECK(ctx->insn_flags & ASE_MT);
8106 gen_helper_mtc0_tcstatus(cpu_env, arg);
8107 register_name = "TCStatus";
8108 break;
8109 case CP0_REG02__TCBIND:
8110 CP0_CHECK(ctx->insn_flags & ASE_MT);
8111 gen_helper_mtc0_tcbind(cpu_env, arg);
8112 register_name = "TCBind";
8113 break;
8114 case CP0_REG02__TCRESTART:
8115 CP0_CHECK(ctx->insn_flags & ASE_MT);
8116 gen_helper_mtc0_tcrestart(cpu_env, arg);
8117 register_name = "TCRestart";
8118 break;
8119 case CP0_REG02__TCHALT:
8120 CP0_CHECK(ctx->insn_flags & ASE_MT);
8121 gen_helper_mtc0_tchalt(cpu_env, arg);
8122 register_name = "TCHalt";
8123 break;
8124 case CP0_REG02__TCCONTEXT:
8125 CP0_CHECK(ctx->insn_flags & ASE_MT);
8126 gen_helper_mtc0_tccontext(cpu_env, arg);
8127 register_name = "TCContext";
8128 break;
8129 case CP0_REG02__TCSCHEDULE:
8130 CP0_CHECK(ctx->insn_flags & ASE_MT);
8131 gen_helper_mtc0_tcschedule(cpu_env, arg);
8132 register_name = "TCSchedule";
8133 break;
8134 case CP0_REG02__TCSCHEFBACK:
8135 CP0_CHECK(ctx->insn_flags & ASE_MT);
8136 gen_helper_mtc0_tcschefback(cpu_env, arg);
8137 register_name = "TCScheFBack";
8138 break;
8139 default:
8140 goto cp0_unimplemented;
8141 }
8142 break;
8143 case CP0_REGISTER_03:
8144 switch (sel) {
8145 case CP0_REG03__ENTRYLO1:
8146 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8147 register_name = "EntryLo1";
8148 break;
8149 case CP0_REG03__GLOBALNUM:
8150 CP0_CHECK(ctx->vp);
8151
8152 register_name = "GlobalNumber";
8153 break;
8154 default:
8155 goto cp0_unimplemented;
8156 }
8157 break;
8158 case CP0_REGISTER_04:
8159 switch (sel) {
8160 case CP0_REG04__CONTEXT:
8161 gen_helper_mtc0_context(cpu_env, arg);
8162 register_name = "Context";
8163 break;
8164 case CP0_REG04__CONTEXTCONFIG:
8165
8166
8167 register_name = "ContextConfig";
8168 goto cp0_unimplemented;
8169 case CP0_REG04__USERLOCAL:
8170 CP0_CHECK(ctx->ulri);
8171 tcg_gen_st_tl(arg, cpu_env,
8172 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8173 register_name = "UserLocal";
8174 break;
8175 case CP0_REG04__MMID:
8176 CP0_CHECK(ctx->mi);
8177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8178 register_name = "MMID";
8179 break;
8180 default:
8181 goto cp0_unimplemented;
8182 }
8183 break;
8184 case CP0_REGISTER_05:
8185 switch (sel) {
8186 case CP0_REG05__PAGEMASK:
8187 gen_helper_mtc0_pagemask(cpu_env, arg);
8188 register_name = "PageMask";
8189 break;
8190 case CP0_REG05__PAGEGRAIN:
8191 check_insn(ctx, ISA_MIPS_R2);
8192 gen_helper_mtc0_pagegrain(cpu_env, arg);
8193 register_name = "PageGrain";
8194 break;
8195 case CP0_REG05__SEGCTL0:
8196 CP0_CHECK(ctx->sc);
8197 gen_helper_mtc0_segctl0(cpu_env, arg);
8198 register_name = "SegCtl0";
8199 break;
8200 case CP0_REG05__SEGCTL1:
8201 CP0_CHECK(ctx->sc);
8202 gen_helper_mtc0_segctl1(cpu_env, arg);
8203 register_name = "SegCtl1";
8204 break;
8205 case CP0_REG05__SEGCTL2:
8206 CP0_CHECK(ctx->sc);
8207 gen_helper_mtc0_segctl2(cpu_env, arg);
8208 register_name = "SegCtl2";
8209 break;
8210 case CP0_REG05__PWBASE:
8211 check_pw(ctx);
8212 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8213 register_name = "PWBase";
8214 break;
8215 case CP0_REG05__PWFIELD:
8216 check_pw(ctx);
8217 gen_helper_mtc0_pwfield(cpu_env, arg);
8218 register_name = "PWField";
8219 break;
8220 case CP0_REG05__PWSIZE:
8221 check_pw(ctx);
8222 gen_helper_mtc0_pwsize(cpu_env, arg);
8223 register_name = "PWSize";
8224 break;
8225 default:
8226 goto cp0_unimplemented;
8227 }
8228 break;
8229 case CP0_REGISTER_06:
8230 switch (sel) {
8231 case CP0_REG06__WIRED:
8232 gen_helper_mtc0_wired(cpu_env, arg);
8233 register_name = "Wired";
8234 break;
8235 case CP0_REG06__SRSCONF0:
8236 check_insn(ctx, ISA_MIPS_R2);
8237 gen_helper_mtc0_srsconf0(cpu_env, arg);
8238 register_name = "SRSConf0";
8239 break;
8240 case CP0_REG06__SRSCONF1:
8241 check_insn(ctx, ISA_MIPS_R2);
8242 gen_helper_mtc0_srsconf1(cpu_env, arg);
8243 register_name = "SRSConf1";
8244 break;
8245 case CP0_REG06__SRSCONF2:
8246 check_insn(ctx, ISA_MIPS_R2);
8247 gen_helper_mtc0_srsconf2(cpu_env, arg);
8248 register_name = "SRSConf2";
8249 break;
8250 case CP0_REG06__SRSCONF3:
8251 check_insn(ctx, ISA_MIPS_R2);
8252 gen_helper_mtc0_srsconf3(cpu_env, arg);
8253 register_name = "SRSConf3";
8254 break;
8255 case CP0_REG06__SRSCONF4:
8256 check_insn(ctx, ISA_MIPS_R2);
8257 gen_helper_mtc0_srsconf4(cpu_env, arg);
8258 register_name = "SRSConf4";
8259 break;
8260 case CP0_REG06__PWCTL:
8261 check_pw(ctx);
8262 gen_helper_mtc0_pwctl(cpu_env, arg);
8263 register_name = "PWCtl";
8264 break;
8265 default:
8266 goto cp0_unimplemented;
8267 }
8268 break;
8269 case CP0_REGISTER_07:
8270 switch (sel) {
8271 case CP0_REG07__HWRENA:
8272 check_insn(ctx, ISA_MIPS_R2);
8273 gen_helper_mtc0_hwrena(cpu_env, arg);
8274 ctx->base.is_jmp = DISAS_STOP;
8275 register_name = "HWREna";
8276 break;
8277 default:
8278 goto cp0_unimplemented;
8279 }
8280 break;
8281 case CP0_REGISTER_08:
8282 switch (sel) {
8283 case CP0_REG08__BADVADDR:
8284
8285 register_name = "BadVAddr";
8286 break;
8287 case CP0_REG08__BADINSTR:
8288
8289 register_name = "BadInstr";
8290 break;
8291 case CP0_REG08__BADINSTRP:
8292
8293 register_name = "BadInstrP";
8294 break;
8295 case CP0_REG08__BADINSTRX:
8296
8297 register_name = "BadInstrX";
8298 break;
8299 default:
8300 goto cp0_unimplemented;
8301 }
8302 break;
8303 case CP0_REGISTER_09:
8304 switch (sel) {
8305 case CP0_REG09__COUNT:
8306 gen_helper_mtc0_count(cpu_env, arg);
8307 register_name = "Count";
8308 break;
8309 case CP0_REG09__SAARI:
8310 CP0_CHECK(ctx->saar);
8311 gen_helper_mtc0_saari(cpu_env, arg);
8312 register_name = "SAARI";
8313 break;
8314 case CP0_REG09__SAAR:
8315 CP0_CHECK(ctx->saar);
8316 gen_helper_mtc0_saar(cpu_env, arg);
8317 register_name = "SAAR";
8318 break;
8319 default:
8320 goto cp0_unimplemented;
8321 }
8322
8323 ctx->base.is_jmp = DISAS_STOP;
8324 break;
8325 case CP0_REGISTER_10:
8326 switch (sel) {
8327 case CP0_REG10__ENTRYHI:
8328 gen_helper_mtc0_entryhi(cpu_env, arg);
8329 register_name = "EntryHi";
8330 break;
8331 default:
8332 goto cp0_unimplemented;
8333 }
8334 break;
8335 case CP0_REGISTER_11:
8336 switch (sel) {
8337 case CP0_REG11__COMPARE:
8338 gen_helper_mtc0_compare(cpu_env, arg);
8339 register_name = "Compare";
8340 break;
8341
8342 default:
8343 goto cp0_unimplemented;
8344 }
8345
8346 ctx->base.is_jmp = DISAS_STOP;
8347 break;
8348 case CP0_REGISTER_12:
8349 switch (sel) {
8350 case CP0_REG12__STATUS:
8351 save_cpu_state(ctx, 1);
8352 gen_helper_mtc0_status(cpu_env, arg);
8353
8354 gen_save_pc(ctx->base.pc_next + 4);
8355 ctx->base.is_jmp = DISAS_EXIT;
8356 register_name = "Status";
8357 break;
8358 case CP0_REG12__INTCTL:
8359 check_insn(ctx, ISA_MIPS_R2);
8360 gen_helper_mtc0_intctl(cpu_env, arg);
8361
8362 ctx->base.is_jmp = DISAS_STOP;
8363 register_name = "IntCtl";
8364 break;
8365 case CP0_REG12__SRSCTL:
8366 check_insn(ctx, ISA_MIPS_R2);
8367 gen_helper_mtc0_srsctl(cpu_env, arg);
8368
8369 ctx->base.is_jmp = DISAS_STOP;
8370 register_name = "SRSCtl";
8371 break;
8372 case CP0_REG12__SRSMAP:
8373 check_insn(ctx, ISA_MIPS_R2);
8374 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8375
8376 ctx->base.is_jmp = DISAS_STOP;
8377 register_name = "SRSMap";
8378 break;
8379 default:
8380 goto cp0_unimplemented;
8381 }
8382 break;
8383 case CP0_REGISTER_13:
8384 switch (sel) {
8385 case CP0_REG13__CAUSE:
8386 save_cpu_state(ctx, 1);
8387 gen_helper_mtc0_cause(cpu_env, arg);
8388
8389
8390
8391
8392
8393 gen_save_pc(ctx->base.pc_next + 4);
8394 ctx->base.is_jmp = DISAS_EXIT;
8395 register_name = "Cause";
8396 break;
8397 default:
8398 goto cp0_unimplemented;
8399 }
8400 break;
8401 case CP0_REGISTER_14:
8402 switch (sel) {
8403 case CP0_REG14__EPC:
8404 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8405 register_name = "EPC";
8406 break;
8407 default:
8408 goto cp0_unimplemented;
8409 }
8410 break;
8411 case CP0_REGISTER_15:
8412 switch (sel) {
8413 case CP0_REG15__PRID:
8414
8415 register_name = "PRid";
8416 break;
8417 case CP0_REG15__EBASE:
8418 check_insn(ctx, ISA_MIPS_R2);
8419 gen_helper_mtc0_ebase(cpu_env, arg);
8420 register_name = "EBase";
8421 break;
8422 default:
8423 goto cp0_unimplemented;
8424 }
8425 break;
8426 case CP0_REGISTER_16:
8427 switch (sel) {
8428 case CP0_REG16__CONFIG:
8429 gen_helper_mtc0_config0(cpu_env, arg);
8430 register_name = "Config";
8431
8432 ctx->base.is_jmp = DISAS_STOP;
8433 break;
8434 case CP0_REG16__CONFIG1:
8435
8436 register_name = "Config1";
8437 break;
8438 case CP0_REG16__CONFIG2:
8439 gen_helper_mtc0_config2(cpu_env, arg);
8440 register_name = "Config2";
8441
8442 ctx->base.is_jmp = DISAS_STOP;
8443 break;
8444 case CP0_REG16__CONFIG3:
8445 gen_helper_mtc0_config3(cpu_env, arg);
8446 register_name = "Config3";
8447
8448 ctx->base.is_jmp = DISAS_STOP;
8449 break;
8450 case CP0_REG16__CONFIG4:
8451
8452 register_name = "Config4";
8453 break;
8454 case CP0_REG16__CONFIG5:
8455 gen_helper_mtc0_config5(cpu_env, arg);
8456 register_name = "Config5";
8457
8458 ctx->base.is_jmp = DISAS_STOP;
8459 break;
8460
8461 default:
8462 register_name = "Invalid config selector";
8463 goto cp0_unimplemented;
8464 }
8465 break;
8466 case CP0_REGISTER_17:
8467 switch (sel) {
8468 case CP0_REG17__LLADDR:
8469 gen_helper_mtc0_lladdr(cpu_env, arg);
8470 register_name = "LLAddr";
8471 break;
8472 case CP0_REG17__MAAR:
8473 CP0_CHECK(ctx->mrp);
8474 gen_helper_mtc0_maar(cpu_env, arg);
8475 register_name = "MAAR";
8476 break;
8477 case CP0_REG17__MAARI:
8478 CP0_CHECK(ctx->mrp);
8479 gen_helper_mtc0_maari(cpu_env, arg);
8480 register_name = "MAARI";
8481 break;
8482 default:
8483 goto cp0_unimplemented;
8484 }
8485 break;
8486 case CP0_REGISTER_18:
8487 switch (sel) {
8488 case CP0_REG18__WATCHLO0:
8489 case CP0_REG18__WATCHLO1:
8490 case CP0_REG18__WATCHLO2:
8491 case CP0_REG18__WATCHLO3:
8492 case CP0_REG18__WATCHLO4:
8493 case CP0_REG18__WATCHLO5:
8494 case CP0_REG18__WATCHLO6:
8495 case CP0_REG18__WATCHLO7:
8496 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8497 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8498 register_name = "WatchLo";
8499 break;
8500 default:
8501 goto cp0_unimplemented;
8502 }
8503 break;
8504 case CP0_REGISTER_19:
8505 switch (sel) {
8506 case CP0_REG19__WATCHHI0:
8507 case CP0_REG19__WATCHHI1:
8508 case CP0_REG19__WATCHHI2:
8509 case CP0_REG19__WATCHHI3:
8510 case CP0_REG19__WATCHHI4:
8511 case CP0_REG19__WATCHHI5:
8512 case CP0_REG19__WATCHHI6:
8513 case CP0_REG19__WATCHHI7:
8514 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8515 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8516 register_name = "WatchHi";
8517 break;
8518 default:
8519 goto cp0_unimplemented;
8520 }
8521 break;
8522 case CP0_REGISTER_20:
8523 switch (sel) {
8524 case CP0_REG20__XCONTEXT:
8525 check_insn(ctx, ISA_MIPS3);
8526 gen_helper_mtc0_xcontext(cpu_env, arg);
8527 register_name = "XContext";
8528 break;
8529 default:
8530 goto cp0_unimplemented;
8531 }
8532 break;
8533 case CP0_REGISTER_21:
8534
8535 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8536 switch (sel) {
8537 case 0:
8538 gen_helper_mtc0_framemask(cpu_env, arg);
8539 register_name = "Framemask";
8540 break;
8541 default:
8542 goto cp0_unimplemented;
8543 }
8544 break;
8545 case CP0_REGISTER_22:
8546
8547 register_name = "Diagnostic";
8548 break;
8549 case CP0_REGISTER_23:
8550 switch (sel) {
8551 case CP0_REG23__DEBUG:
8552 gen_helper_mtc0_debug(cpu_env, arg);
8553
8554 gen_save_pc(ctx->base.pc_next + 4);
8555 ctx->base.is_jmp = DISAS_EXIT;
8556 register_name = "Debug";
8557 break;
8558 case CP0_REG23__TRACECONTROL:
8559
8560
8561
8562 ctx->base.is_jmp = DISAS_STOP;
8563 register_name = "TraceControl";
8564 goto cp0_unimplemented;
8565 case CP0_REG23__TRACECONTROL2:
8566
8567
8568
8569 ctx->base.is_jmp = DISAS_STOP;
8570 register_name = "TraceControl2";
8571 goto cp0_unimplemented;
8572 case CP0_REG23__USERTRACEDATA1:
8573
8574
8575
8576 ctx->base.is_jmp = DISAS_STOP;
8577 register_name = "UserTraceData1";
8578 goto cp0_unimplemented;
8579 case CP0_REG23__TRACEIBPC:
8580
8581
8582
8583 ctx->base.is_jmp = DISAS_STOP;
8584 register_name = "TraceIBPC";
8585 goto cp0_unimplemented;
8586 case CP0_REG23__TRACEDBPC:
8587
8588
8589
8590 ctx->base.is_jmp = DISAS_STOP;
8591 register_name = "TraceDBPC";
8592 goto cp0_unimplemented;
8593 default:
8594 goto cp0_unimplemented;
8595 }
8596 break;
8597 case CP0_REGISTER_24:
8598 switch (sel) {
8599 case CP0_REG24__DEPC:
8600
8601 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8602 register_name = "DEPC";
8603 break;
8604 default:
8605 goto cp0_unimplemented;
8606 }
8607 break;
8608 case CP0_REGISTER_25:
8609 switch (sel) {
8610 case CP0_REG25__PERFCTL0:
8611 gen_helper_mtc0_performance0(cpu_env, arg);
8612 register_name = "Performance0";
8613 break;
8614 case CP0_REG25__PERFCNT0:
8615
8616 register_name = "Performance1";
8617 goto cp0_unimplemented;
8618 case CP0_REG25__PERFCTL1:
8619
8620 register_name = "Performance2";
8621 goto cp0_unimplemented;
8622 case CP0_REG25__PERFCNT1:
8623
8624 register_name = "Performance3";
8625 goto cp0_unimplemented;
8626 case CP0_REG25__PERFCTL2:
8627
8628 register_name = "Performance4";
8629 goto cp0_unimplemented;
8630 case CP0_REG25__PERFCNT2:
8631
8632 register_name = "Performance5";
8633 goto cp0_unimplemented;
8634 case CP0_REG25__PERFCTL3:
8635
8636 register_name = "Performance6";
8637 goto cp0_unimplemented;
8638 case CP0_REG25__PERFCNT3:
8639
8640 register_name = "Performance7";
8641 goto cp0_unimplemented;
8642 default:
8643 goto cp0_unimplemented;
8644 }
8645 break;
8646 case CP0_REGISTER_26:
8647 switch (sel) {
8648 case CP0_REG26__ERRCTL:
8649 gen_helper_mtc0_errctl(cpu_env, arg);
8650 ctx->base.is_jmp = DISAS_STOP;
8651 register_name = "ErrCtl";
8652 break;
8653 default:
8654 goto cp0_unimplemented;
8655 }
8656 break;
8657 case CP0_REGISTER_27:
8658 switch (sel) {
8659 case CP0_REG27__CACHERR:
8660
8661 register_name = "CacheErr";
8662 break;
8663 default:
8664 goto cp0_unimplemented;
8665 }
8666 break;
8667 case CP0_REGISTER_28:
8668 switch (sel) {
8669 case CP0_REG28__TAGLO:
8670 case CP0_REG28__TAGLO1:
8671 case CP0_REG28__TAGLO2:
8672 case CP0_REG28__TAGLO3:
8673 gen_helper_mtc0_taglo(cpu_env, arg);
8674 register_name = "TagLo";
8675 break;
8676 case CP0_REG28__DATALO:
8677 case CP0_REG28__DATALO1:
8678 case CP0_REG28__DATALO2:
8679 case CP0_REG28__DATALO3:
8680 gen_helper_mtc0_datalo(cpu_env, arg);
8681 register_name = "DataLo";
8682 break;
8683 default:
8684 goto cp0_unimplemented;
8685 }
8686 break;
8687 case CP0_REGISTER_29:
8688 switch (sel) {
8689 case CP0_REG29__TAGHI:
8690 case CP0_REG29__TAGHI1:
8691 case CP0_REG29__TAGHI2:
8692 case CP0_REG29__TAGHI3:
8693 gen_helper_mtc0_taghi(cpu_env, arg);
8694 register_name = "TagHi";
8695 break;
8696 case CP0_REG29__DATAHI:
8697 case CP0_REG29__DATAHI1:
8698 case CP0_REG29__DATAHI2:
8699 case CP0_REG29__DATAHI3:
8700 gen_helper_mtc0_datahi(cpu_env, arg);
8701 register_name = "DataHi";
8702 break;
8703 default:
8704 register_name = "invalid sel";
8705 goto cp0_unimplemented;
8706 }
8707 break;
8708 case CP0_REGISTER_30:
8709 switch (sel) {
8710 case CP0_REG30__ERROREPC:
8711 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8712 register_name = "ErrorEPC";
8713 break;
8714 default:
8715 goto cp0_unimplemented;
8716 }
8717 break;
8718 case CP0_REGISTER_31:
8719 switch (sel) {
8720 case CP0_REG31__DESAVE:
8721
8722 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8723 register_name = "DESAVE";
8724 break;
8725 case CP0_REG31__KSCRATCH1:
8726 case CP0_REG31__KSCRATCH2:
8727 case CP0_REG31__KSCRATCH3:
8728 case CP0_REG31__KSCRATCH4:
8729 case CP0_REG31__KSCRATCH5:
8730 case CP0_REG31__KSCRATCH6:
8731 CP0_CHECK(ctx->kscrexist & (1 << sel));
8732 tcg_gen_st_tl(arg, cpu_env,
8733 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8734 register_name = "KScratch";
8735 break;
8736 default:
8737 goto cp0_unimplemented;
8738 }
8739 break;
8740 default:
8741 goto cp0_unimplemented;
8742 }
8743 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8744
8745
8746 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8747
8748
8749
8750
8751 gen_save_pc(ctx->base.pc_next + 4);
8752 ctx->base.is_jmp = DISAS_EXIT;
8753 }
8754 return;
8755
8756cp0_unimplemented:
8757 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8758 register_name, reg, sel);
8759}
8760#endif
8761
8762static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8763 int u, int sel, int h)
8764{
8765 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8766 TCGv t0 = tcg_temp_local_new();
8767
8768 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8769 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8770 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8771 tcg_gen_movi_tl(t0, -1);
8772 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8773 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8774 tcg_gen_movi_tl(t0, -1);
8775 } else if (u == 0) {
8776 switch (rt) {
8777 case 1:
8778 switch (sel) {
8779 case 1:
8780 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8781 break;
8782 case 2:
8783 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8784 break;
8785 default:
8786 goto die;
8787 break;
8788 }
8789 break;
8790 case 2:
8791 switch (sel) {
8792 case 1:
8793 gen_helper_mftc0_tcstatus(t0, cpu_env);
8794 break;
8795 case 2:
8796 gen_helper_mftc0_tcbind(t0, cpu_env);
8797 break;
8798 case 3:
8799 gen_helper_mftc0_tcrestart(t0, cpu_env);
8800 break;
8801 case 4:
8802 gen_helper_mftc0_tchalt(t0, cpu_env);
8803 break;
8804 case 5:
8805 gen_helper_mftc0_tccontext(t0, cpu_env);
8806 break;
8807 case 6:
8808 gen_helper_mftc0_tcschedule(t0, cpu_env);
8809 break;
8810 case 7:
8811 gen_helper_mftc0_tcschefback(t0, cpu_env);
8812 break;
8813 default:
8814 gen_mfc0(ctx, t0, rt, sel);
8815 break;
8816 }
8817 break;
8818 case 10:
8819 switch (sel) {
8820 case 0:
8821 gen_helper_mftc0_entryhi(t0, cpu_env);
8822 break;
8823 default:
8824 gen_mfc0(ctx, t0, rt, sel);
8825 break;
8826 }
8827 break;
8828 case 12:
8829 switch (sel) {
8830 case 0:
8831 gen_helper_mftc0_status(t0, cpu_env);
8832 break;
8833 default:
8834 gen_mfc0(ctx, t0, rt, sel);
8835 break;
8836 }
8837 break;
8838 case 13:
8839 switch (sel) {
8840 case 0:
8841 gen_helper_mftc0_cause(t0, cpu_env);
8842 break;
8843 default:
8844 goto die;
8845 break;
8846 }
8847 break;
8848 case 14:
8849 switch (sel) {
8850 case 0:
8851 gen_helper_mftc0_epc(t0, cpu_env);
8852 break;
8853 default:
8854 goto die;
8855 break;
8856 }
8857 break;
8858 case 15:
8859 switch (sel) {
8860 case 1:
8861 gen_helper_mftc0_ebase(t0, cpu_env);
8862 break;
8863 default:
8864 goto die;
8865 break;
8866 }
8867 break;
8868 case 16:
8869 switch (sel) {
8870 case 0:
8871 case 1:
8872 case 2:
8873 case 3:
8874 case 4:
8875 case 5:
8876 case 6:
8877 case 7:
8878 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8879 break;
8880 default:
8881 goto die;
8882 break;
8883 }
8884 break;
8885 case 23:
8886 switch (sel) {
8887 case 0:
8888 gen_helper_mftc0_debug(t0, cpu_env);
8889 break;
8890 default:
8891 gen_mfc0(ctx, t0, rt, sel);
8892 break;
8893 }
8894 break;
8895 default:
8896 gen_mfc0(ctx, t0, rt, sel);
8897 }
8898 } else {
8899 switch (sel) {
8900
8901 case 0:
8902 gen_helper_1e0i(mftgpr, t0, rt);
8903 break;
8904
8905 case 1:
8906 switch (rt) {
8907 case 0:
8908 gen_helper_1e0i(mftlo, t0, 0);
8909 break;
8910 case 1:
8911 gen_helper_1e0i(mfthi, t0, 0);
8912 break;
8913 case 2:
8914 gen_helper_1e0i(mftacx, t0, 0);
8915 break;
8916 case 4:
8917 gen_helper_1e0i(mftlo, t0, 1);
8918 break;
8919 case 5:
8920 gen_helper_1e0i(mfthi, t0, 1);
8921 break;
8922 case 6:
8923 gen_helper_1e0i(mftacx, t0, 1);
8924 break;
8925 case 8:
8926 gen_helper_1e0i(mftlo, t0, 2);
8927 break;
8928 case 9:
8929 gen_helper_1e0i(mfthi, t0, 2);
8930 break;
8931 case 10:
8932 gen_helper_1e0i(mftacx, t0, 2);
8933 break;
8934 case 12:
8935 gen_helper_1e0i(mftlo, t0, 3);
8936 break;
8937 case 13:
8938 gen_helper_1e0i(mfthi, t0, 3);
8939 break;
8940 case 14:
8941 gen_helper_1e0i(mftacx, t0, 3);
8942 break;
8943 case 16:
8944 gen_helper_mftdsp(t0, cpu_env);
8945 break;
8946 default:
8947 goto die;
8948 }
8949 break;
8950
8951 case 2:
8952
8953 if (h == 0) {
8954 TCGv_i32 fp0 = tcg_temp_new_i32();
8955
8956 gen_load_fpr32(ctx, fp0, rt);
8957 tcg_gen_ext_i32_tl(t0, fp0);
8958 tcg_temp_free_i32(fp0);
8959 } else {
8960 TCGv_i32 fp0 = tcg_temp_new_i32();
8961
8962 gen_load_fpr32h(ctx, fp0, rt);
8963 tcg_gen_ext_i32_tl(t0, fp0);
8964 tcg_temp_free_i32(fp0);
8965 }
8966 break;
8967 case 3:
8968
8969 gen_helper_1e0i(cfc1, t0, rt);
8970 break;
8971
8972 case 4:
8973 case 5:
8974
8975 default:
8976 goto die;
8977 }
8978 }
8979 trace_mips_translate_tr("mftr", rt, u, sel, h);
8980 gen_store_gpr(t0, rd);
8981 tcg_temp_free(t0);
8982 return;
8983
8984die:
8985 tcg_temp_free(t0);
8986 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8987 gen_reserved_instruction(ctx);
8988}
8989
8990static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8991 int u, int sel, int h)
8992{
8993 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8994 TCGv t0 = tcg_temp_local_new();
8995
8996 gen_load_gpr(t0, rt);
8997 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8998 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8999 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9000
9001 ;
9002 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9003 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
9004
9005 ;
9006 } else if (u == 0) {
9007 switch (rd) {
9008 case 1:
9009 switch (sel) {
9010 case 1:
9011 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9012 break;
9013 case 2:
9014 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9015 break;
9016 default:
9017 goto die;
9018 break;
9019 }
9020 break;
9021 case 2:
9022 switch (sel) {
9023 case 1:
9024 gen_helper_mttc0_tcstatus(cpu_env, t0);
9025 break;
9026 case 2:
9027 gen_helper_mttc0_tcbind(cpu_env, t0);
9028 break;
9029 case 3:
9030 gen_helper_mttc0_tcrestart(cpu_env, t0);
9031 break;
9032 case 4:
9033 gen_helper_mttc0_tchalt(cpu_env, t0);
9034 break;
9035 case 5:
9036 gen_helper_mttc0_tccontext(cpu_env, t0);
9037 break;
9038 case 6:
9039 gen_helper_mttc0_tcschedule(cpu_env, t0);
9040 break;
9041 case 7:
9042 gen_helper_mttc0_tcschefback(cpu_env, t0);
9043 break;
9044 default:
9045 gen_mtc0(ctx, t0, rd, sel);
9046 break;
9047 }
9048 break;
9049 case 10:
9050 switch (sel) {
9051 case 0:
9052 gen_helper_mttc0_entryhi(cpu_env, t0);
9053 break;
9054 default:
9055 gen_mtc0(ctx, t0, rd, sel);
9056 break;
9057 }
9058 break;
9059 case 12:
9060 switch (sel) {
9061 case 0:
9062 gen_helper_mttc0_status(cpu_env, t0);
9063 break;
9064 default:
9065 gen_mtc0(ctx, t0, rd, sel);
9066 break;
9067 }
9068 break;
9069 case 13:
9070 switch (sel) {
9071 case 0:
9072 gen_helper_mttc0_cause(cpu_env, t0);
9073 break;
9074 default:
9075 goto die;
9076 break;
9077 }
9078 break;
9079 case 15:
9080 switch (sel) {
9081 case 1:
9082 gen_helper_mttc0_ebase(cpu_env, t0);
9083 break;
9084 default:
9085 goto die;
9086 break;
9087 }
9088 break;
9089 case 23:
9090 switch (sel) {
9091 case 0:
9092 gen_helper_mttc0_debug(cpu_env, t0);
9093 break;
9094 default:
9095 gen_mtc0(ctx, t0, rd, sel);
9096 break;
9097 }
9098 break;
9099 default:
9100 gen_mtc0(ctx, t0, rd, sel);
9101 }
9102 } else {
9103 switch (sel) {
9104
9105 case 0:
9106 gen_helper_0e1i(mttgpr, t0, rd);
9107 break;
9108
9109 case 1:
9110 switch (rd) {
9111 case 0:
9112 gen_helper_0e1i(mttlo, t0, 0);
9113 break;
9114 case 1:
9115 gen_helper_0e1i(mtthi, t0, 0);
9116 break;
9117 case 2:
9118 gen_helper_0e1i(mttacx, t0, 0);
9119 break;
9120 case 4:
9121 gen_helper_0e1i(mttlo, t0, 1);
9122 break;
9123 case 5:
9124 gen_helper_0e1i(mtthi, t0, 1);
9125 break;
9126 case 6:
9127 gen_helper_0e1i(mttacx, t0, 1);
9128 break;
9129 case 8:
9130 gen_helper_0e1i(mttlo, t0, 2);
9131 break;
9132 case 9:
9133 gen_helper_0e1i(mtthi, t0, 2);
9134 break;
9135 case 10:
9136 gen_helper_0e1i(mttacx, t0, 2);
9137 break;
9138 case 12:
9139 gen_helper_0e1i(mttlo, t0, 3);
9140 break;
9141 case 13:
9142 gen_helper_0e1i(mtthi, t0, 3);
9143 break;
9144 case 14:
9145 gen_helper_0e1i(mttacx, t0, 3);
9146 break;
9147 case 16:
9148 gen_helper_mttdsp(cpu_env, t0);
9149 break;
9150 default:
9151 goto die;
9152 }
9153 break;
9154
9155 case 2:
9156
9157 if (h == 0) {
9158 TCGv_i32 fp0 = tcg_temp_new_i32();
9159
9160 tcg_gen_trunc_tl_i32(fp0, t0);
9161 gen_store_fpr32(ctx, fp0, rd);
9162 tcg_temp_free_i32(fp0);
9163 } else {
9164 TCGv_i32 fp0 = tcg_temp_new_i32();
9165
9166 tcg_gen_trunc_tl_i32(fp0, t0);
9167 gen_store_fpr32h(ctx, fp0, rd);
9168 tcg_temp_free_i32(fp0);
9169 }
9170 break;
9171 case 3:
9172
9173 {
9174 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9175
9176 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9177 tcg_temp_free_i32(fs_tmp);
9178 }
9179
9180 ctx->base.is_jmp = DISAS_STOP;
9181 break;
9182
9183 case 4:
9184 case 5:
9185
9186 default:
9187 goto die;
9188 }
9189 }
9190 trace_mips_translate_tr("mttr", rd, u, sel, h);
9191 tcg_temp_free(t0);
9192 return;
9193
9194die:
9195 tcg_temp_free(t0);
9196 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9197 gen_reserved_instruction(ctx);
9198}
9199
9200static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9201 int rt, int rd)
9202{
9203 const char *opn = "ldst";
9204
9205 check_cp0_enabled(ctx);
9206 switch (opc) {
9207 case OPC_MFC0:
9208 if (rt == 0) {
9209
9210 return;
9211 }
9212 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9213 opn = "mfc0";
9214 break;
9215 case OPC_MTC0:
9216 {
9217 TCGv t0 = tcg_temp_new();
9218
9219 gen_load_gpr(t0, rt);
9220 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9221 tcg_temp_free(t0);
9222 }
9223 opn = "mtc0";
9224 break;
9225#if defined(TARGET_MIPS64)
9226 case OPC_DMFC0:
9227 check_insn(ctx, ISA_MIPS3);
9228 if (rt == 0) {
9229
9230 return;
9231 }
9232 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9233 opn = "dmfc0";
9234 break;
9235 case OPC_DMTC0:
9236 check_insn(ctx, ISA_MIPS3);
9237 {
9238 TCGv t0 = tcg_temp_new();
9239
9240 gen_load_gpr(t0, rt);
9241 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9242 tcg_temp_free(t0);
9243 }
9244 opn = "dmtc0";
9245 break;
9246#endif
9247 case OPC_MFHC0:
9248 check_mvh(ctx);
9249 if (rt == 0) {
9250
9251 return;
9252 }
9253 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9254 opn = "mfhc0";
9255 break;
9256 case OPC_MTHC0:
9257 check_mvh(ctx);
9258 {
9259 TCGv t0 = tcg_temp_new();
9260 gen_load_gpr(t0, rt);
9261 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9262 tcg_temp_free(t0);
9263 }
9264 opn = "mthc0";
9265 break;
9266 case OPC_MFTR:
9267 check_cp0_enabled(ctx);
9268 if (rd == 0) {
9269
9270 return;
9271 }
9272 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9273 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9274 opn = "mftr";
9275 break;
9276 case OPC_MTTR:
9277 check_cp0_enabled(ctx);
9278 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9279 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9280 opn = "mttr";
9281 break;
9282 case OPC_TLBWI:
9283 opn = "tlbwi";
9284 if (!env->tlb->helper_tlbwi) {
9285 goto die;
9286 }
9287 gen_helper_tlbwi(cpu_env);
9288 break;
9289 case OPC_TLBINV:
9290 opn = "tlbinv";
9291 if (ctx->ie >= 2) {
9292 if (!env->tlb->helper_tlbinv) {
9293 goto die;
9294 }
9295 gen_helper_tlbinv(cpu_env);
9296 }
9297 break;
9298 case OPC_TLBINVF:
9299 opn = "tlbinvf";
9300 if (ctx->ie >= 2) {
9301 if (!env->tlb->helper_tlbinvf) {
9302 goto die;
9303 }
9304 gen_helper_tlbinvf(cpu_env);
9305 }
9306 break;
9307 case OPC_TLBWR:
9308 opn = "tlbwr";
9309 if (!env->tlb->helper_tlbwr) {
9310 goto die;
9311 }
9312 gen_helper_tlbwr(cpu_env);
9313 break;
9314 case OPC_TLBP:
9315 opn = "tlbp";
9316 if (!env->tlb->helper_tlbp) {
9317 goto die;
9318 }
9319 gen_helper_tlbp(cpu_env);
9320 break;
9321 case OPC_TLBR:
9322 opn = "tlbr";
9323 if (!env->tlb->helper_tlbr) {
9324 goto die;
9325 }
9326 gen_helper_tlbr(cpu_env);
9327 break;
9328 case OPC_ERET:
9329 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9330 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9331 goto die;
9332 } else {
9333 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9334 if (ctx->opcode & (1 << bit_shift)) {
9335
9336 opn = "eretnc";
9337 check_insn(ctx, ISA_MIPS_R5);
9338 gen_helper_eretnc(cpu_env);
9339 } else {
9340
9341 opn = "eret";
9342 check_insn(ctx, ISA_MIPS2);
9343 gen_helper_eret(cpu_env);
9344 }
9345 ctx->base.is_jmp = DISAS_EXIT;
9346 }
9347 break;
9348 case OPC_DERET:
9349 opn = "deret";
9350 check_insn(ctx, ISA_MIPS_R1);
9351 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9352 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9353 goto die;
9354 }
9355 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9356 MIPS_INVAL(opn);
9357 gen_reserved_instruction(ctx);
9358 } else {
9359 gen_helper_deret(cpu_env);
9360 ctx->base.is_jmp = DISAS_EXIT;
9361 }
9362 break;
9363 case OPC_WAIT:
9364 opn = "wait";
9365 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9366 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9367 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9368 goto die;
9369 }
9370
9371 ctx->base.pc_next += 4;
9372 save_cpu_state(ctx, 1);
9373 ctx->base.pc_next -= 4;
9374 gen_helper_wait(cpu_env);
9375 ctx->base.is_jmp = DISAS_NORETURN;
9376 break;
9377 default:
9378 die:
9379 MIPS_INVAL(opn);
9380 gen_reserved_instruction(ctx);
9381 return;
9382 }
9383 (void)opn;
9384}
9385#endif
9386
9387
9388static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9389 int32_t cc, int32_t offset)
9390{
9391 target_ulong btarget;
9392 TCGv_i32 t0 = tcg_temp_new_i32();
9393
9394 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9395 gen_reserved_instruction(ctx);
9396 goto out;
9397 }
9398
9399 if (cc != 0) {
9400 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9401 }
9402
9403 btarget = ctx->base.pc_next + 4 + offset;
9404
9405 switch (op) {
9406 case OPC_BC1F:
9407 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9408 tcg_gen_not_i32(t0, t0);
9409 tcg_gen_andi_i32(t0, t0, 1);
9410 tcg_gen_extu_i32_tl(bcond, t0);
9411 goto not_likely;
9412 case OPC_BC1FL:
9413 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9414 tcg_gen_not_i32(t0, t0);
9415 tcg_gen_andi_i32(t0, t0, 1);
9416 tcg_gen_extu_i32_tl(bcond, t0);
9417 goto likely;
9418 case OPC_BC1T:
9419 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9420 tcg_gen_andi_i32(t0, t0, 1);
9421 tcg_gen_extu_i32_tl(bcond, t0);
9422 goto not_likely;
9423 case OPC_BC1TL:
9424 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9425 tcg_gen_andi_i32(t0, t0, 1);
9426 tcg_gen_extu_i32_tl(bcond, t0);
9427 likely:
9428 ctx->hflags |= MIPS_HFLAG_BL;
9429 break;
9430 case OPC_BC1FANY2:
9431 {
9432 TCGv_i32 t1 = tcg_temp_new_i32();
9433 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9434 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9435 tcg_gen_nand_i32(t0, t0, t1);
9436 tcg_temp_free_i32(t1);
9437 tcg_gen_andi_i32(t0, t0, 1);
9438 tcg_gen_extu_i32_tl(bcond, t0);
9439 }
9440 goto not_likely;
9441 case OPC_BC1TANY2:
9442 {
9443 TCGv_i32 t1 = tcg_temp_new_i32();
9444 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9445 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9446 tcg_gen_or_i32(t0, t0, t1);
9447 tcg_temp_free_i32(t1);
9448 tcg_gen_andi_i32(t0, t0, 1);
9449 tcg_gen_extu_i32_tl(bcond, t0);
9450 }
9451 goto not_likely;
9452 case OPC_BC1FANY4:
9453 {
9454 TCGv_i32 t1 = tcg_temp_new_i32();
9455 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9456 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9457 tcg_gen_and_i32(t0, t0, t1);
9458 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9459 tcg_gen_and_i32(t0, t0, t1);
9460 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9461 tcg_gen_nand_i32(t0, t0, t1);
9462 tcg_temp_free_i32(t1);
9463 tcg_gen_andi_i32(t0, t0, 1);
9464 tcg_gen_extu_i32_tl(bcond, t0);
9465 }
9466 goto not_likely;
9467 case OPC_BC1TANY4:
9468 {
9469 TCGv_i32 t1 = tcg_temp_new_i32();
9470 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9471 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9472 tcg_gen_or_i32(t0, t0, t1);
9473 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9474 tcg_gen_or_i32(t0, t0, t1);
9475 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9476 tcg_gen_or_i32(t0, t0, t1);
9477 tcg_temp_free_i32(t1);
9478 tcg_gen_andi_i32(t0, t0, 1);
9479 tcg_gen_extu_i32_tl(bcond, t0);
9480 }
9481 not_likely:
9482 ctx->hflags |= MIPS_HFLAG_BC;
9483 break;
9484 default:
9485 MIPS_INVAL("cp1 cond branch");
9486 gen_reserved_instruction(ctx);
9487 goto out;
9488 }
9489 ctx->btarget = btarget;
9490 ctx->hflags |= MIPS_HFLAG_BDS32;
9491 out:
9492 tcg_temp_free_i32(t0);
9493}
9494
9495
9496static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9497 int32_t ft, int32_t offset,
9498 int delayslot_size)
9499{
9500 target_ulong btarget;
9501 TCGv_i64 t0 = tcg_temp_new_i64();
9502
9503 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9504#ifdef MIPS_DEBUG_DISAS
9505 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9506 "\n", ctx->base.pc_next);
9507#endif
9508 gen_reserved_instruction(ctx);
9509 goto out;
9510 }
9511
9512 gen_load_fpr64(ctx, t0, ft);
9513 tcg_gen_andi_i64(t0, t0, 1);
9514
9515 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9516
9517 switch (op) {
9518 case OPC_BC1EQZ:
9519 tcg_gen_xori_i64(t0, t0, 1);
9520 ctx->hflags |= MIPS_HFLAG_BC;
9521 break;
9522 case OPC_BC1NEZ:
9523
9524 ctx->hflags |= MIPS_HFLAG_BC;
9525 break;
9526 default:
9527 MIPS_INVAL("cp1 cond branch");
9528 gen_reserved_instruction(ctx);
9529 goto out;
9530 }
9531
9532 tcg_gen_trunc_i64_tl(bcond, t0);
9533
9534 ctx->btarget = btarget;
9535
9536 switch (delayslot_size) {
9537 case 2:
9538 ctx->hflags |= MIPS_HFLAG_BDS16;
9539 break;
9540 case 4:
9541 ctx->hflags |= MIPS_HFLAG_BDS32;
9542 break;
9543 }
9544
9545out:
9546 tcg_temp_free_i64(t0);
9547}
9548
9549
9550
9551#define FOP(func, fmt) (((fmt) << 21) | (func))
9552
9553enum fopcode {
9554 OPC_ADD_S = FOP(0, FMT_S),
9555 OPC_SUB_S = FOP(1, FMT_S),
9556 OPC_MUL_S = FOP(2, FMT_S),
9557 OPC_DIV_S = FOP(3, FMT_S),
9558 OPC_SQRT_S = FOP(4, FMT_S),
9559 OPC_ABS_S = FOP(5, FMT_S),
9560 OPC_MOV_S = FOP(6, FMT_S),
9561 OPC_NEG_S = FOP(7, FMT_S),
9562 OPC_ROUND_L_S = FOP(8, FMT_S),
9563 OPC_TRUNC_L_S = FOP(9, FMT_S),
9564 OPC_CEIL_L_S = FOP(10, FMT_S),
9565 OPC_FLOOR_L_S = FOP(11, FMT_S),
9566 OPC_ROUND_W_S = FOP(12, FMT_S),
9567 OPC_TRUNC_W_S = FOP(13, FMT_S),
9568 OPC_CEIL_W_S = FOP(14, FMT_S),
9569 OPC_FLOOR_W_S = FOP(15, FMT_S),
9570 OPC_SEL_S = FOP(16, FMT_S),
9571 OPC_MOVCF_S = FOP(17, FMT_S),
9572 OPC_MOVZ_S = FOP(18, FMT_S),
9573 OPC_MOVN_S = FOP(19, FMT_S),
9574 OPC_SELEQZ_S = FOP(20, FMT_S),
9575 OPC_RECIP_S = FOP(21, FMT_S),
9576 OPC_RSQRT_S = FOP(22, FMT_S),
9577 OPC_SELNEZ_S = FOP(23, FMT_S),
9578 OPC_MADDF_S = FOP(24, FMT_S),
9579 OPC_MSUBF_S = FOP(25, FMT_S),
9580 OPC_RINT_S = FOP(26, FMT_S),
9581 OPC_CLASS_S = FOP(27, FMT_S),
9582 OPC_MIN_S = FOP(28, FMT_S),
9583 OPC_RECIP2_S = FOP(28, FMT_S),
9584 OPC_MINA_S = FOP(29, FMT_S),
9585 OPC_RECIP1_S = FOP(29, FMT_S),
9586 OPC_MAX_S = FOP(30, FMT_S),
9587 OPC_RSQRT1_S = FOP(30, FMT_S),
9588 OPC_MAXA_S = FOP(31, FMT_S),
9589 OPC_RSQRT2_S = FOP(31, FMT_S),
9590 OPC_CVT_D_S = FOP(33, FMT_S),
9591 OPC_CVT_W_S = FOP(36, FMT_S),
9592 OPC_CVT_L_S = FOP(37, FMT_S),
9593 OPC_CVT_PS_S = FOP(38, FMT_S),
9594 OPC_CMP_F_S = FOP(48, FMT_S),
9595 OPC_CMP_UN_S = FOP(49, FMT_S),
9596 OPC_CMP_EQ_S = FOP(50, FMT_S),
9597 OPC_CMP_UEQ_S = FOP(51, FMT_S),
9598 OPC_CMP_OLT_S = FOP(52, FMT_S),
9599 OPC_CMP_ULT_S = FOP(53, FMT_S),
9600 OPC_CMP_OLE_S = FOP(54, FMT_S),
9601 OPC_CMP_ULE_S = FOP(55, FMT_S),
9602 OPC_CMP_SF_S = FOP(56, FMT_S),
9603 OPC_CMP_NGLE_S = FOP(57, FMT_S),
9604 OPC_CMP_SEQ_S = FOP(58, FMT_S),
9605 OPC_CMP_NGL_S = FOP(59, FMT_S),
9606 OPC_CMP_LT_S = FOP(60, FMT_S),
9607 OPC_CMP_NGE_S = FOP(61, FMT_S),
9608 OPC_CMP_LE_S = FOP(62, FMT_S),
9609 OPC_CMP_NGT_S = FOP(63, FMT_S),
9610
9611 OPC_ADD_D = FOP(0, FMT_D),
9612 OPC_SUB_D = FOP(1, FMT_D),
9613 OPC_MUL_D = FOP(2, FMT_D),
9614 OPC_DIV_D = FOP(3, FMT_D),
9615 OPC_SQRT_D = FOP(4, FMT_D),
9616 OPC_ABS_D = FOP(5, FMT_D),
9617 OPC_MOV_D = FOP(6, FMT_D),
9618 OPC_NEG_D = FOP(7, FMT_D),
9619 OPC_ROUND_L_D = FOP(8, FMT_D),
9620 OPC_TRUNC_L_D = FOP(9, FMT_D),
9621 OPC_CEIL_L_D = FOP(10, FMT_D),
9622 OPC_FLOOR_L_D = FOP(11, FMT_D),
9623 OPC_ROUND_W_D = FOP(12, FMT_D),
9624 OPC_TRUNC_W_D = FOP(13, FMT_D),
9625 OPC_CEIL_W_D = FOP(14, FMT_D),
9626 OPC_FLOOR_W_D = FOP(15, FMT_D),
9627 OPC_SEL_D = FOP(16, FMT_D),
9628 OPC_MOVCF_D = FOP(17, FMT_D),
9629 OPC_MOVZ_D = FOP(18, FMT_D),
9630 OPC_MOVN_D = FOP(19, FMT_D),
9631 OPC_SELEQZ_D = FOP(20, FMT_D),
9632 OPC_RECIP_D = FOP(21, FMT_D),
9633 OPC_RSQRT_D = FOP(22, FMT_D),
9634 OPC_SELNEZ_D = FOP(23, FMT_D),
9635 OPC_MADDF_D = FOP(24, FMT_D),
9636 OPC_MSUBF_D = FOP(25, FMT_D),
9637 OPC_RINT_D = FOP(26, FMT_D),
9638 OPC_CLASS_D = FOP(27, FMT_D),
9639 OPC_MIN_D = FOP(28, FMT_D),
9640 OPC_RECIP2_D = FOP(28, FMT_D),
9641 OPC_MINA_D = FOP(29, FMT_D),
9642 OPC_RECIP1_D = FOP(29, FMT_D),
9643 OPC_MAX_D = FOP(30, FMT_D),
9644 OPC_RSQRT1_D = FOP(30, FMT_D),
9645 OPC_MAXA_D = FOP(31, FMT_D),
9646 OPC_RSQRT2_D = FOP(31, FMT_D),
9647 OPC_CVT_S_D = FOP(32, FMT_D),
9648 OPC_CVT_W_D = FOP(36, FMT_D),
9649 OPC_CVT_L_D = FOP(37, FMT_D),
9650 OPC_CMP_F_D = FOP(48, FMT_D),
9651 OPC_CMP_UN_D = FOP(49, FMT_D),
9652 OPC_CMP_EQ_D = FOP(50, FMT_D),
9653 OPC_CMP_UEQ_D = FOP(51, FMT_D),
9654 OPC_CMP_OLT_D = FOP(52, FMT_D),
9655 OPC_CMP_ULT_D = FOP(53, FMT_D),
9656 OPC_CMP_OLE_D = FOP(54, FMT_D),
9657 OPC_CMP_ULE_D = FOP(55, FMT_D),
9658 OPC_CMP_SF_D = FOP(56, FMT_D),
9659 OPC_CMP_NGLE_D = FOP(57, FMT_D),
9660 OPC_CMP_SEQ_D = FOP(58, FMT_D),
9661 OPC_CMP_NGL_D = FOP(59, FMT_D),
9662 OPC_CMP_LT_D = FOP(60, FMT_D),
9663 OPC_CMP_NGE_D = FOP(61, FMT_D),
9664 OPC_CMP_LE_D = FOP(62, FMT_D),
9665 OPC_CMP_NGT_D = FOP(63, FMT_D),
9666
9667 OPC_CVT_S_W = FOP(32, FMT_W),
9668 OPC_CVT_D_W = FOP(33, FMT_W),
9669 OPC_CVT_S_L = FOP(32, FMT_L),
9670 OPC_CVT_D_L = FOP(33, FMT_L),
9671 OPC_CVT_PS_PW = FOP(38, FMT_W),
9672
9673 OPC_ADD_PS = FOP(0, FMT_PS),
9674 OPC_SUB_PS = FOP(1, FMT_PS),
9675 OPC_MUL_PS = FOP(2, FMT_PS),
9676 OPC_DIV_PS = FOP(3, FMT_PS),
9677 OPC_ABS_PS = FOP(5, FMT_PS),
9678 OPC_MOV_PS = FOP(6, FMT_PS),
9679 OPC_NEG_PS = FOP(7, FMT_PS),
9680 OPC_MOVCF_PS = FOP(17, FMT_PS),
9681 OPC_MOVZ_PS = FOP(18, FMT_PS),
9682 OPC_MOVN_PS = FOP(19, FMT_PS),
9683 OPC_ADDR_PS = FOP(24, FMT_PS),
9684 OPC_MULR_PS = FOP(26, FMT_PS),
9685 OPC_RECIP2_PS = FOP(28, FMT_PS),
9686 OPC_RECIP1_PS = FOP(29, FMT_PS),
9687 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9688 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9689
9690 OPC_CVT_S_PU = FOP(32, FMT_PS),
9691 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9692 OPC_CVT_S_PL = FOP(40, FMT_PS),
9693 OPC_PLL_PS = FOP(44, FMT_PS),
9694 OPC_PLU_PS = FOP(45, FMT_PS),
9695 OPC_PUL_PS = FOP(46, FMT_PS),
9696 OPC_PUU_PS = FOP(47, FMT_PS),
9697 OPC_CMP_F_PS = FOP(48, FMT_PS),
9698 OPC_CMP_UN_PS = FOP(49, FMT_PS),
9699 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9700 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9701 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9702 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9703 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9704 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9705 OPC_CMP_SF_PS = FOP(56, FMT_PS),
9706 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9707 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9708 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9709 OPC_CMP_LT_PS = FOP(60, FMT_PS),
9710 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9711 OPC_CMP_LE_PS = FOP(62, FMT_PS),
9712 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9713};
9714
9715enum r6_f_cmp_op {
9716 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9717 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9718 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9719 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9720 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9721 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9722 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9723 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9724 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9725 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9726 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9727 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9728 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9729 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9730 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9731 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9732 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9733 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9734 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9735 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9736 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9737 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9738
9739 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9740 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9741 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9742 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9743 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9744 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9745 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9746 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9747 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9748 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9749 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9750 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9751 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9752 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9753 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9754 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9755 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9756 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9757 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9758 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9759 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9760 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9761};
9762
9763static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9764{
9765 TCGv t0 = tcg_temp_new();
9766
9767 switch (opc) {
9768 case OPC_MFC1:
9769 {
9770 TCGv_i32 fp0 = tcg_temp_new_i32();
9771
9772 gen_load_fpr32(ctx, fp0, fs);
9773 tcg_gen_ext_i32_tl(t0, fp0);
9774 tcg_temp_free_i32(fp0);
9775 }
9776 gen_store_gpr(t0, rt);
9777 break;
9778 case OPC_MTC1:
9779 gen_load_gpr(t0, rt);
9780 {
9781 TCGv_i32 fp0 = tcg_temp_new_i32();
9782
9783 tcg_gen_trunc_tl_i32(fp0, t0);
9784 gen_store_fpr32(ctx, fp0, fs);
9785 tcg_temp_free_i32(fp0);
9786 }
9787 break;
9788 case OPC_CFC1:
9789 gen_helper_1e0i(cfc1, t0, fs);
9790 gen_store_gpr(t0, rt);
9791 break;
9792 case OPC_CTC1:
9793 gen_load_gpr(t0, rt);
9794 save_cpu_state(ctx, 0);
9795 {
9796 TCGv_i32 fs_tmp = tcg_const_i32(fs);
9797
9798 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9799 tcg_temp_free_i32(fs_tmp);
9800 }
9801
9802 ctx->base.is_jmp = DISAS_STOP;
9803 break;
9804#if defined(TARGET_MIPS64)
9805 case OPC_DMFC1:
9806 gen_load_fpr64(ctx, t0, fs);
9807 gen_store_gpr(t0, rt);
9808 break;
9809 case OPC_DMTC1:
9810 gen_load_gpr(t0, rt);
9811 gen_store_fpr64(ctx, t0, fs);
9812 break;
9813#endif
9814 case OPC_MFHC1:
9815 {
9816 TCGv_i32 fp0 = tcg_temp_new_i32();
9817
9818 gen_load_fpr32h(ctx, fp0, fs);
9819 tcg_gen_ext_i32_tl(t0, fp0);
9820 tcg_temp_free_i32(fp0);
9821 }
9822 gen_store_gpr(t0, rt);
9823 break;
9824 case OPC_MTHC1:
9825 gen_load_gpr(t0, rt);
9826 {
9827 TCGv_i32 fp0 = tcg_temp_new_i32();
9828
9829 tcg_gen_trunc_tl_i32(fp0, t0);
9830 gen_store_fpr32h(ctx, fp0, fs);
9831 tcg_temp_free_i32(fp0);
9832 }
9833 break;
9834 default:
9835 MIPS_INVAL("cp1 move");
9836 gen_reserved_instruction(ctx);
9837 goto out;
9838 }
9839
9840 out:
9841 tcg_temp_free(t0);
9842}
9843
9844static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9845{
9846 TCGLabel *l1;
9847 TCGCond cond;
9848 TCGv_i32 t0;
9849
9850 if (rd == 0) {
9851
9852 return;
9853 }
9854
9855 if (tf) {
9856 cond = TCG_COND_EQ;
9857 } else {
9858 cond = TCG_COND_NE;
9859 }
9860
9861 l1 = gen_new_label();
9862 t0 = tcg_temp_new_i32();
9863 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9864 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9865 tcg_temp_free_i32(t0);
9866 gen_load_gpr(cpu_gpr[rd], rs);
9867 gen_set_label(l1);
9868}
9869
9870static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9871 int tf)
9872{
9873 int cond;
9874 TCGv_i32 t0 = tcg_temp_new_i32();
9875 TCGLabel *l1 = gen_new_label();
9876
9877 if (tf) {
9878 cond = TCG_COND_EQ;
9879 } else {
9880 cond = TCG_COND_NE;
9881 }
9882
9883 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9884 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9885 gen_load_fpr32(ctx, t0, fs);
9886 gen_store_fpr32(ctx, t0, fd);
9887 gen_set_label(l1);
9888 tcg_temp_free_i32(t0);
9889}
9890
9891static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9892 int tf)
9893{
9894 int cond;
9895 TCGv_i32 t0 = tcg_temp_new_i32();
9896 TCGv_i64 fp0;
9897 TCGLabel *l1 = gen_new_label();
9898
9899 if (tf) {
9900 cond = TCG_COND_EQ;
9901 } else {
9902 cond = TCG_COND_NE;
9903 }
9904
9905 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9906 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9907 tcg_temp_free_i32(t0);
9908 fp0 = tcg_temp_new_i64();
9909 gen_load_fpr64(ctx, fp0, fs);
9910 gen_store_fpr64(ctx, fp0, fd);
9911 tcg_temp_free_i64(fp0);
9912 gen_set_label(l1);
9913}
9914
9915static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9916 int cc, int tf)
9917{
9918 int cond;
9919 TCGv_i32 t0 = tcg_temp_new_i32();
9920 TCGLabel *l1 = gen_new_label();
9921 TCGLabel *l2 = gen_new_label();
9922
9923 if (tf) {
9924 cond = TCG_COND_EQ;
9925 } else {
9926 cond = TCG_COND_NE;
9927 }
9928
9929 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9930 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9931 gen_load_fpr32(ctx, t0, fs);
9932 gen_store_fpr32(ctx, t0, fd);
9933 gen_set_label(l1);
9934
9935 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9936 tcg_gen_brcondi_i32(cond, t0, 0, l2);
9937 gen_load_fpr32h(ctx, t0, fs);
9938 gen_store_fpr32h(ctx, t0, fd);
9939 tcg_temp_free_i32(t0);
9940 gen_set_label(l2);
9941}
9942
9943static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9944 int fs)
9945{
9946 TCGv_i32 t1 = tcg_const_i32(0);
9947 TCGv_i32 fp0 = tcg_temp_new_i32();
9948 TCGv_i32 fp1 = tcg_temp_new_i32();
9949 TCGv_i32 fp2 = tcg_temp_new_i32();
9950 gen_load_fpr32(ctx, fp0, fd);
9951 gen_load_fpr32(ctx, fp1, ft);
9952 gen_load_fpr32(ctx, fp2, fs);
9953
9954 switch (op1) {
9955 case OPC_SEL_S:
9956 tcg_gen_andi_i32(fp0, fp0, 1);
9957 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9958 break;
9959 case OPC_SELEQZ_S:
9960 tcg_gen_andi_i32(fp1, fp1, 1);
9961 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9962 break;
9963 case OPC_SELNEZ_S:
9964 tcg_gen_andi_i32(fp1, fp1, 1);
9965 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9966 break;
9967 default:
9968 MIPS_INVAL("gen_sel_s");
9969 gen_reserved_instruction(ctx);
9970 break;
9971 }
9972
9973 gen_store_fpr32(ctx, fp0, fd);
9974 tcg_temp_free_i32(fp2);
9975 tcg_temp_free_i32(fp1);
9976 tcg_temp_free_i32(fp0);
9977 tcg_temp_free_i32(t1);
9978}
9979
9980static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9981 int fs)
9982{
9983 TCGv_i64 t1 = tcg_const_i64(0);
9984 TCGv_i64 fp0 = tcg_temp_new_i64();
9985 TCGv_i64 fp1 = tcg_temp_new_i64();
9986 TCGv_i64 fp2 = tcg_temp_new_i64();
9987 gen_load_fpr64(ctx, fp0, fd);
9988 gen_load_fpr64(ctx, fp1, ft);
9989 gen_load_fpr64(ctx, fp2, fs);
9990
9991 switch (op1) {
9992 case OPC_SEL_D:
9993 tcg_gen_andi_i64(fp0, fp0, 1);
9994 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9995 break;
9996 case OPC_SELEQZ_D:
9997 tcg_gen_andi_i64(fp1, fp1, 1);
9998 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9999 break;
10000 case OPC_SELNEZ_D:
10001 tcg_gen_andi_i64(fp1, fp1, 1);
10002 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10003 break;
10004 default:
10005 MIPS_INVAL("gen_sel_d");
10006 gen_reserved_instruction(ctx);
10007 break;
10008 }
10009
10010 gen_store_fpr64(ctx, fp0, fd);
10011 tcg_temp_free_i64(fp2);
10012 tcg_temp_free_i64(fp1);
10013 tcg_temp_free_i64(fp0);
10014 tcg_temp_free_i64(t1);
10015}
10016
10017static void gen_farith(DisasContext *ctx, enum fopcode op1,
10018 int ft, int fs, int fd, int cc)
10019{
10020 uint32_t func = ctx->opcode & 0x3f;
10021 switch (op1) {
10022 case OPC_ADD_S:
10023 {
10024 TCGv_i32 fp0 = tcg_temp_new_i32();
10025 TCGv_i32 fp1 = tcg_temp_new_i32();
10026
10027 gen_load_fpr32(ctx, fp0, fs);
10028 gen_load_fpr32(ctx, fp1, ft);
10029 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10030 tcg_temp_free_i32(fp1);
10031 gen_store_fpr32(ctx, fp0, fd);
10032 tcg_temp_free_i32(fp0);
10033 }
10034 break;
10035 case OPC_SUB_S:
10036 {
10037 TCGv_i32 fp0 = tcg_temp_new_i32();
10038 TCGv_i32 fp1 = tcg_temp_new_i32();
10039
10040 gen_load_fpr32(ctx, fp0, fs);
10041 gen_load_fpr32(ctx, fp1, ft);
10042 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10043 tcg_temp_free_i32(fp1);
10044 gen_store_fpr32(ctx, fp0, fd);
10045 tcg_temp_free_i32(fp0);
10046 }
10047 break;
10048 case OPC_MUL_S:
10049 {
10050 TCGv_i32 fp0 = tcg_temp_new_i32();
10051 TCGv_i32 fp1 = tcg_temp_new_i32();
10052
10053 gen_load_fpr32(ctx, fp0, fs);
10054 gen_load_fpr32(ctx, fp1, ft);
10055 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10056 tcg_temp_free_i32(fp1);
10057 gen_store_fpr32(ctx, fp0, fd);
10058 tcg_temp_free_i32(fp0);
10059 }
10060 break;
10061 case OPC_DIV_S:
10062 {
10063 TCGv_i32 fp0 = tcg_temp_new_i32();
10064 TCGv_i32 fp1 = tcg_temp_new_i32();
10065
10066 gen_load_fpr32(ctx, fp0, fs);
10067 gen_load_fpr32(ctx, fp1, ft);
10068 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10069 tcg_temp_free_i32(fp1);
10070 gen_store_fpr32(ctx, fp0, fd);
10071 tcg_temp_free_i32(fp0);
10072 }
10073 break;
10074 case OPC_SQRT_S:
10075 {
10076 TCGv_i32 fp0 = tcg_temp_new_i32();
10077
10078 gen_load_fpr32(ctx, fp0, fs);
10079 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10080 gen_store_fpr32(ctx, fp0, fd);
10081 tcg_temp_free_i32(fp0);
10082 }
10083 break;
10084 case OPC_ABS_S:
10085 {
10086 TCGv_i32 fp0 = tcg_temp_new_i32();
10087
10088 gen_load_fpr32(ctx, fp0, fs);
10089 if (ctx->abs2008) {
10090 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10091 } else {
10092 gen_helper_float_abs_s(fp0, fp0);
10093 }
10094 gen_store_fpr32(ctx, fp0, fd);
10095 tcg_temp_free_i32(fp0);
10096 }
10097 break;
10098 case OPC_MOV_S:
10099 {
10100 TCGv_i32 fp0 = tcg_temp_new_i32();
10101
10102 gen_load_fpr32(ctx, fp0, fs);
10103 gen_store_fpr32(ctx, fp0, fd);
10104 tcg_temp_free_i32(fp0);
10105 }
10106 break;
10107 case OPC_NEG_S:
10108 {
10109 TCGv_i32 fp0 = tcg_temp_new_i32();
10110
10111 gen_load_fpr32(ctx, fp0, fs);
10112 if (ctx->abs2008) {
10113 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10114 } else {
10115 gen_helper_float_chs_s(fp0, fp0);
10116 }
10117 gen_store_fpr32(ctx, fp0, fd);
10118 tcg_temp_free_i32(fp0);
10119 }
10120 break;
10121 case OPC_ROUND_L_S:
10122 check_cp1_64bitmode(ctx);
10123 {
10124 TCGv_i32 fp32 = tcg_temp_new_i32();
10125 TCGv_i64 fp64 = tcg_temp_new_i64();
10126
10127 gen_load_fpr32(ctx, fp32, fs);
10128 if (ctx->nan2008) {
10129 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10130 } else {
10131 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10132 }
10133 tcg_temp_free_i32(fp32);
10134 gen_store_fpr64(ctx, fp64, fd);
10135 tcg_temp_free_i64(fp64);
10136 }
10137 break;
10138 case OPC_TRUNC_L_S:
10139 check_cp1_64bitmode(ctx);
10140 {
10141 TCGv_i32 fp32 = tcg_temp_new_i32();
10142 TCGv_i64 fp64 = tcg_temp_new_i64();
10143
10144 gen_load_fpr32(ctx, fp32, fs);
10145 if (ctx->nan2008) {
10146 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10147 } else {
10148 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10149 }
10150 tcg_temp_free_i32(fp32);
10151 gen_store_fpr64(ctx, fp64, fd);
10152 tcg_temp_free_i64(fp64);
10153 }
10154 break;
10155 case OPC_CEIL_L_S:
10156 check_cp1_64bitmode(ctx);
10157 {
10158 TCGv_i32 fp32 = tcg_temp_new_i32();
10159 TCGv_i64 fp64 = tcg_temp_new_i64();
10160
10161 gen_load_fpr32(ctx, fp32, fs);
10162 if (ctx->nan2008) {
10163 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10164 } else {
10165 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10166 }
10167 tcg_temp_free_i32(fp32);
10168 gen_store_fpr64(ctx, fp64, fd);
10169 tcg_temp_free_i64(fp64);
10170 }
10171 break;
10172 case OPC_FLOOR_L_S:
10173 check_cp1_64bitmode(ctx);
10174 {
10175 TCGv_i32 fp32 = tcg_temp_new_i32();
10176 TCGv_i64 fp64 = tcg_temp_new_i64();
10177
10178 gen_load_fpr32(ctx, fp32, fs);
10179 if (ctx->nan2008) {
10180 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10181 } else {
10182 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10183 }
10184 tcg_temp_free_i32(fp32);
10185 gen_store_fpr64(ctx, fp64, fd);
10186 tcg_temp_free_i64(fp64);
10187 }
10188 break;
10189 case OPC_ROUND_W_S:
10190 {
10191 TCGv_i32 fp0 = tcg_temp_new_i32();
10192
10193 gen_load_fpr32(ctx, fp0, fs);
10194 if (ctx->nan2008) {
10195 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10196 } else {
10197 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10198 }
10199 gen_store_fpr32(ctx, fp0, fd);
10200 tcg_temp_free_i32(fp0);
10201 }
10202 break;
10203 case OPC_TRUNC_W_S:
10204 {
10205 TCGv_i32 fp0 = tcg_temp_new_i32();
10206
10207 gen_load_fpr32(ctx, fp0, fs);
10208 if (ctx->nan2008) {
10209 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10210 } else {
10211 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10212 }
10213 gen_store_fpr32(ctx, fp0, fd);
10214 tcg_temp_free_i32(fp0);
10215 }
10216 break;
10217 case OPC_CEIL_W_S:
10218 {
10219 TCGv_i32 fp0 = tcg_temp_new_i32();
10220
10221 gen_load_fpr32(ctx, fp0, fs);
10222 if (ctx->nan2008) {
10223 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10224 } else {
10225 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10226 }
10227 gen_store_fpr32(ctx, fp0, fd);
10228 tcg_temp_free_i32(fp0);
10229 }
10230 break;
10231 case OPC_FLOOR_W_S:
10232 {
10233 TCGv_i32 fp0 = tcg_temp_new_i32();
10234
10235 gen_load_fpr32(ctx, fp0, fs);
10236 if (ctx->nan2008) {
10237 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10238 } else {
10239 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10240 }
10241 gen_store_fpr32(ctx, fp0, fd);
10242 tcg_temp_free_i32(fp0);
10243 }
10244 break;
10245 case OPC_SEL_S:
10246 check_insn(ctx, ISA_MIPS_R6);
10247 gen_sel_s(ctx, op1, fd, ft, fs);
10248 break;
10249 case OPC_SELEQZ_S:
10250 check_insn(ctx, ISA_MIPS_R6);
10251 gen_sel_s(ctx, op1, fd, ft, fs);
10252 break;
10253 case OPC_SELNEZ_S:
10254 check_insn(ctx, ISA_MIPS_R6);
10255 gen_sel_s(ctx, op1, fd, ft, fs);
10256 break;
10257 case OPC_MOVCF_S:
10258 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10259 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10260 break;
10261 case OPC_MOVZ_S:
10262 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10263 {
10264 TCGLabel *l1 = gen_new_label();
10265 TCGv_i32 fp0;
10266
10267 if (ft != 0) {
10268 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10269 }
10270 fp0 = tcg_temp_new_i32();
10271 gen_load_fpr32(ctx, fp0, fs);
10272 gen_store_fpr32(ctx, fp0, fd);
10273 tcg_temp_free_i32(fp0);
10274 gen_set_label(l1);
10275 }
10276 break;
10277 case OPC_MOVN_S:
10278 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10279 {
10280 TCGLabel *l1 = gen_new_label();
10281 TCGv_i32 fp0;
10282
10283 if (ft != 0) {
10284 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10285 fp0 = tcg_temp_new_i32();
10286 gen_load_fpr32(ctx, fp0, fs);
10287 gen_store_fpr32(ctx, fp0, fd);
10288 tcg_temp_free_i32(fp0);
10289 gen_set_label(l1);
10290 }
10291 }
10292 break;
10293 case OPC_RECIP_S:
10294 {
10295 TCGv_i32 fp0 = tcg_temp_new_i32();
10296
10297 gen_load_fpr32(ctx, fp0, fs);
10298 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10299 gen_store_fpr32(ctx, fp0, fd);
10300 tcg_temp_free_i32(fp0);
10301 }
10302 break;
10303 case OPC_RSQRT_S:
10304 {
10305 TCGv_i32 fp0 = tcg_temp_new_i32();
10306
10307 gen_load_fpr32(ctx, fp0, fs);
10308 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10309 gen_store_fpr32(ctx, fp0, fd);
10310 tcg_temp_free_i32(fp0);
10311 }
10312 break;
10313 case OPC_MADDF_S:
10314 check_insn(ctx, ISA_MIPS_R6);
10315 {
10316 TCGv_i32 fp0 = tcg_temp_new_i32();
10317 TCGv_i32 fp1 = tcg_temp_new_i32();
10318 TCGv_i32 fp2 = tcg_temp_new_i32();
10319 gen_load_fpr32(ctx, fp0, fs);
10320 gen_load_fpr32(ctx, fp1, ft);
10321 gen_load_fpr32(ctx, fp2, fd);
10322 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10323 gen_store_fpr32(ctx, fp2, fd);
10324 tcg_temp_free_i32(fp2);
10325 tcg_temp_free_i32(fp1);
10326 tcg_temp_free_i32(fp0);
10327 }
10328 break;
10329 case OPC_MSUBF_S:
10330 check_insn(ctx, ISA_MIPS_R6);
10331 {
10332 TCGv_i32 fp0 = tcg_temp_new_i32();
10333 TCGv_i32 fp1 = tcg_temp_new_i32();
10334 TCGv_i32 fp2 = tcg_temp_new_i32();
10335 gen_load_fpr32(ctx, fp0, fs);
10336 gen_load_fpr32(ctx, fp1, ft);
10337 gen_load_fpr32(ctx, fp2, fd);
10338 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10339 gen_store_fpr32(ctx, fp2, fd);
10340 tcg_temp_free_i32(fp2);
10341 tcg_temp_free_i32(fp1);
10342 tcg_temp_free_i32(fp0);
10343 }
10344 break;
10345 case OPC_RINT_S:
10346 check_insn(ctx, ISA_MIPS_R6);
10347 {
10348 TCGv_i32 fp0 = tcg_temp_new_i32();
10349 gen_load_fpr32(ctx, fp0, fs);
10350 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10351 gen_store_fpr32(ctx, fp0, fd);
10352 tcg_temp_free_i32(fp0);
10353 }
10354 break;
10355 case OPC_CLASS_S:
10356 check_insn(ctx, ISA_MIPS_R6);
10357 {
10358 TCGv_i32 fp0 = tcg_temp_new_i32();
10359 gen_load_fpr32(ctx, fp0, fs);
10360 gen_helper_float_class_s(fp0, cpu_env, fp0);
10361 gen_store_fpr32(ctx, fp0, fd);
10362 tcg_temp_free_i32(fp0);
10363 }
10364 break;
10365 case OPC_MIN_S:
10366 if (ctx->insn_flags & ISA_MIPS_R6) {
10367
10368 TCGv_i32 fp0 = tcg_temp_new_i32();
10369 TCGv_i32 fp1 = tcg_temp_new_i32();
10370 TCGv_i32 fp2 = tcg_temp_new_i32();
10371 gen_load_fpr32(ctx, fp0, fs);
10372 gen_load_fpr32(ctx, fp1, ft);
10373 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10374 gen_store_fpr32(ctx, fp2, fd);
10375 tcg_temp_free_i32(fp2);
10376 tcg_temp_free_i32(fp1);
10377 tcg_temp_free_i32(fp0);
10378 } else {
10379
10380 check_cp1_64bitmode(ctx);
10381 {
10382 TCGv_i32 fp0 = tcg_temp_new_i32();
10383 TCGv_i32 fp1 = tcg_temp_new_i32();
10384
10385 gen_load_fpr32(ctx, fp0, fs);
10386 gen_load_fpr32(ctx, fp1, ft);
10387 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10388 tcg_temp_free_i32(fp1);
10389 gen_store_fpr32(ctx, fp0, fd);
10390 tcg_temp_free_i32(fp0);
10391 }
10392 }
10393 break;
10394 case OPC_MINA_S:
10395 if (ctx->insn_flags & ISA_MIPS_R6) {
10396
10397 TCGv_i32 fp0 = tcg_temp_new_i32();
10398 TCGv_i32 fp1 = tcg_temp_new_i32();
10399 TCGv_i32 fp2 = tcg_temp_new_i32();
10400 gen_load_fpr32(ctx, fp0, fs);
10401 gen_load_fpr32(ctx, fp1, ft);
10402 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10403 gen_store_fpr32(ctx, fp2, fd);
10404 tcg_temp_free_i32(fp2);
10405 tcg_temp_free_i32(fp1);
10406 tcg_temp_free_i32(fp0);
10407 } else {
10408
10409 check_cp1_64bitmode(ctx);
10410 {
10411 TCGv_i32 fp0 = tcg_temp_new_i32();
10412
10413 gen_load_fpr32(ctx, fp0, fs);
10414 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10415 gen_store_fpr32(ctx, fp0, fd);
10416 tcg_temp_free_i32(fp0);
10417 }
10418 }
10419 break;
10420 case OPC_MAX_S:
10421 if (ctx->insn_flags & ISA_MIPS_R6) {
10422
10423 TCGv_i32 fp0 = tcg_temp_new_i32();
10424 TCGv_i32 fp1 = tcg_temp_new_i32();
10425 gen_load_fpr32(ctx, fp0, fs);
10426 gen_load_fpr32(ctx, fp1, ft);
10427 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10428 gen_store_fpr32(ctx, fp1, fd);
10429 tcg_temp_free_i32(fp1);
10430 tcg_temp_free_i32(fp0);
10431 } else {
10432
10433 check_cp1_64bitmode(ctx);
10434 {
10435 TCGv_i32 fp0 = tcg_temp_new_i32();
10436
10437 gen_load_fpr32(ctx, fp0, fs);
10438 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10439 gen_store_fpr32(ctx, fp0, fd);
10440 tcg_temp_free_i32(fp0);
10441 }
10442 }
10443 break;
10444 case OPC_MAXA_S:
10445 if (ctx->insn_flags & ISA_MIPS_R6) {
10446
10447 TCGv_i32 fp0 = tcg_temp_new_i32();
10448 TCGv_i32 fp1 = tcg_temp_new_i32();
10449 gen_load_fpr32(ctx, fp0, fs);
10450 gen_load_fpr32(ctx, fp1, ft);
10451 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10452 gen_store_fpr32(ctx, fp1, fd);
10453 tcg_temp_free_i32(fp1);
10454 tcg_temp_free_i32(fp0);
10455 } else {
10456
10457 check_cp1_64bitmode(ctx);
10458 {
10459 TCGv_i32 fp0 = tcg_temp_new_i32();
10460 TCGv_i32 fp1 = tcg_temp_new_i32();
10461
10462 gen_load_fpr32(ctx, fp0, fs);
10463 gen_load_fpr32(ctx, fp1, ft);
10464 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10465 tcg_temp_free_i32(fp1);
10466 gen_store_fpr32(ctx, fp0, fd);
10467 tcg_temp_free_i32(fp0);
10468 }
10469 }
10470 break;
10471 case OPC_CVT_D_S:
10472 check_cp1_registers(ctx, fd);
10473 {
10474 TCGv_i32 fp32 = tcg_temp_new_i32();
10475 TCGv_i64 fp64 = tcg_temp_new_i64();
10476
10477 gen_load_fpr32(ctx, fp32, fs);
10478 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10479 tcg_temp_free_i32(fp32);
10480 gen_store_fpr64(ctx, fp64, fd);
10481 tcg_temp_free_i64(fp64);
10482 }
10483 break;
10484 case OPC_CVT_W_S:
10485 {
10486 TCGv_i32 fp0 = tcg_temp_new_i32();
10487
10488 gen_load_fpr32(ctx, fp0, fs);
10489 if (ctx->nan2008) {
10490 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10491 } else {
10492 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10493 }
10494 gen_store_fpr32(ctx, fp0, fd);
10495 tcg_temp_free_i32(fp0);
10496 }
10497 break;
10498 case OPC_CVT_L_S:
10499 check_cp1_64bitmode(ctx);
10500 {
10501 TCGv_i32 fp32 = tcg_temp_new_i32();
10502 TCGv_i64 fp64 = tcg_temp_new_i64();
10503
10504 gen_load_fpr32(ctx, fp32, fs);
10505 if (ctx->nan2008) {
10506 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10507 } else {
10508 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10509 }
10510 tcg_temp_free_i32(fp32);
10511 gen_store_fpr64(ctx, fp64, fd);
10512 tcg_temp_free_i64(fp64);
10513 }
10514 break;
10515 case OPC_CVT_PS_S:
10516 check_ps(ctx);
10517 {
10518 TCGv_i64 fp64 = tcg_temp_new_i64();
10519 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10520 TCGv_i32 fp32_1 = tcg_temp_new_i32();
10521
10522 gen_load_fpr32(ctx, fp32_0, fs);
10523 gen_load_fpr32(ctx, fp32_1, ft);
10524 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10525 tcg_temp_free_i32(fp32_1);
10526 tcg_temp_free_i32(fp32_0);
10527 gen_store_fpr64(ctx, fp64, fd);
10528 tcg_temp_free_i64(fp64);
10529 }
10530 break;
10531 case OPC_CMP_F_S:
10532 case OPC_CMP_UN_S:
10533 case OPC_CMP_EQ_S:
10534 case OPC_CMP_UEQ_S:
10535 case OPC_CMP_OLT_S:
10536 case OPC_CMP_ULT_S:
10537 case OPC_CMP_OLE_S:
10538 case OPC_CMP_ULE_S:
10539 case OPC_CMP_SF_S:
10540 case OPC_CMP_NGLE_S:
10541 case OPC_CMP_SEQ_S:
10542 case OPC_CMP_NGL_S:
10543 case OPC_CMP_LT_S:
10544 case OPC_CMP_NGE_S:
10545 case OPC_CMP_LE_S:
10546 case OPC_CMP_NGT_S:
10547 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10548 if (ctx->opcode & (1 << 6)) {
10549 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10550 } else {
10551 gen_cmp_s(ctx, func - 48, ft, fs, cc);
10552 }
10553 break;
10554 case OPC_ADD_D:
10555 check_cp1_registers(ctx, fs | ft | fd);
10556 {
10557 TCGv_i64 fp0 = tcg_temp_new_i64();
10558 TCGv_i64 fp1 = tcg_temp_new_i64();
10559
10560 gen_load_fpr64(ctx, fp0, fs);
10561 gen_load_fpr64(ctx, fp1, ft);
10562 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10563 tcg_temp_free_i64(fp1);
10564 gen_store_fpr64(ctx, fp0, fd);
10565 tcg_temp_free_i64(fp0);
10566 }
10567 break;
10568 case OPC_SUB_D:
10569 check_cp1_registers(ctx, fs | ft | fd);
10570 {
10571 TCGv_i64 fp0 = tcg_temp_new_i64();
10572 TCGv_i64 fp1 = tcg_temp_new_i64();
10573
10574 gen_load_fpr64(ctx, fp0, fs);
10575 gen_load_fpr64(ctx, fp1, ft);
10576 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10577 tcg_temp_free_i64(fp1);
10578 gen_store_fpr64(ctx, fp0, fd);
10579 tcg_temp_free_i64(fp0);
10580 }
10581 break;
10582 case OPC_MUL_D:
10583 check_cp1_registers(ctx, fs | ft | fd);
10584 {
10585 TCGv_i64 fp0 = tcg_temp_new_i64();
10586 TCGv_i64 fp1 = tcg_temp_new_i64();
10587
10588 gen_load_fpr64(ctx, fp0, fs);
10589 gen_load_fpr64(ctx, fp1, ft);
10590 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10591 tcg_temp_free_i64(fp1);
10592 gen_store_fpr64(ctx, fp0, fd);
10593 tcg_temp_free_i64(fp0);
10594 }
10595 break;
10596 case OPC_DIV_D:
10597 check_cp1_registers(ctx, fs | ft | fd);
10598 {
10599 TCGv_i64 fp0 = tcg_temp_new_i64();
10600 TCGv_i64 fp1 = tcg_temp_new_i64();
10601
10602 gen_load_fpr64(ctx, fp0, fs);
10603 gen_load_fpr64(ctx, fp1, ft);
10604 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10605 tcg_temp_free_i64(fp1);
10606 gen_store_fpr64(ctx, fp0, fd);
10607 tcg_temp_free_i64(fp0);
10608 }
10609 break;
10610 case OPC_SQRT_D:
10611 check_cp1_registers(ctx, fs | fd);
10612 {
10613 TCGv_i64 fp0 = tcg_temp_new_i64();
10614
10615 gen_load_fpr64(ctx, fp0, fs);
10616 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10617 gen_store_fpr64(ctx, fp0, fd);
10618 tcg_temp_free_i64(fp0);
10619 }
10620 break;
10621 case OPC_ABS_D:
10622 check_cp1_registers(ctx, fs | fd);
10623 {
10624 TCGv_i64 fp0 = tcg_temp_new_i64();
10625
10626 gen_load_fpr64(ctx, fp0, fs);
10627 if (ctx->abs2008) {
10628 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10629 } else {
10630 gen_helper_float_abs_d(fp0, fp0);
10631 }
10632 gen_store_fpr64(ctx, fp0, fd);
10633 tcg_temp_free_i64(fp0);
10634 }
10635 break;
10636 case OPC_MOV_D:
10637 check_cp1_registers(ctx, fs | fd);
10638 {
10639 TCGv_i64 fp0 = tcg_temp_new_i64();
10640
10641 gen_load_fpr64(ctx, fp0, fs);
10642 gen_store_fpr64(ctx, fp0, fd);
10643 tcg_temp_free_i64(fp0);
10644 }
10645 break;
10646 case OPC_NEG_D:
10647 check_cp1_registers(ctx, fs | fd);
10648 {
10649 TCGv_i64 fp0 = tcg_temp_new_i64();
10650
10651 gen_load_fpr64(ctx, fp0, fs);
10652 if (ctx->abs2008) {
10653 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10654 } else {
10655 gen_helper_float_chs_d(fp0, fp0);
10656 }
10657 gen_store_fpr64(ctx, fp0, fd);
10658 tcg_temp_free_i64(fp0);
10659 }
10660 break;
10661 case OPC_ROUND_L_D:
10662 check_cp1_64bitmode(ctx);
10663 {
10664 TCGv_i64 fp0 = tcg_temp_new_i64();
10665
10666 gen_load_fpr64(ctx, fp0, fs);
10667 if (ctx->nan2008) {
10668 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10669 } else {
10670 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10671 }
10672 gen_store_fpr64(ctx, fp0, fd);
10673 tcg_temp_free_i64(fp0);
10674 }
10675 break;
10676 case OPC_TRUNC_L_D:
10677 check_cp1_64bitmode(ctx);
10678 {
10679 TCGv_i64 fp0 = tcg_temp_new_i64();
10680
10681 gen_load_fpr64(ctx, fp0, fs);
10682 if (ctx->nan2008) {
10683 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10684 } else {
10685 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10686 }
10687 gen_store_fpr64(ctx, fp0, fd);
10688 tcg_temp_free_i64(fp0);
10689 }
10690 break;
10691 case OPC_CEIL_L_D:
10692 check_cp1_64bitmode(ctx);
10693 {
10694 TCGv_i64 fp0 = tcg_temp_new_i64();
10695
10696 gen_load_fpr64(ctx, fp0, fs);
10697 if (ctx->nan2008) {
10698 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10699 } else {
10700 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10701 }
10702 gen_store_fpr64(ctx, fp0, fd);
10703 tcg_temp_free_i64(fp0);
10704 }
10705 break;
10706 case OPC_FLOOR_L_D:
10707 check_cp1_64bitmode(ctx);
10708 {
10709 TCGv_i64 fp0 = tcg_temp_new_i64();
10710
10711 gen_load_fpr64(ctx, fp0, fs);
10712 if (ctx->nan2008) {
10713 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10714 } else {
10715 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10716 }
10717 gen_store_fpr64(ctx, fp0, fd);
10718 tcg_temp_free_i64(fp0);
10719 }
10720 break;
10721 case OPC_ROUND_W_D:
10722 check_cp1_registers(ctx, fs);
10723 {
10724 TCGv_i32 fp32 = tcg_temp_new_i32();
10725 TCGv_i64 fp64 = tcg_temp_new_i64();
10726
10727 gen_load_fpr64(ctx, fp64, fs);
10728 if (ctx->nan2008) {
10729 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10730 } else {
10731 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10732 }
10733 tcg_temp_free_i64(fp64);
10734 gen_store_fpr32(ctx, fp32, fd);
10735 tcg_temp_free_i32(fp32);
10736 }
10737 break;
10738 case OPC_TRUNC_W_D:
10739 check_cp1_registers(ctx, fs);
10740 {
10741 TCGv_i32 fp32 = tcg_temp_new_i32();
10742 TCGv_i64 fp64 = tcg_temp_new_i64();
10743
10744 gen_load_fpr64(ctx, fp64, fs);
10745 if (ctx->nan2008) {
10746 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10747 } else {
10748 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10749 }
10750 tcg_temp_free_i64(fp64);
10751 gen_store_fpr32(ctx, fp32, fd);
10752 tcg_temp_free_i32(fp32);
10753 }
10754 break;
10755 case OPC_CEIL_W_D:
10756 check_cp1_registers(ctx, fs);
10757 {
10758 TCGv_i32 fp32 = tcg_temp_new_i32();
10759 TCGv_i64 fp64 = tcg_temp_new_i64();
10760
10761 gen_load_fpr64(ctx, fp64, fs);
10762 if (ctx->nan2008) {
10763 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10764 } else {
10765 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10766 }
10767 tcg_temp_free_i64(fp64);
10768 gen_store_fpr32(ctx, fp32, fd);
10769 tcg_temp_free_i32(fp32);
10770 }
10771 break;
10772 case OPC_FLOOR_W_D:
10773 check_cp1_registers(ctx, fs);
10774 {
10775 TCGv_i32 fp32 = tcg_temp_new_i32();
10776 TCGv_i64 fp64 = tcg_temp_new_i64();
10777
10778 gen_load_fpr64(ctx, fp64, fs);
10779 if (ctx->nan2008) {
10780 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10781 } else {
10782 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10783 }
10784 tcg_temp_free_i64(fp64);
10785 gen_store_fpr32(ctx, fp32, fd);
10786 tcg_temp_free_i32(fp32);
10787 }
10788 break;
10789 case OPC_SEL_D:
10790 check_insn(ctx, ISA_MIPS_R6);
10791 gen_sel_d(ctx, op1, fd, ft, fs);
10792 break;
10793 case OPC_SELEQZ_D:
10794 check_insn(ctx, ISA_MIPS_R6);
10795 gen_sel_d(ctx, op1, fd, ft, fs);
10796 break;
10797 case OPC_SELNEZ_D:
10798 check_insn(ctx, ISA_MIPS_R6);
10799 gen_sel_d(ctx, op1, fd, ft, fs);
10800 break;
10801 case OPC_MOVCF_D:
10802 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10803 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10804 break;
10805 case OPC_MOVZ_D:
10806 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10807 {
10808 TCGLabel *l1 = gen_new_label();
10809 TCGv_i64 fp0;
10810
10811 if (ft != 0) {
10812 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10813 }
10814 fp0 = tcg_temp_new_i64();
10815 gen_load_fpr64(ctx, fp0, fs);
10816 gen_store_fpr64(ctx, fp0, fd);
10817 tcg_temp_free_i64(fp0);
10818 gen_set_label(l1);
10819 }
10820 break;
10821 case OPC_MOVN_D:
10822 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10823 {
10824 TCGLabel *l1 = gen_new_label();
10825 TCGv_i64 fp0;
10826
10827 if (ft != 0) {
10828 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10829 fp0 = tcg_temp_new_i64();
10830 gen_load_fpr64(ctx, fp0, fs);
10831 gen_store_fpr64(ctx, fp0, fd);
10832 tcg_temp_free_i64(fp0);
10833 gen_set_label(l1);
10834 }
10835 }
10836 break;
10837 case OPC_RECIP_D:
10838 check_cp1_registers(ctx, fs | fd);
10839 {
10840 TCGv_i64 fp0 = tcg_temp_new_i64();
10841
10842 gen_load_fpr64(ctx, fp0, fs);
10843 gen_helper_float_recip_d(fp0, cpu_env, fp0);
10844 gen_store_fpr64(ctx, fp0, fd);
10845 tcg_temp_free_i64(fp0);
10846 }
10847 break;
10848 case OPC_RSQRT_D:
10849 check_cp1_registers(ctx, fs | fd);
10850 {
10851 TCGv_i64 fp0 = tcg_temp_new_i64();
10852
10853 gen_load_fpr64(ctx, fp0, fs);
10854 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10855 gen_store_fpr64(ctx, fp0, fd);
10856 tcg_temp_free_i64(fp0);
10857 }
10858 break;
10859 case OPC_MADDF_D:
10860 check_insn(ctx, ISA_MIPS_R6);
10861 {
10862 TCGv_i64 fp0 = tcg_temp_new_i64();
10863 TCGv_i64 fp1 = tcg_temp_new_i64();
10864 TCGv_i64 fp2 = tcg_temp_new_i64();
10865 gen_load_fpr64(ctx, fp0, fs);
10866 gen_load_fpr64(ctx, fp1, ft);
10867 gen_load_fpr64(ctx, fp2, fd);
10868 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10869 gen_store_fpr64(ctx, fp2, fd);
10870 tcg_temp_free_i64(fp2);
10871 tcg_temp_free_i64(fp1);
10872 tcg_temp_free_i64(fp0);
10873 }
10874 break;
10875 case OPC_MSUBF_D:
10876 check_insn(ctx, ISA_MIPS_R6);
10877 {
10878 TCGv_i64 fp0 = tcg_temp_new_i64();
10879 TCGv_i64 fp1 = tcg_temp_new_i64();
10880 TCGv_i64 fp2 = tcg_temp_new_i64();
10881 gen_load_fpr64(ctx, fp0, fs);
10882 gen_load_fpr64(ctx, fp1, ft);
10883 gen_load_fpr64(ctx, fp2, fd);
10884 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10885 gen_store_fpr64(ctx, fp2, fd);
10886 tcg_temp_free_i64(fp2);
10887 tcg_temp_free_i64(fp1);
10888 tcg_temp_free_i64(fp0);
10889 }
10890 break;
10891 case OPC_RINT_D:
10892 check_insn(ctx, ISA_MIPS_R6);
10893 {
10894 TCGv_i64 fp0 = tcg_temp_new_i64();
10895 gen_load_fpr64(ctx, fp0, fs);
10896 gen_helper_float_rint_d(fp0, cpu_env, fp0);
10897 gen_store_fpr64(ctx, fp0, fd);
10898 tcg_temp_free_i64(fp0);
10899 }
10900 break;
10901 case OPC_CLASS_D:
10902 check_insn(ctx, ISA_MIPS_R6);
10903 {
10904 TCGv_i64 fp0 = tcg_temp_new_i64();
10905 gen_load_fpr64(ctx, fp0, fs);
10906 gen_helper_float_class_d(fp0, cpu_env, fp0);
10907 gen_store_fpr64(ctx, fp0, fd);
10908 tcg_temp_free_i64(fp0);
10909 }
10910 break;
10911 case OPC_MIN_D:
10912 if (ctx->insn_flags & ISA_MIPS_R6) {
10913
10914 TCGv_i64 fp0 = tcg_temp_new_i64();
10915 TCGv_i64 fp1 = tcg_temp_new_i64();
10916 gen_load_fpr64(ctx, fp0, fs);
10917 gen_load_fpr64(ctx, fp1, ft);
10918 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10919 gen_store_fpr64(ctx, fp1, fd);
10920 tcg_temp_free_i64(fp1);
10921 tcg_temp_free_i64(fp0);
10922 } else {
10923
10924 check_cp1_64bitmode(ctx);
10925 {
10926 TCGv_i64 fp0 = tcg_temp_new_i64();
10927 TCGv_i64 fp1 = tcg_temp_new_i64();
10928
10929 gen_load_fpr64(ctx, fp0, fs);
10930 gen_load_fpr64(ctx, fp1, ft);
10931 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10932 tcg_temp_free_i64(fp1);
10933 gen_store_fpr64(ctx, fp0, fd);
10934 tcg_temp_free_i64(fp0);
10935 }
10936 }
10937 break;
10938 case OPC_MINA_D:
10939 if (ctx->insn_flags & ISA_MIPS_R6) {
10940
10941 TCGv_i64 fp0 = tcg_temp_new_i64();
10942 TCGv_i64 fp1 = tcg_temp_new_i64();
10943 gen_load_fpr64(ctx, fp0, fs);
10944 gen_load_fpr64(ctx, fp1, ft);
10945 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10946 gen_store_fpr64(ctx, fp1, fd);
10947 tcg_temp_free_i64(fp1);
10948 tcg_temp_free_i64(fp0);
10949 } else {
10950
10951 check_cp1_64bitmode(ctx);
10952 {
10953 TCGv_i64 fp0 = tcg_temp_new_i64();
10954
10955 gen_load_fpr64(ctx, fp0, fs);
10956 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10957 gen_store_fpr64(ctx, fp0, fd);
10958 tcg_temp_free_i64(fp0);
10959 }
10960 }
10961 break;
10962 case OPC_MAX_D:
10963 if (ctx->insn_flags & ISA_MIPS_R6) {
10964
10965 TCGv_i64 fp0 = tcg_temp_new_i64();
10966 TCGv_i64 fp1 = tcg_temp_new_i64();
10967 gen_load_fpr64(ctx, fp0, fs);
10968 gen_load_fpr64(ctx, fp1, ft);
10969 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10970 gen_store_fpr64(ctx, fp1, fd);
10971 tcg_temp_free_i64(fp1);
10972 tcg_temp_free_i64(fp0);
10973 } else {
10974
10975 check_cp1_64bitmode(ctx);
10976 {
10977 TCGv_i64 fp0 = tcg_temp_new_i64();
10978
10979 gen_load_fpr64(ctx, fp0, fs);
10980 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10981 gen_store_fpr64(ctx, fp0, fd);
10982 tcg_temp_free_i64(fp0);
10983 }
10984 }
10985 break;
10986 case OPC_MAXA_D:
10987 if (ctx->insn_flags & ISA_MIPS_R6) {
10988
10989 TCGv_i64 fp0 = tcg_temp_new_i64();
10990 TCGv_i64 fp1 = tcg_temp_new_i64();
10991 gen_load_fpr64(ctx, fp0, fs);
10992 gen_load_fpr64(ctx, fp1, ft);
10993 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10994 gen_store_fpr64(ctx, fp1, fd);
10995 tcg_temp_free_i64(fp1);
10996 tcg_temp_free_i64(fp0);
10997 } else {
10998
10999 check_cp1_64bitmode(ctx);
11000 {
11001 TCGv_i64 fp0 = tcg_temp_new_i64();
11002 TCGv_i64 fp1 = tcg_temp_new_i64();
11003
11004 gen_load_fpr64(ctx, fp0, fs);
11005 gen_load_fpr64(ctx, fp1, ft);
11006 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11007 tcg_temp_free_i64(fp1);
11008 gen_store_fpr64(ctx, fp0, fd);
11009 tcg_temp_free_i64(fp0);
11010 }
11011 }
11012 break;
11013 case OPC_CMP_F_D:
11014 case OPC_CMP_UN_D:
11015 case OPC_CMP_EQ_D:
11016 case OPC_CMP_UEQ_D:
11017 case OPC_CMP_OLT_D:
11018 case OPC_CMP_ULT_D:
11019 case OPC_CMP_OLE_D:
11020 case OPC_CMP_ULE_D:
11021 case OPC_CMP_SF_D:
11022 case OPC_CMP_NGLE_D:
11023 case OPC_CMP_SEQ_D:
11024 case OPC_CMP_NGL_D:
11025 case OPC_CMP_LT_D:
11026 case OPC_CMP_NGE_D:
11027 case OPC_CMP_LE_D:
11028 case OPC_CMP_NGT_D:
11029 check_insn_opc_removed(ctx, ISA_MIPS_R6);
11030 if (ctx->opcode & (1 << 6)) {
11031 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
11032 } else {
11033 gen_cmp_d(ctx, func - 48, ft, fs, cc);
11034 }
11035 break;
11036 case OPC_CVT_S_D:
11037 check_cp1_registers(ctx, fs);
11038 {
11039 TCGv_i32 fp32 = tcg_temp_new_i32();
11040 TCGv_i64 fp64 = tcg_temp_new_i64();
11041
11042 gen_load_fpr64(ctx, fp64, fs);
11043 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11044 tcg_temp_free_i64(fp64);
11045 gen_store_fpr32(ctx, fp32, fd);
11046 tcg_temp_free_i32(fp32);
11047 }
11048 break;
11049 case OPC_CVT_W_D:
11050 check_cp1_registers(ctx, fs);
11051 {
11052 TCGv_i32 fp32 = tcg_temp_new_i32();
11053 TCGv_i64 fp64 = tcg_temp_new_i64();
11054
11055 gen_load_fpr64(ctx, fp64, fs);
11056 if (ctx->nan2008) {
11057 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11058 } else {
11059 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11060 }
11061 tcg_temp_free_i64(fp64);
11062 gen_store_fpr32(ctx, fp32, fd);
11063 tcg_temp_free_i32(fp32);
11064 }
11065 break;
11066 case OPC_CVT_L_D:
11067 check_cp1_64bitmode(ctx);
11068 {
11069 TCGv_i64 fp0 = tcg_temp_new_i64();
11070
11071 gen_load_fpr64(ctx, fp0, fs);
11072 if (ctx->nan2008) {
11073 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11074 } else {
11075 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11076 }
11077 gen_store_fpr64(ctx, fp0, fd);
11078 tcg_temp_free_i64(fp0);
11079 }
11080 break;
11081 case OPC_CVT_S_W:
11082 {
11083 TCGv_i32 fp0 = tcg_temp_new_i32();
11084
11085 gen_load_fpr32(ctx, fp0, fs);
11086 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11087 gen_store_fpr32(ctx, fp0, fd);
11088 tcg_temp_free_i32(fp0);
11089 }
11090 break;
11091 case OPC_CVT_D_W:
11092 check_cp1_registers(ctx, fd);
11093 {
11094 TCGv_i32 fp32 = tcg_temp_new_i32();
11095 TCGv_i64 fp64 = tcg_temp_new_i64();
11096
11097 gen_load_fpr32(ctx, fp32, fs);
11098 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11099 tcg_temp_free_i32(fp32);
11100 gen_store_fpr64(ctx, fp64, fd);
11101 tcg_temp_free_i64(fp64);
11102 }
11103 break;
11104 case OPC_CVT_S_L:
11105 check_cp1_64bitmode(ctx);
11106 {
11107 TCGv_i32 fp32 = tcg_temp_new_i32();
11108 TCGv_i64 fp64 = tcg_temp_new_i64();
11109
11110 gen_load_fpr64(ctx, fp64, fs);
11111 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11112 tcg_temp_free_i64(fp64);
11113 gen_store_fpr32(ctx, fp32, fd);
11114 tcg_temp_free_i32(fp32);
11115 }
11116 break;
11117 case OPC_CVT_D_L:
11118 check_cp1_64bitmode(ctx);
11119 {
11120 TCGv_i64 fp0 = tcg_temp_new_i64();
11121
11122 gen_load_fpr64(ctx, fp0, fs);
11123 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11124 gen_store_fpr64(ctx, fp0, fd);
11125 tcg_temp_free_i64(fp0);
11126 }
11127 break;
11128 case OPC_CVT_PS_PW:
11129 check_ps(ctx);
11130 {
11131 TCGv_i64 fp0 = tcg_temp_new_i64();
11132
11133 gen_load_fpr64(ctx, fp0, fs);
11134 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11135 gen_store_fpr64(ctx, fp0, fd);
11136 tcg_temp_free_i64(fp0);
11137 }
11138 break;
11139 case OPC_ADD_PS:
11140 check_ps(ctx);
11141 {
11142 TCGv_i64 fp0 = tcg_temp_new_i64();
11143 TCGv_i64 fp1 = tcg_temp_new_i64();
11144
11145 gen_load_fpr64(ctx, fp0, fs);
11146 gen_load_fpr64(ctx, fp1, ft);
11147 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11148 tcg_temp_free_i64(fp1);
11149 gen_store_fpr64(ctx, fp0, fd);
11150 tcg_temp_free_i64(fp0);
11151 }
11152 break;
11153 case OPC_SUB_PS:
11154 check_ps(ctx);
11155 {
11156 TCGv_i64 fp0 = tcg_temp_new_i64();
11157 TCGv_i64 fp1 = tcg_temp_new_i64();
11158
11159 gen_load_fpr64(ctx, fp0, fs);
11160 gen_load_fpr64(ctx, fp1, ft);
11161 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11162 tcg_temp_free_i64(fp1);
11163 gen_store_fpr64(ctx, fp0, fd);
11164 tcg_temp_free_i64(fp0);
11165 }
11166 break;
11167 case OPC_MUL_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_mul_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_ABS_PS:
11182 check_ps(ctx);
11183 {
11184 TCGv_i64 fp0 = tcg_temp_new_i64();
11185
11186 gen_load_fpr64(ctx, fp0, fs);
11187 gen_helper_float_abs_ps(fp0, fp0);
11188 gen_store_fpr64(ctx, fp0, fd);
11189 tcg_temp_free_i64(fp0);
11190 }
11191 break;
11192 case OPC_MOV_PS:
11193 check_ps(ctx);
11194 {
11195 TCGv_i64 fp0 = tcg_temp_new_i64();
11196
11197 gen_load_fpr64(ctx, fp0, fs);
11198 gen_store_fpr64(ctx, fp0, fd);
11199 tcg_temp_free_i64(fp0);
11200 }
11201 break;
11202 case OPC_NEG_PS:
11203 check_ps(ctx);
11204 {
11205 TCGv_i64 fp0 = tcg_temp_new_i64();
11206
11207 gen_load_fpr64(ctx, fp0, fs);
11208 gen_helper_float_chs_ps(fp0, fp0);
11209 gen_store_fpr64(ctx, fp0, fd);
11210 tcg_temp_free_i64(fp0);
11211 }
11212 break;
11213 case OPC_MOVCF_PS:
11214 check_ps(ctx);
11215 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11216 break;
11217 case OPC_MOVZ_PS:
11218 check_ps(ctx);
11219 {
11220 TCGLabel *l1 = gen_new_label();
11221 TCGv_i64 fp0;
11222
11223 if (ft != 0) {
11224 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11225 }
11226 fp0 = tcg_temp_new_i64();
11227 gen_load_fpr64(ctx, fp0, fs);
11228 gen_store_fpr64(ctx, fp0, fd);
11229 tcg_temp_free_i64(fp0);
11230 gen_set_label(l1);
11231 }
11232 break;
11233 case OPC_MOVN_PS:
11234 check_ps(ctx);
11235 {
11236 TCGLabel *l1 = gen_new_label();
11237 TCGv_i64 fp0;
11238
11239 if (ft != 0) {
11240 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11241 fp0 = tcg_temp_new_i64();
11242 gen_load_fpr64(ctx, fp0, fs);
11243 gen_store_fpr64(ctx, fp0, fd);
11244 tcg_temp_free_i64(fp0);
11245 gen_set_label(l1);
11246 }
11247 }
11248 break;
11249 case OPC_ADDR_PS:
11250 check_ps(ctx);
11251 {
11252 TCGv_i64 fp0 = tcg_temp_new_i64();
11253 TCGv_i64 fp1 = tcg_temp_new_i64();
11254
11255 gen_load_fpr64(ctx, fp0, ft);
11256 gen_load_fpr64(ctx, fp1, fs);
11257 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11258 tcg_temp_free_i64(fp1);
11259 gen_store_fpr64(ctx, fp0, fd);
11260 tcg_temp_free_i64(fp0);
11261 }
11262 break;
11263 case OPC_MULR_PS:
11264 check_ps(ctx);
11265 {
11266 TCGv_i64 fp0 = tcg_temp_new_i64();
11267 TCGv_i64 fp1 = tcg_temp_new_i64();
11268
11269 gen_load_fpr64(ctx, fp0, ft);
11270 gen_load_fpr64(ctx, fp1, fs);
11271 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11272 tcg_temp_free_i64(fp1);
11273 gen_store_fpr64(ctx, fp0, fd);
11274 tcg_temp_free_i64(fp0);
11275 }
11276 break;
11277 case OPC_RECIP2_PS:
11278 check_ps(ctx);
11279 {
11280 TCGv_i64 fp0 = tcg_temp_new_i64();
11281 TCGv_i64 fp1 = tcg_temp_new_i64();
11282
11283 gen_load_fpr64(ctx, fp0, fs);
11284 gen_load_fpr64(ctx, fp1, ft);
11285 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11286 tcg_temp_free_i64(fp1);
11287 gen_store_fpr64(ctx, fp0, fd);
11288 tcg_temp_free_i64(fp0);
11289 }
11290 break;
11291 case OPC_RECIP1_PS:
11292 check_ps(ctx);
11293 {
11294 TCGv_i64 fp0 = tcg_temp_new_i64();
11295
11296 gen_load_fpr64(ctx, fp0, fs);
11297 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11298 gen_store_fpr64(ctx, fp0, fd);
11299 tcg_temp_free_i64(fp0);
11300 }
11301 break;
11302 case OPC_RSQRT1_PS:
11303 check_ps(ctx);
11304 {
11305 TCGv_i64 fp0 = tcg_temp_new_i64();
11306
11307 gen_load_fpr64(ctx, fp0, fs);
11308 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11309 gen_store_fpr64(ctx, fp0, fd);
11310 tcg_temp_free_i64(fp0);
11311 }
11312 break;
11313 case OPC_RSQRT2_PS:
11314 check_ps(ctx);
11315 {
11316 TCGv_i64 fp0 = tcg_temp_new_i64();
11317 TCGv_i64 fp1 = tcg_temp_new_i64();
11318
11319 gen_load_fpr64(ctx, fp0, fs);
11320 gen_load_fpr64(ctx, fp1, ft);
11321 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11322 tcg_temp_free_i64(fp1);
11323 gen_store_fpr64(ctx, fp0, fd);
11324 tcg_temp_free_i64(fp0);
11325 }
11326 break;
11327 case OPC_CVT_S_PU:
11328 check_cp1_64bitmode(ctx);
11329 {
11330 TCGv_i32 fp0 = tcg_temp_new_i32();
11331
11332 gen_load_fpr32h(ctx, fp0, fs);
11333 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11334 gen_store_fpr32(ctx, fp0, fd);
11335 tcg_temp_free_i32(fp0);
11336 }
11337 break;
11338 case OPC_CVT_PW_PS:
11339 check_ps(ctx);
11340 {
11341 TCGv_i64 fp0 = tcg_temp_new_i64();
11342
11343 gen_load_fpr64(ctx, fp0, fs);
11344 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11345 gen_store_fpr64(ctx, fp0, fd);
11346 tcg_temp_free_i64(fp0);
11347 }
11348 break;
11349 case OPC_CVT_S_PL:
11350 check_cp1_64bitmode(ctx);
11351 {
11352 TCGv_i32 fp0 = tcg_temp_new_i32();
11353
11354 gen_load_fpr32(ctx, fp0, fs);
11355 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11356 gen_store_fpr32(ctx, fp0, fd);
11357 tcg_temp_free_i32(fp0);
11358 }
11359 break;
11360 case OPC_PLL_PS:
11361 check_ps(ctx);
11362 {
11363 TCGv_i32 fp0 = tcg_temp_new_i32();
11364 TCGv_i32 fp1 = tcg_temp_new_i32();
11365
11366 gen_load_fpr32(ctx, fp0, fs);
11367 gen_load_fpr32(ctx, fp1, ft);
11368 gen_store_fpr32h(ctx, fp0, fd);
11369 gen_store_fpr32(ctx, fp1, fd);
11370 tcg_temp_free_i32(fp0);
11371 tcg_temp_free_i32(fp1);
11372 }
11373 break;
11374 case OPC_PLU_PS:
11375 check_ps(ctx);
11376 {
11377 TCGv_i32 fp0 = tcg_temp_new_i32();
11378 TCGv_i32 fp1 = tcg_temp_new_i32();
11379
11380 gen_load_fpr32(ctx, fp0, fs);
11381 gen_load_fpr32h(ctx, fp1, ft);
11382 gen_store_fpr32(ctx, fp1, fd);
11383 gen_store_fpr32h(ctx, fp0, fd);
11384 tcg_temp_free_i32(fp0);
11385 tcg_temp_free_i32(fp1);
11386 }
11387 break;
11388 case OPC_PUL_PS:
11389 check_ps(ctx);
11390 {
11391 TCGv_i32 fp0 = tcg_temp_new_i32();
11392 TCGv_i32 fp1 = tcg_temp_new_i32();
11393
11394 gen_load_fpr32h(ctx, fp0, fs);
11395 gen_load_fpr32(ctx, fp1, ft);
11396 gen_store_fpr32(ctx, fp1, fd);
11397 gen_store_fpr32h(ctx, fp0, fd);
11398 tcg_temp_free_i32(fp0);
11399 tcg_temp_free_i32(fp1);
11400 }
11401 break;
11402 case OPC_PUU_PS:
11403 check_ps(ctx);
11404 {
11405 TCGv_i32 fp0 = tcg_temp_new_i32();
11406 TCGv_i32 fp1 = tcg_temp_new_i32();
11407
11408 gen_load_fpr32h(ctx, fp0, fs);
11409 gen_load_fpr32h(ctx, fp1, ft);
11410 gen_store_fpr32(ctx, fp1, fd);
11411 gen_store_fpr32h(ctx, fp0, fd);
11412 tcg_temp_free_i32(fp0);
11413 tcg_temp_free_i32(fp1);
11414 }
11415 break;
11416 case OPC_CMP_F_PS:
11417 case OPC_CMP_UN_PS:
11418 case OPC_CMP_EQ_PS:
11419 case OPC_CMP_UEQ_PS:
11420 case OPC_CMP_OLT_PS:
11421 case OPC_CMP_ULT_PS:
11422 case OPC_CMP_OLE_PS:
11423 case OPC_CMP_ULE_PS:
11424 case OPC_CMP_SF_PS:
11425 case OPC_CMP_NGLE_PS:
11426 case OPC_CMP_SEQ_PS:
11427 case OPC_CMP_NGL_PS:
11428 case OPC_CMP_LT_PS:
11429 case OPC_CMP_NGE_PS:
11430 case OPC_CMP_LE_PS:
11431 case OPC_CMP_NGT_PS:
11432 if (ctx->opcode & (1 << 6)) {
11433 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11434 } else {
11435 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11436 }
11437 break;
11438 default:
11439 MIPS_INVAL("farith");
11440 gen_reserved_instruction(ctx);
11441 return;
11442 }
11443}
11444
11445
11446static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11447 int fd, int fs, int base, int index)
11448{
11449 TCGv t0 = tcg_temp_new();
11450
11451 if (base == 0) {
11452 gen_load_gpr(t0, index);
11453 } else if (index == 0) {
11454 gen_load_gpr(t0, base);
11455 } else {
11456 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11457 }
11458
11459
11460
11461
11462 switch (opc) {
11463 case OPC_LWXC1:
11464 check_cop1x(ctx);
11465 {
11466 TCGv_i32 fp0 = tcg_temp_new_i32();
11467
11468 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11469 tcg_gen_trunc_tl_i32(fp0, t0);
11470 gen_store_fpr32(ctx, fp0, fd);
11471 tcg_temp_free_i32(fp0);
11472 }
11473 break;
11474 case OPC_LDXC1:
11475 check_cop1x(ctx);
11476 check_cp1_registers(ctx, fd);
11477 {
11478 TCGv_i64 fp0 = tcg_temp_new_i64();
11479 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11480 gen_store_fpr64(ctx, fp0, fd);
11481 tcg_temp_free_i64(fp0);
11482 }
11483 break;
11484 case OPC_LUXC1:
11485 check_cp1_64bitmode(ctx);
11486 tcg_gen_andi_tl(t0, t0, ~0x7);
11487 {
11488 TCGv_i64 fp0 = tcg_temp_new_i64();
11489
11490 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11491 gen_store_fpr64(ctx, fp0, fd);
11492 tcg_temp_free_i64(fp0);
11493 }
11494 break;
11495 case OPC_SWXC1:
11496 check_cop1x(ctx);
11497 {
11498 TCGv_i32 fp0 = tcg_temp_new_i32();
11499 gen_load_fpr32(ctx, fp0, fs);
11500 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11501 tcg_temp_free_i32(fp0);
11502 }
11503 break;
11504 case OPC_SDXC1:
11505 check_cop1x(ctx);
11506 check_cp1_registers(ctx, fs);
11507 {
11508 TCGv_i64 fp0 = tcg_temp_new_i64();
11509 gen_load_fpr64(ctx, fp0, fs);
11510 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11511 tcg_temp_free_i64(fp0);
11512 }
11513 break;
11514 case OPC_SUXC1:
11515 check_cp1_64bitmode(ctx);
11516 tcg_gen_andi_tl(t0, t0, ~0x7);
11517 {
11518 TCGv_i64 fp0 = tcg_temp_new_i64();
11519 gen_load_fpr64(ctx, fp0, fs);
11520 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11521 tcg_temp_free_i64(fp0);
11522 }
11523 break;
11524 }
11525 tcg_temp_free(t0);
11526}
11527
11528static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11529 int fd, int fr, int fs, int ft)
11530{
11531 switch (opc) {
11532 case OPC_ALNV_PS:
11533 check_ps(ctx);
11534 {
11535 TCGv t0 = tcg_temp_local_new();
11536 TCGv_i32 fp = tcg_temp_new_i32();
11537 TCGv_i32 fph = tcg_temp_new_i32();
11538 TCGLabel *l1 = gen_new_label();
11539 TCGLabel *l2 = gen_new_label();
11540
11541 gen_load_gpr(t0, fr);
11542 tcg_gen_andi_tl(t0, t0, 0x7);
11543
11544 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11545 gen_load_fpr32(ctx, fp, fs);
11546 gen_load_fpr32h(ctx, fph, fs);
11547 gen_store_fpr32(ctx, fp, fd);
11548 gen_store_fpr32h(ctx, fph, fd);
11549 tcg_gen_br(l2);
11550 gen_set_label(l1);
11551 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11552 tcg_temp_free(t0);
11553#ifdef TARGET_WORDS_BIGENDIAN
11554 gen_load_fpr32(ctx, fp, fs);
11555 gen_load_fpr32h(ctx, fph, ft);
11556 gen_store_fpr32h(ctx, fp, fd);
11557 gen_store_fpr32(ctx, fph, fd);
11558#else
11559 gen_load_fpr32h(ctx, fph, fs);
11560 gen_load_fpr32(ctx, fp, ft);
11561 gen_store_fpr32(ctx, fph, fd);
11562 gen_store_fpr32h(ctx, fp, fd);
11563#endif
11564 gen_set_label(l2);
11565 tcg_temp_free_i32(fp);
11566 tcg_temp_free_i32(fph);
11567 }
11568 break;
11569 case OPC_MADD_S:
11570 check_cop1x(ctx);
11571 {
11572 TCGv_i32 fp0 = tcg_temp_new_i32();
11573 TCGv_i32 fp1 = tcg_temp_new_i32();
11574 TCGv_i32 fp2 = tcg_temp_new_i32();
11575
11576 gen_load_fpr32(ctx, fp0, fs);
11577 gen_load_fpr32(ctx, fp1, ft);
11578 gen_load_fpr32(ctx, fp2, fr);
11579 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11580 tcg_temp_free_i32(fp0);
11581 tcg_temp_free_i32(fp1);
11582 gen_store_fpr32(ctx, fp2, fd);
11583 tcg_temp_free_i32(fp2);
11584 }
11585 break;
11586 case OPC_MADD_D:
11587 check_cop1x(ctx);
11588 check_cp1_registers(ctx, fd | fs | ft | fr);
11589 {
11590 TCGv_i64 fp0 = tcg_temp_new_i64();
11591 TCGv_i64 fp1 = tcg_temp_new_i64();
11592 TCGv_i64 fp2 = tcg_temp_new_i64();
11593
11594 gen_load_fpr64(ctx, fp0, fs);
11595 gen_load_fpr64(ctx, fp1, ft);
11596 gen_load_fpr64(ctx, fp2, fr);
11597 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11598 tcg_temp_free_i64(fp0);
11599 tcg_temp_free_i64(fp1);
11600 gen_store_fpr64(ctx, fp2, fd);
11601 tcg_temp_free_i64(fp2);
11602 }
11603 break;
11604 case OPC_MADD_PS:
11605 check_ps(ctx);
11606 {
11607 TCGv_i64 fp0 = tcg_temp_new_i64();
11608 TCGv_i64 fp1 = tcg_temp_new_i64();
11609 TCGv_i64 fp2 = tcg_temp_new_i64();
11610
11611 gen_load_fpr64(ctx, fp0, fs);
11612 gen_load_fpr64(ctx, fp1, ft);
11613 gen_load_fpr64(ctx, fp2, fr);
11614 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11615 tcg_temp_free_i64(fp0);
11616 tcg_temp_free_i64(fp1);
11617 gen_store_fpr64(ctx, fp2, fd);
11618 tcg_temp_free_i64(fp2);
11619 }
11620 break;
11621 case OPC_MSUB_S:
11622 check_cop1x(ctx);
11623 {
11624 TCGv_i32 fp0 = tcg_temp_new_i32();
11625 TCGv_i32 fp1 = tcg_temp_new_i32();
11626 TCGv_i32 fp2 = tcg_temp_new_i32();
11627
11628 gen_load_fpr32(ctx, fp0, fs);
11629 gen_load_fpr32(ctx, fp1, ft);
11630 gen_load_fpr32(ctx, fp2, fr);
11631 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11632 tcg_temp_free_i32(fp0);
11633 tcg_temp_free_i32(fp1);
11634 gen_store_fpr32(ctx, fp2, fd);
11635 tcg_temp_free_i32(fp2);
11636 }
11637 break;
11638 case OPC_MSUB_D:
11639 check_cop1x(ctx);
11640 check_cp1_registers(ctx, fd | fs | ft | fr);
11641 {
11642 TCGv_i64 fp0 = tcg_temp_new_i64();
11643 TCGv_i64 fp1 = tcg_temp_new_i64();
11644 TCGv_i64 fp2 = tcg_temp_new_i64();
11645
11646 gen_load_fpr64(ctx, fp0, fs);
11647 gen_load_fpr64(ctx, fp1, ft);
11648 gen_load_fpr64(ctx, fp2, fr);
11649 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11650 tcg_temp_free_i64(fp0);
11651 tcg_temp_free_i64(fp1);
11652 gen_store_fpr64(ctx, fp2, fd);
11653 tcg_temp_free_i64(fp2);
11654 }
11655 break;
11656 case OPC_MSUB_PS:
11657 check_ps(ctx);
11658 {
11659 TCGv_i64 fp0 = tcg_temp_new_i64();
11660 TCGv_i64 fp1 = tcg_temp_new_i64();
11661 TCGv_i64 fp2 = tcg_temp_new_i64();
11662
11663 gen_load_fpr64(ctx, fp0, fs);
11664 gen_load_fpr64(ctx, fp1, ft);
11665 gen_load_fpr64(ctx, fp2, fr);
11666 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11667 tcg_temp_free_i64(fp0);
11668 tcg_temp_free_i64(fp1);
11669 gen_store_fpr64(ctx, fp2, fd);
11670 tcg_temp_free_i64(fp2);
11671 }
11672 break;
11673 case OPC_NMADD_S:
11674 check_cop1x(ctx);
11675 {
11676 TCGv_i32 fp0 = tcg_temp_new_i32();
11677 TCGv_i32 fp1 = tcg_temp_new_i32();
11678 TCGv_i32 fp2 = tcg_temp_new_i32();
11679
11680 gen_load_fpr32(ctx, fp0, fs);
11681 gen_load_fpr32(ctx, fp1, ft);
11682 gen_load_fpr32(ctx, fp2, fr);
11683 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11684 tcg_temp_free_i32(fp0);
11685 tcg_temp_free_i32(fp1);
11686 gen_store_fpr32(ctx, fp2, fd);
11687 tcg_temp_free_i32(fp2);
11688 }
11689 break;
11690 case OPC_NMADD_D:
11691 check_cop1x(ctx);
11692 check_cp1_registers(ctx, fd | fs | ft | fr);
11693 {
11694 TCGv_i64 fp0 = tcg_temp_new_i64();
11695 TCGv_i64 fp1 = tcg_temp_new_i64();
11696 TCGv_i64 fp2 = tcg_temp_new_i64();
11697
11698 gen_load_fpr64(ctx, fp0, fs);
11699 gen_load_fpr64(ctx, fp1, ft);
11700 gen_load_fpr64(ctx, fp2, fr);
11701 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11702 tcg_temp_free_i64(fp0);
11703 tcg_temp_free_i64(fp1);
11704 gen_store_fpr64(ctx, fp2, fd);
11705 tcg_temp_free_i64(fp2);
11706 }
11707 break;
11708 case OPC_NMADD_PS:
11709 check_ps(ctx);
11710 {
11711 TCGv_i64 fp0 = tcg_temp_new_i64();
11712 TCGv_i64 fp1 = tcg_temp_new_i64();
11713 TCGv_i64 fp2 = tcg_temp_new_i64();
11714
11715 gen_load_fpr64(ctx, fp0, fs);
11716 gen_load_fpr64(ctx, fp1, ft);
11717 gen_load_fpr64(ctx, fp2, fr);
11718 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11719 tcg_temp_free_i64(fp0);
11720 tcg_temp_free_i64(fp1);
11721 gen_store_fpr64(ctx, fp2, fd);
11722 tcg_temp_free_i64(fp2);
11723 }
11724 break;
11725 case OPC_NMSUB_S:
11726 check_cop1x(ctx);
11727 {
11728 TCGv_i32 fp0 = tcg_temp_new_i32();
11729 TCGv_i32 fp1 = tcg_temp_new_i32();
11730 TCGv_i32 fp2 = tcg_temp_new_i32();
11731
11732 gen_load_fpr32(ctx, fp0, fs);
11733 gen_load_fpr32(ctx, fp1, ft);
11734 gen_load_fpr32(ctx, fp2, fr);
11735 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11736 tcg_temp_free_i32(fp0);
11737 tcg_temp_free_i32(fp1);
11738 gen_store_fpr32(ctx, fp2, fd);
11739 tcg_temp_free_i32(fp2);
11740 }
11741 break;
11742 case OPC_NMSUB_D:
11743 check_cop1x(ctx);
11744 check_cp1_registers(ctx, fd | fs | ft | fr);
11745 {
11746 TCGv_i64 fp0 = tcg_temp_new_i64();
11747 TCGv_i64 fp1 = tcg_temp_new_i64();
11748 TCGv_i64 fp2 = tcg_temp_new_i64();
11749
11750 gen_load_fpr64(ctx, fp0, fs);
11751 gen_load_fpr64(ctx, fp1, ft);
11752 gen_load_fpr64(ctx, fp2, fr);
11753 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11754 tcg_temp_free_i64(fp0);
11755 tcg_temp_free_i64(fp1);
11756 gen_store_fpr64(ctx, fp2, fd);
11757 tcg_temp_free_i64(fp2);
11758 }
11759 break;
11760 case OPC_NMSUB_PS:
11761 check_ps(ctx);
11762 {
11763 TCGv_i64 fp0 = tcg_temp_new_i64();
11764 TCGv_i64 fp1 = tcg_temp_new_i64();
11765 TCGv_i64 fp2 = tcg_temp_new_i64();
11766
11767 gen_load_fpr64(ctx, fp0, fs);
11768 gen_load_fpr64(ctx, fp1, ft);
11769 gen_load_fpr64(ctx, fp2, fr);
11770 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11771 tcg_temp_free_i64(fp0);
11772 tcg_temp_free_i64(fp1);
11773 gen_store_fpr64(ctx, fp2, fd);
11774 tcg_temp_free_i64(fp2);
11775 }
11776 break;
11777 default:
11778 MIPS_INVAL("flt3_arith");
11779 gen_reserved_instruction(ctx);
11780 return;
11781 }
11782}
11783
11784void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11785{
11786 TCGv t0;
11787
11788#if !defined(CONFIG_USER_ONLY)
11789
11790
11791
11792
11793 check_insn(ctx, ISA_MIPS_R2);
11794#endif
11795 t0 = tcg_temp_new();
11796
11797 switch (rd) {
11798 case 0:
11799 gen_helper_rdhwr_cpunum(t0, cpu_env);
11800 gen_store_gpr(t0, rt);
11801 break;
11802 case 1:
11803 gen_helper_rdhwr_synci_step(t0, cpu_env);
11804 gen_store_gpr(t0, rt);
11805 break;
11806 case 2:
11807 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11808 gen_io_start();
11809 }
11810 gen_helper_rdhwr_cc(t0, cpu_env);
11811 gen_store_gpr(t0, rt);
11812
11813
11814
11815
11816
11817 gen_save_pc(ctx->base.pc_next + 4);
11818 ctx->base.is_jmp = DISAS_EXIT;
11819 break;
11820 case 3:
11821 gen_helper_rdhwr_ccres(t0, cpu_env);
11822 gen_store_gpr(t0, rt);
11823 break;
11824 case 4:
11825 check_insn(ctx, ISA_MIPS_R6);
11826 if (sel != 0) {
11827
11828
11829
11830
11831 generate_exception(ctx, EXCP_RI);
11832 }
11833 gen_helper_rdhwr_performance(t0, cpu_env);
11834 gen_store_gpr(t0, rt);
11835 break;
11836 case 5:
11837 check_insn(ctx, ISA_MIPS_R6);
11838 gen_helper_rdhwr_xnp(t0, cpu_env);
11839 gen_store_gpr(t0, rt);
11840 break;
11841 case 29:
11842#if defined(CONFIG_USER_ONLY)
11843 tcg_gen_ld_tl(t0, cpu_env,
11844 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11845 gen_store_gpr(t0, rt);
11846 break;
11847#else
11848 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11849 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11850 tcg_gen_ld_tl(t0, cpu_env,
11851 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11852 gen_store_gpr(t0, rt);
11853 } else {
11854 gen_reserved_instruction(ctx);
11855 }
11856 break;
11857#endif
11858 default:
11859 MIPS_INVAL("rdhwr");
11860 gen_reserved_instruction(ctx);
11861 break;
11862 }
11863 tcg_temp_free(t0);
11864}
11865
11866static inline void clear_branch_hflags(DisasContext *ctx)
11867{
11868 ctx->hflags &= ~MIPS_HFLAG_BMASK;
11869 if (ctx->base.is_jmp == DISAS_NEXT) {
11870 save_cpu_state(ctx, 0);
11871 } else {
11872
11873
11874
11875
11876 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11877 }
11878}
11879
11880static void gen_branch(DisasContext *ctx, int insn_bytes)
11881{
11882 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11883 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11884
11885 clear_branch_hflags(ctx);
11886 ctx->base.is_jmp = DISAS_NORETURN;
11887
11888 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11889 case MIPS_HFLAG_FBNSLOT:
11890 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11891 break;
11892 case MIPS_HFLAG_B:
11893
11894 if (proc_hflags & MIPS_HFLAG_BX) {
11895 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11896 }
11897 gen_goto_tb(ctx, 0, ctx->btarget);
11898 break;
11899 case MIPS_HFLAG_BL:
11900
11901 gen_goto_tb(ctx, 0, ctx->btarget);
11902 break;
11903 case MIPS_HFLAG_BC:
11904
11905 {
11906 TCGLabel *l1 = gen_new_label();
11907
11908 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11909 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11910 gen_set_label(l1);
11911 gen_goto_tb(ctx, 0, ctx->btarget);
11912 }
11913 break;
11914 case MIPS_HFLAG_BR:
11915
11916 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11917 TCGv t0 = tcg_temp_new();
11918 TCGv_i32 t1 = tcg_temp_new_i32();
11919
11920 tcg_gen_andi_tl(t0, btarget, 0x1);
11921 tcg_gen_trunc_tl_i32(t1, t0);
11922 tcg_temp_free(t0);
11923 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11924 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11925 tcg_gen_or_i32(hflags, hflags, t1);
11926 tcg_temp_free_i32(t1);
11927
11928 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11929 } else {
11930 tcg_gen_mov_tl(cpu_PC, btarget);
11931 }
11932 if (ctx->base.singlestep_enabled) {
11933 save_cpu_state(ctx, 0);
11934 gen_helper_raise_exception_debug(cpu_env);
11935 }
11936 tcg_gen_lookup_and_goto_ptr();
11937 break;
11938 default:
11939 LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11940 gen_reserved_instruction(ctx);
11941 }
11942 }
11943}
11944
11945
11946static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11947 int rs, int rt, int32_t offset)
11948{
11949 int bcond_compute = 0;
11950 TCGv t0 = tcg_temp_new();
11951 TCGv t1 = tcg_temp_new();
11952 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11953
11954 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11955#ifdef MIPS_DEBUG_DISAS
11956 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11957 "\n", ctx->base.pc_next);
11958#endif
11959 gen_reserved_instruction(ctx);
11960 goto out;
11961 }
11962
11963
11964 switch (opc) {
11965
11966 case OPC_BOVC:
11967 case OPC_BNVC:
11968 gen_load_gpr(t0, rs);
11969 gen_load_gpr(t1, rt);
11970 bcond_compute = 1;
11971 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11972 if (rs <= rt && rs == 0) {
11973
11974 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11975 }
11976 break;
11977 case OPC_BLEZC:
11978 case OPC_BGTZC:
11979 gen_load_gpr(t0, rs);
11980 gen_load_gpr(t1, rt);
11981 bcond_compute = 1;
11982 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11983 break;
11984 case OPC_BLEZALC:
11985 case OPC_BGTZALC:
11986 if (rs == 0 || rs == rt) {
11987
11988
11989 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11990 }
11991 gen_load_gpr(t0, rs);
11992 gen_load_gpr(t1, rt);
11993 bcond_compute = 1;
11994 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11995 break;
11996 case OPC_BC:
11997 case OPC_BALC:
11998 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11999 break;
12000 case OPC_BEQZC:
12001 case OPC_BNEZC:
12002 if (rs != 0) {
12003
12004 gen_load_gpr(t0, rs);
12005 bcond_compute = 1;
12006 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12007 } else {
12008
12009 TCGv tbase = tcg_temp_new();
12010 TCGv toffset = tcg_temp_new();
12011
12012 gen_load_gpr(tbase, rt);
12013 tcg_gen_movi_tl(toffset, offset);
12014 gen_op_addr_add(ctx, btarget, tbase, toffset);
12015 tcg_temp_free(tbase);
12016 tcg_temp_free(toffset);
12017 }
12018 break;
12019 default:
12020 MIPS_INVAL("Compact branch/jump");
12021 gen_reserved_instruction(ctx);
12022 goto out;
12023 }
12024
12025 if (bcond_compute == 0) {
12026
12027 switch (opc) {
12028 case OPC_JIALC:
12029 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12030
12031 case OPC_JIC:
12032 ctx->hflags |= MIPS_HFLAG_BR;
12033 break;
12034 case OPC_BALC:
12035 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12036
12037 case OPC_BC:
12038 ctx->hflags |= MIPS_HFLAG_B;
12039 break;
12040 default:
12041 MIPS_INVAL("Compact branch/jump");
12042 gen_reserved_instruction(ctx);
12043 goto out;
12044 }
12045
12046
12047 gen_branch(ctx, 4);
12048 } else {
12049
12050 TCGLabel *fs = gen_new_label();
12051 save_cpu_state(ctx, 0);
12052
12053 switch (opc) {
12054 case OPC_BLEZALC:
12055 if (rs == 0 && rt != 0) {
12056
12057 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12058 } else if (rs != 0 && rt != 0 && rs == rt) {
12059
12060 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12061 } else {
12062
12063 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12064 }
12065 break;
12066 case OPC_BGTZALC:
12067 if (rs == 0 && rt != 0) {
12068
12069 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12070 } else if (rs != 0 && rt != 0 && rs == rt) {
12071
12072 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12073 } else {
12074
12075 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12076 }
12077 break;
12078 case OPC_BLEZC:
12079 if (rs == 0 && rt != 0) {
12080
12081 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12082 } else if (rs != 0 && rt != 0 && rs == rt) {
12083
12084 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12085 } else {
12086
12087 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12088 }
12089 break;
12090 case OPC_BGTZC:
12091 if (rs == 0 && rt != 0) {
12092
12093 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12094 } else if (rs != 0 && rt != 0 && rs == rt) {
12095
12096 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12097 } else {
12098
12099 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12100 }
12101 break;
12102 case OPC_BOVC:
12103 case OPC_BNVC:
12104 if (rs >= rt) {
12105
12106 TCGv t2 = tcg_temp_new();
12107 TCGv t3 = tcg_temp_new();
12108 TCGv t4 = tcg_temp_new();
12109 TCGv input_overflow = tcg_temp_new();
12110
12111 gen_load_gpr(t0, rs);
12112 gen_load_gpr(t1, rt);
12113 tcg_gen_ext32s_tl(t2, t0);
12114 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12115 tcg_gen_ext32s_tl(t3, t1);
12116 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12117 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12118
12119 tcg_gen_add_tl(t4, t2, t3);
12120 tcg_gen_ext32s_tl(t4, t4);
12121 tcg_gen_xor_tl(t2, t2, t3);
12122 tcg_gen_xor_tl(t3, t4, t3);
12123 tcg_gen_andc_tl(t2, t3, t2);
12124 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12125 tcg_gen_or_tl(t4, t4, input_overflow);
12126 if (opc == OPC_BOVC) {
12127
12128 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12129 } else {
12130
12131 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12132 }
12133 tcg_temp_free(input_overflow);
12134 tcg_temp_free(t4);
12135 tcg_temp_free(t3);
12136 tcg_temp_free(t2);
12137 } else if (rs < rt && rs == 0) {
12138
12139 if (opc == OPC_BEQZALC) {
12140
12141 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12142 } else {
12143
12144 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12145 }
12146 } else {
12147
12148 if (opc == OPC_BEQC) {
12149
12150 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12151 } else {
12152
12153 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12154 }
12155 }
12156 break;
12157 case OPC_BEQZC:
12158 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12159 break;
12160 case OPC_BNEZC:
12161 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12162 break;
12163 default:
12164 MIPS_INVAL("Compact conditional branch/jump");
12165 gen_reserved_instruction(ctx);
12166 goto out;
12167 }
12168
12169
12170 gen_goto_tb(ctx, 1, ctx->btarget);
12171 gen_set_label(fs);
12172
12173 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12174 }
12175
12176out:
12177 tcg_temp_free(t0);
12178 tcg_temp_free(t1);
12179}
12180
12181void gen_addiupc(DisasContext *ctx, int rx, int imm,
12182 int is_64_bit, int extended)
12183{
12184 TCGv t0;
12185
12186 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12187 gen_reserved_instruction(ctx);
12188 return;
12189 }
12190
12191 t0 = tcg_temp_new();
12192
12193 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12194 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12195 if (!is_64_bit) {
12196 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12197 }
12198
12199 tcg_temp_free(t0);
12200}
12201
12202static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12203 int16_t offset)
12204{
12205 TCGv_i32 t0 = tcg_const_i32(op);
12206 TCGv t1 = tcg_temp_new();
12207 gen_base_offset_addr(ctx, t1, base, offset);
12208 gen_helper_cache(cpu_env, t1, t0);
12209 tcg_temp_free(t1);
12210 tcg_temp_free_i32(t0);
12211}
12212
12213static inline bool is_uhi(int sdbbp_code)
12214{
12215#ifdef CONFIG_USER_ONLY
12216 return false;
12217#else
12218 return semihosting_enabled() && sdbbp_code == 1;
12219#endif
12220}
12221
12222#ifdef CONFIG_USER_ONLY
12223
12224static inline void gen_helper_do_semihosting(void *env)
12225{
12226 g_assert_not_reached();
12227}
12228#endif
12229
12230void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
12231{
12232 TCGv t0 = tcg_temp_new();
12233 TCGv t1 = tcg_temp_new();
12234
12235 gen_load_gpr(t0, base);
12236
12237 if (index != 0) {
12238 gen_load_gpr(t1, index);
12239 tcg_gen_shli_tl(t1, t1, 2);
12240 gen_op_addr_add(ctx, t0, t1, t0);
12241 }
12242
12243 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12244 gen_store_gpr(t1, rd);
12245
12246 tcg_temp_free(t0);
12247 tcg_temp_free(t1);
12248}
12249
12250static void gen_sync(int stype)
12251{
12252 TCGBar tcg_mo = TCG_BAR_SC;
12253
12254 switch (stype) {
12255 case 0x4:
12256 tcg_mo |= TCG_MO_ST_ST;
12257 break;
12258 case 0x10:
12259 tcg_mo |= TCG_MO_ALL;
12260 break;
12261 case 0x11:
12262 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12263 break;
12264 case 0x12:
12265 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12266 break;
12267 case 0x13:
12268 tcg_mo |= TCG_MO_LD_LD;
12269 break;
12270 default:
12271 tcg_mo |= TCG_MO_ALL;
12272 break;
12273 }
12274
12275 tcg_gen_mb(tcg_mo);
12276}
12277
12278
12279
12280
12281#include "mips16e_translate.c.inc"
12282
12283
12284
12285
12286
12287
12288
12289enum {
12290 FMT_SD_S = 0,
12291 FMT_SD_D = 1,
12292
12293 FMT_SDPS_S = 0,
12294 FMT_SDPS_D = 1,
12295 FMT_SDPS_PS = 2,
12296
12297 FMT_SWL_S = 0,
12298 FMT_SWL_W = 1,
12299 FMT_SWL_L = 2,
12300
12301 FMT_DWL_D = 0,
12302 FMT_DWL_W = 1,
12303 FMT_DWL_L = 2
12304};
12305
12306#include "micromips_translate.c.inc"
12307
12308#include "nanomips_translate.c.inc"
12309
12310
12311static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12312 int rd, int base, int offset)
12313{
12314 TCGv t0;
12315
12316 check_dsp(ctx);
12317 t0 = tcg_temp_new();
12318
12319 if (base == 0) {
12320 gen_load_gpr(t0, offset);
12321 } else if (offset == 0) {
12322 gen_load_gpr(t0, base);
12323 } else {
12324 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12325 }
12326
12327 switch (opc) {
12328 case OPC_LBUX:
12329 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12330 gen_store_gpr(t0, rd);
12331 break;
12332 case OPC_LHX:
12333 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12334 gen_store_gpr(t0, rd);
12335 break;
12336 case OPC_LWX:
12337 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12338 gen_store_gpr(t0, rd);
12339 break;
12340#if defined(TARGET_MIPS64)
12341 case OPC_LDX:
12342 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12343 gen_store_gpr(t0, rd);
12344 break;
12345#endif
12346 }
12347 tcg_temp_free(t0);
12348}
12349
12350static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12351 int ret, int v1, int v2)
12352{
12353 TCGv v1_t;
12354 TCGv v2_t;
12355
12356 if (ret == 0) {
12357
12358 return;
12359 }
12360
12361 v1_t = tcg_temp_new();
12362 v2_t = tcg_temp_new();
12363
12364 gen_load_gpr(v1_t, v1);
12365 gen_load_gpr(v2_t, v2);
12366
12367 switch (op1) {
12368
12369 case OPC_MULT_G_2E:
12370 check_dsp_r2(ctx);
12371 switch (op2) {
12372 case OPC_ADDUH_QB:
12373 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12374 break;
12375 case OPC_ADDUH_R_QB:
12376 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12377 break;
12378 case OPC_ADDQH_PH:
12379 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12380 break;
12381 case OPC_ADDQH_R_PH:
12382 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12383 break;
12384 case OPC_ADDQH_W:
12385 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12386 break;
12387 case OPC_ADDQH_R_W:
12388 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12389 break;
12390 case OPC_SUBUH_QB:
12391 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12392 break;
12393 case OPC_SUBUH_R_QB:
12394 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12395 break;
12396 case OPC_SUBQH_PH:
12397 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12398 break;
12399 case OPC_SUBQH_R_PH:
12400 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12401 break;
12402 case OPC_SUBQH_W:
12403 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12404 break;
12405 case OPC_SUBQH_R_W:
12406 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12407 break;
12408 }
12409 break;
12410 case OPC_ABSQ_S_PH_DSP:
12411 switch (op2) {
12412 case OPC_ABSQ_S_QB:
12413 check_dsp_r2(ctx);
12414 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12415 break;
12416 case OPC_ABSQ_S_PH:
12417 check_dsp(ctx);
12418 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12419 break;
12420 case OPC_ABSQ_S_W:
12421 check_dsp(ctx);
12422 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12423 break;
12424 case OPC_PRECEQ_W_PHL:
12425 check_dsp(ctx);
12426 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12427 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12428 break;
12429 case OPC_PRECEQ_W_PHR:
12430 check_dsp(ctx);
12431 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12432 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12433 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12434 break;
12435 case OPC_PRECEQU_PH_QBL:
12436 check_dsp(ctx);
12437 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12438 break;
12439 case OPC_PRECEQU_PH_QBR:
12440 check_dsp(ctx);
12441 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12442 break;
12443 case OPC_PRECEQU_PH_QBLA:
12444 check_dsp(ctx);
12445 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12446 break;
12447 case OPC_PRECEQU_PH_QBRA:
12448 check_dsp(ctx);
12449 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12450 break;
12451 case OPC_PRECEU_PH_QBL:
12452 check_dsp(ctx);
12453 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12454 break;
12455 case OPC_PRECEU_PH_QBR:
12456 check_dsp(ctx);
12457 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12458 break;
12459 case OPC_PRECEU_PH_QBLA:
12460 check_dsp(ctx);
12461 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12462 break;
12463 case OPC_PRECEU_PH_QBRA:
12464 check_dsp(ctx);
12465 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12466 break;
12467 }
12468 break;
12469 case OPC_ADDU_QB_DSP:
12470 switch (op2) {
12471 case OPC_ADDQ_PH:
12472 check_dsp(ctx);
12473 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12474 break;
12475 case OPC_ADDQ_S_PH:
12476 check_dsp(ctx);
12477 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12478 break;
12479 case OPC_ADDQ_S_W:
12480 check_dsp(ctx);
12481 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12482 break;
12483 case OPC_ADDU_QB:
12484 check_dsp(ctx);
12485 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12486 break;
12487 case OPC_ADDU_S_QB:
12488 check_dsp(ctx);
12489 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12490 break;
12491 case OPC_ADDU_PH:
12492 check_dsp_r2(ctx);
12493 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12494 break;
12495 case OPC_ADDU_S_PH:
12496 check_dsp_r2(ctx);
12497 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12498 break;
12499 case OPC_SUBQ_PH:
12500 check_dsp(ctx);
12501 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12502 break;
12503 case OPC_SUBQ_S_PH:
12504 check_dsp(ctx);
12505 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12506 break;
12507 case OPC_SUBQ_S_W:
12508 check_dsp(ctx);
12509 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12510 break;
12511 case OPC_SUBU_QB:
12512 check_dsp(ctx);
12513 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12514 break;
12515 case OPC_SUBU_S_QB:
12516 check_dsp(ctx);
12517 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12518 break;
12519 case OPC_SUBU_PH:
12520 check_dsp_r2(ctx);
12521 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12522 break;
12523 case OPC_SUBU_S_PH:
12524 check_dsp_r2(ctx);
12525 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12526 break;
12527 case OPC_ADDSC:
12528 check_dsp(ctx);
12529 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12530 break;
12531 case OPC_ADDWC:
12532 check_dsp(ctx);
12533 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12534 break;
12535 case OPC_MODSUB:
12536 check_dsp(ctx);
12537 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12538 break;
12539 case OPC_RADDU_W_QB:
12540 check_dsp(ctx);
12541 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12542 break;
12543 }
12544 break;
12545 case OPC_CMPU_EQ_QB_DSP:
12546 switch (op2) {
12547 case OPC_PRECR_QB_PH:
12548 check_dsp_r2(ctx);
12549 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12550 break;
12551 case OPC_PRECRQ_QB_PH:
12552 check_dsp(ctx);
12553 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12554 break;
12555 case OPC_PRECR_SRA_PH_W:
12556 check_dsp_r2(ctx);
12557 {
12558 TCGv_i32 sa_t = tcg_const_i32(v2);
12559 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12560 cpu_gpr[ret]);
12561 tcg_temp_free_i32(sa_t);
12562 break;
12563 }
12564 case OPC_PRECR_SRA_R_PH_W:
12565 check_dsp_r2(ctx);
12566 {
12567 TCGv_i32 sa_t = tcg_const_i32(v2);
12568 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12569 cpu_gpr[ret]);
12570 tcg_temp_free_i32(sa_t);
12571 break;
12572 }
12573 case OPC_PRECRQ_PH_W:
12574 check_dsp(ctx);
12575 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12576 break;
12577 case OPC_PRECRQ_RS_PH_W:
12578 check_dsp(ctx);
12579 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12580 break;
12581 case OPC_PRECRQU_S_QB_PH:
12582 check_dsp(ctx);
12583 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12584 break;
12585 }
12586 break;
12587#ifdef TARGET_MIPS64
12588 case OPC_ABSQ_S_QH_DSP:
12589 switch (op2) {
12590 case OPC_PRECEQ_L_PWL:
12591 check_dsp(ctx);
12592 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12593 break;
12594 case OPC_PRECEQ_L_PWR:
12595 check_dsp(ctx);
12596 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12597 break;
12598 case OPC_PRECEQ_PW_QHL:
12599 check_dsp(ctx);
12600 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12601 break;
12602 case OPC_PRECEQ_PW_QHR:
12603 check_dsp(ctx);
12604 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12605 break;
12606 case OPC_PRECEQ_PW_QHLA:
12607 check_dsp(ctx);
12608 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12609 break;
12610 case OPC_PRECEQ_PW_QHRA:
12611 check_dsp(ctx);
12612 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12613 break;
12614 case OPC_PRECEQU_QH_OBL:
12615 check_dsp(ctx);
12616 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12617 break;
12618 case OPC_PRECEQU_QH_OBR:
12619 check_dsp(ctx);
12620 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12621 break;
12622 case OPC_PRECEQU_QH_OBLA:
12623 check_dsp(ctx);
12624 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12625 break;
12626 case OPC_PRECEQU_QH_OBRA:
12627 check_dsp(ctx);
12628 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12629 break;
12630 case OPC_PRECEU_QH_OBL:
12631 check_dsp(ctx);
12632 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12633 break;
12634 case OPC_PRECEU_QH_OBR:
12635 check_dsp(ctx);
12636 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12637 break;
12638 case OPC_PRECEU_QH_OBLA:
12639 check_dsp(ctx);
12640 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12641 break;
12642 case OPC_PRECEU_QH_OBRA:
12643 check_dsp(ctx);
12644 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12645 break;
12646 case OPC_ABSQ_S_OB:
12647 check_dsp_r2(ctx);
12648 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12649 break;
12650 case OPC_ABSQ_S_PW:
12651 check_dsp(ctx);
12652 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12653 break;
12654 case OPC_ABSQ_S_QH:
12655 check_dsp(ctx);
12656 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12657 break;
12658 }
12659 break;
12660 case OPC_ADDU_OB_DSP:
12661 switch (op2) {
12662 case OPC_RADDU_L_OB:
12663 check_dsp(ctx);
12664 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12665 break;
12666 case OPC_SUBQ_PW:
12667 check_dsp(ctx);
12668 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12669 break;
12670 case OPC_SUBQ_S_PW:
12671 check_dsp(ctx);
12672 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12673 break;
12674 case OPC_SUBQ_QH:
12675 check_dsp(ctx);
12676 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12677 break;
12678 case OPC_SUBQ_S_QH:
12679 check_dsp(ctx);
12680 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12681 break;
12682 case OPC_SUBU_OB:
12683 check_dsp(ctx);
12684 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12685 break;
12686 case OPC_SUBU_S_OB:
12687 check_dsp(ctx);
12688 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12689 break;
12690 case OPC_SUBU_QH:
12691 check_dsp_r2(ctx);
12692 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12693 break;
12694 case OPC_SUBU_S_QH:
12695 check_dsp_r2(ctx);
12696 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12697 break;
12698 case OPC_SUBUH_OB:
12699 check_dsp_r2(ctx);
12700 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12701 break;
12702 case OPC_SUBUH_R_OB:
12703 check_dsp_r2(ctx);
12704 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12705 break;
12706 case OPC_ADDQ_PW:
12707 check_dsp(ctx);
12708 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12709 break;
12710 case OPC_ADDQ_S_PW:
12711 check_dsp(ctx);
12712 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12713 break;
12714 case OPC_ADDQ_QH:
12715 check_dsp(ctx);
12716 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12717 break;
12718 case OPC_ADDQ_S_QH:
12719 check_dsp(ctx);
12720 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12721 break;
12722 case OPC_ADDU_OB:
12723 check_dsp(ctx);
12724 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12725 break;
12726 case OPC_ADDU_S_OB:
12727 check_dsp(ctx);
12728 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12729 break;
12730 case OPC_ADDU_QH:
12731 check_dsp_r2(ctx);
12732 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12733 break;
12734 case OPC_ADDU_S_QH:
12735 check_dsp_r2(ctx);
12736 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12737 break;
12738 case OPC_ADDUH_OB:
12739 check_dsp_r2(ctx);
12740 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_ADDUH_R_OB:
12743 check_dsp_r2(ctx);
12744 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12745 break;
12746 }
12747 break;
12748 case OPC_CMPU_EQ_OB_DSP:
12749 switch (op2) {
12750 case OPC_PRECR_OB_QH:
12751 check_dsp_r2(ctx);
12752 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_PRECR_SRA_QH_PW:
12755 check_dsp_r2(ctx);
12756 {
12757 TCGv_i32 ret_t = tcg_const_i32(ret);
12758 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12759 tcg_temp_free_i32(ret_t);
12760 break;
12761 }
12762 case OPC_PRECR_SRA_R_QH_PW:
12763 check_dsp_r2(ctx);
12764 {
12765 TCGv_i32 sa_v = tcg_const_i32(ret);
12766 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12767 tcg_temp_free_i32(sa_v);
12768 break;
12769 }
12770 case OPC_PRECRQ_OB_QH:
12771 check_dsp(ctx);
12772 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12773 break;
12774 case OPC_PRECRQ_PW_L:
12775 check_dsp(ctx);
12776 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12777 break;
12778 case OPC_PRECRQ_QH_PW:
12779 check_dsp(ctx);
12780 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12781 break;
12782 case OPC_PRECRQ_RS_QH_PW:
12783 check_dsp(ctx);
12784 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12785 break;
12786 case OPC_PRECRQU_S_OB_QH:
12787 check_dsp(ctx);
12788 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12789 break;
12790 }
12791 break;
12792#endif
12793 }
12794
12795 tcg_temp_free(v1_t);
12796 tcg_temp_free(v2_t);
12797}
12798
12799static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12800 int ret, int v1, int v2)
12801{
12802 uint32_t op2;
12803 TCGv t0;
12804 TCGv v1_t;
12805 TCGv v2_t;
12806
12807 if (ret == 0) {
12808
12809 return;
12810 }
12811
12812 t0 = tcg_temp_new();
12813 v1_t = tcg_temp_new();
12814 v2_t = tcg_temp_new();
12815
12816 tcg_gen_movi_tl(t0, v1);
12817 gen_load_gpr(v1_t, v1);
12818 gen_load_gpr(v2_t, v2);
12819
12820 switch (opc) {
12821 case OPC_SHLL_QB_DSP:
12822 {
12823 op2 = MASK_SHLL_QB(ctx->opcode);
12824 switch (op2) {
12825 case OPC_SHLL_QB:
12826 check_dsp(ctx);
12827 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12828 break;
12829 case OPC_SHLLV_QB:
12830 check_dsp(ctx);
12831 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12832 break;
12833 case OPC_SHLL_PH:
12834 check_dsp(ctx);
12835 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12836 break;
12837 case OPC_SHLLV_PH:
12838 check_dsp(ctx);
12839 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 break;
12841 case OPC_SHLL_S_PH:
12842 check_dsp(ctx);
12843 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12844 break;
12845 case OPC_SHLLV_S_PH:
12846 check_dsp(ctx);
12847 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 break;
12849 case OPC_SHLL_S_W:
12850 check_dsp(ctx);
12851 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12852 break;
12853 case OPC_SHLLV_S_W:
12854 check_dsp(ctx);
12855 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 break;
12857 case OPC_SHRL_QB:
12858 check_dsp(ctx);
12859 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12860 break;
12861 case OPC_SHRLV_QB:
12862 check_dsp(ctx);
12863 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12864 break;
12865 case OPC_SHRL_PH:
12866 check_dsp_r2(ctx);
12867 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12868 break;
12869 case OPC_SHRLV_PH:
12870 check_dsp_r2(ctx);
12871 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12872 break;
12873 case OPC_SHRA_QB:
12874 check_dsp_r2(ctx);
12875 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12876 break;
12877 case OPC_SHRA_R_QB:
12878 check_dsp_r2(ctx);
12879 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12880 break;
12881 case OPC_SHRAV_QB:
12882 check_dsp_r2(ctx);
12883 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12884 break;
12885 case OPC_SHRAV_R_QB:
12886 check_dsp_r2(ctx);
12887 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12888 break;
12889 case OPC_SHRA_PH:
12890 check_dsp(ctx);
12891 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12892 break;
12893 case OPC_SHRA_R_PH:
12894 check_dsp(ctx);
12895 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12896 break;
12897 case OPC_SHRAV_PH:
12898 check_dsp(ctx);
12899 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12900 break;
12901 case OPC_SHRAV_R_PH:
12902 check_dsp(ctx);
12903 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12904 break;
12905 case OPC_SHRA_R_W:
12906 check_dsp(ctx);
12907 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12908 break;
12909 case OPC_SHRAV_R_W:
12910 check_dsp(ctx);
12911 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12912 break;
12913 default:
12914 MIPS_INVAL("MASK SHLL.QB");
12915 gen_reserved_instruction(ctx);
12916 break;
12917 }
12918 break;
12919 }
12920#ifdef TARGET_MIPS64
12921 case OPC_SHLL_OB_DSP:
12922 op2 = MASK_SHLL_OB(ctx->opcode);
12923 switch (op2) {
12924 case OPC_SHLL_PW:
12925 check_dsp(ctx);
12926 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12927 break;
12928 case OPC_SHLLV_PW:
12929 check_dsp(ctx);
12930 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12931 break;
12932 case OPC_SHLL_S_PW:
12933 check_dsp(ctx);
12934 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12935 break;
12936 case OPC_SHLLV_S_PW:
12937 check_dsp(ctx);
12938 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12939 break;
12940 case OPC_SHLL_OB:
12941 check_dsp(ctx);
12942 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12943 break;
12944 case OPC_SHLLV_OB:
12945 check_dsp(ctx);
12946 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12947 break;
12948 case OPC_SHLL_QH:
12949 check_dsp(ctx);
12950 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12951 break;
12952 case OPC_SHLLV_QH:
12953 check_dsp(ctx);
12954 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12955 break;
12956 case OPC_SHLL_S_QH:
12957 check_dsp(ctx);
12958 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12959 break;
12960 case OPC_SHLLV_S_QH:
12961 check_dsp(ctx);
12962 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12963 break;
12964 case OPC_SHRA_OB:
12965 check_dsp_r2(ctx);
12966 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12967 break;
12968 case OPC_SHRAV_OB:
12969 check_dsp_r2(ctx);
12970 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12971 break;
12972 case OPC_SHRA_R_OB:
12973 check_dsp_r2(ctx);
12974 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12975 break;
12976 case OPC_SHRAV_R_OB:
12977 check_dsp_r2(ctx);
12978 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12979 break;
12980 case OPC_SHRA_PW:
12981 check_dsp(ctx);
12982 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12983 break;
12984 case OPC_SHRAV_PW:
12985 check_dsp(ctx);
12986 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12987 break;
12988 case OPC_SHRA_R_PW:
12989 check_dsp(ctx);
12990 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12991 break;
12992 case OPC_SHRAV_R_PW:
12993 check_dsp(ctx);
12994 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12995 break;
12996 case OPC_SHRA_QH:
12997 check_dsp(ctx);
12998 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12999 break;
13000 case OPC_SHRAV_QH:
13001 check_dsp(ctx);
13002 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13003 break;
13004 case OPC_SHRA_R_QH:
13005 check_dsp(ctx);
13006 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13007 break;
13008 case OPC_SHRAV_R_QH:
13009 check_dsp(ctx);
13010 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13011 break;
13012 case OPC_SHRL_OB:
13013 check_dsp(ctx);
13014 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13015 break;
13016 case OPC_SHRLV_OB:
13017 check_dsp(ctx);
13018 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13019 break;
13020 case OPC_SHRL_QH:
13021 check_dsp_r2(ctx);
13022 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13023 break;
13024 case OPC_SHRLV_QH:
13025 check_dsp_r2(ctx);
13026 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13027 break;
13028 default:
13029 MIPS_INVAL("MASK SHLL.OB");
13030 gen_reserved_instruction(ctx);
13031 break;
13032 }
13033 break;
13034#endif
13035 }
13036
13037 tcg_temp_free(t0);
13038 tcg_temp_free(v1_t);
13039 tcg_temp_free(v2_t);
13040}
13041
13042static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13043 int ret, int v1, int v2, int check_ret)
13044{
13045 TCGv_i32 t0;
13046 TCGv v1_t;
13047 TCGv v2_t;
13048
13049 if ((ret == 0) && (check_ret == 1)) {
13050
13051 return;
13052 }
13053
13054 t0 = tcg_temp_new_i32();
13055 v1_t = tcg_temp_new();
13056 v2_t = tcg_temp_new();
13057
13058 tcg_gen_movi_i32(t0, ret);
13059 gen_load_gpr(v1_t, v1);
13060 gen_load_gpr(v2_t, v2);
13061
13062 switch (op1) {
13063
13064
13065
13066
13067 case OPC_MULT_G_2E:
13068 check_dsp_r2(ctx);
13069 switch (op2) {
13070 case OPC_MUL_PH:
13071 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072 break;
13073 case OPC_MUL_S_PH:
13074 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 break;
13076 case OPC_MULQ_S_W:
13077 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13078 break;
13079 case OPC_MULQ_RS_W:
13080 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13081 break;
13082 }
13083 break;
13084 case OPC_DPA_W_PH_DSP:
13085 switch (op2) {
13086 case OPC_DPAU_H_QBL:
13087 check_dsp(ctx);
13088 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13089 break;
13090 case OPC_DPAU_H_QBR:
13091 check_dsp(ctx);
13092 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13093 break;
13094 case OPC_DPSU_H_QBL:
13095 check_dsp(ctx);
13096 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13097 break;
13098 case OPC_DPSU_H_QBR:
13099 check_dsp(ctx);
13100 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13101 break;
13102 case OPC_DPA_W_PH:
13103 check_dsp_r2(ctx);
13104 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13105 break;
13106 case OPC_DPAX_W_PH:
13107 check_dsp_r2(ctx);
13108 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13109 break;
13110 case OPC_DPAQ_S_W_PH:
13111 check_dsp(ctx);
13112 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13113 break;
13114 case OPC_DPAQX_S_W_PH:
13115 check_dsp_r2(ctx);
13116 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13117 break;
13118 case OPC_DPAQX_SA_W_PH:
13119 check_dsp_r2(ctx);
13120 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13121 break;
13122 case OPC_DPS_W_PH:
13123 check_dsp_r2(ctx);
13124 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13125 break;
13126 case OPC_DPSX_W_PH:
13127 check_dsp_r2(ctx);
13128 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13129 break;
13130 case OPC_DPSQ_S_W_PH:
13131 check_dsp(ctx);
13132 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13133 break;
13134 case OPC_DPSQX_S_W_PH:
13135 check_dsp_r2(ctx);
13136 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13137 break;
13138 case OPC_DPSQX_SA_W_PH:
13139 check_dsp_r2(ctx);
13140 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13141 break;
13142 case OPC_MULSAQ_S_W_PH:
13143 check_dsp(ctx);
13144 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13145 break;
13146 case OPC_DPAQ_SA_L_W:
13147 check_dsp(ctx);
13148 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13149 break;
13150 case OPC_DPSQ_SA_L_W:
13151 check_dsp(ctx);
13152 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13153 break;
13154 case OPC_MAQ_S_W_PHL:
13155 check_dsp(ctx);
13156 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13157 break;
13158 case OPC_MAQ_S_W_PHR:
13159 check_dsp(ctx);
13160 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13161 break;
13162 case OPC_MAQ_SA_W_PHL:
13163 check_dsp(ctx);
13164 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13165 break;
13166 case OPC_MAQ_SA_W_PHR:
13167 check_dsp(ctx);
13168 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13169 break;
13170 case OPC_MULSA_W_PH:
13171 check_dsp_r2(ctx);
13172 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13173 break;
13174 }
13175 break;
13176#ifdef TARGET_MIPS64
13177 case OPC_DPAQ_W_QH_DSP:
13178 {
13179 int ac = ret & 0x03;
13180 tcg_gen_movi_i32(t0, ac);
13181
13182 switch (op2) {
13183 case OPC_DMADD:
13184 check_dsp(ctx);
13185 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13186 break;
13187 case OPC_DMADDU:
13188 check_dsp(ctx);
13189 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13190 break;
13191 case OPC_DMSUB:
13192 check_dsp(ctx);
13193 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13194 break;
13195 case OPC_DMSUBU:
13196 check_dsp(ctx);
13197 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13198 break;
13199 case OPC_DPA_W_QH:
13200 check_dsp_r2(ctx);
13201 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13202 break;
13203 case OPC_DPAQ_S_W_QH:
13204 check_dsp(ctx);
13205 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13206 break;
13207 case OPC_DPAQ_SA_L_PW:
13208 check_dsp(ctx);
13209 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13210 break;
13211 case OPC_DPAU_H_OBL:
13212 check_dsp(ctx);
13213 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13214 break;
13215 case OPC_DPAU_H_OBR:
13216 check_dsp(ctx);
13217 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13218 break;
13219 case OPC_DPS_W_QH:
13220 check_dsp_r2(ctx);
13221 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13222 break;
13223 case OPC_DPSQ_S_W_QH:
13224 check_dsp(ctx);
13225 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13226 break;
13227 case OPC_DPSQ_SA_L_PW:
13228 check_dsp(ctx);
13229 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13230 break;
13231 case OPC_DPSU_H_OBL:
13232 check_dsp(ctx);
13233 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13234 break;
13235 case OPC_DPSU_H_OBR:
13236 check_dsp(ctx);
13237 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13238 break;
13239 case OPC_MAQ_S_L_PWL:
13240 check_dsp(ctx);
13241 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13242 break;
13243 case OPC_MAQ_S_L_PWR:
13244 check_dsp(ctx);
13245 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13246 break;
13247 case OPC_MAQ_S_W_QHLL:
13248 check_dsp(ctx);
13249 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13250 break;
13251 case OPC_MAQ_SA_W_QHLL:
13252 check_dsp(ctx);
13253 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13254 break;
13255 case OPC_MAQ_S_W_QHLR:
13256 check_dsp(ctx);
13257 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13258 break;
13259 case OPC_MAQ_SA_W_QHLR:
13260 check_dsp(ctx);
13261 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13262 break;
13263 case OPC_MAQ_S_W_QHRL:
13264 check_dsp(ctx);
13265 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13266 break;
13267 case OPC_MAQ_SA_W_QHRL:
13268 check_dsp(ctx);
13269 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13270 break;
13271 case OPC_MAQ_S_W_QHRR:
13272 check_dsp(ctx);
13273 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13274 break;
13275 case OPC_MAQ_SA_W_QHRR:
13276 check_dsp(ctx);
13277 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13278 break;
13279 case OPC_MULSAQ_S_L_PW:
13280 check_dsp(ctx);
13281 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13282 break;
13283 case OPC_MULSAQ_S_W_QH:
13284 check_dsp(ctx);
13285 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13286 break;
13287 }
13288 }
13289 break;
13290#endif
13291 case OPC_ADDU_QB_DSP:
13292 switch (op2) {
13293 case OPC_MULEU_S_PH_QBL:
13294 check_dsp(ctx);
13295 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13296 break;
13297 case OPC_MULEU_S_PH_QBR:
13298 check_dsp(ctx);
13299 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13300 break;
13301 case OPC_MULQ_RS_PH:
13302 check_dsp(ctx);
13303 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13304 break;
13305 case OPC_MULEQ_S_W_PHL:
13306 check_dsp(ctx);
13307 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13308 break;
13309 case OPC_MULEQ_S_W_PHR:
13310 check_dsp(ctx);
13311 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13312 break;
13313 case OPC_MULQ_S_PH:
13314 check_dsp_r2(ctx);
13315 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13316 break;
13317 }
13318 break;
13319#ifdef TARGET_MIPS64
13320 case OPC_ADDU_OB_DSP:
13321 switch (op2) {
13322 case OPC_MULEQ_S_PW_QHL:
13323 check_dsp(ctx);
13324 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13325 break;
13326 case OPC_MULEQ_S_PW_QHR:
13327 check_dsp(ctx);
13328 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13329 break;
13330 case OPC_MULEU_S_QH_OBL:
13331 check_dsp(ctx);
13332 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13333 break;
13334 case OPC_MULEU_S_QH_OBR:
13335 check_dsp(ctx);
13336 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13337 break;
13338 case OPC_MULQ_RS_QH:
13339 check_dsp(ctx);
13340 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13341 break;
13342 }
13343 break;
13344#endif
13345 }
13346
13347 tcg_temp_free_i32(t0);
13348 tcg_temp_free(v1_t);
13349 tcg_temp_free(v2_t);
13350}
13351
13352static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13353 int ret, int val)
13354{
13355 int16_t imm;
13356 TCGv t0;
13357 TCGv val_t;
13358
13359 if (ret == 0) {
13360
13361 return;
13362 }
13363
13364 t0 = tcg_temp_new();
13365 val_t = tcg_temp_new();
13366 gen_load_gpr(val_t, val);
13367
13368 switch (op1) {
13369 case OPC_ABSQ_S_PH_DSP:
13370 switch (op2) {
13371 case OPC_BITREV:
13372 check_dsp(ctx);
13373 gen_helper_bitrev(cpu_gpr[ret], val_t);
13374 break;
13375 case OPC_REPL_QB:
13376 check_dsp(ctx);
13377 {
13378 target_long result;
13379 imm = (ctx->opcode >> 16) & 0xFF;
13380 result = (uint32_t)imm << 24 |
13381 (uint32_t)imm << 16 |
13382 (uint32_t)imm << 8 |
13383 (uint32_t)imm;
13384 result = (int32_t)result;
13385 tcg_gen_movi_tl(cpu_gpr[ret], result);
13386 }
13387 break;
13388 case OPC_REPLV_QB:
13389 check_dsp(ctx);
13390 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13391 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13392 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13393 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13394 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13395 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13396 break;
13397 case OPC_REPL_PH:
13398 check_dsp(ctx);
13399 {
13400 imm = (ctx->opcode >> 16) & 0x03FF;
13401 imm = (int16_t)(imm << 6) >> 6;
13402 tcg_gen_movi_tl(cpu_gpr[ret], \
13403 (target_long)((int32_t)imm << 16 | \
13404 (uint16_t)imm));
13405 }
13406 break;
13407 case OPC_REPLV_PH:
13408 check_dsp(ctx);
13409 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13410 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13411 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13412 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13413 break;
13414 }
13415 break;
13416#ifdef TARGET_MIPS64
13417 case OPC_ABSQ_S_QH_DSP:
13418 switch (op2) {
13419 case OPC_REPL_OB:
13420 check_dsp(ctx);
13421 {
13422 target_long temp;
13423
13424 imm = (ctx->opcode >> 16) & 0xFF;
13425 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13426 temp = (temp << 16) | temp;
13427 temp = (temp << 32) | temp;
13428 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13429 break;
13430 }
13431 case OPC_REPL_PW:
13432 check_dsp(ctx);
13433 {
13434 target_long temp;
13435
13436 imm = (ctx->opcode >> 16) & 0x03FF;
13437 imm = (int16_t)(imm << 6) >> 6;
13438 temp = ((target_long)imm << 32) \
13439 | ((target_long)imm & 0xFFFFFFFF);
13440 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13441 break;
13442 }
13443 case OPC_REPL_QH:
13444 check_dsp(ctx);
13445 {
13446 target_long temp;
13447
13448 imm = (ctx->opcode >> 16) & 0x03FF;
13449 imm = (int16_t)(imm << 6) >> 6;
13450
13451 temp = ((uint64_t)(uint16_t)imm << 48) |
13452 ((uint64_t)(uint16_t)imm << 32) |
13453 ((uint64_t)(uint16_t)imm << 16) |
13454 (uint64_t)(uint16_t)imm;
13455 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13456 break;
13457 }
13458 case OPC_REPLV_OB:
13459 check_dsp(ctx);
13460 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13461 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13462 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13463 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13464 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13465 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13466 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13467 break;
13468 case OPC_REPLV_PW:
13469 check_dsp(ctx);
13470 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13471 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13472 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13473 break;
13474 case OPC_REPLV_QH:
13475 check_dsp(ctx);
13476 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13477 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13478 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13479 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13480 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13481 break;
13482 }
13483 break;
13484#endif
13485 }
13486 tcg_temp_free(t0);
13487 tcg_temp_free(val_t);
13488}
13489
13490static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13491 uint32_t op1, uint32_t op2,
13492 int ret, int v1, int v2, int check_ret)
13493{
13494 TCGv t1;
13495 TCGv v1_t;
13496 TCGv v2_t;
13497
13498 if ((ret == 0) && (check_ret == 1)) {
13499
13500 return;
13501 }
13502
13503 t1 = tcg_temp_new();
13504 v1_t = tcg_temp_new();
13505 v2_t = tcg_temp_new();
13506
13507 gen_load_gpr(v1_t, v1);
13508 gen_load_gpr(v2_t, v2);
13509
13510 switch (op1) {
13511 case OPC_CMPU_EQ_QB_DSP:
13512 switch (op2) {
13513 case OPC_CMPU_EQ_QB:
13514 check_dsp(ctx);
13515 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13516 break;
13517 case OPC_CMPU_LT_QB:
13518 check_dsp(ctx);
13519 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13520 break;
13521 case OPC_CMPU_LE_QB:
13522 check_dsp(ctx);
13523 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13524 break;
13525 case OPC_CMPGU_EQ_QB:
13526 check_dsp(ctx);
13527 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13528 break;
13529 case OPC_CMPGU_LT_QB:
13530 check_dsp(ctx);
13531 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13532 break;
13533 case OPC_CMPGU_LE_QB:
13534 check_dsp(ctx);
13535 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13536 break;
13537 case OPC_CMPGDU_EQ_QB:
13538 check_dsp_r2(ctx);
13539 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13540 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13541 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13542 tcg_gen_shli_tl(t1, t1, 24);
13543 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13544 break;
13545 case OPC_CMPGDU_LT_QB:
13546 check_dsp_r2(ctx);
13547 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13548 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13549 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13550 tcg_gen_shli_tl(t1, t1, 24);
13551 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13552 break;
13553 case OPC_CMPGDU_LE_QB:
13554 check_dsp_r2(ctx);
13555 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13556 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13557 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13558 tcg_gen_shli_tl(t1, t1, 24);
13559 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13560 break;
13561 case OPC_CMP_EQ_PH:
13562 check_dsp(ctx);
13563 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13564 break;
13565 case OPC_CMP_LT_PH:
13566 check_dsp(ctx);
13567 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13568 break;
13569 case OPC_CMP_LE_PH:
13570 check_dsp(ctx);
13571 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13572 break;
13573 case OPC_PICK_QB:
13574 check_dsp(ctx);
13575 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13576 break;
13577 case OPC_PICK_PH:
13578 check_dsp(ctx);
13579 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13580 break;
13581 case OPC_PACKRL_PH:
13582 check_dsp(ctx);
13583 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13584 break;
13585 }
13586 break;
13587#ifdef TARGET_MIPS64
13588 case OPC_CMPU_EQ_OB_DSP:
13589 switch (op2) {
13590 case OPC_CMP_EQ_PW:
13591 check_dsp(ctx);
13592 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13593 break;
13594 case OPC_CMP_LT_PW:
13595 check_dsp(ctx);
13596 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13597 break;
13598 case OPC_CMP_LE_PW:
13599 check_dsp(ctx);
13600 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13601 break;
13602 case OPC_CMP_EQ_QH:
13603 check_dsp(ctx);
13604 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13605 break;
13606 case OPC_CMP_LT_QH:
13607 check_dsp(ctx);
13608 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13609 break;
13610 case OPC_CMP_LE_QH:
13611 check_dsp(ctx);
13612 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13613 break;
13614 case OPC_CMPGDU_EQ_OB:
13615 check_dsp_r2(ctx);
13616 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13617 break;
13618 case OPC_CMPGDU_LT_OB:
13619 check_dsp_r2(ctx);
13620 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13621 break;
13622 case OPC_CMPGDU_LE_OB:
13623 check_dsp_r2(ctx);
13624 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13625 break;
13626 case OPC_CMPGU_EQ_OB:
13627 check_dsp(ctx);
13628 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13629 break;
13630 case OPC_CMPGU_LT_OB:
13631 check_dsp(ctx);
13632 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13633 break;
13634 case OPC_CMPGU_LE_OB:
13635 check_dsp(ctx);
13636 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13637 break;
13638 case OPC_CMPU_EQ_OB:
13639 check_dsp(ctx);
13640 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13641 break;
13642 case OPC_CMPU_LT_OB:
13643 check_dsp(ctx);
13644 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13645 break;
13646 case OPC_CMPU_LE_OB:
13647 check_dsp(ctx);
13648 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13649 break;
13650 case OPC_PACKRL_PW:
13651 check_dsp(ctx);
13652 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13653 break;
13654 case OPC_PICK_OB:
13655 check_dsp(ctx);
13656 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13657 break;
13658 case OPC_PICK_PW:
13659 check_dsp(ctx);
13660 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13661 break;
13662 case OPC_PICK_QH:
13663 check_dsp(ctx);
13664 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13665 break;
13666 }
13667 break;
13668#endif
13669 }
13670
13671 tcg_temp_free(t1);
13672 tcg_temp_free(v1_t);
13673 tcg_temp_free(v2_t);
13674}
13675
13676static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13677 uint32_t op1, int rt, int rs, int sa)
13678{
13679 TCGv t0;
13680
13681 check_dsp_r2(ctx);
13682
13683 if (rt == 0) {
13684
13685 return;
13686 }
13687
13688 t0 = tcg_temp_new();
13689 gen_load_gpr(t0, rs);
13690
13691 switch (op1) {
13692 case OPC_APPEND_DSP:
13693 switch (MASK_APPEND(ctx->opcode)) {
13694 case OPC_APPEND:
13695 if (sa != 0) {
13696 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13697 }
13698 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13699 break;
13700 case OPC_PREPEND:
13701 if (sa != 0) {
13702 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13703 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13704 tcg_gen_shli_tl(t0, t0, 32 - sa);
13705 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13706 }
13707 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13708 break;
13709 case OPC_BALIGN:
13710 sa &= 3;
13711 if (sa != 0 && sa != 2) {
13712 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13713 tcg_gen_ext32u_tl(t0, t0);
13714 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13715 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13716 }
13717 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13718 break;
13719 default:
13720 MIPS_INVAL("MASK APPEND");
13721 gen_reserved_instruction(ctx);
13722 break;
13723 }
13724 break;
13725#ifdef TARGET_MIPS64
13726 case OPC_DAPPEND_DSP:
13727 switch (MASK_DAPPEND(ctx->opcode)) {
13728 case OPC_DAPPEND:
13729 if (sa != 0) {
13730 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13731 }
13732 break;
13733 case OPC_PREPENDD:
13734 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13735 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13736 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13737 break;
13738 case OPC_PREPENDW:
13739 if (sa != 0) {
13740 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13741 tcg_gen_shli_tl(t0, t0, 64 - sa);
13742 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13743 }
13744 break;
13745 case OPC_DBALIGN:
13746 sa &= 7;
13747 if (sa != 0 && sa != 2 && sa != 4) {
13748 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13749 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13750 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13751 }
13752 break;
13753 default:
13754 MIPS_INVAL("MASK DAPPEND");
13755 gen_reserved_instruction(ctx);
13756 break;
13757 }
13758 break;
13759#endif
13760 }
13761 tcg_temp_free(t0);
13762}
13763
13764static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13765 int ret, int v1, int v2, int check_ret)
13766
13767{
13768 TCGv t0;
13769 TCGv t1;
13770 TCGv v1_t;
13771 TCGv v2_t;
13772 int16_t imm;
13773
13774 if ((ret == 0) && (check_ret == 1)) {
13775
13776 return;
13777 }
13778
13779 t0 = tcg_temp_new();
13780 t1 = tcg_temp_new();
13781 v1_t = tcg_temp_new();
13782 v2_t = tcg_temp_new();
13783
13784 gen_load_gpr(v1_t, v1);
13785 gen_load_gpr(v2_t, v2);
13786
13787 switch (op1) {
13788 case OPC_EXTR_W_DSP:
13789 check_dsp(ctx);
13790 switch (op2) {
13791 case OPC_EXTR_W:
13792 tcg_gen_movi_tl(t0, v2);
13793 tcg_gen_movi_tl(t1, v1);
13794 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13795 break;
13796 case OPC_EXTR_R_W:
13797 tcg_gen_movi_tl(t0, v2);
13798 tcg_gen_movi_tl(t1, v1);
13799 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13800 break;
13801 case OPC_EXTR_RS_W:
13802 tcg_gen_movi_tl(t0, v2);
13803 tcg_gen_movi_tl(t1, v1);
13804 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13805 break;
13806 case OPC_EXTR_S_H:
13807 tcg_gen_movi_tl(t0, v2);
13808 tcg_gen_movi_tl(t1, v1);
13809 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13810 break;
13811 case OPC_EXTRV_S_H:
13812 tcg_gen_movi_tl(t0, v2);
13813 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13814 break;
13815 case OPC_EXTRV_W:
13816 tcg_gen_movi_tl(t0, v2);
13817 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13818 break;
13819 case OPC_EXTRV_R_W:
13820 tcg_gen_movi_tl(t0, v2);
13821 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13822 break;
13823 case OPC_EXTRV_RS_W:
13824 tcg_gen_movi_tl(t0, v2);
13825 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13826 break;
13827 case OPC_EXTP:
13828 tcg_gen_movi_tl(t0, v2);
13829 tcg_gen_movi_tl(t1, v1);
13830 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13831 break;
13832 case OPC_EXTPV:
13833 tcg_gen_movi_tl(t0, v2);
13834 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13835 break;
13836 case OPC_EXTPDP:
13837 tcg_gen_movi_tl(t0, v2);
13838 tcg_gen_movi_tl(t1, v1);
13839 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13840 break;
13841 case OPC_EXTPDPV:
13842 tcg_gen_movi_tl(t0, v2);
13843 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13844 break;
13845 case OPC_SHILO:
13846 imm = (ctx->opcode >> 20) & 0x3F;
13847 tcg_gen_movi_tl(t0, ret);
13848 tcg_gen_movi_tl(t1, imm);
13849 gen_helper_shilo(t0, t1, cpu_env);
13850 break;
13851 case OPC_SHILOV:
13852 tcg_gen_movi_tl(t0, ret);
13853 gen_helper_shilo(t0, v1_t, cpu_env);
13854 break;
13855 case OPC_MTHLIP:
13856 tcg_gen_movi_tl(t0, ret);
13857 gen_helper_mthlip(t0, v1_t, cpu_env);
13858 break;
13859 case OPC_WRDSP:
13860 imm = (ctx->opcode >> 11) & 0x3FF;
13861 tcg_gen_movi_tl(t0, imm);
13862 gen_helper_wrdsp(v1_t, t0, cpu_env);
13863 break;
13864 case OPC_RDDSP:
13865 imm = (ctx->opcode >> 16) & 0x03FF;
13866 tcg_gen_movi_tl(t0, imm);
13867 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13868 break;
13869 }
13870 break;
13871#ifdef TARGET_MIPS64
13872 case OPC_DEXTR_W_DSP:
13873 check_dsp(ctx);
13874 switch (op2) {
13875 case OPC_DMTHLIP:
13876 tcg_gen_movi_tl(t0, ret);
13877 gen_helper_dmthlip(v1_t, t0, cpu_env);
13878 break;
13879 case OPC_DSHILO:
13880 {
13881 int shift = (ctx->opcode >> 19) & 0x7F;
13882 int ac = (ctx->opcode >> 11) & 0x03;
13883 tcg_gen_movi_tl(t0, shift);
13884 tcg_gen_movi_tl(t1, ac);
13885 gen_helper_dshilo(t0, t1, cpu_env);
13886 break;
13887 }
13888 case OPC_DSHILOV:
13889 {
13890 int ac = (ctx->opcode >> 11) & 0x03;
13891 tcg_gen_movi_tl(t0, ac);
13892 gen_helper_dshilo(v1_t, t0, cpu_env);
13893 break;
13894 }
13895 case OPC_DEXTP:
13896 tcg_gen_movi_tl(t0, v2);
13897 tcg_gen_movi_tl(t1, v1);
13898
13899 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13900 break;
13901 case OPC_DEXTPV:
13902 tcg_gen_movi_tl(t0, v2);
13903 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13904 break;
13905 case OPC_DEXTPDP:
13906 tcg_gen_movi_tl(t0, v2);
13907 tcg_gen_movi_tl(t1, v1);
13908 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13909 break;
13910 case OPC_DEXTPDPV:
13911 tcg_gen_movi_tl(t0, v2);
13912 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13913 break;
13914 case OPC_DEXTR_L:
13915 tcg_gen_movi_tl(t0, v2);
13916 tcg_gen_movi_tl(t1, v1);
13917 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13918 break;
13919 case OPC_DEXTR_R_L:
13920 tcg_gen_movi_tl(t0, v2);
13921 tcg_gen_movi_tl(t1, v1);
13922 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13923 break;
13924 case OPC_DEXTR_RS_L:
13925 tcg_gen_movi_tl(t0, v2);
13926 tcg_gen_movi_tl(t1, v1);
13927 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13928 break;
13929 case OPC_DEXTR_W:
13930 tcg_gen_movi_tl(t0, v2);
13931 tcg_gen_movi_tl(t1, v1);
13932 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13933 break;
13934 case OPC_DEXTR_R_W:
13935 tcg_gen_movi_tl(t0, v2);
13936 tcg_gen_movi_tl(t1, v1);
13937 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13938 break;
13939 case OPC_DEXTR_RS_W:
13940 tcg_gen_movi_tl(t0, v2);
13941 tcg_gen_movi_tl(t1, v1);
13942 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13943 break;
13944 case OPC_DEXTR_S_H:
13945 tcg_gen_movi_tl(t0, v2);
13946 tcg_gen_movi_tl(t1, v1);
13947 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13948 break;
13949 case OPC_DEXTRV_S_H:
13950 tcg_gen_movi_tl(t0, v2);
13951 tcg_gen_movi_tl(t1, v1);
13952 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13953 break;
13954 case OPC_DEXTRV_L:
13955 tcg_gen_movi_tl(t0, v2);
13956 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13957 break;
13958 case OPC_DEXTRV_R_L:
13959 tcg_gen_movi_tl(t0, v2);
13960 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13961 break;
13962 case OPC_DEXTRV_RS_L:
13963 tcg_gen_movi_tl(t0, v2);
13964 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13965 break;
13966 case OPC_DEXTRV_W:
13967 tcg_gen_movi_tl(t0, v2);
13968 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13969 break;
13970 case OPC_DEXTRV_R_W:
13971 tcg_gen_movi_tl(t0, v2);
13972 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13973 break;
13974 case OPC_DEXTRV_RS_W:
13975 tcg_gen_movi_tl(t0, v2);
13976 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13977 break;
13978 }
13979 break;
13980#endif
13981 }
13982
13983 tcg_temp_free(t0);
13984 tcg_temp_free(t1);
13985 tcg_temp_free(v1_t);
13986 tcg_temp_free(v2_t);
13987}
13988
13989
13990
13991static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13992{
13993 int rs, rt, rd, sa;
13994 uint32_t op1, op2;
13995
13996 rs = (ctx->opcode >> 21) & 0x1f;
13997 rt = (ctx->opcode >> 16) & 0x1f;
13998 rd = (ctx->opcode >> 11) & 0x1f;
13999 sa = (ctx->opcode >> 6) & 0x1f;
14000
14001 op1 = MASK_SPECIAL(ctx->opcode);
14002 switch (op1) {
14003 case OPC_MULT:
14004 case OPC_MULTU:
14005 case OPC_DIV:
14006 case OPC_DIVU:
14007 op2 = MASK_R6_MULDIV(ctx->opcode);
14008 switch (op2) {
14009 case R6_OPC_MUL:
14010 case R6_OPC_MUH:
14011 case R6_OPC_MULU:
14012 case R6_OPC_MUHU:
14013 case R6_OPC_DIV:
14014 case R6_OPC_MOD:
14015 case R6_OPC_DIVU:
14016 case R6_OPC_MODU:
14017 gen_r6_muldiv(ctx, op2, rd, rs, rt);
14018 break;
14019 default:
14020 MIPS_INVAL("special_r6 muldiv");
14021 gen_reserved_instruction(ctx);
14022 break;
14023 }
14024 break;
14025 case OPC_SELEQZ:
14026 case OPC_SELNEZ:
14027 gen_cond_move(ctx, op1, rd, rs, rt);
14028 break;
14029 case R6_OPC_CLO:
14030 case R6_OPC_CLZ:
14031 if (rt == 0 && sa == 1) {
14032
14033
14034
14035
14036 gen_cl(ctx, op1, rd, rs);
14037 } else {
14038 gen_reserved_instruction(ctx);
14039 }
14040 break;
14041 case R6_OPC_SDBBP:
14042 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14043 gen_helper_do_semihosting(cpu_env);
14044 } else {
14045 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14046 gen_reserved_instruction(ctx);
14047 } else {
14048 generate_exception_end(ctx, EXCP_DBp);
14049 }
14050 }
14051 break;
14052#if defined(TARGET_MIPS64)
14053 case R6_OPC_DCLO:
14054 case R6_OPC_DCLZ:
14055 if (rt == 0 && sa == 1) {
14056
14057
14058
14059
14060 check_mips_64(ctx);
14061 gen_cl(ctx, op1, rd, rs);
14062 } else {
14063 gen_reserved_instruction(ctx);
14064 }
14065 break;
14066 case OPC_DMULT:
14067 case OPC_DMULTU:
14068 case OPC_DDIV:
14069 case OPC_DDIVU:
14070
14071 op2 = MASK_R6_MULDIV(ctx->opcode);
14072 switch (op2) {
14073 case R6_OPC_DMUL:
14074 case R6_OPC_DMUH:
14075 case R6_OPC_DMULU:
14076 case R6_OPC_DMUHU:
14077 case R6_OPC_DDIV:
14078 case R6_OPC_DMOD:
14079 case R6_OPC_DDIVU:
14080 case R6_OPC_DMODU:
14081 check_mips_64(ctx);
14082 gen_r6_muldiv(ctx, op2, rd, rs, rt);
14083 break;
14084 default:
14085 MIPS_INVAL("special_r6 muldiv");
14086 gen_reserved_instruction(ctx);
14087 break;
14088 }
14089 break;
14090#endif
14091 default:
14092 MIPS_INVAL("special_r6");
14093 gen_reserved_instruction(ctx);
14094 break;
14095 }
14096}
14097
14098static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
14099{
14100 int rs = extract32(ctx->opcode, 21, 5);
14101 int rt = extract32(ctx->opcode, 16, 5);
14102 int rd = extract32(ctx->opcode, 11, 5);
14103 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
14104
14105 switch (op1) {
14106 case OPC_MOVN:
14107 case OPC_MOVZ:
14108 gen_cond_move(ctx, op1, rd, rs, rt);
14109 break;
14110 case OPC_MFHI:
14111 case OPC_MFLO:
14112 gen_HILO(ctx, op1, 0, rd);
14113 break;
14114 case OPC_MTHI:
14115 case OPC_MTLO:
14116 gen_HILO(ctx, op1, 0, rs);
14117 break;
14118 case OPC_MULT:
14119 case OPC_MULTU:
14120 gen_mul_txx9(ctx, op1, rd, rs, rt);
14121 break;
14122 case OPC_DIV:
14123 case OPC_DIVU:
14124 gen_muldiv(ctx, op1, 0, rs, rt);
14125 break;
14126#if defined(TARGET_MIPS64)
14127 case OPC_DMULT:
14128 case OPC_DMULTU:
14129 case OPC_DDIV:
14130 case OPC_DDIVU:
14131 check_insn_opc_user_only(ctx, INSN_R5900);
14132 gen_muldiv(ctx, op1, 0, rs, rt);
14133 break;
14134#endif
14135 case OPC_JR:
14136 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14137 break;
14138 default:
14139 MIPS_INVAL("special_tx79");
14140 gen_reserved_instruction(ctx);
14141 break;
14142 }
14143}
14144
14145static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14146{
14147 int rs, rt, rd, sa;
14148 uint32_t op1;
14149
14150 rs = (ctx->opcode >> 21) & 0x1f;
14151 rt = (ctx->opcode >> 16) & 0x1f;
14152 rd = (ctx->opcode >> 11) & 0x1f;
14153 sa = (ctx->opcode >> 6) & 0x1f;
14154
14155 op1 = MASK_SPECIAL(ctx->opcode);
14156 switch (op1) {
14157 case OPC_MOVN:
14158 case OPC_MOVZ:
14159 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
14160 INSN_LOONGSON2E | INSN_LOONGSON2F);
14161 gen_cond_move(ctx, op1, rd, rs, rt);
14162 break;
14163 case OPC_MFHI:
14164 case OPC_MFLO:
14165 gen_HILO(ctx, op1, rs & 3, rd);
14166 break;
14167 case OPC_MTHI:
14168 case OPC_MTLO:
14169 gen_HILO(ctx, op1, rd & 3, rs);
14170 break;
14171 case OPC_MOVCI:
14172 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
14173 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14174 check_cp1_enabled(ctx);
14175 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14176 (ctx->opcode >> 16) & 1);
14177 } else {
14178 generate_exception_err(ctx, EXCP_CpU, 1);
14179 }
14180 break;
14181 case OPC_MULT:
14182 case OPC_MULTU:
14183 if (sa) {
14184 check_insn(ctx, INSN_VR54XX);
14185 op1 = MASK_MUL_VR54XX(ctx->opcode);
14186 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14187 } else {
14188 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14189 }
14190 break;
14191 case OPC_DIV:
14192 case OPC_DIVU:
14193 gen_muldiv(ctx, op1, 0, rs, rt);
14194 break;
14195#if defined(TARGET_MIPS64)
14196 case OPC_DMULT:
14197 case OPC_DMULTU:
14198 case OPC_DDIV:
14199 case OPC_DDIVU:
14200 check_insn(ctx, ISA_MIPS3);
14201 check_mips_64(ctx);
14202 gen_muldiv(ctx, op1, 0, rs, rt);
14203 break;
14204#endif
14205 case OPC_JR:
14206 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14207 break;
14208 case OPC_SPIM:
14209#ifdef MIPS_STRICT_STANDARD
14210 MIPS_INVAL("SPIM");
14211 gen_reserved_instruction(ctx);
14212#else
14213
14214 MIPS_INVAL("spim (unofficial)");
14215 gen_reserved_instruction(ctx);
14216#endif
14217 break;
14218 default:
14219 MIPS_INVAL("special_legacy");
14220 gen_reserved_instruction(ctx);
14221 break;
14222 }
14223}
14224
14225static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
14226{
14227 int rs, rt, rd, sa;
14228 uint32_t op1;
14229
14230 rs = (ctx->opcode >> 21) & 0x1f;
14231 rt = (ctx->opcode >> 16) & 0x1f;
14232 rd = (ctx->opcode >> 11) & 0x1f;
14233 sa = (ctx->opcode >> 6) & 0x1f;
14234
14235 op1 = MASK_SPECIAL(ctx->opcode);
14236 switch (op1) {
14237 case OPC_SLL:
14238 if (sa == 5 && rd == 0 &&
14239 rs == 0 && rt == 0) {
14240 if ((ctx->insn_flags & ISA_MIPS_R6) &&
14241 (ctx->hflags & MIPS_HFLAG_BMASK)) {
14242 gen_reserved_instruction(ctx);
14243 break;
14244 }
14245 }
14246
14247 case OPC_SRA:
14248 gen_shift_imm(ctx, op1, rd, rt, sa);
14249 break;
14250 case OPC_SRL:
14251 switch ((ctx->opcode >> 21) & 0x1f) {
14252 case 1:
14253
14254 if (ctx->insn_flags & ISA_MIPS_R2) {
14255 op1 = OPC_ROTR;
14256 }
14257
14258 case 0:
14259 gen_shift_imm(ctx, op1, rd, rt, sa);
14260 break;
14261 default:
14262 gen_reserved_instruction(ctx);
14263 break;
14264 }
14265 break;
14266 case OPC_ADD:
14267 case OPC_ADDU:
14268 case OPC_SUB:
14269 case OPC_SUBU:
14270 gen_arith(ctx, op1, rd, rs, rt);
14271 break;
14272 case OPC_SLLV:
14273 case OPC_SRAV:
14274 gen_shift(ctx, op1, rd, rs, rt);
14275 break;
14276 case OPC_SRLV:
14277 switch ((ctx->opcode >> 6) & 0x1f) {
14278 case 1:
14279
14280 if (ctx->insn_flags & ISA_MIPS_R2) {
14281 op1 = OPC_ROTRV;
14282 }
14283
14284 case 0:
14285 gen_shift(ctx, op1, rd, rs, rt);
14286 break;
14287 default:
14288 gen_reserved_instruction(ctx);
14289 break;
14290 }
14291 break;
14292 case OPC_SLT:
14293 case OPC_SLTU:
14294 gen_slt(ctx, op1, rd, rs, rt);
14295 break;
14296 case OPC_AND:
14297 case OPC_OR:
14298 case OPC_NOR:
14299 case OPC_XOR:
14300 gen_logic(ctx, op1, rd, rs, rt);
14301 break;
14302 case OPC_JALR:
14303 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14304 break;
14305 case OPC_TGE:
14306 case OPC_TGEU:
14307 case OPC_TLT:
14308 case OPC_TLTU:
14309 case OPC_TEQ:
14310 case OPC_TNE:
14311 check_insn(ctx, ISA_MIPS2);
14312 gen_trap(ctx, op1, rs, rt, -1);
14313 break;
14314 case OPC_PMON:
14315
14316#ifdef MIPS_STRICT_STANDARD
14317 MIPS_INVAL("PMON / selsl");
14318 gen_reserved_instruction(ctx);
14319#else
14320 gen_helper_0e0i(pmon, sa);
14321#endif
14322 break;
14323 case OPC_SYSCALL:
14324 generate_exception_end(ctx, EXCP_SYSCALL);
14325 break;
14326 case OPC_BREAK:
14327 generate_exception_end(ctx, EXCP_BREAK);
14328 break;
14329 case OPC_SYNC:
14330 check_insn(ctx, ISA_MIPS2);
14331 gen_sync(extract32(ctx->opcode, 6, 5));
14332 break;
14333
14334#if defined(TARGET_MIPS64)
14335
14336 case OPC_DSLL:
14337 case OPC_DSRA:
14338 case OPC_DSLL32:
14339 case OPC_DSRA32:
14340 check_insn(ctx, ISA_MIPS3);
14341 check_mips_64(ctx);
14342 gen_shift_imm(ctx, op1, rd, rt, sa);
14343 break;
14344 case OPC_DSRL:
14345 switch ((ctx->opcode >> 21) & 0x1f) {
14346 case 1:
14347
14348 if (ctx->insn_flags & ISA_MIPS_R2) {
14349 op1 = OPC_DROTR;
14350 }
14351
14352 case 0:
14353 check_insn(ctx, ISA_MIPS3);
14354 check_mips_64(ctx);
14355 gen_shift_imm(ctx, op1, rd, rt, sa);
14356 break;
14357 default:
14358 gen_reserved_instruction(ctx);
14359 break;
14360 }
14361 break;
14362 case OPC_DSRL32:
14363 switch ((ctx->opcode >> 21) & 0x1f) {
14364 case 1:
14365
14366 if (ctx->insn_flags & ISA_MIPS_R2) {
14367 op1 = OPC_DROTR32;
14368 }
14369
14370 case 0:
14371 check_insn(ctx, ISA_MIPS3);
14372 check_mips_64(ctx);
14373 gen_shift_imm(ctx, op1, rd, rt, sa);
14374 break;
14375 default:
14376 gen_reserved_instruction(ctx);
14377 break;
14378 }
14379 break;
14380 case OPC_DADD:
14381 case OPC_DADDU:
14382 case OPC_DSUB:
14383 case OPC_DSUBU:
14384 check_insn(ctx, ISA_MIPS3);
14385 check_mips_64(ctx);
14386 gen_arith(ctx, op1, rd, rs, rt);
14387 break;
14388 case OPC_DSLLV:
14389 case OPC_DSRAV:
14390 check_insn(ctx, ISA_MIPS3);
14391 check_mips_64(ctx);
14392 gen_shift(ctx, op1, rd, rs, rt);
14393 break;
14394 case OPC_DSRLV:
14395 switch ((ctx->opcode >> 6) & 0x1f) {
14396 case 1:
14397
14398 if (ctx->insn_flags & ISA_MIPS_R2) {
14399 op1 = OPC_DROTRV;
14400 }
14401
14402 case 0:
14403 check_insn(ctx, ISA_MIPS3);
14404 check_mips_64(ctx);
14405 gen_shift(ctx, op1, rd, rs, rt);
14406 break;
14407 default:
14408 gen_reserved_instruction(ctx);
14409 break;
14410 }
14411 break;
14412#endif
14413 default:
14414 if (ctx->insn_flags & ISA_MIPS_R6) {
14415 decode_opc_special_r6(env, ctx);
14416 } else if (ctx->insn_flags & INSN_R5900) {
14417 decode_opc_special_tx79(env, ctx);
14418 } else {
14419 decode_opc_special_legacy(env, ctx);
14420 }
14421 }
14422}
14423
14424
14425static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
14426{
14427 int rs, rt, rd;
14428 uint32_t op1;
14429
14430 rs = (ctx->opcode >> 21) & 0x1f;
14431 rt = (ctx->opcode >> 16) & 0x1f;
14432 rd = (ctx->opcode >> 11) & 0x1f;
14433
14434 op1 = MASK_SPECIAL2(ctx->opcode);
14435 switch (op1) {
14436 case OPC_MADD:
14437 case OPC_MADDU:
14438 case OPC_MSUB:
14439 case OPC_MSUBU:
14440 check_insn(ctx, ISA_MIPS_R1);
14441 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14442 break;
14443 case OPC_MUL:
14444 gen_arith(ctx, op1, rd, rs, rt);
14445 break;
14446 case OPC_DIV_G_2F:
14447 case OPC_DIVU_G_2F:
14448 case OPC_MULT_G_2F:
14449 case OPC_MULTU_G_2F:
14450 case OPC_MOD_G_2F:
14451 case OPC_MODU_G_2F:
14452 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14453 gen_loongson_integer(ctx, op1, rd, rs, rt);
14454 break;
14455 case OPC_CLO:
14456 case OPC_CLZ:
14457 check_insn(ctx, ISA_MIPS_R1);
14458 gen_cl(ctx, op1, rd, rs);
14459 break;
14460 case OPC_SDBBP:
14461 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14462 gen_helper_do_semihosting(cpu_env);
14463 } else {
14464
14465
14466
14467
14468 check_insn(ctx, ISA_MIPS_R1);
14469 generate_exception_end(ctx, EXCP_DBp);
14470 }
14471 break;
14472#if defined(TARGET_MIPS64)
14473 case OPC_DCLO:
14474 case OPC_DCLZ:
14475 check_insn(ctx, ISA_MIPS_R1);
14476 check_mips_64(ctx);
14477 gen_cl(ctx, op1, rd, rs);
14478 break;
14479 case OPC_DMULT_G_2F:
14480 case OPC_DMULTU_G_2F:
14481 case OPC_DDIV_G_2F:
14482 case OPC_DDIVU_G_2F:
14483 case OPC_DMOD_G_2F:
14484 case OPC_DMODU_G_2F:
14485 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14486 gen_loongson_integer(ctx, op1, rd, rs, rt);
14487 break;
14488#endif
14489 default:
14490 MIPS_INVAL("special2_legacy");
14491 gen_reserved_instruction(ctx);
14492 break;
14493 }
14494}
14495
14496static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14497{
14498 int rs, rt, rd, sa;
14499 uint32_t op1, op2;
14500 int16_t imm;
14501
14502 rs = (ctx->opcode >> 21) & 0x1f;
14503 rt = (ctx->opcode >> 16) & 0x1f;
14504 rd = (ctx->opcode >> 11) & 0x1f;
14505 sa = (ctx->opcode >> 6) & 0x1f;
14506 imm = (int16_t)ctx->opcode >> 7;
14507
14508 op1 = MASK_SPECIAL3(ctx->opcode);
14509 switch (op1) {
14510 case R6_OPC_PREF:
14511 if (rt >= 24) {
14512
14513 gen_reserved_instruction(ctx);
14514 }
14515
14516 break;
14517 case R6_OPC_CACHE:
14518 check_cp0_enabled(ctx);
14519 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14520 gen_cache_operation(ctx, rt, rs, imm);
14521 }
14522 break;
14523 case R6_OPC_SC:
14524 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14525 break;
14526 case R6_OPC_LL:
14527 gen_ld(ctx, op1, rt, rs, imm);
14528 break;
14529 case OPC_BSHFL:
14530 {
14531 if (rd == 0) {
14532
14533 break;
14534 }
14535 op2 = MASK_BSHFL(ctx->opcode);
14536 switch (op2) {
14537 case OPC_ALIGN:
14538 case OPC_ALIGN_1:
14539 case OPC_ALIGN_2:
14540 case OPC_ALIGN_3:
14541 gen_align(ctx, 32, rd, rs, rt, sa & 3);
14542 break;
14543 case OPC_BITSWAP:
14544 gen_bitswap(ctx, op2, rd, rt);
14545 break;
14546 }
14547 }
14548 break;
14549#ifndef CONFIG_USER_ONLY
14550 case OPC_GINV:
14551 if (unlikely(ctx->gi <= 1)) {
14552 gen_reserved_instruction(ctx);
14553 }
14554 check_cp0_enabled(ctx);
14555 switch ((ctx->opcode >> 6) & 3) {
14556 case 0:
14557
14558 break;
14559 case 2:
14560 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14561 break;
14562 default:
14563 gen_reserved_instruction(ctx);
14564 break;
14565 }
14566 break;
14567#endif
14568#if defined(TARGET_MIPS64)
14569 case R6_OPC_SCD:
14570 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
14571 break;
14572 case R6_OPC_LLD:
14573 gen_ld(ctx, op1, rt, rs, imm);
14574 break;
14575 case OPC_DBSHFL:
14576 check_mips_64(ctx);
14577 {
14578 if (rd == 0) {
14579
14580 break;
14581 }
14582 op2 = MASK_DBSHFL(ctx->opcode);
14583 switch (op2) {
14584 case OPC_DALIGN:
14585 case OPC_DALIGN_1:
14586 case OPC_DALIGN_2:
14587 case OPC_DALIGN_3:
14588 case OPC_DALIGN_4:
14589 case OPC_DALIGN_5:
14590 case OPC_DALIGN_6:
14591 case OPC_DALIGN_7:
14592 gen_align(ctx, 64, rd, rs, rt, sa & 7);
14593 break;
14594 case OPC_DBITSWAP:
14595 gen_bitswap(ctx, op2, rd, rt);
14596 break;
14597 }
14598
14599 }
14600 break;
14601#endif
14602 default:
14603 MIPS_INVAL("special3_r6");
14604 gen_reserved_instruction(ctx);
14605 break;
14606 }
14607}
14608
14609static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14610{
14611 int rs, rt, rd;
14612 uint32_t op1, op2;
14613
14614 rs = (ctx->opcode >> 21) & 0x1f;
14615 rt = (ctx->opcode >> 16) & 0x1f;
14616 rd = (ctx->opcode >> 11) & 0x1f;
14617
14618 op1 = MASK_SPECIAL3(ctx->opcode);
14619 switch (op1) {
14620 case OPC_DIV_G_2E:
14621 case OPC_DIVU_G_2E:
14622 case OPC_MOD_G_2E:
14623 case OPC_MODU_G_2E:
14624 case OPC_MULT_G_2E:
14625 case OPC_MULTU_G_2E:
14626
14627
14628
14629
14630 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
14631 op2 = MASK_ADDUH_QB(ctx->opcode);
14632 switch (op2) {
14633 case OPC_ADDUH_QB:
14634 case OPC_ADDUH_R_QB:
14635 case OPC_ADDQH_PH:
14636 case OPC_ADDQH_R_PH:
14637 case OPC_ADDQH_W:
14638 case OPC_ADDQH_R_W:
14639 case OPC_SUBUH_QB:
14640 case OPC_SUBUH_R_QB:
14641 case OPC_SUBQH_PH:
14642 case OPC_SUBQH_R_PH:
14643 case OPC_SUBQH_W:
14644 case OPC_SUBQH_R_W:
14645 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14646 break;
14647 case OPC_MUL_PH:
14648 case OPC_MUL_S_PH:
14649 case OPC_MULQ_S_W:
14650 case OPC_MULQ_RS_W:
14651 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14652 break;
14653 default:
14654 MIPS_INVAL("MASK ADDUH.QB");
14655 gen_reserved_instruction(ctx);
14656 break;
14657 }
14658 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14659 gen_loongson_integer(ctx, op1, rd, rs, rt);
14660 } else {
14661 gen_reserved_instruction(ctx);
14662 }
14663 break;
14664 case OPC_LX_DSP:
14665 op2 = MASK_LX(ctx->opcode);
14666 switch (op2) {
14667#if defined(TARGET_MIPS64)
14668 case OPC_LDX:
14669#endif
14670 case OPC_LBUX:
14671 case OPC_LHX:
14672 case OPC_LWX:
14673 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14674 break;
14675 default:
14676 MIPS_INVAL("MASK LX");
14677 gen_reserved_instruction(ctx);
14678 break;
14679 }
14680 break;
14681 case OPC_ABSQ_S_PH_DSP:
14682 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14683 switch (op2) {
14684 case OPC_ABSQ_S_QB:
14685 case OPC_ABSQ_S_PH:
14686 case OPC_ABSQ_S_W:
14687 case OPC_PRECEQ_W_PHL:
14688 case OPC_PRECEQ_W_PHR:
14689 case OPC_PRECEQU_PH_QBL:
14690 case OPC_PRECEQU_PH_QBR:
14691 case OPC_PRECEQU_PH_QBLA:
14692 case OPC_PRECEQU_PH_QBRA:
14693 case OPC_PRECEU_PH_QBL:
14694 case OPC_PRECEU_PH_QBR:
14695 case OPC_PRECEU_PH_QBLA:
14696 case OPC_PRECEU_PH_QBRA:
14697 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14698 break;
14699 case OPC_BITREV:
14700 case OPC_REPL_QB:
14701 case OPC_REPLV_QB:
14702 case OPC_REPL_PH:
14703 case OPC_REPLV_PH:
14704 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14705 break;
14706 default:
14707 MIPS_INVAL("MASK ABSQ_S.PH");
14708 gen_reserved_instruction(ctx);
14709 break;
14710 }
14711 break;
14712 case OPC_ADDU_QB_DSP:
14713 op2 = MASK_ADDU_QB(ctx->opcode);
14714 switch (op2) {
14715 case OPC_ADDQ_PH:
14716 case OPC_ADDQ_S_PH:
14717 case OPC_ADDQ_S_W:
14718 case OPC_ADDU_QB:
14719 case OPC_ADDU_S_QB:
14720 case OPC_ADDU_PH:
14721 case OPC_ADDU_S_PH:
14722 case OPC_SUBQ_PH:
14723 case OPC_SUBQ_S_PH:
14724 case OPC_SUBQ_S_W:
14725 case OPC_SUBU_QB:
14726 case OPC_SUBU_S_QB:
14727 case OPC_SUBU_PH:
14728 case OPC_SUBU_S_PH:
14729 case OPC_ADDSC:
14730 case OPC_ADDWC:
14731 case OPC_MODSUB:
14732 case OPC_RADDU_W_QB:
14733 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14734 break;
14735 case OPC_MULEU_S_PH_QBL:
14736 case OPC_MULEU_S_PH_QBR:
14737 case OPC_MULQ_RS_PH:
14738 case OPC_MULEQ_S_W_PHL:
14739 case OPC_MULEQ_S_W_PHR:
14740 case OPC_MULQ_S_PH:
14741 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14742 break;
14743 default:
14744 MIPS_INVAL("MASK ADDU.QB");
14745 gen_reserved_instruction(ctx);
14746 break;
14747
14748 }
14749 break;
14750 case OPC_CMPU_EQ_QB_DSP:
14751 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14752 switch (op2) {
14753 case OPC_PRECR_SRA_PH_W:
14754 case OPC_PRECR_SRA_R_PH_W:
14755 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14756 break;
14757 case OPC_PRECR_QB_PH:
14758 case OPC_PRECRQ_QB_PH:
14759 case OPC_PRECRQ_PH_W:
14760 case OPC_PRECRQ_RS_PH_W:
14761 case OPC_PRECRQU_S_QB_PH:
14762 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14763 break;
14764 case OPC_CMPU_EQ_QB:
14765 case OPC_CMPU_LT_QB:
14766 case OPC_CMPU_LE_QB:
14767 case OPC_CMP_EQ_PH:
14768 case OPC_CMP_LT_PH:
14769 case OPC_CMP_LE_PH:
14770 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14771 break;
14772 case OPC_CMPGU_EQ_QB:
14773 case OPC_CMPGU_LT_QB:
14774 case OPC_CMPGU_LE_QB:
14775 case OPC_CMPGDU_EQ_QB:
14776 case OPC_CMPGDU_LT_QB:
14777 case OPC_CMPGDU_LE_QB:
14778 case OPC_PICK_QB:
14779 case OPC_PICK_PH:
14780 case OPC_PACKRL_PH:
14781 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14782 break;
14783 default:
14784 MIPS_INVAL("MASK CMPU.EQ.QB");
14785 gen_reserved_instruction(ctx);
14786 break;
14787 }
14788 break;
14789 case OPC_SHLL_QB_DSP:
14790 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14791 break;
14792 case OPC_DPA_W_PH_DSP:
14793 op2 = MASK_DPA_W_PH(ctx->opcode);
14794 switch (op2) {
14795 case OPC_DPAU_H_QBL:
14796 case OPC_DPAU_H_QBR:
14797 case OPC_DPSU_H_QBL:
14798 case OPC_DPSU_H_QBR:
14799 case OPC_DPA_W_PH:
14800 case OPC_DPAX_W_PH:
14801 case OPC_DPAQ_S_W_PH:
14802 case OPC_DPAQX_S_W_PH:
14803 case OPC_DPAQX_SA_W_PH:
14804 case OPC_DPS_W_PH:
14805 case OPC_DPSX_W_PH:
14806 case OPC_DPSQ_S_W_PH:
14807 case OPC_DPSQX_S_W_PH:
14808 case OPC_DPSQX_SA_W_PH:
14809 case OPC_MULSAQ_S_W_PH:
14810 case OPC_DPAQ_SA_L_W:
14811 case OPC_DPSQ_SA_L_W:
14812 case OPC_MAQ_S_W_PHL:
14813 case OPC_MAQ_S_W_PHR:
14814 case OPC_MAQ_SA_W_PHL:
14815 case OPC_MAQ_SA_W_PHR:
14816 case OPC_MULSA_W_PH:
14817 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14818 break;
14819 default:
14820 MIPS_INVAL("MASK DPAW.PH");
14821 gen_reserved_instruction(ctx);
14822 break;
14823 }
14824 break;
14825 case OPC_INSV_DSP:
14826 op2 = MASK_INSV(ctx->opcode);
14827 switch (op2) {
14828 case OPC_INSV:
14829 check_dsp(ctx);
14830 {
14831 TCGv t0, t1;
14832
14833 if (rt == 0) {
14834 break;
14835 }
14836
14837 t0 = tcg_temp_new();
14838 t1 = tcg_temp_new();
14839
14840 gen_load_gpr(t0, rt);
14841 gen_load_gpr(t1, rs);
14842
14843 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14844
14845 tcg_temp_free(t0);
14846 tcg_temp_free(t1);
14847 break;
14848 }
14849 default:
14850 MIPS_INVAL("MASK INSV");
14851 gen_reserved_instruction(ctx);
14852 break;
14853 }
14854 break;
14855 case OPC_APPEND_DSP:
14856 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14857 break;
14858 case OPC_EXTR_W_DSP:
14859 op2 = MASK_EXTR_W(ctx->opcode);
14860 switch (op2) {
14861 case OPC_EXTR_W:
14862 case OPC_EXTR_R_W:
14863 case OPC_EXTR_RS_W:
14864 case OPC_EXTR_S_H:
14865 case OPC_EXTRV_S_H:
14866 case OPC_EXTRV_W:
14867 case OPC_EXTRV_R_W:
14868 case OPC_EXTRV_RS_W:
14869 case OPC_EXTP:
14870 case OPC_EXTPV:
14871 case OPC_EXTPDP:
14872 case OPC_EXTPDPV:
14873 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14874 break;
14875 case OPC_RDDSP:
14876 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14877 break;
14878 case OPC_SHILO:
14879 case OPC_SHILOV:
14880 case OPC_MTHLIP:
14881 case OPC_WRDSP:
14882 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14883 break;
14884 default:
14885 MIPS_INVAL("MASK EXTR.W");
14886 gen_reserved_instruction(ctx);
14887 break;
14888 }
14889 break;
14890#if defined(TARGET_MIPS64)
14891 case OPC_DDIV_G_2E:
14892 case OPC_DDIVU_G_2E:
14893 case OPC_DMULT_G_2E:
14894 case OPC_DMULTU_G_2E:
14895 case OPC_DMOD_G_2E:
14896 case OPC_DMODU_G_2E:
14897 check_insn(ctx, INSN_LOONGSON2E);
14898 gen_loongson_integer(ctx, op1, rd, rs, rt);
14899 break;
14900 case OPC_ABSQ_S_QH_DSP:
14901 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14902 switch (op2) {
14903 case OPC_PRECEQ_L_PWL:
14904 case OPC_PRECEQ_L_PWR:
14905 case OPC_PRECEQ_PW_QHL:
14906 case OPC_PRECEQ_PW_QHR:
14907 case OPC_PRECEQ_PW_QHLA:
14908 case OPC_PRECEQ_PW_QHRA:
14909 case OPC_PRECEQU_QH_OBL:
14910 case OPC_PRECEQU_QH_OBR:
14911 case OPC_PRECEQU_QH_OBLA:
14912 case OPC_PRECEQU_QH_OBRA:
14913 case OPC_PRECEU_QH_OBL:
14914 case OPC_PRECEU_QH_OBR:
14915 case OPC_PRECEU_QH_OBLA:
14916 case OPC_PRECEU_QH_OBRA:
14917 case OPC_ABSQ_S_OB:
14918 case OPC_ABSQ_S_PW:
14919 case OPC_ABSQ_S_QH:
14920 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14921 break;
14922 case OPC_REPL_OB:
14923 case OPC_REPL_PW:
14924 case OPC_REPL_QH:
14925 case OPC_REPLV_OB:
14926 case OPC_REPLV_PW:
14927 case OPC_REPLV_QH:
14928 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14929 break;
14930 default:
14931 MIPS_INVAL("MASK ABSQ_S.QH");
14932 gen_reserved_instruction(ctx);
14933 break;
14934 }
14935 break;
14936 case OPC_ADDU_OB_DSP:
14937 op2 = MASK_ADDU_OB(ctx->opcode);
14938 switch (op2) {
14939 case OPC_RADDU_L_OB:
14940 case OPC_SUBQ_PW:
14941 case OPC_SUBQ_S_PW:
14942 case OPC_SUBQ_QH:
14943 case OPC_SUBQ_S_QH:
14944 case OPC_SUBU_OB:
14945 case OPC_SUBU_S_OB:
14946 case OPC_SUBU_QH:
14947 case OPC_SUBU_S_QH:
14948 case OPC_SUBUH_OB:
14949 case OPC_SUBUH_R_OB:
14950 case OPC_ADDQ_PW:
14951 case OPC_ADDQ_S_PW:
14952 case OPC_ADDQ_QH:
14953 case OPC_ADDQ_S_QH:
14954 case OPC_ADDU_OB:
14955 case OPC_ADDU_S_OB:
14956 case OPC_ADDU_QH:
14957 case OPC_ADDU_S_QH:
14958 case OPC_ADDUH_OB:
14959 case OPC_ADDUH_R_OB:
14960 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14961 break;
14962 case OPC_MULEQ_S_PW_QHL:
14963 case OPC_MULEQ_S_PW_QHR:
14964 case OPC_MULEU_S_QH_OBL:
14965 case OPC_MULEU_S_QH_OBR:
14966 case OPC_MULQ_RS_QH:
14967 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14968 break;
14969 default:
14970 MIPS_INVAL("MASK ADDU.OB");
14971 gen_reserved_instruction(ctx);
14972 break;
14973 }
14974 break;
14975 case OPC_CMPU_EQ_OB_DSP:
14976 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14977 switch (op2) {
14978 case OPC_PRECR_SRA_QH_PW:
14979 case OPC_PRECR_SRA_R_QH_PW:
14980
14981 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14982 break;
14983 case OPC_PRECR_OB_QH:
14984 case OPC_PRECRQ_OB_QH:
14985 case OPC_PRECRQ_PW_L:
14986 case OPC_PRECRQ_QH_PW:
14987 case OPC_PRECRQ_RS_QH_PW:
14988 case OPC_PRECRQU_S_OB_QH:
14989 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14990 break;
14991 case OPC_CMPU_EQ_OB:
14992 case OPC_CMPU_LT_OB:
14993 case OPC_CMPU_LE_OB:
14994 case OPC_CMP_EQ_QH:
14995 case OPC_CMP_LT_QH:
14996 case OPC_CMP_LE_QH:
14997 case OPC_CMP_EQ_PW:
14998 case OPC_CMP_LT_PW:
14999 case OPC_CMP_LE_PW:
15000 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15001 break;
15002 case OPC_CMPGDU_EQ_OB:
15003 case OPC_CMPGDU_LT_OB:
15004 case OPC_CMPGDU_LE_OB:
15005 case OPC_CMPGU_EQ_OB:
15006 case OPC_CMPGU_LT_OB:
15007 case OPC_CMPGU_LE_OB:
15008 case OPC_PACKRL_PW:
15009 case OPC_PICK_OB:
15010 case OPC_PICK_PW:
15011 case OPC_PICK_QH:
15012 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15013 break;
15014 default:
15015 MIPS_INVAL("MASK CMPU_EQ.OB");
15016 gen_reserved_instruction(ctx);
15017 break;
15018 }
15019 break;
15020 case OPC_DAPPEND_DSP:
15021 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15022 break;
15023 case OPC_DEXTR_W_DSP:
15024 op2 = MASK_DEXTR_W(ctx->opcode);
15025 switch (op2) {
15026 case OPC_DEXTP:
15027 case OPC_DEXTPDP:
15028 case OPC_DEXTPDPV:
15029 case OPC_DEXTPV:
15030 case OPC_DEXTR_L:
15031 case OPC_DEXTR_R_L:
15032 case OPC_DEXTR_RS_L:
15033 case OPC_DEXTR_W:
15034 case OPC_DEXTR_R_W:
15035 case OPC_DEXTR_RS_W:
15036 case OPC_DEXTR_S_H:
15037 case OPC_DEXTRV_L:
15038 case OPC_DEXTRV_R_L:
15039 case OPC_DEXTRV_RS_L:
15040 case OPC_DEXTRV_S_H:
15041 case OPC_DEXTRV_W:
15042 case OPC_DEXTRV_R_W:
15043 case OPC_DEXTRV_RS_W:
15044 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15045 break;
15046 case OPC_DMTHLIP:
15047 case OPC_DSHILO:
15048 case OPC_DSHILOV:
15049 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15050 break;
15051 default:
15052 MIPS_INVAL("MASK EXTR.W");
15053 gen_reserved_instruction(ctx);
15054 break;
15055 }
15056 break;
15057 case OPC_DPAQ_W_QH_DSP:
15058 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15059 switch (op2) {
15060 case OPC_DPAU_H_OBL:
15061 case OPC_DPAU_H_OBR:
15062 case OPC_DPSU_H_OBL:
15063 case OPC_DPSU_H_OBR:
15064 case OPC_DPA_W_QH:
15065 case OPC_DPAQ_S_W_QH:
15066 case OPC_DPS_W_QH:
15067 case OPC_DPSQ_S_W_QH:
15068 case OPC_MULSAQ_S_W_QH:
15069 case OPC_DPAQ_SA_L_PW:
15070 case OPC_DPSQ_SA_L_PW:
15071 case OPC_MULSAQ_S_L_PW:
15072 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15073 break;
15074 case OPC_MAQ_S_W_QHLL:
15075 case OPC_MAQ_S_W_QHLR:
15076 case OPC_MAQ_S_W_QHRL:
15077 case OPC_MAQ_S_W_QHRR:
15078 case OPC_MAQ_SA_W_QHLL:
15079 case OPC_MAQ_SA_W_QHLR:
15080 case OPC_MAQ_SA_W_QHRL:
15081 case OPC_MAQ_SA_W_QHRR:
15082 case OPC_MAQ_S_L_PWL:
15083 case OPC_MAQ_S_L_PWR:
15084 case OPC_DMADD:
15085 case OPC_DMADDU:
15086 case OPC_DMSUB:
15087 case OPC_DMSUBU:
15088 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15089 break;
15090 default:
15091 MIPS_INVAL("MASK DPAQ.W.QH");
15092 gen_reserved_instruction(ctx);
15093 break;
15094 }
15095 break;
15096 case OPC_DINSV_DSP:
15097 op2 = MASK_INSV(ctx->opcode);
15098 switch (op2) {
15099 case OPC_DINSV:
15100 {
15101 TCGv t0, t1;
15102
15103 check_dsp(ctx);
15104
15105 if (rt == 0) {
15106 break;
15107 }
15108
15109 t0 = tcg_temp_new();
15110 t1 = tcg_temp_new();
15111
15112 gen_load_gpr(t0, rt);
15113 gen_load_gpr(t1, rs);
15114
15115 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15116
15117 tcg_temp_free(t0);
15118 tcg_temp_free(t1);
15119 break;
15120 }
15121 default:
15122 MIPS_INVAL("MASK DINSV");
15123 gen_reserved_instruction(ctx);
15124 break;
15125 }
15126 break;
15127 case OPC_SHLL_OB_DSP:
15128 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15129 break;
15130#endif
15131 default:
15132 MIPS_INVAL("special3_legacy");
15133 gen_reserved_instruction(ctx);
15134 break;
15135 }
15136}
15137
15138
15139#if defined(TARGET_MIPS64)
15140
15141static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
15142{
15143 uint32_t opc = MASK_MMI(ctx->opcode);
15144 int rs = extract32(ctx->opcode, 21, 5);
15145 int rt = extract32(ctx->opcode, 16, 5);
15146 int rd = extract32(ctx->opcode, 11, 5);
15147
15148 switch (opc) {
15149 case MMI_OPC_MULT1:
15150 case MMI_OPC_MULTU1:
15151 case MMI_OPC_MADD:
15152 case MMI_OPC_MADDU:
15153 case MMI_OPC_MADD1:
15154 case MMI_OPC_MADDU1:
15155 gen_mul_txx9(ctx, opc, rd, rs, rt);
15156 break;
15157 case MMI_OPC_DIV1:
15158 case MMI_OPC_DIVU1:
15159 gen_div1_tx79(ctx, opc, rs, rt);
15160 break;
15161 default:
15162 MIPS_INVAL("TX79 MMI class");
15163 gen_reserved_instruction(ctx);
15164 break;
15165 }
15166}
15167
15168static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
15169{
15170 gen_reserved_instruction(ctx);
15171}
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
15195{
15196 int base = extract32(ctx->opcode, 21, 5);
15197 int rt = extract32(ctx->opcode, 16, 5);
15198 int offset = extract32(ctx->opcode, 0, 16);
15199
15200#ifdef CONFIG_USER_ONLY
15201 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15202 uint32_t op2 = extract32(ctx->opcode, 6, 5);
15203
15204 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15205 int rd = extract32(ctx->opcode, 11, 5);
15206
15207 gen_rdhwr(ctx, rt, rd, 0);
15208 return;
15209 }
15210#endif
15211
15212 gen_mmi_sq(ctx, base, rt, offset);
15213}
15214
15215#endif
15216
15217static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15218{
15219 int rs, rt, rd, sa;
15220 uint32_t op1, op2;
15221 int16_t imm;
15222
15223 rs = (ctx->opcode >> 21) & 0x1f;
15224 rt = (ctx->opcode >> 16) & 0x1f;
15225 rd = (ctx->opcode >> 11) & 0x1f;
15226 sa = (ctx->opcode >> 6) & 0x1f;
15227 imm = sextract32(ctx->opcode, 7, 9);
15228
15229 op1 = MASK_SPECIAL3(ctx->opcode);
15230
15231
15232
15233
15234
15235
15236 if (ctx->eva) {
15237 switch (op1) {
15238 case OPC_LWLE:
15239 case OPC_LWRE:
15240 case OPC_LBUE:
15241 case OPC_LHUE:
15242 case OPC_LBE:
15243 case OPC_LHE:
15244 case OPC_LLE:
15245 case OPC_LWE:
15246 check_cp0_enabled(ctx);
15247 gen_ld(ctx, op1, rt, rs, imm);
15248 return;
15249 case OPC_SWLE:
15250 case OPC_SWRE:
15251 case OPC_SBE:
15252 case OPC_SHE:
15253 case OPC_SWE:
15254 check_cp0_enabled(ctx);
15255 gen_st(ctx, op1, rt, rs, imm);
15256 return;
15257 case OPC_SCE:
15258 check_cp0_enabled(ctx);
15259 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
15260 return;
15261 case OPC_CACHEE:
15262 check_eva(ctx);
15263 check_cp0_enabled(ctx);
15264 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15265 gen_cache_operation(ctx, rt, rs, imm);
15266 }
15267 return;
15268 case OPC_PREFE:
15269 check_cp0_enabled(ctx);
15270
15271 return;
15272 }
15273 }
15274
15275 switch (op1) {
15276 case OPC_EXT:
15277 case OPC_INS:
15278 check_insn(ctx, ISA_MIPS_R2);
15279 gen_bitops(ctx, op1, rt, rs, sa, rd);
15280 break;
15281 case OPC_BSHFL:
15282 op2 = MASK_BSHFL(ctx->opcode);
15283 switch (op2) {
15284 case OPC_ALIGN:
15285 case OPC_ALIGN_1:
15286 case OPC_ALIGN_2:
15287 case OPC_ALIGN_3:
15288 case OPC_BITSWAP:
15289 check_insn(ctx, ISA_MIPS_R6);
15290 decode_opc_special3_r6(env, ctx);
15291 break;
15292 default:
15293 check_insn(ctx, ISA_MIPS_R2);
15294 gen_bshfl(ctx, op2, rt, rd);
15295 break;
15296 }
15297 break;
15298#if defined(TARGET_MIPS64)
15299 case OPC_DEXTM:
15300 case OPC_DEXTU:
15301 case OPC_DEXT:
15302 case OPC_DINSM:
15303 case OPC_DINSU:
15304 case OPC_DINS:
15305 check_insn(ctx, ISA_MIPS_R2);
15306 check_mips_64(ctx);
15307 gen_bitops(ctx, op1, rt, rs, sa, rd);
15308 break;
15309 case OPC_DBSHFL:
15310 op2 = MASK_DBSHFL(ctx->opcode);
15311 switch (op2) {
15312 case OPC_DALIGN:
15313 case OPC_DALIGN_1:
15314 case OPC_DALIGN_2:
15315 case OPC_DALIGN_3:
15316 case OPC_DALIGN_4:
15317 case OPC_DALIGN_5:
15318 case OPC_DALIGN_6:
15319 case OPC_DALIGN_7:
15320 case OPC_DBITSWAP:
15321 check_insn(ctx, ISA_MIPS_R6);
15322 decode_opc_special3_r6(env, ctx);
15323 break;
15324 default:
15325 check_insn(ctx, ISA_MIPS_R2);
15326 check_mips_64(ctx);
15327 op2 = MASK_DBSHFL(ctx->opcode);
15328 gen_bshfl(ctx, op2, rt, rd);
15329 break;
15330 }
15331 break;
15332#endif
15333 case OPC_RDHWR:
15334 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
15335 break;
15336 case OPC_FORK:
15337 check_mt(ctx);
15338 {
15339 TCGv t0 = tcg_temp_new();
15340 TCGv t1 = tcg_temp_new();
15341
15342 gen_load_gpr(t0, rt);
15343 gen_load_gpr(t1, rs);
15344 gen_helper_fork(t0, t1);
15345 tcg_temp_free(t0);
15346 tcg_temp_free(t1);
15347 }
15348 break;
15349 case OPC_YIELD:
15350 check_mt(ctx);
15351 {
15352 TCGv t0 = tcg_temp_new();
15353
15354 gen_load_gpr(t0, rs);
15355 gen_helper_yield(t0, cpu_env, t0);
15356 gen_store_gpr(t0, rd);
15357 tcg_temp_free(t0);
15358 }
15359 break;
15360 default:
15361 if (ctx->insn_flags & ISA_MIPS_R6) {
15362 decode_opc_special3_r6(env, ctx);
15363 } else {
15364 decode_opc_special3_legacy(env, ctx);
15365 }
15366 }
15367}
15368
15369static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
15370{
15371 int32_t offset;
15372 int rs, rt, rd, sa;
15373 uint32_t op, op1;
15374 int16_t imm;
15375
15376 op = MASK_OP_MAJOR(ctx->opcode);
15377 rs = (ctx->opcode >> 21) & 0x1f;
15378 rt = (ctx->opcode >> 16) & 0x1f;
15379 rd = (ctx->opcode >> 11) & 0x1f;
15380 sa = (ctx->opcode >> 6) & 0x1f;
15381 imm = (int16_t)ctx->opcode;
15382 switch (op) {
15383 case OPC_SPECIAL:
15384 decode_opc_special(env, ctx);
15385 break;
15386 case OPC_SPECIAL2:
15387#if defined(TARGET_MIPS64)
15388 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15389 decode_mmi(env, ctx);
15390 break;
15391 }
15392#endif
15393 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
15394 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15395 gen_arith(ctx, OPC_MUL, rd, rs, rt);
15396 } else {
15397 decode_ase_mxu(ctx, ctx->opcode);
15398 }
15399 break;
15400 }
15401 decode_opc_special2_legacy(env, ctx);
15402 break;
15403 case OPC_SPECIAL3:
15404#if defined(TARGET_MIPS64)
15405 if (ctx->insn_flags & INSN_R5900) {
15406 decode_mmi_sq(env, ctx);
15407 } else {
15408 decode_opc_special3(env, ctx);
15409 }
15410#else
15411 decode_opc_special3(env, ctx);
15412#endif
15413 break;
15414 case OPC_REGIMM:
15415 op1 = MASK_REGIMM(ctx->opcode);
15416 switch (op1) {
15417 case OPC_BLTZL:
15418 case OPC_BGEZL:
15419 case OPC_BLTZALL:
15420 case OPC_BGEZALL:
15421 check_insn(ctx, ISA_MIPS2);
15422 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15423
15424 case OPC_BLTZ:
15425 case OPC_BGEZ:
15426 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15427 break;
15428 case OPC_BLTZAL:
15429 case OPC_BGEZAL:
15430 if (ctx->insn_flags & ISA_MIPS_R6) {
15431 if (rs == 0) {
15432
15433 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15434 } else {
15435 gen_reserved_instruction(ctx);
15436 }
15437 } else {
15438 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15439 }
15440 break;
15441 case OPC_TGEI:
15442 case OPC_TGEIU:
15443 case OPC_TLTI:
15444 case OPC_TLTIU:
15445 case OPC_TEQI:
15446
15447 case OPC_TNEI:
15448 check_insn(ctx, ISA_MIPS2);
15449 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15450 gen_trap(ctx, op1, rs, -1, imm);
15451 break;
15452 case OPC_SIGRIE:
15453 check_insn(ctx, ISA_MIPS_R6);
15454 gen_reserved_instruction(ctx);
15455 break;
15456 case OPC_SYNCI:
15457 check_insn(ctx, ISA_MIPS_R2);
15458
15459
15460
15461
15462 ctx->base.is_jmp = DISAS_STOP;
15463 break;
15464 case OPC_BPOSGE32:
15465#if defined(TARGET_MIPS64)
15466 case OPC_BPOSGE64:
15467#endif
15468 check_dsp(ctx);
15469 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
15470 break;
15471#if defined(TARGET_MIPS64)
15472 case OPC_DAHI:
15473 check_insn(ctx, ISA_MIPS_R6);
15474 check_mips_64(ctx);
15475 if (rs != 0) {
15476 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15477 }
15478 break;
15479 case OPC_DATI:
15480 check_insn(ctx, ISA_MIPS_R6);
15481 check_mips_64(ctx);
15482 if (rs != 0) {
15483 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15484 }
15485 break;
15486#endif
15487 default:
15488 MIPS_INVAL("regimm");
15489 gen_reserved_instruction(ctx);
15490 break;
15491 }
15492 break;
15493 case OPC_CP0:
15494 check_cp0_enabled(ctx);
15495 op1 = MASK_CP0(ctx->opcode);
15496 switch (op1) {
15497 case OPC_MFC0:
15498 case OPC_MTC0:
15499 case OPC_MFTR:
15500 case OPC_MTTR:
15501 case OPC_MFHC0:
15502 case OPC_MTHC0:
15503#if defined(TARGET_MIPS64)
15504 case OPC_DMFC0:
15505 case OPC_DMTC0:
15506#endif
15507#ifndef CONFIG_USER_ONLY
15508 gen_cp0(env, ctx, op1, rt, rd);
15509#endif
15510 break;
15511 case OPC_C0:
15512 case OPC_C0_1:
15513 case OPC_C0_2:
15514 case OPC_C0_3:
15515 case OPC_C0_4:
15516 case OPC_C0_5:
15517 case OPC_C0_6:
15518 case OPC_C0_7:
15519 case OPC_C0_8:
15520 case OPC_C0_9:
15521 case OPC_C0_A:
15522 case OPC_C0_B:
15523 case OPC_C0_C:
15524 case OPC_C0_D:
15525 case OPC_C0_E:
15526 case OPC_C0_F:
15527#ifndef CONFIG_USER_ONLY
15528 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15529#endif
15530 break;
15531 case OPC_MFMC0:
15532#ifndef CONFIG_USER_ONLY
15533 {
15534 uint32_t op2;
15535 TCGv t0 = tcg_temp_new();
15536
15537 op2 = MASK_MFMC0(ctx->opcode);
15538 switch (op2) {
15539 case OPC_DMT:
15540 check_cp0_mt(ctx);
15541 gen_helper_dmt(t0);
15542 gen_store_gpr(t0, rt);
15543 break;
15544 case OPC_EMT:
15545 check_cp0_mt(ctx);
15546 gen_helper_emt(t0);
15547 gen_store_gpr(t0, rt);
15548 break;
15549 case OPC_DVPE:
15550 check_cp0_mt(ctx);
15551 gen_helper_dvpe(t0, cpu_env);
15552 gen_store_gpr(t0, rt);
15553 break;
15554 case OPC_EVPE:
15555 check_cp0_mt(ctx);
15556 gen_helper_evpe(t0, cpu_env);
15557 gen_store_gpr(t0, rt);
15558 break;
15559 case OPC_DVP:
15560 check_insn(ctx, ISA_MIPS_R6);
15561 if (ctx->vp) {
15562 gen_helper_dvp(t0, cpu_env);
15563 gen_store_gpr(t0, rt);
15564 }
15565 break;
15566 case OPC_EVP:
15567 check_insn(ctx, ISA_MIPS_R6);
15568 if (ctx->vp) {
15569 gen_helper_evp(t0, cpu_env);
15570 gen_store_gpr(t0, rt);
15571 }
15572 break;
15573 case OPC_DI:
15574 check_insn(ctx, ISA_MIPS_R2);
15575 save_cpu_state(ctx, 1);
15576 gen_helper_di(t0, cpu_env);
15577 gen_store_gpr(t0, rt);
15578
15579
15580
15581
15582 ctx->base.is_jmp = DISAS_STOP;
15583 break;
15584 case OPC_EI:
15585 check_insn(ctx, ISA_MIPS_R2);
15586 save_cpu_state(ctx, 1);
15587 gen_helper_ei(t0, cpu_env);
15588 gen_store_gpr(t0, rt);
15589
15590
15591
15592
15593 gen_save_pc(ctx->base.pc_next + 4);
15594 ctx->base.is_jmp = DISAS_EXIT;
15595 break;
15596 default:
15597 MIPS_INVAL("mfmc0");
15598 gen_reserved_instruction(ctx);
15599 break;
15600 }
15601 tcg_temp_free(t0);
15602 }
15603#endif
15604 break;
15605 case OPC_RDPGPR:
15606 check_insn(ctx, ISA_MIPS_R2);
15607 gen_load_srsgpr(rt, rd);
15608 break;
15609 case OPC_WRPGPR:
15610 check_insn(ctx, ISA_MIPS_R2);
15611 gen_store_srsgpr(rt, rd);
15612 break;
15613 default:
15614 MIPS_INVAL("cp0");
15615 gen_reserved_instruction(ctx);
15616 break;
15617 }
15618 break;
15619 case OPC_BOVC:
15620 if (ctx->insn_flags & ISA_MIPS_R6) {
15621
15622 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15623 } else {
15624
15625
15626 gen_arith_imm(ctx, op, rt, rs, imm);
15627 }
15628 break;
15629 case OPC_ADDIU:
15630 gen_arith_imm(ctx, op, rt, rs, imm);
15631 break;
15632 case OPC_SLTI:
15633 case OPC_SLTIU:
15634 gen_slt_imm(ctx, op, rt, rs, imm);
15635 break;
15636 case OPC_ANDI:
15637 case OPC_LUI:
15638 case OPC_ORI:
15639 case OPC_XORI:
15640 gen_logic_imm(ctx, op, rt, rs, imm);
15641 break;
15642 case OPC_J:
15643 case OPC_JAL:
15644 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15645 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15646 break;
15647
15648 case OPC_BLEZC:
15649 if (ctx->insn_flags & ISA_MIPS_R6) {
15650 if (rt == 0) {
15651 gen_reserved_instruction(ctx);
15652 break;
15653 }
15654
15655 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15656 } else {
15657
15658 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15659 }
15660 break;
15661 case OPC_BGTZC:
15662 if (ctx->insn_flags & ISA_MIPS_R6) {
15663 if (rt == 0) {
15664 gen_reserved_instruction(ctx);
15665 break;
15666 }
15667
15668 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15669 } else {
15670
15671 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15672 }
15673 break;
15674 case OPC_BLEZALC:
15675 if (rt == 0) {
15676
15677 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15678 } else {
15679 check_insn(ctx, ISA_MIPS_R6);
15680
15681 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15682 }
15683 break;
15684 case OPC_BGTZALC:
15685 if (rt == 0) {
15686
15687 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15688 } else {
15689 check_insn(ctx, ISA_MIPS_R6);
15690
15691 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15692 }
15693 break;
15694 case OPC_BEQL:
15695 case OPC_BNEL:
15696 check_insn(ctx, ISA_MIPS2);
15697 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15698
15699 case OPC_BEQ:
15700 case OPC_BNE:
15701 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15702 break;
15703 case OPC_LL:
15704 check_insn(ctx, ISA_MIPS2);
15705 if (ctx->insn_flags & INSN_R5900) {
15706 check_insn_opc_user_only(ctx, INSN_R5900);
15707 }
15708
15709 case OPC_LWL:
15710 case OPC_LWR:
15711 case OPC_LB:
15712 case OPC_LH:
15713 case OPC_LW:
15714 case OPC_LWPC:
15715 case OPC_LBU:
15716 case OPC_LHU:
15717 gen_ld(ctx, op, rt, rs, imm);
15718 break;
15719 case OPC_SWL:
15720 case OPC_SWR:
15721 case OPC_SB:
15722 case OPC_SH:
15723 case OPC_SW:
15724 gen_st(ctx, op, rt, rs, imm);
15725 break;
15726 case OPC_SC:
15727 check_insn(ctx, ISA_MIPS2);
15728 if (ctx->insn_flags & INSN_R5900) {
15729 check_insn_opc_user_only(ctx, INSN_R5900);
15730 }
15731 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15732 break;
15733 case OPC_CACHE:
15734 check_cp0_enabled(ctx);
15735 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
15736 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15737 gen_cache_operation(ctx, rt, rs, imm);
15738 }
15739
15740 break;
15741 case OPC_PREF:
15742 if (ctx->insn_flags & INSN_R5900) {
15743
15744 } else {
15745 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
15746
15747 }
15748 break;
15749
15750
15751 case OPC_LWC1:
15752 case OPC_LDC1:
15753 case OPC_SWC1:
15754 case OPC_SDC1:
15755 gen_cop1_ldst(ctx, op, rt, rs, imm);
15756 break;
15757
15758 case OPC_CP1:
15759 op1 = MASK_CP1(ctx->opcode);
15760
15761 switch (op1) {
15762 case OPC_MFHC1:
15763 case OPC_MTHC1:
15764 check_cp1_enabled(ctx);
15765 check_insn(ctx, ISA_MIPS_R2);
15766
15767 case OPC_MFC1:
15768 case OPC_CFC1:
15769 case OPC_MTC1:
15770 case OPC_CTC1:
15771 check_cp1_enabled(ctx);
15772 gen_cp1(ctx, op1, rt, rd);
15773 break;
15774#if defined(TARGET_MIPS64)
15775 case OPC_DMFC1:
15776 case OPC_DMTC1:
15777 check_cp1_enabled(ctx);
15778 check_insn(ctx, ISA_MIPS3);
15779 check_mips_64(ctx);
15780 gen_cp1(ctx, op1, rt, rd);
15781 break;
15782#endif
15783 case OPC_BC1EQZ:
15784 check_cp1_enabled(ctx);
15785 if (ctx->insn_flags & ISA_MIPS_R6) {
15786
15787 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15788 rt, imm << 2, 4);
15789 } else {
15790
15791 check_cop1x(ctx);
15792 check_insn(ctx, ASE_MIPS3D);
15793 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15794 (rt >> 2) & 0x7, imm << 2);
15795 }
15796 break;
15797 case OPC_BC1NEZ:
15798 check_cp1_enabled(ctx);
15799 check_insn(ctx, ISA_MIPS_R6);
15800 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15801 rt, imm << 2, 4);
15802 break;
15803 case OPC_BC1ANY4:
15804 check_cp1_enabled(ctx);
15805 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15806 check_cop1x(ctx);
15807 check_insn(ctx, ASE_MIPS3D);
15808
15809 case OPC_BC1:
15810 check_cp1_enabled(ctx);
15811 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15812 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15813 (rt >> 2) & 0x7, imm << 2);
15814 break;
15815 case OPC_PS_FMT:
15816 check_ps(ctx);
15817
15818 case OPC_S_FMT:
15819 case OPC_D_FMT:
15820 check_cp1_enabled(ctx);
15821 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15822 (imm >> 8) & 0x7);
15823 break;
15824 case OPC_W_FMT:
15825 case OPC_L_FMT:
15826 {
15827 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15828 check_cp1_enabled(ctx);
15829 if (ctx->insn_flags & ISA_MIPS_R6) {
15830 switch (r6_op) {
15831 case R6_OPC_CMP_AF_S:
15832 case R6_OPC_CMP_UN_S:
15833 case R6_OPC_CMP_EQ_S:
15834 case R6_OPC_CMP_UEQ_S:
15835 case R6_OPC_CMP_LT_S:
15836 case R6_OPC_CMP_ULT_S:
15837 case R6_OPC_CMP_LE_S:
15838 case R6_OPC_CMP_ULE_S:
15839 case R6_OPC_CMP_SAF_S:
15840 case R6_OPC_CMP_SUN_S:
15841 case R6_OPC_CMP_SEQ_S:
15842 case R6_OPC_CMP_SEUQ_S:
15843 case R6_OPC_CMP_SLT_S:
15844 case R6_OPC_CMP_SULT_S:
15845 case R6_OPC_CMP_SLE_S:
15846 case R6_OPC_CMP_SULE_S:
15847 case R6_OPC_CMP_OR_S:
15848 case R6_OPC_CMP_UNE_S:
15849 case R6_OPC_CMP_NE_S:
15850 case R6_OPC_CMP_SOR_S:
15851 case R6_OPC_CMP_SUNE_S:
15852 case R6_OPC_CMP_SNE_S:
15853 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15854 break;
15855 case R6_OPC_CMP_AF_D:
15856 case R6_OPC_CMP_UN_D:
15857 case R6_OPC_CMP_EQ_D:
15858 case R6_OPC_CMP_UEQ_D:
15859 case R6_OPC_CMP_LT_D:
15860 case R6_OPC_CMP_ULT_D:
15861 case R6_OPC_CMP_LE_D:
15862 case R6_OPC_CMP_ULE_D:
15863 case R6_OPC_CMP_SAF_D:
15864 case R6_OPC_CMP_SUN_D:
15865 case R6_OPC_CMP_SEQ_D:
15866 case R6_OPC_CMP_SEUQ_D:
15867 case R6_OPC_CMP_SLT_D:
15868 case R6_OPC_CMP_SULT_D:
15869 case R6_OPC_CMP_SLE_D:
15870 case R6_OPC_CMP_SULE_D:
15871 case R6_OPC_CMP_OR_D:
15872 case R6_OPC_CMP_UNE_D:
15873 case R6_OPC_CMP_NE_D:
15874 case R6_OPC_CMP_SOR_D:
15875 case R6_OPC_CMP_SUNE_D:
15876 case R6_OPC_CMP_SNE_D:
15877 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15878 break;
15879 default:
15880 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15881 rt, rd, sa, (imm >> 8) & 0x7);
15882
15883 break;
15884 }
15885 } else {
15886 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15887 (imm >> 8) & 0x7);
15888 }
15889 break;
15890 }
15891 default:
15892 MIPS_INVAL("cp1");
15893 gen_reserved_instruction(ctx);
15894 break;
15895 }
15896 break;
15897
15898
15899 case OPC_BC:
15900 case OPC_BALC:
15901 if (ctx->insn_flags & ISA_MIPS_R6) {
15902
15903 gen_compute_compact_branch(ctx, op, 0, 0,
15904 sextract32(ctx->opcode << 2, 0, 28));
15905 } else if (ctx->insn_flags & ASE_LEXT) {
15906 gen_loongson_lswc2(ctx, rt, rs, rd);
15907 } else {
15908
15909
15910 generate_exception_err(ctx, EXCP_CpU, 2);
15911 }
15912 break;
15913 case OPC_BEQZC:
15914 case OPC_BNEZC:
15915 if (ctx->insn_flags & ISA_MIPS_R6) {
15916 if (rs != 0) {
15917
15918 gen_compute_compact_branch(ctx, op, rs, 0,
15919 sextract32(ctx->opcode << 2, 0, 23));
15920 } else {
15921
15922 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15923 }
15924 } else if (ctx->insn_flags & ASE_LEXT) {
15925 gen_loongson_lsdc2(ctx, rt, rs, rd);
15926 } else {
15927
15928
15929 generate_exception_err(ctx, EXCP_CpU, 2);
15930 }
15931 break;
15932 case OPC_CP2:
15933 check_insn(ctx, ASE_LMMI);
15934
15935 gen_loongson_multimedia(ctx, sa, rd, rt);
15936 break;
15937
15938 case OPC_CP3:
15939 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15940 check_cp1_enabled(ctx);
15941 op1 = MASK_CP3(ctx->opcode);
15942 switch (op1) {
15943 case OPC_LUXC1:
15944 case OPC_SUXC1:
15945 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15946
15947 case OPC_LWXC1:
15948 case OPC_LDXC1:
15949 case OPC_SWXC1:
15950 case OPC_SDXC1:
15951 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15952 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15953 break;
15954 case OPC_PREFX:
15955 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15956
15957 break;
15958 case OPC_ALNV_PS:
15959 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15960
15961 case OPC_MADD_S:
15962 case OPC_MADD_D:
15963 case OPC_MADD_PS:
15964 case OPC_MSUB_S:
15965 case OPC_MSUB_D:
15966 case OPC_MSUB_PS:
15967 case OPC_NMADD_S:
15968 case OPC_NMADD_D:
15969 case OPC_NMADD_PS:
15970 case OPC_NMSUB_S:
15971 case OPC_NMSUB_D:
15972 case OPC_NMSUB_PS:
15973 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15974 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15975 break;
15976 default:
15977 MIPS_INVAL("cp3");
15978 gen_reserved_instruction(ctx);
15979 break;
15980 }
15981 } else {
15982 generate_exception_err(ctx, EXCP_CpU, 1);
15983 }
15984 break;
15985
15986#if defined(TARGET_MIPS64)
15987
15988 case OPC_LLD:
15989 if (ctx->insn_flags & INSN_R5900) {
15990 check_insn_opc_user_only(ctx, INSN_R5900);
15991 }
15992
15993 case OPC_LDL:
15994 case OPC_LDR:
15995 case OPC_LWU:
15996 case OPC_LD:
15997 check_insn(ctx, ISA_MIPS3);
15998 check_mips_64(ctx);
15999 gen_ld(ctx, op, rt, rs, imm);
16000 break;
16001 case OPC_SDL:
16002 case OPC_SDR:
16003 case OPC_SD:
16004 check_insn(ctx, ISA_MIPS3);
16005 check_mips_64(ctx);
16006 gen_st(ctx, op, rt, rs, imm);
16007 break;
16008 case OPC_SCD:
16009 check_insn(ctx, ISA_MIPS3);
16010 if (ctx->insn_flags & INSN_R5900) {
16011 check_insn_opc_user_only(ctx, INSN_R5900);
16012 }
16013 check_mips_64(ctx);
16014 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
16015 break;
16016 case OPC_BNVC:
16017 if (ctx->insn_flags & ISA_MIPS_R6) {
16018
16019 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
16020 } else {
16021
16022 check_insn(ctx, ISA_MIPS3);
16023 check_mips_64(ctx);
16024 gen_arith_imm(ctx, op, rt, rs, imm);
16025 }
16026 break;
16027 case OPC_DADDIU:
16028 check_insn(ctx, ISA_MIPS3);
16029 check_mips_64(ctx);
16030 gen_arith_imm(ctx, op, rt, rs, imm);
16031 break;
16032#else
16033 case OPC_BNVC:
16034 if (ctx->insn_flags & ISA_MIPS_R6) {
16035 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
16036 } else {
16037 MIPS_INVAL("major opcode");
16038 gen_reserved_instruction(ctx);
16039 }
16040 break;
16041#endif
16042 case OPC_DAUI:
16043 if (ctx->insn_flags & ISA_MIPS_R6) {
16044#if defined(TARGET_MIPS64)
16045
16046 check_mips_64(ctx);
16047 if (rs == 0) {
16048 generate_exception(ctx, EXCP_RI);
16049 } else if (rt != 0) {
16050 TCGv t0 = tcg_temp_new();
16051 gen_load_gpr(t0, rs);
16052 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
16053 tcg_temp_free(t0);
16054 }
16055#else
16056 gen_reserved_instruction(ctx);
16057 MIPS_INVAL("major opcode");
16058#endif
16059 } else {
16060
16061 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
16062 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16063 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
16064 }
16065 break;
16066 case OPC_MDMX:
16067
16068 break;
16069 case OPC_PCREL:
16070 check_insn(ctx, ISA_MIPS_R6);
16071 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
16072 break;
16073 default:
16074 MIPS_INVAL("major opcode");
16075 return false;
16076 }
16077 return true;
16078}
16079
16080static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
16081{
16082
16083 if (ctx->base.pc_next & 0x3) {
16084 env->CP0_BadVAddr = ctx->base.pc_next;
16085 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
16086 return;
16087 }
16088
16089
16090 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
16091 TCGLabel *l1 = gen_new_label();
16092
16093 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
16094 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
16095 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
16096 gen_set_label(l1);
16097 }
16098
16099
16100
16101
16102 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
16103 return;
16104 }
16105
16106
16107 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
16108 return;
16109 }
16110 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
16111 return;
16112 }
16113
16114 if (decode_opc_legacy(env, ctx)) {
16115 return;
16116 }
16117
16118 gen_reserved_instruction(ctx);
16119}
16120
16121static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
16122{
16123 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16124 CPUMIPSState *env = cs->env_ptr;
16125
16126 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
16127 ctx->saved_pc = -1;
16128 ctx->insn_flags = env->insn_flags;
16129 ctx->CP0_Config1 = env->CP0_Config1;
16130 ctx->CP0_Config2 = env->CP0_Config2;
16131 ctx->CP0_Config3 = env->CP0_Config3;
16132 ctx->CP0_Config5 = env->CP0_Config5;
16133 ctx->btarget = 0;
16134 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
16135 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
16136 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
16137 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
16138 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
16139 ctx->PAMask = env->PAMask;
16140 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
16141 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
16142 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
16143 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
16144 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
16145
16146 ctx->hflags = (uint32_t)ctx->base.tb->flags;
16147 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
16148 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
16149 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
16150 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
16151 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
16152 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
16153 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
16154 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
16155 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
16156 restore_cpu_state(env, ctx);
16157#ifdef CONFIG_USER_ONLY
16158 ctx->mem_idx = MIPS_HFLAG_UM;
16159#else
16160 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
16161#endif
16162 ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
16163 INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
16164
16165 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16166 ctx->hflags);
16167}
16168
16169static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16170{
16171}
16172
16173static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16174{
16175 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16176
16177 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16178 ctx->btarget);
16179}
16180
16181static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16182{
16183 CPUMIPSState *env = cs->env_ptr;
16184 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16185 int insn_bytes;
16186 int is_slot;
16187
16188 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
16189 if (ctx->insn_flags & ISA_NANOMIPS32) {
16190 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
16191 insn_bytes = decode_isa_nanomips(env, ctx);
16192 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
16193 ctx->opcode = translator_ldl(env, ctx->base.pc_next);
16194 insn_bytes = 4;
16195 decode_opc(env, ctx);
16196 } else if (ctx->insn_flags & ASE_MICROMIPS) {
16197 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
16198 insn_bytes = decode_isa_micromips(env, ctx);
16199 } else if (ctx->insn_flags & ASE_MIPS16) {
16200 ctx->opcode = translator_lduw(env, ctx->base.pc_next);
16201 insn_bytes = decode_ase_mips16e(env, ctx);
16202 } else {
16203 gen_reserved_instruction(ctx);
16204 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16205 return;
16206 }
16207
16208 if (ctx->hflags & MIPS_HFLAG_BMASK) {
16209 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16210 MIPS_HFLAG_FBNSLOT))) {
16211
16212
16213
16214
16215 is_slot = 1;
16216 }
16217 if ((ctx->hflags & MIPS_HFLAG_M16) &&
16218 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
16219
16220
16221
16222
16223 is_slot = 1;
16224 }
16225 }
16226 if (is_slot) {
16227 gen_branch(ctx, insn_bytes);
16228 }
16229 ctx->base.pc_next += insn_bytes;
16230
16231 if (ctx->base.is_jmp != DISAS_NEXT) {
16232 return;
16233 }
16234
16235
16236
16237
16238
16239
16240 if (ctx->base.singlestep_enabled &&
16241 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
16242 ctx->base.is_jmp = DISAS_TOO_MANY;
16243 }
16244 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
16245 ctx->base.is_jmp = DISAS_TOO_MANY;
16246 }
16247}
16248
16249static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16250{
16251 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16252
16253 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
16254 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
16255 gen_helper_raise_exception_debug(cpu_env);
16256 } else {
16257 switch (ctx->base.is_jmp) {
16258 case DISAS_STOP:
16259 gen_save_pc(ctx->base.pc_next);
16260 tcg_gen_lookup_and_goto_ptr();
16261 break;
16262 case DISAS_NEXT:
16263 case DISAS_TOO_MANY:
16264 save_cpu_state(ctx, 0);
16265 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16266 break;
16267 case DISAS_EXIT:
16268 tcg_gen_exit_tb(NULL, 0);
16269 break;
16270 case DISAS_NORETURN:
16271 break;
16272 default:
16273 g_assert_not_reached();
16274 }
16275 }
16276}
16277
16278static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
16279{
16280 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
16281 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
16282}
16283
16284static const TranslatorOps mips_tr_ops = {
16285 .init_disas_context = mips_tr_init_disas_context,
16286 .tb_start = mips_tr_tb_start,
16287 .insn_start = mips_tr_insn_start,
16288 .translate_insn = mips_tr_translate_insn,
16289 .tb_stop = mips_tr_tb_stop,
16290 .disas_log = mips_tr_disas_log,
16291};
16292
16293void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
16294{
16295 DisasContext ctx;
16296
16297 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
16298}
16299
16300void mips_tcg_init(void)
16301{
16302 int i;
16303
16304 cpu_gpr[0] = NULL;
16305 for (i = 1; i < 32; i++)
16306 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16307 offsetof(CPUMIPSState,
16308 active_tc.gpr[i]),
16309 regnames[i]);
16310#if defined(TARGET_MIPS64)
16311 cpu_gpr_hi[0] = NULL;
16312
16313 for (unsigned i = 1; i < 32; i++) {
16314 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16315
16316 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16317 offsetof(CPUMIPSState,
16318 active_tc.gpr_hi[i]),
16319 rname);
16320 }
16321#endif
16322 for (i = 0; i < 32; i++) {
16323 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
16324
16325 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16326 }
16327 msa_translate_init();
16328 cpu_PC = tcg_global_mem_new(cpu_env,
16329 offsetof(CPUMIPSState, active_tc.PC), "PC");
16330 for (i = 0; i < MIPS_DSP_ACC; i++) {
16331 cpu_HI[i] = tcg_global_mem_new(cpu_env,
16332 offsetof(CPUMIPSState, active_tc.HI[i]),
16333 regnames_HI[i]);
16334 cpu_LO[i] = tcg_global_mem_new(cpu_env,
16335 offsetof(CPUMIPSState, active_tc.LO[i]),
16336 regnames_LO[i]);
16337 }
16338 cpu_dspctrl = tcg_global_mem_new(cpu_env,
16339 offsetof(CPUMIPSState,
16340 active_tc.DSPControl),
16341 "DSPControl");
16342 bcond = tcg_global_mem_new(cpu_env,
16343 offsetof(CPUMIPSState, bcond), "bcond");
16344 btarget = tcg_global_mem_new(cpu_env,
16345 offsetof(CPUMIPSState, btarget), "btarget");
16346 hflags = tcg_global_mem_new_i32(cpu_env,
16347 offsetof(CPUMIPSState, hflags), "hflags");
16348
16349 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
16350 offsetof(CPUMIPSState, active_fpu.fcr0),
16351 "fcr0");
16352 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
16353 offsetof(CPUMIPSState, active_fpu.fcr31),
16354 "fcr31");
16355 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16356 "lladdr");
16357 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16358 "llval");
16359
16360 if (TARGET_LONG_BITS == 32) {
16361 mxu_translate_init();
16362 }
16363}
16364
16365void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16366 target_ulong *data)
16367{
16368 env->active_tc.PC = data[0];
16369 env->hflags &= ~MIPS_HFLAG_BMASK;
16370 env->hflags |= data[1];
16371 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16372 case MIPS_HFLAG_BR:
16373 break;
16374 case MIPS_HFLAG_BC:
16375 case MIPS_HFLAG_BL:
16376 case MIPS_HFLAG_B:
16377 env->btarget = data[2];
16378 break;
16379 }
16380}
16381