master
inc 4,818 lines 141 KB
Raw
1 /*
2 * MIPS emulation for QEMU - nanoMIPS translation routines
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9 *
10 * SPDX-License-Identifier: LGPL-2.1-or-later
11 */
12
13 /* MAJOR, P16, and P32 pools opcodes */
14 enum {
15 NM_P_ADDIU = 0x00,
16 NM_ADDIUPC = 0x01,
17 NM_MOVE_BALC = 0x02,
18 NM_P16_MV = 0x04,
19 NM_LW16 = 0x05,
20 NM_BC16 = 0x06,
21 NM_P16_SR = 0x07,
22
23 NM_POOL32A = 0x08,
24 NM_P_BAL = 0x0a,
25 NM_P16_SHIFT = 0x0c,
26 NM_LWSP16 = 0x0d,
27 NM_BALC16 = 0x0e,
28 NM_P16_4X4 = 0x0f,
29
30 NM_P_GP_W = 0x10,
31 NM_P_GP_BH = 0x11,
32 NM_P_J = 0x12,
33 NM_P16C = 0x14,
34 NM_LWGP16 = 0x15,
35 NM_P16_LB = 0x17,
36
37 NM_P48I = 0x18,
38 NM_P16_A1 = 0x1c,
39 NM_LW4X4 = 0x1d,
40 NM_P16_LH = 0x1f,
41
42 NM_P_U12 = 0x20,
43 NM_P_LS_U12 = 0x21,
44 NM_P_BR1 = 0x22,
45 NM_P16_A2 = 0x24,
46 NM_SW16 = 0x25,
47 NM_BEQZC16 = 0x26,
48
49 NM_POOL32F = 0x28,
50 NM_P_LS_S9 = 0x29,
51 NM_P_BR2 = 0x2a,
52
53 NM_P16_ADDU = 0x2c,
54 NM_SWSP16 = 0x2d,
55 NM_BNEZC16 = 0x2e,
56 NM_MOVEP = 0x2f,
57
58 NM_POOL32S = 0x30,
59 NM_P_BRI = 0x32,
60 NM_LI16 = 0x34,
61 NM_SWGP16 = 0x35,
62 NM_P16_BR = 0x36,
63
64 NM_P_LUI = 0x38,
65 NM_ANDI16 = 0x3c,
66 NM_SW4X4 = 0x3d,
67 NM_MOVEPREV = 0x3f,
68 };
69
70 /* POOL32A instruction pool */
71 enum {
72 NM_POOL32A0 = 0x00,
73 NM_SPECIAL2 = 0x01,
74 NM_COP2_1 = 0x02,
75 NM_UDI = 0x03,
76 NM_POOL32A5 = 0x05,
77 NM_POOL32A7 = 0x07,
78 };
79
80 /* P.GP.W instruction pool */
81 enum {
82 NM_ADDIUGP_W = 0x00,
83 NM_LWGP = 0x02,
84 NM_SWGP = 0x03,
85 };
86
87 /* P48I instruction pool */
88 enum {
89 NM_LI48 = 0x00,
90 NM_ADDIU48 = 0x01,
91 NM_ADDIUGP48 = 0x02,
92 NM_ADDIUPC48 = 0x03,
93 NM_LWPC48 = 0x0b,
94 NM_SWPC48 = 0x0f,
95 };
96
97 /* P.U12 instruction pool */
98 enum {
99 NM_ORI = 0x00,
100 NM_XORI = 0x01,
101 NM_ANDI = 0x02,
102 NM_P_SR = 0x03,
103 NM_SLTI = 0x04,
104 NM_SLTIU = 0x05,
105 NM_SEQI = 0x06,
106 NM_ADDIUNEG = 0x08,
107 NM_P_SHIFT = 0x0c,
108 NM_P_ROTX = 0x0d,
109 NM_P_INS = 0x0e,
110 NM_P_EXT = 0x0f,
111 };
112
113 /* POOL32F instruction pool */
114 enum {
115 NM_POOL32F_0 = 0x00,
116 NM_POOL32F_3 = 0x03,
117 NM_POOL32F_5 = 0x05,
118 };
119
120 /* POOL32S instruction pool */
121 enum {
122 NM_POOL32S_0 = 0x00,
123 NM_POOL32S_4 = 0x04,
124 };
125
126 /* P.LUI instruction pool */
127 enum {
128 NM_LUI = 0x00,
129 NM_ALUIPC = 0x01,
130 };
131
132 /* P.GP.BH instruction pool */
133 enum {
134 NM_LBGP = 0x00,
135 NM_SBGP = 0x01,
136 NM_LBUGP = 0x02,
137 NM_ADDIUGP_B = 0x03,
138 NM_P_GP_LH = 0x04,
139 NM_P_GP_SH = 0x05,
140 NM_P_GP_CP1 = 0x06,
141 };
142
143 /* P.LS.U12 instruction pool */
144 enum {
145 NM_LB = 0x00,
146 NM_SB = 0x01,
147 NM_LBU = 0x02,
148 NM_P_PREFU12 = 0x03,
149 NM_LH = 0x04,
150 NM_SH = 0x05,
151 NM_LHU = 0x06,
152 NM_LWU = 0x07,
153 NM_LW = 0x08,
154 NM_SW = 0x09,
155 NM_LWC1 = 0x0a,
156 NM_SWC1 = 0x0b,
157 NM_LDC1 = 0x0e,
158 NM_SDC1 = 0x0f,
159 };
160
161 /* P.LS.S9 instruction pool */
162 enum {
163 NM_P_LS_S0 = 0x00,
164 NM_P_LS_S1 = 0x01,
165 NM_P_LS_E0 = 0x02,
166 NM_P_LS_WM = 0x04,
167 NM_P_LS_UAWM = 0x05,
168 };
169
170 /* P.BAL instruction pool */
171 enum {
172 NM_BC = 0x00,
173 NM_BALC = 0x01,
174 };
175
176 /* P.J instruction pool */
177 enum {
178 NM_JALRC = 0x00,
179 NM_JALRC_HB = 0x01,
180 NM_P_BALRSC = 0x08,
181 };
182
183 /* P.BR1 instruction pool */
184 enum {
185 NM_BEQC = 0x00,
186 NM_P_BR3A = 0x01,
187 NM_BGEC = 0x02,
188 NM_BGEUC = 0x03,
189 };
190
191 /* P.BR2 instruction pool */
192 enum {
193 NM_BNEC = 0x00,
194 NM_BLTC = 0x02,
195 NM_BLTUC = 0x03,
196 };
197
198 /* P.BRI instruction pool */
199 enum {
200 NM_BEQIC = 0x00,
201 NM_BBEQZC = 0x01,
202 NM_BGEIC = 0x02,
203 NM_BGEIUC = 0x03,
204 NM_BNEIC = 0x04,
205 NM_BBNEZC = 0x05,
206 NM_BLTIC = 0x06,
207 NM_BLTIUC = 0x07,
208 };
209
210 /* P16.SHIFT instruction pool */
211 enum {
212 NM_SLL16 = 0x00,
213 NM_SRL16 = 0x01,
214 };
215
216 /* POOL16C instruction pool */
217 enum {
218 NM_POOL16C_0 = 0x00,
219 NM_LWXS16 = 0x01,
220 };
221
222 /* P16.A1 instruction pool */
223 enum {
224 NM_ADDIUR1SP = 0x01,
225 };
226
227 /* P16.A2 instruction pool */
228 enum {
229 NM_ADDIUR2 = 0x00,
230 NM_P_ADDIURS5 = 0x01,
231 };
232
233 /* P16.ADDU instruction pool */
234 enum {
235 NM_ADDU16 = 0x00,
236 NM_SUBU16 = 0x01,
237 };
238
239 /* P16.SR instruction pool */
240 enum {
241 NM_SAVE16 = 0x00,
242 NM_RESTORE_JRC16 = 0x01,
243 };
244
245 /* P16.4X4 instruction pool */
246 enum {
247 NM_ADDU4X4 = 0x00,
248 NM_MUL4X4 = 0x01,
249 };
250
251 /* P16.LB instruction pool */
252 enum {
253 NM_LB16 = 0x00,
254 NM_SB16 = 0x01,
255 NM_LBU16 = 0x02,
256 };
257
258 /* P16.LH instruction pool */
259 enum {
260 NM_LH16 = 0x00,
261 NM_SH16 = 0x01,
262 NM_LHU16 = 0x02,
263 };
264
265 /* P.RI instruction pool */
266 enum {
267 NM_SIGRIE = 0x00,
268 NM_P_SYSCALL = 0x01,
269 NM_BREAK = 0x02,
270 NM_SDBBP = 0x03,
271 };
272
273 /* POOL32A0 instruction pool */
274 enum {
275 NM_P_TRAP = 0x00,
276 NM_SEB = 0x01,
277 NM_SLLV = 0x02,
278 NM_MUL = 0x03,
279 NM_MFC0 = 0x06,
280 NM_MFHC0 = 0x07,
281 NM_SEH = 0x09,
282 NM_SRLV = 0x0a,
283 NM_MUH = 0x0b,
284 NM_MTC0 = 0x0e,
285 NM_MTHC0 = 0x0f,
286 NM_SRAV = 0x12,
287 NM_MULU = 0x13,
288 NM_ROTRV = 0x1a,
289 NM_MUHU = 0x1b,
290 NM_ADD = 0x22,
291 NM_DIV = 0x23,
292 NM_ADDU = 0x2a,
293 NM_MOD = 0x2b,
294 NM_SUB = 0x32,
295 NM_DIVU = 0x33,
296 NM_RDHWR = 0x38,
297 NM_SUBU = 0x3a,
298 NM_MODU = 0x3b,
299 NM_P_CMOVE = 0x42,
300 NM_FORK = 0x45,
301 NM_MFTR = 0x46,
302 NM_MFHTR = 0x47,
303 NM_AND = 0x4a,
304 NM_YIELD = 0x4d,
305 NM_MTTR = 0x4e,
306 NM_MTHTR = 0x4f,
307 NM_OR = 0x52,
308 NM_D_E_MT_VPE = 0x56,
309 NM_NOR = 0x5a,
310 NM_XOR = 0x62,
311 NM_SLT = 0x6a,
312 NM_P_SLTU = 0x72,
313 NM_SOV = 0x7a,
314 };
315
316 /* CRC32 instruction pool */
317 enum {
318 NM_CRC32B = 0x00,
319 NM_CRC32H = 0x01,
320 NM_CRC32W = 0x02,
321 NM_CRC32CB = 0x04,
322 NM_CRC32CH = 0x05,
323 NM_CRC32CW = 0x06,
324 };
325
326 /* POOL32A5 instruction pool */
327 enum {
328 NM_CMP_EQ_PH = 0x00,
329 NM_CMP_LT_PH = 0x08,
330 NM_CMP_LE_PH = 0x10,
331 NM_CMPGU_EQ_QB = 0x18,
332 NM_CMPGU_LT_QB = 0x20,
333 NM_CMPGU_LE_QB = 0x28,
334 NM_CMPGDU_EQ_QB = 0x30,
335 NM_CMPGDU_LT_QB = 0x38,
336 NM_CMPGDU_LE_QB = 0x40,
337 NM_CMPU_EQ_QB = 0x48,
338 NM_CMPU_LT_QB = 0x50,
339 NM_CMPU_LE_QB = 0x58,
340 NM_ADDQ_S_W = 0x60,
341 NM_SUBQ_S_W = 0x68,
342 NM_ADDSC = 0x70,
343 NM_ADDWC = 0x78,
344
345 NM_ADDQ_S_PH = 0x01,
346 NM_ADDQH_R_PH = 0x09,
347 NM_ADDQH_R_W = 0x11,
348 NM_ADDU_S_QB = 0x19,
349 NM_ADDU_S_PH = 0x21,
350 NM_ADDUH_R_QB = 0x29,
351 NM_SHRAV_R_PH = 0x31,
352 NM_SHRAV_R_QB = 0x39,
353 NM_SUBQ_S_PH = 0x41,
354 NM_SUBQH_R_PH = 0x49,
355 NM_SUBQH_R_W = 0x51,
356 NM_SUBU_S_QB = 0x59,
357 NM_SUBU_S_PH = 0x61,
358 NM_SUBUH_R_QB = 0x69,
359 NM_SHLLV_S_PH = 0x71,
360 NM_PRECR_SRA_R_PH_W = 0x79,
361
362 NM_MULEU_S_PH_QBL = 0x12,
363 NM_MULEU_S_PH_QBR = 0x1a,
364 NM_MULQ_RS_PH = 0x22,
365 NM_MULQ_S_PH = 0x2a,
366 NM_MULQ_RS_W = 0x32,
367 NM_MULQ_S_W = 0x3a,
368 NM_APPEND = 0x42,
369 NM_MODSUB = 0x52,
370 NM_SHRAV_R_W = 0x5a,
371 NM_SHRLV_PH = 0x62,
372 NM_SHRLV_QB = 0x6a,
373 NM_SHLLV_QB = 0x72,
374 NM_SHLLV_S_W = 0x7a,
375
376 NM_SHILO = 0x03,
377
378 NM_MULEQ_S_W_PHL = 0x04,
379 NM_MULEQ_S_W_PHR = 0x0c,
380
381 NM_MUL_S_PH = 0x05,
382 NM_PRECR_QB_PH = 0x0d,
383 NM_PRECRQ_QB_PH = 0x15,
384 NM_PRECRQ_PH_W = 0x1d,
385 NM_PRECRQ_RS_PH_W = 0x25,
386 NM_PRECRQU_S_QB_PH = 0x2d,
387 NM_PACKRL_PH = 0x35,
388 NM_PICK_QB = 0x3d,
389 NM_PICK_PH = 0x45,
390
391 NM_SHRA_R_W = 0x5e,
392 NM_SHRA_R_PH = 0x66,
393 NM_SHLL_S_PH = 0x76,
394 NM_SHLL_S_W = 0x7e,
395
396 NM_REPL_PH = 0x07
397 };
398
399 /* POOL32A7 instruction pool */
400 enum {
401 NM_P_LSX = 0x00,
402 NM_LSA = 0x01,
403 NM_EXTW = 0x03,
404 NM_POOL32AXF = 0x07,
405 };
406
407 /* P.SR instruction pool */
408 enum {
409 NM_PP_SR = 0x00,
410 NM_P_SR_F = 0x01,
411 };
412
413 /* P.SHIFT instruction pool */
414 enum {
415 NM_P_SLL = 0x00,
416 NM_SRL = 0x02,
417 NM_SRA = 0x04,
418 NM_ROTR = 0x06,
419 };
420
421 /* P.ROTX instruction pool */
422 enum {
423 NM_ROTX = 0x00,
424 };
425
426 /* P.INS instruction pool */
427 enum {
428 NM_INS = 0x00,
429 };
430
431 /* P.EXT instruction pool */
432 enum {
433 NM_EXT = 0x00,
434 };
435
436 /* POOL32F_0 (fmt) instruction pool */
437 enum {
438 NM_RINT_S = 0x04,
439 NM_RINT_D = 0x44,
440 NM_ADD_S = 0x06,
441 NM_SELEQZ_S = 0x07,
442 NM_SELEQZ_D = 0x47,
443 NM_CLASS_S = 0x0c,
444 NM_CLASS_D = 0x4c,
445 NM_SUB_S = 0x0e,
446 NM_SELNEZ_S = 0x0f,
447 NM_SELNEZ_D = 0x4f,
448 NM_MUL_S = 0x16,
449 NM_SEL_S = 0x17,
450 NM_SEL_D = 0x57,
451 NM_DIV_S = 0x1e,
452 NM_ADD_D = 0x26,
453 NM_SUB_D = 0x2e,
454 NM_MUL_D = 0x36,
455 NM_MADDF_S = 0x37,
456 NM_MADDF_D = 0x77,
457 NM_DIV_D = 0x3e,
458 NM_MSUBF_S = 0x3f,
459 NM_MSUBF_D = 0x7f,
460 };
461
462 /* POOL32F_3 instruction pool */
463 enum {
464 NM_MIN_FMT = 0x00,
465 NM_MAX_FMT = 0x01,
466 NM_MINA_FMT = 0x04,
467 NM_MAXA_FMT = 0x05,
468 NM_POOL32FXF = 0x07,
469 };
470
471 /* POOL32F_5 instruction pool */
472 enum {
473 NM_CMP_CONDN_S = 0x00,
474 NM_CMP_CONDN_D = 0x02,
475 };
476
477 /* P.GP.LH instruction pool */
478 enum {
479 NM_LHGP = 0x00,
480 NM_LHUGP = 0x01,
481 };
482
483 /* P.GP.SH instruction pool */
484 enum {
485 NM_SHGP = 0x00,
486 };
487
488 /* P.GP.CP1 instruction pool */
489 enum {
490 NM_LWC1GP = 0x00,
491 NM_SWC1GP = 0x01,
492 NM_LDC1GP = 0x02,
493 NM_SDC1GP = 0x03,
494 };
495
496 /* P.LS.S0 instruction pool */
497 enum {
498 NM_LBS9 = 0x00,
499 NM_LHS9 = 0x04,
500 NM_LWS9 = 0x08,
501 NM_LDS9 = 0x0c,
502
503 NM_SBS9 = 0x01,
504 NM_SHS9 = 0x05,
505 NM_SWS9 = 0x09,
506 NM_SDS9 = 0x0d,
507
508 NM_LBUS9 = 0x02,
509 NM_LHUS9 = 0x06,
510 NM_LWC1S9 = 0x0a,
511 NM_LDC1S9 = 0x0e,
512
513 NM_P_PREFS9 = 0x03,
514 NM_LWUS9 = 0x07,
515 NM_SWC1S9 = 0x0b,
516 NM_SDC1S9 = 0x0f,
517 };
518
519 /* P.LS.S1 instruction pool */
520 enum {
521 NM_ASET_ACLR = 0x02,
522 NM_UALH = 0x04,
523 NM_UASH = 0x05,
524 NM_CACHE = 0x07,
525 NM_P_LL = 0x0a,
526 NM_P_SC = 0x0b,
527 };
528
529 /* P.LS.E0 instruction pool */
530 enum {
531 NM_LBE = 0x00,
532 NM_SBE = 0x01,
533 NM_LBUE = 0x02,
534 NM_P_PREFE = 0x03,
535 NM_LHE = 0x04,
536 NM_SHE = 0x05,
537 NM_LHUE = 0x06,
538 NM_CACHEE = 0x07,
539 NM_LWE = 0x08,
540 NM_SWE = 0x09,
541 NM_P_LLE = 0x0a,
542 NM_P_SCE = 0x0b,
543 };
544
545 /* P.PREFE instruction pool */
546 enum {
547 NM_SYNCIE = 0x00,
548 NM_PREFE = 0x01,
549 };
550
551 /* P.LLE instruction pool */
552 enum {
553 NM_LLE = 0x00,
554 NM_LLWPE = 0x01,
555 };
556
557 /* P.SCE instruction pool */
558 enum {
559 NM_SCE = 0x00,
560 NM_SCWPE = 0x01,
561 };
562
563 /* P.LS.WM instruction pool */
564 enum {
565 NM_LWM = 0x00,
566 NM_SWM = 0x01,
567 };
568
569 /* P.LS.UAWM instruction pool */
570 enum {
571 NM_UALWM = 0x00,
572 NM_UASWM = 0x01,
573 };
574
575 /* P.BR3A instruction pool */
576 enum {
577 NM_BC1EQZC = 0x00,
578 NM_BC1NEZC = 0x01,
579 NM_BC2EQZC = 0x02,
580 NM_BC2NEZC = 0x03,
581 NM_BPOSGE32C = 0x04,
582 };
583
584 /* P16.RI instruction pool */
585 enum {
586 NM_P16_SYSCALL = 0x01,
587 NM_BREAK16 = 0x02,
588 NM_SDBBP16 = 0x03,
589 };
590
591 /* POOL16C_0 instruction pool */
592 enum {
593 NM_POOL16C_00 = 0x00,
594 };
595
596 /* P16.JRC instruction pool */
597 enum {
598 NM_JRC = 0x00,
599 NM_JALRC16 = 0x01,
600 };
601
602 /* P.SYSCALL instruction pool */
603 enum {
604 NM_SYSCALL = 0x00,
605 NM_HYPCALL = 0x01,
606 };
607
608 /* P.TRAP instruction pool */
609 enum {
610 NM_TEQ = 0x00,
611 NM_TNE = 0x01,
612 };
613
614 /* P.CMOVE instruction pool */
615 enum {
616 NM_MOVZ = 0x00,
617 NM_MOVN = 0x01,
618 };
619
620 /* POOL32Axf instruction pool */
621 enum {
622 NM_POOL32AXF_1 = 0x01,
623 NM_POOL32AXF_2 = 0x02,
624 NM_POOL32AXF_4 = 0x04,
625 NM_POOL32AXF_5 = 0x05,
626 NM_POOL32AXF_7 = 0x07,
627 };
628
629 /* POOL32Axf_1 instruction pool */
630 enum {
631 NM_POOL32AXF_1_0 = 0x00,
632 NM_POOL32AXF_1_1 = 0x01,
633 NM_POOL32AXF_1_3 = 0x03,
634 NM_POOL32AXF_1_4 = 0x04,
635 NM_POOL32AXF_1_5 = 0x05,
636 NM_POOL32AXF_1_7 = 0x07,
637 };
638
639 /* POOL32Axf_2 instruction pool */
640 enum {
641 NM_POOL32AXF_2_0_7 = 0x00,
642 NM_POOL32AXF_2_8_15 = 0x01,
643 NM_POOL32AXF_2_16_23 = 0x02,
644 NM_POOL32AXF_2_24_31 = 0x03,
645 };
646
647 /* POOL32Axf_7 instruction pool */
648 enum {
649 NM_SHRA_R_QB = 0x0,
650 NM_SHRL_PH = 0x1,
651 NM_REPL_QB = 0x2,
652 };
653
654 /* POOL32Axf_1_0 instruction pool */
655 enum {
656 NM_MFHI = 0x0,
657 NM_MFLO = 0x1,
658 NM_MTHI = 0x2,
659 NM_MTLO = 0x3,
660 };
661
662 /* POOL32Axf_1_1 instruction pool */
663 enum {
664 NM_MTHLIP = 0x0,
665 NM_SHILOV = 0x1,
666 };
667
668 /* POOL32Axf_1_3 instruction pool */
669 enum {
670 NM_RDDSP = 0x0,
671 NM_WRDSP = 0x1,
672 NM_EXTP = 0x2,
673 NM_EXTPDP = 0x3,
674 };
675
676 /* POOL32Axf_1_4 instruction pool */
677 enum {
678 NM_SHLL_QB = 0x0,
679 NM_SHRL_QB = 0x1,
680 };
681
682 /* POOL32Axf_1_5 instruction pool */
683 enum {
684 NM_MAQ_S_W_PHR = 0x0,
685 NM_MAQ_S_W_PHL = 0x1,
686 NM_MAQ_SA_W_PHR = 0x2,
687 NM_MAQ_SA_W_PHL = 0x3,
688 };
689
690 /* POOL32Axf_1_7 instruction pool */
691 enum {
692 NM_EXTR_W = 0x0,
693 NM_EXTR_R_W = 0x1,
694 NM_EXTR_RS_W = 0x2,
695 NM_EXTR_S_H = 0x3,
696 };
697
698 /* POOL32Axf_2_0_7 instruction pool */
699 enum {
700 NM_DPA_W_PH = 0x0,
701 NM_DPAQ_S_W_PH = 0x1,
702 NM_DPS_W_PH = 0x2,
703 NM_DPSQ_S_W_PH = 0x3,
704 NM_BALIGN = 0x4,
705 NM_MADD = 0x5,
706 NM_MULT = 0x6,
707 NM_EXTRV_W = 0x7,
708 };
709
710 /* POOL32Axf_2_8_15 instruction pool */
711 enum {
712 NM_DPAX_W_PH = 0x0,
713 NM_DPAQ_SA_L_W = 0x1,
714 NM_DPSX_W_PH = 0x2,
715 NM_DPSQ_SA_L_W = 0x3,
716 NM_MADDU = 0x5,
717 NM_MULTU = 0x6,
718 NM_EXTRV_R_W = 0x7,
719 };
720
721 /* POOL32Axf_2_16_23 instruction pool */
722 enum {
723 NM_DPAU_H_QBL = 0x0,
724 NM_DPAQX_S_W_PH = 0x1,
725 NM_DPSU_H_QBL = 0x2,
726 NM_DPSQX_S_W_PH = 0x3,
727 NM_EXTPV = 0x4,
728 NM_MSUB = 0x5,
729 NM_MULSA_W_PH = 0x6,
730 NM_EXTRV_RS_W = 0x7,
731 };
732
733 /* POOL32Axf_2_24_31 instruction pool */
734 enum {
735 NM_DPAU_H_QBR = 0x0,
736 NM_DPAQX_SA_W_PH = 0x1,
737 NM_DPSU_H_QBR = 0x2,
738 NM_DPSQX_SA_W_PH = 0x3,
739 NM_EXTPDPV = 0x4,
740 NM_MSUBU = 0x5,
741 NM_MULSAQ_S_W_PH = 0x6,
742 NM_EXTRV_S_H = 0x7,
743 };
744
745 /* POOL32Axf_{4, 5} instruction pool */
746 enum {
747 NM_CLO = 0x25,
748 NM_CLZ = 0x2d,
749
750 NM_TLBP = 0x01,
751 NM_TLBR = 0x09,
752 NM_TLBWI = 0x11,
753 NM_TLBWR = 0x19,
754 NM_TLBINV = 0x03,
755 NM_TLBINVF = 0x0b,
756 NM_DI = 0x23,
757 NM_EI = 0x2b,
758 NM_RDPGPR = 0x70,
759 NM_WRPGPR = 0x78,
760 NM_WAIT = 0x61,
761 NM_DERET = 0x71,
762 NM_ERETX = 0x79,
763
764 /* nanoMIPS DSP instructions */
765 NM_ABSQ_S_QB = 0x00,
766 NM_ABSQ_S_PH = 0x08,
767 NM_ABSQ_S_W = 0x10,
768 NM_PRECEQ_W_PHL = 0x28,
769 NM_PRECEQ_W_PHR = 0x30,
770 NM_PRECEQU_PH_QBL = 0x38,
771 NM_PRECEQU_PH_QBR = 0x48,
772 NM_PRECEU_PH_QBL = 0x58,
773 NM_PRECEU_PH_QBR = 0x68,
774 NM_PRECEQU_PH_QBLA = 0x39,
775 NM_PRECEQU_PH_QBRA = 0x49,
776 NM_PRECEU_PH_QBLA = 0x59,
777 NM_PRECEU_PH_QBRA = 0x69,
778 NM_REPLV_PH = 0x01,
779 NM_REPLV_QB = 0x09,
780 NM_BITREV = 0x18,
781 NM_INSV = 0x20,
782 NM_RADDU_W_QB = 0x78,
783
784 NM_BITSWAP = 0x05,
785 NM_WSBH = 0x3d,
786 };
787
788 /* PP.SR instruction pool */
789 enum {
790 NM_SAVE = 0x00,
791 NM_RESTORE = 0x02,
792 NM_RESTORE_JRC = 0x03,
793 };
794
795 /* P.SR.F instruction pool */
796 enum {
797 NM_SAVEF = 0x00,
798 NM_RESTOREF = 0x01,
799 };
800
801 /* P16.SYSCALL instruction pool */
802 enum {
803 NM_SYSCALL16 = 0x00,
804 NM_HYPCALL16 = 0x01,
805 };
806
807 /* POOL16C_00 instruction pool */
808 enum {
809 NM_NOT16 = 0x00,
810 NM_XOR16 = 0x01,
811 NM_AND16 = 0x02,
812 NM_OR16 = 0x03,
813 };
814
815 /* PP.LSX and PP.LSXS instruction pool */
816 enum {
817 NM_LBX = 0x00,
818 NM_LHX = 0x04,
819 NM_LWX = 0x08,
820 NM_LDX = 0x0c,
821
822 NM_SBX = 0x01,
823 NM_SHX = 0x05,
824 NM_SWX = 0x09,
825 NM_SDX = 0x0d,
826
827 NM_LBUX = 0x02,
828 NM_LHUX = 0x06,
829 NM_LWC1X = 0x0a,
830 NM_LDC1X = 0x0e,
831
832 NM_LWUX = 0x07,
833 NM_SWC1X = 0x0b,
834 NM_SDC1X = 0x0f,
835
836 NM_LHXS = 0x04,
837 NM_LWXS = 0x08,
838 NM_LDXS = 0x0c,
839
840 NM_SHXS = 0x05,
841 NM_SWXS = 0x09,
842 NM_SDXS = 0x0d,
843
844 NM_LHUXS = 0x06,
845 NM_LWC1XS = 0x0a,
846 NM_LDC1XS = 0x0e,
847
848 NM_LWUXS = 0x07,
849 NM_SWC1XS = 0x0b,
850 NM_SDC1XS = 0x0f,
851 };
852
853 /* ERETx instruction pool */
854 enum {
855 NM_ERET = 0x00,
856 NM_ERETNC = 0x01,
857 };
858
859 /* POOL32FxF_{0, 1} insturction pool */
860 enum {
861 NM_CFC1 = 0x40,
862 NM_CTC1 = 0x60,
863 NM_MFC1 = 0x80,
864 NM_MTC1 = 0xa0,
865 NM_MFHC1 = 0xc0,
866 NM_MTHC1 = 0xe0,
867
868 NM_CVT_S_PL = 0x84,
869 NM_CVT_S_PU = 0xa4,
870
871 NM_CVT_L_S = 0x004,
872 NM_CVT_L_D = 0x104,
873 NM_CVT_W_S = 0x024,
874 NM_CVT_W_D = 0x124,
875
876 NM_RSQRT_S = 0x008,
877 NM_RSQRT_D = 0x108,
878
879 NM_SQRT_S = 0x028,
880 NM_SQRT_D = 0x128,
881
882 NM_RECIP_S = 0x048,
883 NM_RECIP_D = 0x148,
884
885 NM_FLOOR_L_S = 0x00c,
886 NM_FLOOR_L_D = 0x10c,
887
888 NM_FLOOR_W_S = 0x02c,
889 NM_FLOOR_W_D = 0x12c,
890
891 NM_CEIL_L_S = 0x04c,
892 NM_CEIL_L_D = 0x14c,
893 NM_CEIL_W_S = 0x06c,
894 NM_CEIL_W_D = 0x16c,
895 NM_TRUNC_L_S = 0x08c,
896 NM_TRUNC_L_D = 0x18c,
897 NM_TRUNC_W_S = 0x0ac,
898 NM_TRUNC_W_D = 0x1ac,
899 NM_ROUND_L_S = 0x0cc,
900 NM_ROUND_L_D = 0x1cc,
901 NM_ROUND_W_S = 0x0ec,
902 NM_ROUND_W_D = 0x1ec,
903
904 NM_MOV_S = 0x01,
905 NM_MOV_D = 0x81,
906 NM_ABS_S = 0x0d,
907 NM_ABS_D = 0x8d,
908 NM_NEG_S = 0x2d,
909 NM_NEG_D = 0xad,
910 NM_CVT_D_S = 0x04d,
911 NM_CVT_D_W = 0x0cd,
912 NM_CVT_D_L = 0x14d,
913 NM_CVT_S_D = 0x06d,
914 NM_CVT_S_W = 0x0ed,
915 NM_CVT_S_L = 0x16d,
916 };
917
918 /* P.LL instruction pool */
919 enum {
920 NM_LL = 0x00,
921 NM_LLWP = 0x01,
922 };
923
924 /* P.SC instruction pool */
925 enum {
926 NM_SC = 0x00,
927 NM_SCWP = 0x01,
928 };
929
930 /* P.DVP instruction pool */
931 enum {
932 NM_DVP = 0x00,
933 NM_EVP = 0x01,
934 };
935
936
937 /*
938 *
939 * nanoMIPS decoding engine
940 *
941 */
942
943
944 /* extraction utilities */
945
946 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
947 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
948 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
949 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
950 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
951
952 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
953 static inline int decode_gpr_gpr3(int r)
954 {
955 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
956
957 return map[r & 0x7];
958 }
959
960 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
961 static inline int decode_gpr_gpr3_src_store(int r)
962 {
963 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
964
965 return map[r & 0x7];
966 }
967
968 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
969 static inline int decode_gpr_gpr4(int r)
970 {
971 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
972 16, 17, 18, 19, 20, 21, 22, 23 };
973
974 return map[r & 0xf];
975 }
976
977 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
978 static inline int decode_gpr_gpr4_zero(int r)
979 {
980 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
981 16, 17, 18, 19, 20, 21, 22, 23 };
982
983 return map[r & 0xf];
984 }
985
986 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
987 int shift)
988 {
989 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
990 }
991
992 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
993 uint32_t reg1, uint32_t reg2)
994 {
995 TCGv taddr = tcg_temp_new();
996 TCGv_i64 tval = tcg_temp_new_i64();
997 TCGv tmp1 = tcg_temp_new();
998 TCGv tmp2 = tcg_temp_new();
999
1000 gen_base_offset_addr(ctx, taddr, base, offset);
1001 tcg_gen_qemu_ld_i64(tval, taddr, ctx->mem_idx,
1002 mo_endian(ctx) | MO_UQ | MO_ALIGN);
1003 if (disas_is_bigendian(ctx)) {
1004 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
1005 } else {
1006 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
1007 }
1008 gen_store_gpr(tmp1, reg1);
1009 gen_store_gpr(tmp2, reg2);
1010 tcg_gen_st_i64(tval, tcg_env, offsetof(CPUMIPSState, llval_wp));
1011 tcg_gen_st_tl(taddr, tcg_env, offsetof(CPUMIPSState, lladdr));
1012 }
1013
1014 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
1015 uint32_t reg1, uint32_t reg2, bool eva)
1016 {
1017 TCGv taddr = tcg_temp_new();
1018 TCGv lladdr = tcg_temp_new();
1019 TCGv_i64 tval = tcg_temp_new_i64();
1020 TCGv_i64 llval = tcg_temp_new_i64();
1021 TCGv_i64 val = tcg_temp_new_i64();
1022 TCGv tmp1 = tcg_temp_new();
1023 TCGv tmp2 = tcg_temp_new();
1024 TCGLabel *lab_fail = gen_new_label();
1025 TCGLabel *lab_done = gen_new_label();
1026
1027 gen_base_offset_addr(ctx, taddr, base, offset);
1028
1029 tcg_gen_ld_tl(lladdr, tcg_env, offsetof(CPUMIPSState, lladdr));
1030 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
1031
1032 gen_load_gpr(tmp1, reg1);
1033 gen_load_gpr(tmp2, reg2);
1034
1035 if (disas_is_bigendian(ctx)) {
1036 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
1037 } else {
1038 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
1039 }
1040
1041 tcg_gen_ld_i64(llval, tcg_env, offsetof(CPUMIPSState, llval_wp));
1042 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
1043 eva ? MIPS_HFLAG_UM : ctx->mem_idx,
1044 MO_64 | MO_ALIGN);
1045 if (reg1 != 0) {
1046 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
1047 }
1048 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
1049
1050 gen_set_label(lab_fail);
1051
1052 if (reg1 != 0) {
1053 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
1054 }
1055 gen_set_label(lab_done);
1056 tcg_gen_st_tl(tcg_constant_tl(-1), tcg_env, offsetof(CPUMIPSState, lladdr));
1057 }
1058
1059 static void gen_adjust_sp(DisasContext *ctx, int u)
1060 {
1061 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
1062 }
1063
1064 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
1065 uint8_t gp, uint16_t u)
1066 {
1067 int counter = 0;
1068 TCGv va = tcg_temp_new();
1069 TCGv t0 = tcg_temp_new();
1070
1071 while (counter != count) {
1072 bool use_gp = gp && (counter == count - 1);
1073 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
1074 int this_offset = -((counter + 1) << 2);
1075 gen_base_offset_addr(ctx, va, 29, this_offset);
1076 gen_load_gpr(t0, this_rt);
1077 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
1078 mo_endian(ctx) | MO_UL | ctx->default_tcg_memop_mask);
1079 counter++;
1080 }
1081
1082 /* adjust stack pointer */
1083 gen_adjust_sp(ctx, -u);
1084 }
1085
1086 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
1087 uint8_t gp, uint16_t u)
1088 {
1089 int counter = 0;
1090 TCGv va = tcg_temp_new();
1091 TCGv t0 = tcg_temp_new();
1092
1093 while (counter != count) {
1094 bool use_gp = gp && (counter == count - 1);
1095 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
1096 int this_offset = u - ((counter + 1) << 2);
1097 gen_base_offset_addr(ctx, va, 29, this_offset);
1098 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx,
1099 mo_endian(ctx) | MO_SL | ctx->default_tcg_memop_mask);
1100 tcg_gen_ext32s_tl(t0, t0);
1101 gen_store_gpr(t0, this_rt);
1102 counter++;
1103 }
1104
1105 /* adjust stack pointer */
1106 gen_adjust_sp(ctx, u);
1107 }
1108
1109 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
1110 int insn_bytes,
1111 int rs, int rt, int32_t offset)
1112 {
1113 target_ulong btgt = -1;
1114 int bcond_compute = 0;
1115 TCGv t0 = tcg_temp_new();
1116 TCGv t1 = tcg_temp_new();
1117
1118 /* Load needed operands */
1119 switch (opc) {
1120 case OPC_BEQ:
1121 case OPC_BNE:
1122 /* Compare two registers */
1123 if (rs != rt) {
1124 gen_load_gpr(t0, rs);
1125 gen_load_gpr(t1, rt);
1126 bcond_compute = 1;
1127 }
1128 btgt = ctx->base.pc_next + insn_bytes + offset;
1129 break;
1130 case OPC_BGEZAL:
1131 /* Compare to zero */
1132 if (rs != 0) {
1133 gen_load_gpr(t0, rs);
1134 bcond_compute = 1;
1135 }
1136 btgt = ctx->base.pc_next + insn_bytes + offset;
1137 break;
1138 case OPC_BPOSGE32:
1139 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
1140 bcond_compute = 1;
1141 btgt = ctx->base.pc_next + insn_bytes + offset;
1142 break;
1143 case OPC_JR:
1144 case OPC_JALR:
1145 /* Jump to register */
1146 if (offset != 0 && offset != 16) {
1147 /*
1148 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1149 * others are reserved.
1150 */
1151 MIPS_INVAL("jump hint");
1152 gen_reserved_instruction(ctx);
1153 goto out;
1154 }
1155 gen_load_gpr(btarget, rs);
1156 break;
1157 default:
1158 MIPS_INVAL("branch/jump");
1159 gen_reserved_instruction(ctx);
1160 goto out;
1161 }
1162 if (bcond_compute == 0) {
1163 /* No condition to be computed */
1164 switch (opc) {
1165 case OPC_BEQ: /* rx == rx */
1166 /* Always take */
1167 ctx->hflags |= MIPS_HFLAG_B;
1168 break;
1169 case OPC_BGEZAL: /* 0 >= 0 */
1170 /* Always take and link */
1171 tcg_gen_movi_tl(cpu_gpr[31],
1172 ctx->base.pc_next + insn_bytes);
1173 ctx->hflags |= MIPS_HFLAG_B;
1174 break;
1175 case OPC_BNE: /* rx != rx */
1176 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
1177 /* Skip the instruction in the delay slot */
1178 ctx->base.pc_next += 4;
1179 goto out;
1180 case OPC_JR:
1181 ctx->hflags |= MIPS_HFLAG_BR;
1182 break;
1183 case OPC_JALR:
1184 if (rt > 0) {
1185 tcg_gen_movi_tl(cpu_gpr[rt],
1186 ctx->base.pc_next + insn_bytes);
1187 }
1188 ctx->hflags |= MIPS_HFLAG_BR;
1189 break;
1190 default:
1191 MIPS_INVAL("branch/jump");
1192 gen_reserved_instruction(ctx);
1193 goto out;
1194 }
1195 } else {
1196 switch (opc) {
1197 case OPC_BEQ:
1198 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1199 goto not_likely;
1200 case OPC_BNE:
1201 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1202 goto not_likely;
1203 case OPC_BGEZAL:
1204 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1205 tcg_gen_movi_tl(cpu_gpr[31],
1206 ctx->base.pc_next + insn_bytes);
1207 goto not_likely;
1208 case OPC_BPOSGE32:
1209 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
1210 not_likely:
1211 ctx->hflags |= MIPS_HFLAG_BC;
1212 break;
1213 default:
1214 MIPS_INVAL("conditional branch/jump");
1215 gen_reserved_instruction(ctx);
1216 goto out;
1217 }
1218 }
1219
1220 ctx->btarget = btgt;
1221
1222 out:
1223 if (insn_bytes == 2) {
1224 ctx->hflags |= MIPS_HFLAG_B16;
1225 }
1226 }
1227
1228 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
1229 {
1230 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
1231 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
1232
1233 switch (extract32(ctx->opcode, 2, 2)) {
1234 case NM_NOT16:
1235 gen_logic(ctx, OPC_NOR, rt, rs, 0);
1236 break;
1237 case NM_AND16:
1238 gen_logic(ctx, OPC_AND, rt, rt, rs);
1239 break;
1240 case NM_XOR16:
1241 gen_logic(ctx, OPC_XOR, rt, rt, rs);
1242 break;
1243 case NM_OR16:
1244 gen_logic(ctx, OPC_OR, rt, rt, rs);
1245 break;
1246 }
1247 }
1248
1249 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
1250 {
1251 int rt = extract32(ctx->opcode, 21, 5);
1252 int rs = extract32(ctx->opcode, 16, 5);
1253 int rd = extract32(ctx->opcode, 11, 5);
1254
1255 switch (extract32(ctx->opcode, 3, 7)) {
1256 case NM_P_TRAP:
1257 switch (extract32(ctx->opcode, 10, 1)) {
1258 case NM_TEQ:
1259 check_nms(ctx);
1260 gen_trap(ctx, OPC_TEQ, rs, rt, -1, rd);
1261 break;
1262 case NM_TNE:
1263 check_nms(ctx);
1264 gen_trap(ctx, OPC_TNE, rs, rt, -1, rd);
1265 break;
1266 }
1267 break;
1268 case NM_RDHWR:
1269 check_nms(ctx);
1270 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
1271 break;
1272 case NM_SEB:
1273 check_nms(ctx);
1274 gen_bshfl(ctx, OPC_SEB, rs, rt);
1275 break;
1276 case NM_SEH:
1277 gen_bshfl(ctx, OPC_SEH, rs, rt);
1278 break;
1279 case NM_SLLV:
1280 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
1281 break;
1282 case NM_SRLV:
1283 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
1284 break;
1285 case NM_SRAV:
1286 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
1287 break;
1288 case NM_ROTRV:
1289 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
1290 break;
1291 case NM_ADD:
1292 gen_arith(ctx, OPC_ADD, rd, rs, rt);
1293 break;
1294 case NM_ADDU:
1295 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
1296 break;
1297 case NM_SUB:
1298 check_nms(ctx);
1299 gen_arith(ctx, OPC_SUB, rd, rs, rt);
1300 break;
1301 case NM_SUBU:
1302 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
1303 break;
1304 case NM_P_CMOVE:
1305 switch (extract32(ctx->opcode, 10, 1)) {
1306 case NM_MOVZ:
1307 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
1308 break;
1309 case NM_MOVN:
1310 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
1311 break;
1312 }
1313 break;
1314 case NM_AND:
1315 gen_logic(ctx, OPC_AND, rd, rs, rt);
1316 break;
1317 case NM_OR:
1318 gen_logic(ctx, OPC_OR, rd, rs, rt);
1319 break;
1320 case NM_NOR:
1321 gen_logic(ctx, OPC_NOR, rd, rs, rt);
1322 break;
1323 case NM_XOR:
1324 gen_logic(ctx, OPC_XOR, rd, rs, rt);
1325 break;
1326 case NM_SLT:
1327 gen_slt(ctx, OPC_SLT, rd, rs, rt);
1328 break;
1329 case NM_P_SLTU:
1330 if (rd == 0) {
1331 /* P_DVP */
1332 #ifndef CONFIG_USER_ONLY
1333 TCGv t0 = tcg_temp_new();
1334 switch (extract32(ctx->opcode, 10, 1)) {
1335 case NM_DVP:
1336 if (ctx->vp) {
1337 check_cp0_enabled(ctx);
1338 gen_helper_dvp(t0, tcg_env);
1339 gen_store_gpr(t0, rt);
1340 }
1341 break;
1342 case NM_EVP:
1343 if (ctx->vp) {
1344 check_cp0_enabled(ctx);
1345 gen_helper_evp(t0, tcg_env);
1346 gen_store_gpr(t0, rt);
1347 }
1348 break;
1349 }
1350 #endif
1351 } else {
1352 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
1353 }
1354 break;
1355 case NM_SOV:
1356 {
1357 TCGv t0 = tcg_temp_new();
1358 TCGv t1 = tcg_temp_new();
1359 TCGv t2 = tcg_temp_new();
1360
1361 gen_load_gpr(t1, rs);
1362 gen_load_gpr(t2, rt);
1363 tcg_gen_add_tl(t0, t1, t2);
1364 tcg_gen_ext32s_tl(t0, t0);
1365 tcg_gen_xor_tl(t1, t1, t2);
1366 tcg_gen_xor_tl(t2, t0, t2);
1367 tcg_gen_andc_tl(t1, t2, t1);
1368
1369 /* operands of same sign, result different sign */
1370 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
1371 gen_store_gpr(t0, rd);
1372 }
1373 break;
1374 case NM_MUL:
1375 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
1376 break;
1377 case NM_MUH:
1378 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
1379 break;
1380 case NM_MULU:
1381 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
1382 break;
1383 case NM_MUHU:
1384 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
1385 break;
1386 case NM_DIV:
1387 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
1388 break;
1389 case NM_MOD:
1390 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
1391 break;
1392 case NM_DIVU:
1393 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
1394 break;
1395 case NM_MODU:
1396 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
1397 break;
1398 #ifndef CONFIG_USER_ONLY
1399 case NM_MFC0:
1400 check_cp0_enabled(ctx);
1401 if (rt == 0) {
1402 /* Treat as NOP. */
1403 break;
1404 }
1405 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
1406 break;
1407 case NM_MTC0:
1408 check_cp0_enabled(ctx);
1409 {
1410 TCGv t0 = tcg_temp_new();
1411
1412 gen_load_gpr(t0, rt);
1413 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
1414 }
1415 break;
1416 case NM_D_E_MT_VPE:
1417 {
1418 uint8_t sc = extract32(ctx->opcode, 10, 1);
1419 TCGv t0 = tcg_temp_new();
1420
1421 switch (sc) {
1422 case 0:
1423 if (rs == 1) {
1424 /* DMT */
1425 check_cp0_mt(ctx);
1426 gen_helper_dmt(t0);
1427 gen_store_gpr(t0, rt);
1428 } else if (rs == 0) {
1429 /* DVPE */
1430 check_cp0_mt(ctx);
1431 gen_helper_dvpe(t0, tcg_env);
1432 gen_store_gpr(t0, rt);
1433 } else {
1434 gen_reserved_instruction(ctx);
1435 }
1436 break;
1437 case 1:
1438 if (rs == 1) {
1439 /* EMT */
1440 check_cp0_mt(ctx);
1441 gen_helper_emt(t0);
1442 gen_store_gpr(t0, rt);
1443 } else if (rs == 0) {
1444 /* EVPE */
1445 check_cp0_mt(ctx);
1446 gen_helper_evpe(t0, tcg_env);
1447 gen_store_gpr(t0, rt);
1448 } else {
1449 gen_reserved_instruction(ctx);
1450 }
1451 break;
1452 }
1453 }
1454 break;
1455 case NM_FORK:
1456 check_mt(ctx);
1457 {
1458 TCGv t0 = tcg_temp_new();
1459 TCGv t1 = tcg_temp_new();
1460
1461 gen_load_gpr(t0, rt);
1462 gen_load_gpr(t1, rs);
1463 gen_helper_fork(t0, t1);
1464 }
1465 break;
1466 case NM_MFTR:
1467 case NM_MFHTR:
1468 check_cp0_enabled(ctx);
1469 if (rd == 0) {
1470 /* Treat as NOP. */
1471 return;
1472 }
1473 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
1474 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
1475 break;
1476 case NM_MTTR:
1477 case NM_MTHTR:
1478 check_cp0_enabled(ctx);
1479 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
1480 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
1481 break;
1482 case NM_YIELD:
1483 check_mt(ctx);
1484 {
1485 TCGv t0 = tcg_temp_new();
1486
1487 gen_load_gpr(t0, rs);
1488 gen_helper_yield(t0, tcg_env, t0);
1489 gen_store_gpr(t0, rt);
1490 }
1491 break;
1492 #endif
1493 default:
1494 gen_reserved_instruction(ctx);
1495 break;
1496 }
1497 }
1498
1499 /* dsp */
1500 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
1501 int ret, int v1, int v2)
1502 {
1503 TCGv_i32 t0;
1504 TCGv v0_t;
1505 TCGv v1_t;
1506
1507 t0 = tcg_temp_new_i32();
1508
1509 v0_t = tcg_temp_new();
1510 v1_t = tcg_temp_new();
1511
1512 tcg_gen_movi_i32(t0, v2 >> 3);
1513
1514 gen_load_gpr(v0_t, ret);
1515 gen_load_gpr(v1_t, v1);
1516
1517 switch (opc) {
1518 case NM_MAQ_S_W_PHR:
1519 check_dsp(ctx);
1520 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, tcg_env);
1521 break;
1522 case NM_MAQ_S_W_PHL:
1523 check_dsp(ctx);
1524 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, tcg_env);
1525 break;
1526 case NM_MAQ_SA_W_PHR:
1527 check_dsp(ctx);
1528 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, tcg_env);
1529 break;
1530 case NM_MAQ_SA_W_PHL:
1531 check_dsp(ctx);
1532 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, tcg_env);
1533 break;
1534 default:
1535 gen_reserved_instruction(ctx);
1536 break;
1537 }
1538 }
1539
1540
1541 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
1542 int ret, int v1, int v2)
1543 {
1544 int16_t imm;
1545 TCGv t0 = tcg_temp_new();
1546 TCGv v0_t = tcg_temp_new();
1547
1548 gen_load_gpr(v0_t, v1);
1549
1550 switch (opc) {
1551 case NM_POOL32AXF_1_0:
1552 check_dsp(ctx);
1553 switch (extract32(ctx->opcode, 12, 2)) {
1554 case NM_MFHI:
1555 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
1556 break;
1557 case NM_MFLO:
1558 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
1559 break;
1560 case NM_MTHI:
1561 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
1562 break;
1563 case NM_MTLO:
1564 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
1565 break;
1566 }
1567 break;
1568 case NM_POOL32AXF_1_1:
1569 check_dsp(ctx);
1570 switch (extract32(ctx->opcode, 12, 2)) {
1571 case NM_MTHLIP:
1572 gen_helper_mthlip(tcg_constant_tl(v2 >> 3), v0_t, tcg_env);
1573 break;
1574 case NM_SHILOV:
1575 gen_helper_shilo(tcg_constant_tl(v2 >> 3), v0_t, tcg_env);
1576 break;
1577 default:
1578 gen_reserved_instruction(ctx);
1579 break;
1580 }
1581 break;
1582 case NM_POOL32AXF_1_3:
1583 check_dsp(ctx);
1584 imm = extract32(ctx->opcode, 14, 7);
1585 switch (extract32(ctx->opcode, 12, 2)) {
1586 case NM_RDDSP:
1587 gen_helper_rddsp(t0, tcg_constant_tl(imm), tcg_env);
1588 gen_store_gpr(t0, ret);
1589 break;
1590 case NM_WRDSP:
1591 gen_load_gpr(t0, ret);
1592 gen_helper_wrdsp(t0, tcg_constant_tl(imm), tcg_env);
1593 break;
1594 case NM_EXTP:
1595 gen_helper_extp(t0, tcg_constant_tl(v2 >> 3),
1596 tcg_constant_tl(v1), tcg_env);
1597 gen_store_gpr(t0, ret);
1598 break;
1599 case NM_EXTPDP:
1600 gen_helper_extpdp(t0, tcg_constant_tl(v2 >> 3),
1601 tcg_constant_tl(v1), tcg_env);
1602 gen_store_gpr(t0, ret);
1603 break;
1604 }
1605 break;
1606 case NM_POOL32AXF_1_4:
1607 check_dsp(ctx);
1608 switch (extract32(ctx->opcode, 12, 1)) {
1609 case NM_SHLL_QB:
1610 gen_helper_shll_qb(t0, tcg_constant_tl(v2 >> 2), v0_t, tcg_env);
1611 gen_store_gpr(t0, ret);
1612 break;
1613 case NM_SHRL_QB:
1614 gen_helper_shrl_qb(t0, tcg_constant_tl(v2 >> 2), v0_t);
1615 gen_store_gpr(t0, ret);
1616 break;
1617 }
1618 break;
1619 case NM_POOL32AXF_1_5:
1620 opc = extract32(ctx->opcode, 12, 2);
1621 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
1622 break;
1623 case NM_POOL32AXF_1_7:
1624 check_dsp(ctx);
1625 switch (extract32(ctx->opcode, 12, 2)) {
1626 case NM_EXTR_W:
1627 gen_helper_extr_w(t0, tcg_constant_tl(v2 >> 3),
1628 tcg_constant_tl(v1), tcg_env);
1629 gen_store_gpr(t0, ret);
1630 break;
1631 case NM_EXTR_R_W:
1632 gen_helper_extr_r_w(t0, tcg_constant_tl(v2 >> 3),
1633 tcg_constant_tl(v1), tcg_env);
1634 gen_store_gpr(t0, ret);
1635 break;
1636 case NM_EXTR_RS_W:
1637 gen_helper_extr_rs_w(t0, tcg_constant_tl(v2 >> 3),
1638 tcg_constant_tl(v1), tcg_env);
1639 gen_store_gpr(t0, ret);
1640 break;
1641 case NM_EXTR_S_H:
1642 gen_helper_extr_s_h(t0, tcg_constant_tl(v2 >> 3),
1643 tcg_constant_tl(v1), tcg_env);
1644 gen_store_gpr(t0, ret);
1645 break;
1646 }
1647 break;
1648 default:
1649 gen_reserved_instruction(ctx);
1650 break;
1651 }
1652 }
1653
1654 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
1655 TCGv v0, TCGv v1, int rd)
1656 {
1657 TCGv_i32 t0;
1658
1659 t0 = tcg_temp_new_i32();
1660
1661 tcg_gen_movi_i32(t0, rd >> 3);
1662
1663 switch (opc) {
1664 case NM_POOL32AXF_2_0_7:
1665 switch (extract32(ctx->opcode, 9, 3)) {
1666 case NM_DPA_W_PH:
1667 check_dsp_r2(ctx);
1668 gen_helper_dpa_w_ph(t0, v1, v0, tcg_env);
1669 break;
1670 case NM_DPAQ_S_W_PH:
1671 check_dsp(ctx);
1672 gen_helper_dpaq_s_w_ph(t0, v1, v0, tcg_env);
1673 break;
1674 case NM_DPS_W_PH:
1675 check_dsp_r2(ctx);
1676 gen_helper_dps_w_ph(t0, v1, v0, tcg_env);
1677 break;
1678 case NM_DPSQ_S_W_PH:
1679 check_dsp(ctx);
1680 gen_helper_dpsq_s_w_ph(t0, v1, v0, tcg_env);
1681 break;
1682 default:
1683 gen_reserved_instruction(ctx);
1684 break;
1685 }
1686 break;
1687 case NM_POOL32AXF_2_8_15:
1688 switch (extract32(ctx->opcode, 9, 3)) {
1689 case NM_DPAX_W_PH:
1690 check_dsp_r2(ctx);
1691 gen_helper_dpax_w_ph(t0, v0, v1, tcg_env);
1692 break;
1693 case NM_DPAQ_SA_L_W:
1694 check_dsp(ctx);
1695 gen_helper_dpaq_sa_l_w(t0, v0, v1, tcg_env);
1696 break;
1697 case NM_DPSX_W_PH:
1698 check_dsp_r2(ctx);
1699 gen_helper_dpsx_w_ph(t0, v0, v1, tcg_env);
1700 break;
1701 case NM_DPSQ_SA_L_W:
1702 check_dsp(ctx);
1703 gen_helper_dpsq_sa_l_w(t0, v0, v1, tcg_env);
1704 break;
1705 default:
1706 gen_reserved_instruction(ctx);
1707 break;
1708 }
1709 break;
1710 case NM_POOL32AXF_2_16_23:
1711 switch (extract32(ctx->opcode, 9, 3)) {
1712 case NM_DPAU_H_QBL:
1713 check_dsp(ctx);
1714 gen_helper_dpau_h_qbl(t0, v0, v1, tcg_env);
1715 break;
1716 case NM_DPAQX_S_W_PH:
1717 check_dsp_r2(ctx);
1718 gen_helper_dpaqx_s_w_ph(t0, v0, v1, tcg_env);
1719 break;
1720 case NM_DPSU_H_QBL:
1721 check_dsp(ctx);
1722 gen_helper_dpsu_h_qbl(t0, v0, v1, tcg_env);
1723 break;
1724 case NM_DPSQX_S_W_PH:
1725 check_dsp_r2(ctx);
1726 gen_helper_dpsqx_s_w_ph(t0, v0, v1, tcg_env);
1727 break;
1728 case NM_MULSA_W_PH:
1729 check_dsp_r2(ctx);
1730 gen_helper_mulsa_w_ph(t0, v0, v1, tcg_env);
1731 break;
1732 default:
1733 gen_reserved_instruction(ctx);
1734 break;
1735 }
1736 break;
1737 case NM_POOL32AXF_2_24_31:
1738 switch (extract32(ctx->opcode, 9, 3)) {
1739 case NM_DPAU_H_QBR:
1740 check_dsp(ctx);
1741 gen_helper_dpau_h_qbr(t0, v1, v0, tcg_env);
1742 break;
1743 case NM_DPAQX_SA_W_PH:
1744 check_dsp_r2(ctx);
1745 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, tcg_env);
1746 break;
1747 case NM_DPSU_H_QBR:
1748 check_dsp(ctx);
1749 gen_helper_dpsu_h_qbr(t0, v1, v0, tcg_env);
1750 break;
1751 case NM_DPSQX_SA_W_PH:
1752 check_dsp_r2(ctx);
1753 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, tcg_env);
1754 break;
1755 case NM_MULSAQ_S_W_PH:
1756 check_dsp(ctx);
1757 gen_helper_mulsaq_s_w_ph(t0, v1, v0, tcg_env);
1758 break;
1759 default:
1760 gen_reserved_instruction(ctx);
1761 break;
1762 }
1763 break;
1764 default:
1765 gen_reserved_instruction(ctx);
1766 break;
1767 }
1768 }
1769
1770 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
1771 int rt, int rs, int rd)
1772 {
1773 int ret = rt;
1774 TCGv t0 = tcg_temp_new();
1775 TCGv t1 = tcg_temp_new();
1776 TCGv v0_t = tcg_temp_new();
1777 TCGv v1_t = tcg_temp_new();
1778
1779 gen_load_gpr(v0_t, rt);
1780 gen_load_gpr(v1_t, rs);
1781
1782 switch (opc) {
1783 case NM_POOL32AXF_2_0_7:
1784 switch (extract32(ctx->opcode, 9, 3)) {
1785 case NM_DPA_W_PH:
1786 case NM_DPAQ_S_W_PH:
1787 case NM_DPS_W_PH:
1788 case NM_DPSQ_S_W_PH:
1789 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
1790 break;
1791 case NM_BALIGN:
1792 check_dsp_r2(ctx);
1793 if (rt != 0) {
1794 gen_load_gpr(t0, rs);
1795 rd &= 3;
1796 if (rd != 0 && rd != 2) {
1797 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
1798 tcg_gen_ext32u_tl(t0, t0);
1799 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
1800 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
1801 }
1802 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
1803 }
1804 break;
1805 case NM_MADD:
1806 check_dsp(ctx);
1807 {
1808 int acc = extract32(ctx->opcode, 14, 2);
1809 TCGv_i64 t2 = tcg_temp_new_i64();
1810 TCGv_i64 t3 = tcg_temp_new_i64();
1811
1812 gen_load_gpr(t0, rt);
1813 gen_load_gpr(t1, rs);
1814 tcg_gen_ext_tl_i64(t2, t0);
1815 tcg_gen_ext_tl_i64(t3, t1);
1816 tcg_gen_mul_i64(t2, t2, t3);
1817 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
1818 tcg_gen_add_i64(t2, t2, t3);
1819 gen_move_low32(cpu_LO[acc], t2);
1820 gen_move_high32(cpu_HI[acc], t2);
1821 }
1822 break;
1823 case NM_MULT:
1824 check_dsp(ctx);
1825 {
1826 int acc = extract32(ctx->opcode, 14, 2);
1827 TCGv_i32 t2 = tcg_temp_new_i32();
1828 TCGv_i32 t3 = tcg_temp_new_i32();
1829
1830 if (acc || ctx->insn_flags & ISA_MIPS_R6) {
1831 check_dsp_r2(ctx);
1832 }
1833 gen_load_gpr(t0, rs);
1834 gen_load_gpr(t1, rt);
1835 tcg_gen_trunc_tl_i32(t2, t0);
1836 tcg_gen_trunc_tl_i32(t3, t1);
1837 tcg_gen_muls2_i32(t2, t3, t2, t3);
1838 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
1839 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
1840 }
1841 break;
1842 case NM_EXTRV_W:
1843 check_dsp(ctx);
1844 gen_load_gpr(v1_t, rs);
1845 gen_helper_extr_w(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env);
1846 gen_store_gpr(t0, ret);
1847 break;
1848 }
1849 break;
1850 case NM_POOL32AXF_2_8_15:
1851 switch (extract32(ctx->opcode, 9, 3)) {
1852 case NM_DPAX_W_PH:
1853 case NM_DPAQ_SA_L_W:
1854 case NM_DPSX_W_PH:
1855 case NM_DPSQ_SA_L_W:
1856 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
1857 break;
1858 case NM_MADDU:
1859 check_dsp(ctx);
1860 {
1861 int acc = extract32(ctx->opcode, 14, 2);
1862 TCGv_i64 t2 = tcg_temp_new_i64();
1863 TCGv_i64 t3 = tcg_temp_new_i64();
1864
1865 gen_load_gpr(t0, rs);
1866 gen_load_gpr(t1, rt);
1867 tcg_gen_ext32u_tl(t0, t0);
1868 tcg_gen_ext32u_tl(t1, t1);
1869 tcg_gen_extu_tl_i64(t2, t0);
1870 tcg_gen_extu_tl_i64(t3, t1);
1871 tcg_gen_mul_i64(t2, t2, t3);
1872 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
1873 tcg_gen_add_i64(t2, t2, t3);
1874 gen_move_low32(cpu_LO[acc], t2);
1875 gen_move_high32(cpu_HI[acc], t2);
1876 }
1877 break;
1878 case NM_MULTU:
1879 check_dsp(ctx);
1880 {
1881 int acc = extract32(ctx->opcode, 14, 2);
1882 TCGv_i32 t2 = tcg_temp_new_i32();
1883 TCGv_i32 t3 = tcg_temp_new_i32();
1884
1885 if (acc || ctx->insn_flags & ISA_MIPS_R6) {
1886 check_dsp_r2(ctx);
1887 }
1888 gen_load_gpr(t0, rs);
1889 gen_load_gpr(t1, rt);
1890 tcg_gen_trunc_tl_i32(t2, t0);
1891 tcg_gen_trunc_tl_i32(t3, t1);
1892 tcg_gen_mulu2_i32(t2, t3, t2, t3);
1893 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
1894 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
1895 }
1896 break;
1897 case NM_EXTRV_R_W:
1898 check_dsp(ctx);
1899 gen_helper_extr_r_w(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env);
1900 gen_store_gpr(t0, ret);
1901 break;
1902 default:
1903 gen_reserved_instruction(ctx);
1904 break;
1905 }
1906 break;
1907 case NM_POOL32AXF_2_16_23:
1908 switch (extract32(ctx->opcode, 9, 3)) {
1909 case NM_DPAU_H_QBL:
1910 case NM_DPAQX_S_W_PH:
1911 case NM_DPSU_H_QBL:
1912 case NM_DPSQX_S_W_PH:
1913 case NM_MULSA_W_PH:
1914 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
1915 break;
1916 case NM_EXTPV:
1917 check_dsp(ctx);
1918 gen_helper_extp(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env);
1919 gen_store_gpr(t0, ret);
1920 break;
1921 case NM_MSUB:
1922 check_dsp(ctx);
1923 {
1924 int acc = extract32(ctx->opcode, 14, 2);
1925 TCGv_i64 t2 = tcg_temp_new_i64();
1926 TCGv_i64 t3 = tcg_temp_new_i64();
1927
1928 gen_load_gpr(t0, rs);
1929 gen_load_gpr(t1, rt);
1930 tcg_gen_ext_tl_i64(t2, t0);
1931 tcg_gen_ext_tl_i64(t3, t1);
1932 tcg_gen_mul_i64(t2, t2, t3);
1933 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
1934 tcg_gen_sub_i64(t2, t3, t2);
1935 gen_move_low32(cpu_LO[acc], t2);
1936 gen_move_high32(cpu_HI[acc], t2);
1937 }
1938 break;
1939 case NM_EXTRV_RS_W:
1940 check_dsp(ctx);
1941 gen_helper_extr_rs_w(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env);
1942 gen_store_gpr(t0, ret);
1943 break;
1944 }
1945 break;
1946 case NM_POOL32AXF_2_24_31:
1947 switch (extract32(ctx->opcode, 9, 3)) {
1948 case NM_DPAU_H_QBR:
1949 case NM_DPAQX_SA_W_PH:
1950 case NM_DPSU_H_QBR:
1951 case NM_DPSQX_SA_W_PH:
1952 case NM_MULSAQ_S_W_PH:
1953 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
1954 break;
1955 case NM_EXTPDPV:
1956 check_dsp(ctx);
1957 gen_helper_extpdp(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env);
1958 gen_store_gpr(t0, ret);
1959 break;
1960 case NM_MSUBU:
1961 check_dsp(ctx);
1962 {
1963 int acc = extract32(ctx->opcode, 14, 2);
1964 TCGv_i64 t2 = tcg_temp_new_i64();
1965 TCGv_i64 t3 = tcg_temp_new_i64();
1966
1967 gen_load_gpr(t0, rs);
1968 gen_load_gpr(t1, rt);
1969 tcg_gen_ext32u_tl(t0, t0);
1970 tcg_gen_ext32u_tl(t1, t1);
1971 tcg_gen_extu_tl_i64(t2, t0);
1972 tcg_gen_extu_tl_i64(t3, t1);
1973 tcg_gen_mul_i64(t2, t2, t3);
1974 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
1975 tcg_gen_sub_i64(t2, t3, t2);
1976 gen_move_low32(cpu_LO[acc], t2);
1977 gen_move_high32(cpu_HI[acc], t2);
1978 }
1979 break;
1980 case NM_EXTRV_S_H:
1981 check_dsp(ctx);
1982 gen_helper_extr_s_h(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env);
1983 gen_store_gpr(t0, ret);
1984 break;
1985 }
1986 break;
1987 default:
1988 gen_reserved_instruction(ctx);
1989 break;
1990 }
1991 }
1992
1993 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
1994 int rt, int rs)
1995 {
1996 int ret = rt;
1997 TCGv t0 = tcg_temp_new();
1998 TCGv v0_t = tcg_temp_new();
1999
2000 gen_load_gpr(v0_t, rs);
2001
2002 switch (opc) {
2003 case NM_ABSQ_S_QB:
2004 check_dsp_r2(ctx);
2005 gen_helper_absq_s_qb(v0_t, v0_t, tcg_env);
2006 gen_store_gpr(v0_t, ret);
2007 break;
2008 case NM_ABSQ_S_PH:
2009 check_dsp(ctx);
2010 gen_helper_absq_s_ph(v0_t, v0_t, tcg_env);
2011 gen_store_gpr(v0_t, ret);
2012 break;
2013 case NM_ABSQ_S_W:
2014 check_dsp(ctx);
2015 gen_helper_absq_s_w(v0_t, v0_t, tcg_env);
2016 gen_store_gpr(v0_t, ret);
2017 break;
2018 case NM_PRECEQ_W_PHL:
2019 check_dsp(ctx);
2020 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
2021 tcg_gen_ext32s_tl(v0_t, v0_t);
2022 gen_store_gpr(v0_t, ret);
2023 break;
2024 case NM_PRECEQ_W_PHR:
2025 check_dsp(ctx);
2026 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
2027 tcg_gen_shli_tl(v0_t, v0_t, 16);
2028 tcg_gen_ext32s_tl(v0_t, v0_t);
2029 gen_store_gpr(v0_t, ret);
2030 break;
2031 case NM_PRECEQU_PH_QBL:
2032 check_dsp(ctx);
2033 gen_helper_precequ_ph_qbl(v0_t, v0_t);
2034 gen_store_gpr(v0_t, ret);
2035 break;
2036 case NM_PRECEQU_PH_QBR:
2037 check_dsp(ctx);
2038 gen_helper_precequ_ph_qbr(v0_t, v0_t);
2039 gen_store_gpr(v0_t, ret);
2040 break;
2041 case NM_PRECEQU_PH_QBLA:
2042 check_dsp(ctx);
2043 gen_helper_precequ_ph_qbla(v0_t, v0_t);
2044 gen_store_gpr(v0_t, ret);
2045 break;
2046 case NM_PRECEQU_PH_QBRA:
2047 check_dsp(ctx);
2048 gen_helper_precequ_ph_qbra(v0_t, v0_t);
2049 gen_store_gpr(v0_t, ret);
2050 break;
2051 case NM_PRECEU_PH_QBL:
2052 check_dsp(ctx);
2053 gen_helper_preceu_ph_qbl(v0_t, v0_t);
2054 gen_store_gpr(v0_t, ret);
2055 break;
2056 case NM_PRECEU_PH_QBR:
2057 check_dsp(ctx);
2058 gen_helper_preceu_ph_qbr(v0_t, v0_t);
2059 gen_store_gpr(v0_t, ret);
2060 break;
2061 case NM_PRECEU_PH_QBLA:
2062 check_dsp(ctx);
2063 gen_helper_preceu_ph_qbla(v0_t, v0_t);
2064 gen_store_gpr(v0_t, ret);
2065 break;
2066 case NM_PRECEU_PH_QBRA:
2067 check_dsp(ctx);
2068 gen_helper_preceu_ph_qbra(v0_t, v0_t);
2069 gen_store_gpr(v0_t, ret);
2070 break;
2071 case NM_REPLV_PH:
2072 check_dsp(ctx);
2073 tcg_gen_ext16u_tl(v0_t, v0_t);
2074 tcg_gen_shli_tl(t0, v0_t, 16);
2075 tcg_gen_or_tl(v0_t, v0_t, t0);
2076 tcg_gen_ext32s_tl(v0_t, v0_t);
2077 gen_store_gpr(v0_t, ret);
2078 break;
2079 case NM_REPLV_QB:
2080 check_dsp(ctx);
2081 tcg_gen_ext8u_tl(v0_t, v0_t);
2082 tcg_gen_shli_tl(t0, v0_t, 8);
2083 tcg_gen_or_tl(v0_t, v0_t, t0);
2084 tcg_gen_shli_tl(t0, v0_t, 16);
2085 tcg_gen_or_tl(v0_t, v0_t, t0);
2086 tcg_gen_ext32s_tl(v0_t, v0_t);
2087 gen_store_gpr(v0_t, ret);
2088 break;
2089 case NM_BITREV:
2090 check_dsp(ctx);
2091 gen_helper_bitrev(v0_t, v0_t);
2092 gen_store_gpr(v0_t, ret);
2093 break;
2094 case NM_INSV:
2095 check_dsp(ctx);
2096 {
2097 TCGv tv0 = tcg_temp_new();
2098
2099 gen_load_gpr(tv0, rt);
2100 gen_helper_insv(v0_t, tcg_env, v0_t, tv0);
2101 gen_store_gpr(v0_t, ret);
2102 }
2103 break;
2104 case NM_RADDU_W_QB:
2105 check_dsp(ctx);
2106 gen_helper_raddu_w_qb(v0_t, v0_t);
2107 gen_store_gpr(v0_t, ret);
2108 break;
2109 case NM_BITSWAP:
2110 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
2111 break;
2112 case NM_CLO:
2113 check_nms(ctx);
2114 gen_cl(ctx, OPC_CLO, ret, rs);
2115 break;
2116 case NM_CLZ:
2117 check_nms(ctx);
2118 gen_cl(ctx, OPC_CLZ, ret, rs);
2119 break;
2120 case NM_WSBH:
2121 gen_bshfl(ctx, OPC_WSBH, ret, rs);
2122 break;
2123 default:
2124 gen_reserved_instruction(ctx);
2125 break;
2126 }
2127 }
2128
2129 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
2130 int rt, int rs, int rd)
2131 {
2132 TCGv t0 = tcg_temp_new();
2133 TCGv rs_t = tcg_temp_new();
2134
2135 gen_load_gpr(rs_t, rs);
2136
2137 switch (opc) {
2138 case NM_SHRA_R_QB:
2139 check_dsp_r2(ctx);
2140 switch (extract32(ctx->opcode, 12, 1)) {
2141 case 0:
2142 /* NM_SHRA_QB */
2143 gen_helper_shra_qb(t0, tcg_constant_tl(rd >> 2), rs_t);
2144 gen_store_gpr(t0, rt);
2145 break;
2146 case 1:
2147 /* NM_SHRA_R_QB */
2148 gen_helper_shra_r_qb(t0, tcg_constant_tl(rd >> 2), rs_t);
2149 gen_store_gpr(t0, rt);
2150 break;
2151 }
2152 break;
2153 case NM_SHRL_PH:
2154 check_dsp_r2(ctx);
2155 gen_helper_shrl_ph(t0, tcg_constant_tl(rd >> 1), rs_t);
2156 gen_store_gpr(t0, rt);
2157 break;
2158 case NM_REPL_QB:
2159 check_dsp(ctx);
2160 {
2161 int16_t imm;
2162 target_long result;
2163 imm = extract32(ctx->opcode, 13, 8);
2164 result = (uint32_t)imm << 24 |
2165 (uint32_t)imm << 16 |
2166 (uint32_t)imm << 8 |
2167 (uint32_t)imm;
2168 result = (int32_t)result;
2169 gen_store_gpr(tcg_constant_tl(result), rt);
2170 }
2171 break;
2172 default:
2173 gen_reserved_instruction(ctx);
2174 break;
2175 }
2176 }
2177
2178
2179 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
2180 {
2181 int rt = extract32(ctx->opcode, 21, 5);
2182 int rs = extract32(ctx->opcode, 16, 5);
2183 int rd = extract32(ctx->opcode, 11, 5);
2184
2185 switch (extract32(ctx->opcode, 6, 3)) {
2186 case NM_POOL32AXF_1:
2187 {
2188 int32_t op1 = extract32(ctx->opcode, 9, 3);
2189 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
2190 }
2191 break;
2192 case NM_POOL32AXF_2:
2193 {
2194 int32_t op1 = extract32(ctx->opcode, 12, 2);
2195 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
2196 }
2197 break;
2198 case NM_POOL32AXF_4:
2199 {
2200 int32_t op1 = extract32(ctx->opcode, 9, 7);
2201 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
2202 }
2203 break;
2204 case NM_POOL32AXF_5:
2205 switch (extract32(ctx->opcode, 9, 7)) {
2206 #ifndef CONFIG_USER_ONLY
2207 case NM_TLBP:
2208 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
2209 break;
2210 case NM_TLBR:
2211 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
2212 break;
2213 case NM_TLBWI:
2214 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
2215 break;
2216 case NM_TLBWR:
2217 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
2218 break;
2219 case NM_TLBINV:
2220 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
2221 break;
2222 case NM_TLBINVF:
2223 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
2224 break;
2225 case NM_DI:
2226 check_cp0_enabled(ctx);
2227 {
2228 TCGv t0 = tcg_temp_new();
2229
2230 save_cpu_state(ctx, 1);
2231 gen_helper_di(t0, tcg_env);
2232 gen_store_gpr(t0, rt);
2233 /* Stop translation as we may have switched the execution mode */
2234 ctx->base.is_jmp = DISAS_STOP;
2235 }
2236 break;
2237 case NM_EI:
2238 check_cp0_enabled(ctx);
2239 {
2240 TCGv t0 = tcg_temp_new();
2241
2242 save_cpu_state(ctx, 1);
2243 gen_helper_ei(t0, tcg_env);
2244 gen_store_gpr(t0, rt);
2245 /* Stop translation as we may have switched the execution mode */
2246 ctx->base.is_jmp = DISAS_STOP;
2247 }
2248 break;
2249 case NM_RDPGPR:
2250 check_cp0_enabled(ctx);
2251 gen_load_srsgpr(rs, rt);
2252 break;
2253 case NM_WRPGPR:
2254 check_cp0_enabled(ctx);
2255 gen_store_srsgpr(rs, rt);
2256 break;
2257 case NM_WAIT:
2258 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
2259 break;
2260 case NM_DERET:
2261 gen_cp0(env, ctx, OPC_DERET, 0, 0);
2262 break;
2263 case NM_ERETX:
2264 gen_cp0(env, ctx, OPC_ERET, 0, 0);
2265 break;
2266 #endif
2267 default:
2268 gen_reserved_instruction(ctx);
2269 break;
2270 }
2271 break;
2272 case NM_POOL32AXF_7:
2273 {
2274 int32_t op1 = extract32(ctx->opcode, 9, 3);
2275 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
2276 }
2277 break;
2278 default:
2279 gen_reserved_instruction(ctx);
2280 break;
2281 }
2282 }
2283
2284 /* Immediate Value Compact Branches */
2285 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
2286 int rt, int32_t imm, int32_t offset)
2287 {
2288 TCGCond cond = TCG_COND_ALWAYS;
2289 TCGv t0 = tcg_temp_new();
2290 TCGv timm = tcg_constant_tl(imm);
2291
2292 gen_load_gpr(t0, rt);
2293 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2294
2295 /* Load needed operands and calculate btarget */
2296 switch (opc) {
2297 case NM_BEQIC:
2298 if (rt == 0 && imm == 0) {
2299 /* Unconditional branch */
2300 } else if (rt == 0 && imm != 0) {
2301 /* Treat as NOP */
2302 return;
2303 } else {
2304 cond = TCG_COND_EQ;
2305 }
2306 break;
2307 case NM_BBEQZC:
2308 case NM_BBNEZC:
2309 check_nms(ctx);
2310 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
2311 gen_reserved_instruction(ctx);
2312 return;
2313 } else if (rt == 0 && opc == NM_BBEQZC) {
2314 /* Unconditional branch */
2315 } else if (rt == 0 && opc == NM_BBNEZC) {
2316 /* Treat as NOP */
2317 return;
2318 } else {
2319 tcg_gen_shri_tl(t0, t0, imm);
2320 tcg_gen_andi_tl(t0, t0, 1);
2321 timm = tcg_constant_tl(0);
2322 if (opc == NM_BBEQZC) {
2323 cond = TCG_COND_EQ;
2324 } else {
2325 cond = TCG_COND_NE;
2326 }
2327 }
2328 break;
2329 case NM_BNEIC:
2330 if (rt == 0 && imm == 0) {
2331 /* Treat as NOP */
2332 return;
2333 } else if (rt == 0 && imm != 0) {
2334 /* Unconditional branch */
2335 } else {
2336 cond = TCG_COND_NE;
2337 }
2338 break;
2339 case NM_BGEIC:
2340 if (rt == 0 && imm == 0) {
2341 /* Unconditional branch */
2342 } else {
2343 cond = TCG_COND_GE;
2344 }
2345 break;
2346 case NM_BLTIC:
2347 cond = TCG_COND_LT;
2348 break;
2349 case NM_BGEIUC:
2350 if (rt == 0 && imm == 0) {
2351 /* Unconditional branch */
2352 } else {
2353 cond = TCG_COND_GEU;
2354 }
2355 break;
2356 case NM_BLTIUC:
2357 cond = TCG_COND_LTU;
2358 break;
2359 default:
2360 MIPS_INVAL("Immediate Value Compact branch");
2361 gen_reserved_instruction(ctx);
2362 return;
2363 }
2364
2365 /* branch completion */
2366 clear_branch_hflags(ctx);
2367 ctx->base.is_jmp = DISAS_NORETURN;
2368
2369 if (cond == TCG_COND_ALWAYS) {
2370 /* Uncoditional compact branch */
2371 gen_goto_tb(ctx, 0, ctx->btarget);
2372 } else {
2373 /* Conditional compact branch */
2374 TCGLabel *fs = gen_new_label();
2375
2376 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, timm, fs);
2377
2378 gen_goto_tb(ctx, 1, ctx->btarget);
2379 gen_set_label(fs);
2380
2381 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
2382 }
2383 }
2384
2385 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
2386 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
2387 int rt)
2388 {
2389 TCGv t0 = tcg_temp_new();
2390
2391 /* load rs */
2392 gen_load_gpr(t0, rs);
2393
2394 /* link */
2395 if (rt != 0) {
2396 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
2397 }
2398
2399 /* calculate btarget */
2400 tcg_gen_shli_tl(t0, t0, 1);
2401 gen_op_addr_add(ctx, btarget, tcg_constant_tl(ctx->base.pc_next + 4), t0);
2402
2403 /* branch completion */
2404 clear_branch_hflags(ctx);
2405 ctx->base.is_jmp = DISAS_NORETURN;
2406
2407 /* unconditional branch to register */
2408 tcg_gen_mov_tl(cpu_PC, btarget);
2409 tcg_gen_lookup_and_goto_ptr();
2410 }
2411
2412 /* nanoMIPS Branches */
2413 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
2414 int rs, int rt, int32_t offset)
2415 {
2416 int bcond_compute = 0;
2417 TCGv t0 = tcg_temp_new();
2418 TCGv t1 = tcg_temp_new();
2419
2420 /* Load needed operands and calculate btarget */
2421 switch (opc) {
2422 /* compact branch */
2423 case OPC_BGEC:
2424 case OPC_BLTC:
2425 gen_load_gpr(t0, rs);
2426 gen_load_gpr(t1, rt);
2427 bcond_compute = 1;
2428 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2429 break;
2430 case OPC_BGEUC:
2431 case OPC_BLTUC:
2432 if (rs == 0 || rs == rt) {
2433 /* OPC_BLEZALC, OPC_BGEZALC */
2434 /* OPC_BGTZALC, OPC_BLTZALC */
2435 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
2436 }
2437 gen_load_gpr(t0, rs);
2438 gen_load_gpr(t1, rt);
2439 bcond_compute = 1;
2440 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2441 break;
2442 case OPC_BC:
2443 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2444 break;
2445 case OPC_BEQZC:
2446 if (rs != 0) {
2447 /* OPC_BEQZC, OPC_BNEZC */
2448 gen_load_gpr(t0, rs);
2449 bcond_compute = 1;
2450 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2451 } else {
2452 /* OPC_JIC, OPC_JIALC */
2453 TCGv tbase = tcg_temp_new();
2454
2455 gen_load_gpr(tbase, rt);
2456 gen_op_addr_addi(ctx, btarget, tbase, offset);
2457 }
2458 break;
2459 default:
2460 MIPS_INVAL("Compact branch/jump");
2461 gen_reserved_instruction(ctx);
2462 return;
2463 }
2464
2465 if (bcond_compute == 0) {
2466 /* Uncoditional compact branch */
2467 switch (opc) {
2468 case OPC_BC:
2469 gen_goto_tb(ctx, 0, ctx->btarget);
2470 break;
2471 default:
2472 MIPS_INVAL("Compact branch/jump");
2473 gen_reserved_instruction(ctx);
2474 return;
2475 }
2476 } else {
2477 /* Conditional compact branch */
2478 TCGLabel *fs = gen_new_label();
2479
2480 switch (opc) {
2481 case OPC_BGEUC:
2482 if (rs == 0 && rt != 0) {
2483 /* OPC_BLEZALC */
2484 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
2485 } else if (rs != 0 && rt != 0 && rs == rt) {
2486 /* OPC_BGEZALC */
2487 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
2488 } else {
2489 /* OPC_BGEUC */
2490 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
2491 }
2492 break;
2493 case OPC_BLTUC:
2494 if (rs == 0 && rt != 0) {
2495 /* OPC_BGTZALC */
2496 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
2497 } else if (rs != 0 && rt != 0 && rs == rt) {
2498 /* OPC_BLTZALC */
2499 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
2500 } else {
2501 /* OPC_BLTUC */
2502 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
2503 }
2504 break;
2505 case OPC_BGEC:
2506 if (rs == 0 && rt != 0) {
2507 /* OPC_BLEZC */
2508 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
2509 } else if (rs != 0 && rt != 0 && rs == rt) {
2510 /* OPC_BGEZC */
2511 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
2512 } else {
2513 /* OPC_BGEC */
2514 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
2515 }
2516 break;
2517 case OPC_BLTC:
2518 if (rs == 0 && rt != 0) {
2519 /* OPC_BGTZC */
2520 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
2521 } else if (rs != 0 && rt != 0 && rs == rt) {
2522 /* OPC_BLTZC */
2523 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
2524 } else {
2525 /* OPC_BLTC */
2526 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
2527 }
2528 break;
2529 case OPC_BEQZC:
2530 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
2531 break;
2532 default:
2533 MIPS_INVAL("Compact conditional branch/jump");
2534 gen_reserved_instruction(ctx);
2535 return;
2536 }
2537
2538 /* branch completion */
2539 clear_branch_hflags(ctx);
2540 ctx->base.is_jmp = DISAS_NORETURN;
2541
2542 /* Generating branch here as compact branches don't have delay slot */
2543 gen_goto_tb(ctx, 1, ctx->btarget);
2544 gen_set_label(fs);
2545
2546 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
2547 }
2548 }
2549
2550
2551 /* nanoMIPS CP1 Branches */
2552 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
2553 int32_t ft, int32_t offset)
2554 {
2555 target_ulong btarget;
2556 TCGv_i64 t0 = tcg_temp_new_i64();
2557
2558 gen_load_fpr64(ctx, t0, ft);
2559 tcg_gen_andi_i64(t0, t0, 1);
2560
2561 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2562
2563 switch (op) {
2564 case NM_BC1EQZC:
2565 tcg_gen_xori_i64(t0, t0, 1);
2566 ctx->hflags |= MIPS_HFLAG_BC;
2567 break;
2568 case NM_BC1NEZC:
2569 /* t0 already set */
2570 ctx->hflags |= MIPS_HFLAG_BC;
2571 break;
2572 default:
2573 MIPS_INVAL("cp1 cond branch");
2574 gen_reserved_instruction(ctx);
2575 return;
2576 }
2577
2578 tcg_gen_trunc_i64_tl(bcond, t0);
2579
2580 ctx->btarget = btarget;
2581 }
2582
2583
2584 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
2585 {
2586 TCGv t0, t1;
2587 t0 = tcg_temp_new();
2588 t1 = tcg_temp_new();
2589
2590 gen_load_gpr(t0, rs);
2591 gen_load_gpr(t1, rt);
2592
2593 if ((extract32(ctx->opcode, 6, 1)) == 1) {
2594 /* PP.LSXS instructions require shifting */
2595 switch (extract32(ctx->opcode, 7, 4)) {
2596 case NM_SHXS:
2597 check_nms(ctx);
2598 /* fall through */
2599 case NM_LHXS:
2600 case NM_LHUXS:
2601 tcg_gen_shli_tl(t0, t0, 1);
2602 break;
2603 case NM_SWXS:
2604 check_nms(ctx);
2605 /* fall through */
2606 case NM_LWXS:
2607 case NM_LWC1XS:
2608 case NM_SWC1XS:
2609 tcg_gen_shli_tl(t0, t0, 2);
2610 break;
2611 case NM_LDC1XS:
2612 case NM_SDC1XS:
2613 tcg_gen_shli_tl(t0, t0, 3);
2614 break;
2615 default:
2616 gen_reserved_instruction(ctx);
2617 return;
2618 }
2619 }
2620 gen_op_addr_add(ctx, t0, t0, t1);
2621
2622 switch (extract32(ctx->opcode, 7, 4)) {
2623 case NM_LBX:
2624 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2625 gen_store_gpr(t0, rd);
2626 break;
2627 case NM_LHX:
2628 /*case NM_LHXS:*/
2629 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2630 mo_endian(ctx) | MO_SW | ctx->default_tcg_memop_mask);
2631 gen_store_gpr(t0, rd);
2632 break;
2633 case NM_LWX:
2634 /*case NM_LWXS:*/
2635 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2636 mo_endian(ctx) | MO_SL | ctx->default_tcg_memop_mask);
2637 gen_store_gpr(t0, rd);
2638 break;
2639 case NM_LBUX:
2640 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2641 gen_store_gpr(t0, rd);
2642 break;
2643 case NM_LHUX:
2644 /*case NM_LHUXS:*/
2645 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2646 mo_endian(ctx) | MO_UW | ctx->default_tcg_memop_mask);
2647 gen_store_gpr(t0, rd);
2648 break;
2649 case NM_SBX:
2650 check_nms(ctx);
2651 gen_load_gpr(t1, rd);
2652 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2653 break;
2654 case NM_SHX:
2655 /*case NM_SHXS:*/
2656 check_nms(ctx);
2657 gen_load_gpr(t1, rd);
2658 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
2659 mo_endian(ctx) | MO_UW | ctx->default_tcg_memop_mask);
2660 break;
2661 case NM_SWX:
2662 /*case NM_SWXS:*/
2663 check_nms(ctx);
2664 gen_load_gpr(t1, rd);
2665 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
2666 mo_endian(ctx) | MO_UL | ctx->default_tcg_memop_mask);
2667 break;
2668 case NM_LWC1X:
2669 /*case NM_LWC1XS:*/
2670 case NM_LDC1X:
2671 /*case NM_LDC1XS:*/
2672 case NM_SWC1X:
2673 /*case NM_SWC1XS:*/
2674 case NM_SDC1X:
2675 /*case NM_SDC1XS:*/
2676 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2677 check_cp1_enabled(ctx);
2678 switch (extract32(ctx->opcode, 7, 4)) {
2679 case NM_LWC1X:
2680 /*case NM_LWC1XS:*/
2681 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
2682 break;
2683 case NM_LDC1X:
2684 /*case NM_LDC1XS:*/
2685 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
2686 break;
2687 case NM_SWC1X:
2688 /*case NM_SWC1XS:*/
2689 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
2690 break;
2691 case NM_SDC1X:
2692 /*case NM_SDC1XS:*/
2693 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
2694 break;
2695 }
2696 } else {
2697 generate_exception_err(ctx, EXCP_CpU, 1);
2698 }
2699 break;
2700 default:
2701 gen_reserved_instruction(ctx);
2702 break;
2703 }
2704 }
2705
2706 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
2707 {
2708 int rt, rs, rd;
2709
2710 rt = extract32(ctx->opcode, 21, 5);
2711 rs = extract32(ctx->opcode, 16, 5);
2712 rd = extract32(ctx->opcode, 11, 5);
2713
2714 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
2715 gen_reserved_instruction(ctx);
2716 return;
2717 }
2718 check_cp1_enabled(ctx);
2719 switch (extract32(ctx->opcode, 0, 3)) {
2720 case NM_POOL32F_0:
2721 switch (extract32(ctx->opcode, 3, 7)) {
2722 case NM_RINT_S:
2723 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
2724 break;
2725 case NM_RINT_D:
2726 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
2727 break;
2728 case NM_CLASS_S:
2729 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
2730 break;
2731 case NM_CLASS_D:
2732 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
2733 break;
2734 case NM_ADD_S:
2735 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
2736 break;
2737 case NM_ADD_D:
2738 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
2739 break;
2740 case NM_SUB_S:
2741 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
2742 break;
2743 case NM_SUB_D:
2744 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
2745 break;
2746 case NM_MUL_S:
2747 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
2748 break;
2749 case NM_MUL_D:
2750 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
2751 break;
2752 case NM_DIV_S:
2753 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
2754 break;
2755 case NM_DIV_D:
2756 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
2757 break;
2758 case NM_SELEQZ_S:
2759 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2760 break;
2761 case NM_SELEQZ_D:
2762 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2763 break;
2764 case NM_SELNEZ_S:
2765 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2766 break;
2767 case NM_SELNEZ_D:
2768 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2769 break;
2770 case NM_SEL_S:
2771 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
2772 break;
2773 case NM_SEL_D:
2774 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
2775 break;
2776 case NM_MADDF_S:
2777 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
2778 break;
2779 case NM_MADDF_D:
2780 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
2781 break;
2782 case NM_MSUBF_S:
2783 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
2784 break;
2785 case NM_MSUBF_D:
2786 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
2787 break;
2788 default:
2789 gen_reserved_instruction(ctx);
2790 break;
2791 }
2792 break;
2793 case NM_POOL32F_3:
2794 switch (extract32(ctx->opcode, 3, 3)) {
2795 case NM_MIN_FMT:
2796 switch (extract32(ctx->opcode, 9, 1)) {
2797 case FMT_SDPS_S:
2798 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
2799 break;
2800 case FMT_SDPS_D:
2801 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
2802 break;
2803 }
2804 break;
2805 case NM_MAX_FMT:
2806 switch (extract32(ctx->opcode, 9, 1)) {
2807 case FMT_SDPS_S:
2808 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
2809 break;
2810 case FMT_SDPS_D:
2811 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
2812 break;
2813 }
2814 break;
2815 case NM_MINA_FMT:
2816 switch (extract32(ctx->opcode, 9, 1)) {
2817 case FMT_SDPS_S:
2818 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
2819 break;
2820 case FMT_SDPS_D:
2821 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
2822 break;
2823 }
2824 break;
2825 case NM_MAXA_FMT:
2826 switch (extract32(ctx->opcode, 9, 1)) {
2827 case FMT_SDPS_S:
2828 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
2829 break;
2830 case FMT_SDPS_D:
2831 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
2832 break;
2833 }
2834 break;
2835 case NM_POOL32FXF:
2836 switch (extract32(ctx->opcode, 6, 8)) {
2837 case NM_CFC1:
2838 gen_cp1(ctx, OPC_CFC1, rt, rs);
2839 break;
2840 case NM_CTC1:
2841 gen_cp1(ctx, OPC_CTC1, rt, rs);
2842 break;
2843 case NM_MFC1:
2844 gen_cp1(ctx, OPC_MFC1, rt, rs);
2845 break;
2846 case NM_MTC1:
2847 gen_cp1(ctx, OPC_MTC1, rt, rs);
2848 break;
2849 case NM_MFHC1:
2850 gen_cp1(ctx, OPC_MFHC1, rt, rs);
2851 break;
2852 case NM_MTHC1:
2853 gen_cp1(ctx, OPC_MTHC1, rt, rs);
2854 break;
2855 case NM_CVT_S_PL:
2856 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
2857 break;
2858 case NM_CVT_S_PU:
2859 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
2860 break;
2861 default:
2862 switch (extract32(ctx->opcode, 6, 9)) {
2863 case NM_CVT_L_S:
2864 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
2865 break;
2866 case NM_CVT_L_D:
2867 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
2868 break;
2869 case NM_CVT_W_S:
2870 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
2871 break;
2872 case NM_CVT_W_D:
2873 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
2874 break;
2875 case NM_RSQRT_S:
2876 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
2877 break;
2878 case NM_RSQRT_D:
2879 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
2880 break;
2881 case NM_SQRT_S:
2882 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
2883 break;
2884 case NM_SQRT_D:
2885 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
2886 break;
2887 case NM_RECIP_S:
2888 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
2889 break;
2890 case NM_RECIP_D:
2891 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
2892 break;
2893 case NM_FLOOR_L_S:
2894 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
2895 break;
2896 case NM_FLOOR_L_D:
2897 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
2898 break;
2899 case NM_FLOOR_W_S:
2900 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
2901 break;
2902 case NM_FLOOR_W_D:
2903 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
2904 break;
2905 case NM_CEIL_L_S:
2906 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
2907 break;
2908 case NM_CEIL_L_D:
2909 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
2910 break;
2911 case NM_CEIL_W_S:
2912 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
2913 break;
2914 case NM_CEIL_W_D:
2915 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
2916 break;
2917 case NM_TRUNC_L_S:
2918 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
2919 break;
2920 case NM_TRUNC_L_D:
2921 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
2922 break;
2923 case NM_TRUNC_W_S:
2924 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
2925 break;
2926 case NM_TRUNC_W_D:
2927 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
2928 break;
2929 case NM_ROUND_L_S:
2930 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
2931 break;
2932 case NM_ROUND_L_D:
2933 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
2934 break;
2935 case NM_ROUND_W_S:
2936 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
2937 break;
2938 case NM_ROUND_W_D:
2939 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
2940 break;
2941 case NM_MOV_S:
2942 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
2943 break;
2944 case NM_MOV_D:
2945 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
2946 break;
2947 case NM_ABS_S:
2948 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
2949 break;
2950 case NM_ABS_D:
2951 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
2952 break;
2953 case NM_NEG_S:
2954 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
2955 break;
2956 case NM_NEG_D:
2957 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
2958 break;
2959 case NM_CVT_D_S:
2960 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
2961 break;
2962 case NM_CVT_D_W:
2963 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
2964 break;
2965 case NM_CVT_D_L:
2966 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
2967 break;
2968 case NM_CVT_S_D:
2969 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
2970 break;
2971 case NM_CVT_S_W:
2972 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
2973 break;
2974 case NM_CVT_S_L:
2975 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
2976 break;
2977 default:
2978 gen_reserved_instruction(ctx);
2979 break;
2980 }
2981 break;
2982 }
2983 break;
2984 }
2985 break;
2986 case NM_POOL32F_5:
2987 switch (extract32(ctx->opcode, 3, 3)) {
2988 case NM_CMP_CONDN_S:
2989 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
2990 break;
2991 case NM_CMP_CONDN_D:
2992 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
2993 break;
2994 default:
2995 gen_reserved_instruction(ctx);
2996 break;
2997 }
2998 break;
2999 default:
3000 gen_reserved_instruction(ctx);
3001 break;
3002 }
3003 }
3004
3005 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
3006 int rd, int rs, int rt)
3007 {
3008 int ret = rd;
3009 TCGv t0 = tcg_temp_new();
3010 TCGv v1_t = tcg_temp_new();
3011 TCGv v2_t = tcg_temp_new();
3012
3013 gen_load_gpr(v1_t, rs);
3014 gen_load_gpr(v2_t, rt);
3015
3016 switch (opc) {
3017 case NM_CMP_EQ_PH:
3018 check_dsp(ctx);
3019 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env);
3020 break;
3021 case NM_CMP_LT_PH:
3022 check_dsp(ctx);
3023 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env);
3024 break;
3025 case NM_CMP_LE_PH:
3026 check_dsp(ctx);
3027 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env);
3028 break;
3029 case NM_CMPU_EQ_QB:
3030 check_dsp(ctx);
3031 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env);
3032 break;
3033 case NM_CMPU_LT_QB:
3034 check_dsp(ctx);
3035 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env);
3036 break;
3037 case NM_CMPU_LE_QB:
3038 check_dsp(ctx);
3039 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env);
3040 break;
3041 case NM_CMPGU_EQ_QB:
3042 check_dsp(ctx);
3043 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
3044 gen_store_gpr(v1_t, ret);
3045 break;
3046 case NM_CMPGU_LT_QB:
3047 check_dsp(ctx);
3048 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
3049 gen_store_gpr(v1_t, ret);
3050 break;
3051 case NM_CMPGU_LE_QB:
3052 check_dsp(ctx);
3053 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
3054 gen_store_gpr(v1_t, ret);
3055 break;
3056 case NM_CMPGDU_EQ_QB:
3057 check_dsp_r2(ctx);
3058 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
3059 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
3060 gen_store_gpr(v1_t, ret);
3061 break;
3062 case NM_CMPGDU_LT_QB:
3063 check_dsp_r2(ctx);
3064 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
3065 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
3066 gen_store_gpr(v1_t, ret);
3067 break;
3068 case NM_CMPGDU_LE_QB:
3069 check_dsp_r2(ctx);
3070 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
3071 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
3072 gen_store_gpr(v1_t, ret);
3073 break;
3074 case NM_PACKRL_PH:
3075 check_dsp(ctx);
3076 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
3077 gen_store_gpr(v1_t, ret);
3078 break;
3079 case NM_PICK_QB:
3080 check_dsp(ctx);
3081 gen_helper_pick_qb(v1_t, v1_t, v2_t, tcg_env);
3082 gen_store_gpr(v1_t, ret);
3083 break;
3084 case NM_PICK_PH:
3085 check_dsp(ctx);
3086 gen_helper_pick_ph(v1_t, v1_t, v2_t, tcg_env);
3087 gen_store_gpr(v1_t, ret);
3088 break;
3089 case NM_ADDQ_S_W:
3090 check_dsp(ctx);
3091 gen_helper_addq_s_w(v1_t, v1_t, v2_t, tcg_env);
3092 gen_store_gpr(v1_t, ret);
3093 break;
3094 case NM_SUBQ_S_W:
3095 check_dsp(ctx);
3096 gen_helper_subq_s_w(v1_t, v1_t, v2_t, tcg_env);
3097 gen_store_gpr(v1_t, ret);
3098 break;
3099 case NM_ADDSC:
3100 check_dsp(ctx);
3101 gen_helper_addsc(v1_t, v1_t, v2_t, tcg_env);
3102 gen_store_gpr(v1_t, ret);
3103 break;
3104 case NM_ADDWC:
3105 check_dsp(ctx);
3106 gen_helper_addwc(v1_t, v1_t, v2_t, tcg_env);
3107 gen_store_gpr(v1_t, ret);
3108 break;
3109 case NM_ADDQ_S_PH:
3110 check_dsp(ctx);
3111 switch (extract32(ctx->opcode, 10, 1)) {
3112 case 0:
3113 /* ADDQ_PH */
3114 gen_helper_addq_ph(v1_t, v1_t, v2_t, tcg_env);
3115 gen_store_gpr(v1_t, ret);
3116 break;
3117 case 1:
3118 /* ADDQ_S_PH */
3119 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, tcg_env);
3120 gen_store_gpr(v1_t, ret);
3121 break;
3122 }
3123 break;
3124 case NM_ADDQH_R_PH:
3125 check_dsp_r2(ctx);
3126 switch (extract32(ctx->opcode, 10, 1)) {
3127 case 0:
3128 /* ADDQH_PH */
3129 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
3130 gen_store_gpr(v1_t, ret);
3131 break;
3132 case 1:
3133 /* ADDQH_R_PH */
3134 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
3135 gen_store_gpr(v1_t, ret);
3136 break;
3137 }
3138 break;
3139 case NM_ADDQH_R_W:
3140 check_dsp_r2(ctx);
3141 switch (extract32(ctx->opcode, 10, 1)) {
3142 case 0:
3143 /* ADDQH_W */
3144 gen_helper_addqh_w(v1_t, v1_t, v2_t);
3145 gen_store_gpr(v1_t, ret);
3146 break;
3147 case 1:
3148 /* ADDQH_R_W */
3149 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
3150 gen_store_gpr(v1_t, ret);
3151 break;
3152 }
3153 break;
3154 case NM_ADDU_S_QB:
3155 check_dsp(ctx);
3156 switch (extract32(ctx->opcode, 10, 1)) {
3157 case 0:
3158 /* ADDU_QB */
3159 gen_helper_addu_qb(v1_t, v1_t, v2_t, tcg_env);
3160 gen_store_gpr(v1_t, ret);
3161 break;
3162 case 1:
3163 /* ADDU_S_QB */
3164 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, tcg_env);
3165 gen_store_gpr(v1_t, ret);
3166 break;
3167 }
3168 break;
3169 case NM_ADDU_S_PH:
3170 check_dsp_r2(ctx);
3171 switch (extract32(ctx->opcode, 10, 1)) {
3172 case 0:
3173 /* ADDU_PH */
3174 gen_helper_addu_ph(v1_t, v1_t, v2_t, tcg_env);
3175 gen_store_gpr(v1_t, ret);
3176 break;
3177 case 1:
3178 /* ADDU_S_PH */
3179 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, tcg_env);
3180 gen_store_gpr(v1_t, ret);
3181 break;
3182 }
3183 break;
3184 case NM_ADDUH_R_QB:
3185 check_dsp_r2(ctx);
3186 switch (extract32(ctx->opcode, 10, 1)) {
3187 case 0:
3188 /* ADDUH_QB */
3189 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
3190 gen_store_gpr(v1_t, ret);
3191 break;
3192 case 1:
3193 /* ADDUH_R_QB */
3194 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
3195 gen_store_gpr(v1_t, ret);
3196 break;
3197 }
3198 break;
3199 case NM_SHRAV_R_PH:
3200 check_dsp(ctx);
3201 switch (extract32(ctx->opcode, 10, 1)) {
3202 case 0:
3203 /* SHRAV_PH */
3204 gen_helper_shra_ph(v1_t, v1_t, v2_t);
3205 gen_store_gpr(v1_t, ret);
3206 break;
3207 case 1:
3208 /* SHRAV_R_PH */
3209 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
3210 gen_store_gpr(v1_t, ret);
3211 break;
3212 }
3213 break;
3214 case NM_SHRAV_R_QB:
3215 check_dsp_r2(ctx);
3216 switch (extract32(ctx->opcode, 10, 1)) {
3217 case 0:
3218 /* SHRAV_QB */
3219 gen_helper_shra_qb(v1_t, v1_t, v2_t);
3220 gen_store_gpr(v1_t, ret);
3221 break;
3222 case 1:
3223 /* SHRAV_R_QB */
3224 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
3225 gen_store_gpr(v1_t, ret);
3226 break;
3227 }
3228 break;
3229 case NM_SUBQ_S_PH:
3230 check_dsp(ctx);
3231 switch (extract32(ctx->opcode, 10, 1)) {
3232 case 0:
3233 /* SUBQ_PH */
3234 gen_helper_subq_ph(v1_t, v1_t, v2_t, tcg_env);
3235 gen_store_gpr(v1_t, ret);
3236 break;
3237 case 1:
3238 /* SUBQ_S_PH */
3239 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, tcg_env);
3240 gen_store_gpr(v1_t, ret);
3241 break;
3242 }
3243 break;
3244 case NM_SUBQH_R_PH:
3245 check_dsp_r2(ctx);
3246 switch (extract32(ctx->opcode, 10, 1)) {
3247 case 0:
3248 /* SUBQH_PH */
3249 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
3250 gen_store_gpr(v1_t, ret);
3251 break;
3252 case 1:
3253 /* SUBQH_R_PH */
3254 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
3255 gen_store_gpr(v1_t, ret);
3256 break;
3257 }
3258 break;
3259 case NM_SUBQH_R_W:
3260 check_dsp_r2(ctx);
3261 switch (extract32(ctx->opcode, 10, 1)) {
3262 case 0:
3263 /* SUBQH_W */
3264 gen_helper_subqh_w(v1_t, v1_t, v2_t);
3265 gen_store_gpr(v1_t, ret);
3266 break;
3267 case 1:
3268 /* SUBQH_R_W */
3269 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
3270 gen_store_gpr(v1_t, ret);
3271 break;
3272 }
3273 break;
3274 case NM_SUBU_S_QB:
3275 check_dsp(ctx);
3276 switch (extract32(ctx->opcode, 10, 1)) {
3277 case 0:
3278 /* SUBU_QB */
3279 gen_helper_subu_qb(v1_t, v1_t, v2_t, tcg_env);
3280 gen_store_gpr(v1_t, ret);
3281 break;
3282 case 1:
3283 /* SUBU_S_QB */
3284 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, tcg_env);
3285 gen_store_gpr(v1_t, ret);
3286 break;
3287 }
3288 break;
3289 case NM_SUBU_S_PH:
3290 check_dsp_r2(ctx);
3291 switch (extract32(ctx->opcode, 10, 1)) {
3292 case 0:
3293 /* SUBU_PH */
3294 gen_helper_subu_ph(v1_t, v1_t, v2_t, tcg_env);
3295 gen_store_gpr(v1_t, ret);
3296 break;
3297 case 1:
3298 /* SUBU_S_PH */
3299 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, tcg_env);
3300 gen_store_gpr(v1_t, ret);
3301 break;
3302 }
3303 break;
3304 case NM_SUBUH_R_QB:
3305 check_dsp_r2(ctx);
3306 switch (extract32(ctx->opcode, 10, 1)) {
3307 case 0:
3308 /* SUBUH_QB */
3309 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
3310 gen_store_gpr(v1_t, ret);
3311 break;
3312 case 1:
3313 /* SUBUH_R_QB */
3314 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
3315 gen_store_gpr(v1_t, ret);
3316 break;
3317 }
3318 break;
3319 case NM_SHLLV_S_PH:
3320 check_dsp(ctx);
3321 switch (extract32(ctx->opcode, 10, 1)) {
3322 case 0:
3323 /* SHLLV_PH */
3324 gen_helper_shll_ph(v1_t, v1_t, v2_t, tcg_env);
3325 gen_store_gpr(v1_t, ret);
3326 break;
3327 case 1:
3328 /* SHLLV_S_PH */
3329 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, tcg_env);
3330 gen_store_gpr(v1_t, ret);
3331 break;
3332 }
3333 break;
3334 case NM_PRECR_SRA_R_PH_W:
3335 check_dsp_r2(ctx);
3336 switch (extract32(ctx->opcode, 10, 1)) {
3337 case 0:
3338 /* PRECR_SRA_PH_W */
3339 {
3340 TCGv_i32 sa_t = tcg_constant_i32(rd);
3341 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
3342 cpu_gpr[rt]);
3343 gen_store_gpr(v1_t, rt);
3344 }
3345 break;
3346 case 1:
3347 /* PRECR_SRA_R_PH_W */
3348 {
3349 TCGv_i32 sa_t = tcg_constant_i32(rd);
3350 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
3351 cpu_gpr[rt]);
3352 gen_store_gpr(v1_t, rt);
3353 }
3354 break;
3355 }
3356 break;
3357 case NM_MULEU_S_PH_QBL:
3358 check_dsp(ctx);
3359 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, tcg_env);
3360 gen_store_gpr(v1_t, ret);
3361 break;
3362 case NM_MULEU_S_PH_QBR:
3363 check_dsp(ctx);
3364 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, tcg_env);
3365 gen_store_gpr(v1_t, ret);
3366 break;
3367 case NM_MULQ_RS_PH:
3368 check_dsp(ctx);
3369 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, tcg_env);
3370 gen_store_gpr(v1_t, ret);
3371 break;
3372 case NM_MULQ_S_PH:
3373 check_dsp_r2(ctx);
3374 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, tcg_env);
3375 gen_store_gpr(v1_t, ret);
3376 break;
3377 case NM_MULQ_RS_W:
3378 check_dsp_r2(ctx);
3379 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, tcg_env);
3380 gen_store_gpr(v1_t, ret);
3381 break;
3382 case NM_MULQ_S_W:
3383 check_dsp_r2(ctx);
3384 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, tcg_env);
3385 gen_store_gpr(v1_t, ret);
3386 break;
3387 case NM_APPEND:
3388 check_dsp_r2(ctx);
3389 gen_load_gpr(t0, rs);
3390 if (rd != 0) {
3391 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
3392 }
3393 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3394 break;
3395 case NM_MODSUB:
3396 check_dsp(ctx);
3397 gen_helper_modsub(v1_t, v1_t, v2_t);
3398 gen_store_gpr(v1_t, ret);
3399 break;
3400 case NM_SHRAV_R_W:
3401 check_dsp(ctx);
3402 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
3403 gen_store_gpr(v1_t, ret);
3404 break;
3405 case NM_SHRLV_PH:
3406 check_dsp_r2(ctx);
3407 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
3408 gen_store_gpr(v1_t, ret);
3409 break;
3410 case NM_SHRLV_QB:
3411 check_dsp(ctx);
3412 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
3413 gen_store_gpr(v1_t, ret);
3414 break;
3415 case NM_SHLLV_QB:
3416 check_dsp(ctx);
3417 gen_helper_shll_qb(v1_t, v1_t, v2_t, tcg_env);
3418 gen_store_gpr(v1_t, ret);
3419 break;
3420 case NM_SHLLV_S_W:
3421 check_dsp(ctx);
3422 gen_helper_shll_s_w(v1_t, v1_t, v2_t, tcg_env);
3423 gen_store_gpr(v1_t, ret);
3424 break;
3425 case NM_SHILO:
3426 check_dsp(ctx);
3427 {
3428 int16_t imm = extract32(ctx->opcode, 16, 7);
3429
3430 gen_helper_shilo(tcg_constant_tl(rd >> 3),
3431 tcg_constant_tl(imm), tcg_env);
3432 }
3433 break;
3434 case NM_MULEQ_S_W_PHL:
3435 check_dsp(ctx);
3436 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, tcg_env);
3437 gen_store_gpr(v1_t, ret);
3438 break;
3439 case NM_MULEQ_S_W_PHR:
3440 check_dsp(ctx);
3441 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, tcg_env);
3442 gen_store_gpr(v1_t, ret);
3443 break;
3444 case NM_MUL_S_PH:
3445 check_dsp_r2(ctx);
3446 switch (extract32(ctx->opcode, 10, 1)) {
3447 case 0:
3448 /* MUL_PH */
3449 gen_helper_mul_ph(v1_t, v1_t, v2_t, tcg_env);
3450 gen_store_gpr(v1_t, ret);
3451 break;
3452 case 1:
3453 /* MUL_S_PH */
3454 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, tcg_env);
3455 gen_store_gpr(v1_t, ret);
3456 break;
3457 }
3458 break;
3459 case NM_PRECR_QB_PH:
3460 check_dsp_r2(ctx);
3461 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
3462 gen_store_gpr(v1_t, ret);
3463 break;
3464 case NM_PRECRQ_QB_PH:
3465 check_dsp(ctx);
3466 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
3467 gen_store_gpr(v1_t, ret);
3468 break;
3469 case NM_PRECRQ_PH_W:
3470 check_dsp(ctx);
3471 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
3472 gen_store_gpr(v1_t, ret);
3473 break;
3474 case NM_PRECRQ_RS_PH_W:
3475 check_dsp(ctx);
3476 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, tcg_env);
3477 gen_store_gpr(v1_t, ret);
3478 break;
3479 case NM_PRECRQU_S_QB_PH:
3480 check_dsp(ctx);
3481 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, tcg_env);
3482 gen_store_gpr(v1_t, ret);
3483 break;
3484 case NM_SHRA_R_W:
3485 check_dsp(ctx);
3486 gen_helper_shra_r_w(v1_t, tcg_constant_tl(rd), v1_t);
3487 gen_store_gpr(v1_t, rt);
3488 break;
3489 case NM_SHRA_R_PH:
3490 check_dsp(ctx);
3491 tcg_gen_movi_tl(t0, rd >> 1);
3492 switch (extract32(ctx->opcode, 10, 1)) {
3493 case 0:
3494 /* SHRA_PH */
3495 gen_helper_shra_ph(v1_t, t0, v1_t);
3496 gen_store_gpr(v1_t, rt);
3497 break;
3498 case 1:
3499 /* SHRA_R_PH */
3500 gen_helper_shra_r_ph(v1_t, t0, v1_t);
3501 gen_store_gpr(v1_t, rt);
3502 break;
3503 }
3504 break;
3505 case NM_SHLL_S_PH:
3506 check_dsp(ctx);
3507 tcg_gen_movi_tl(t0, rd >> 1);
3508 switch (extract32(ctx->opcode, 10, 2)) {
3509 case 0:
3510 /* SHLL_PH */
3511 gen_helper_shll_ph(v1_t, t0, v1_t, tcg_env);
3512 gen_store_gpr(v1_t, rt);
3513 break;
3514 case 2:
3515 /* SHLL_S_PH */
3516 gen_helper_shll_s_ph(v1_t, t0, v1_t, tcg_env);
3517 gen_store_gpr(v1_t, rt);
3518 break;
3519 default:
3520 gen_reserved_instruction(ctx);
3521 break;
3522 }
3523 break;
3524 case NM_SHLL_S_W:
3525 check_dsp(ctx);
3526 gen_helper_shll_s_w(v1_t, tcg_constant_tl(rd), v1_t, tcg_env);
3527 gen_store_gpr(v1_t, rt);
3528 break;
3529 case NM_REPL_PH:
3530 check_dsp(ctx);
3531 {
3532 int16_t imm;
3533 imm = sextract32(ctx->opcode, 11, 11);
3534 imm = (int16_t)(imm << 6) >> 6;
3535 if (rt != 0) {
3536 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
3537 }
3538 }
3539 break;
3540 default:
3541 gen_reserved_instruction(ctx);
3542 break;
3543 }
3544 }
3545
3546 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
3547 {
3548 uint16_t insn;
3549 uint32_t op;
3550 int rt, rs, rd;
3551 int offset;
3552 int imm;
3553
3554 insn = translator_lduw_end(env, &ctx->base, ctx->base.pc_next + 2, mo_endian(ctx));
3555 ctx->opcode = (ctx->opcode << 16) | insn;
3556
3557 rt = extract32(ctx->opcode, 21, 5);
3558 rs = extract32(ctx->opcode, 16, 5);
3559 rd = extract32(ctx->opcode, 11, 5);
3560
3561 op = extract32(ctx->opcode, 26, 6);
3562 switch (op) {
3563 case NM_P_ADDIU:
3564 if (rt == 0) {
3565 /* P.RI */
3566 switch (extract32(ctx->opcode, 19, 2)) {
3567 case NM_SIGRIE:
3568 default:
3569 gen_reserved_instruction(ctx);
3570 break;
3571 case NM_P_SYSCALL:
3572 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
3573 generate_exception_end(ctx, EXCP_SYSCALL);
3574 } else {
3575 gen_reserved_instruction(ctx);
3576 }
3577 break;
3578 case NM_BREAK:
3579 generate_exception_end(ctx, EXCP_BREAK);
3580 break;
3581 case NM_SDBBP:
3582 if (is_uhi(ctx, extract32(ctx->opcode, 0, 19))) {
3583 ctx->base.is_jmp = DISAS_SEMIHOST;
3584 } else {
3585 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3586 gen_reserved_instruction(ctx);
3587 } else {
3588 generate_exception_end(ctx, EXCP_DBp);
3589 }
3590 }
3591 break;
3592 }
3593 } else {
3594 /* NM_ADDIU */
3595 imm = extract32(ctx->opcode, 0, 16);
3596 if (rs != 0) {
3597 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
3598 } else {
3599 tcg_gen_movi_tl(cpu_gpr[rt], imm);
3600 }
3601 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3602 }
3603 break;
3604 case NM_ADDIUPC:
3605 if (rt != 0) {
3606 offset = sextract32(ctx->opcode, 0, 1) << 21 |
3607 extract32(ctx->opcode, 1, 20) << 1;
3608 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
3609 tcg_gen_movi_tl(cpu_gpr[rt], addr);
3610 }
3611 break;
3612 case NM_POOL32A:
3613 switch (ctx->opcode & 0x07) {
3614 case NM_POOL32A0:
3615 gen_pool32a0_nanomips_insn(env, ctx);
3616 break;
3617 case NM_POOL32A5:
3618 {
3619 int32_t op1 = extract32(ctx->opcode, 3, 7);
3620 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
3621 }
3622 break;
3623 case NM_POOL32A7:
3624 switch (extract32(ctx->opcode, 3, 3)) {
3625 case NM_P_LSX:
3626 gen_p_lsx(ctx, rd, rs, rt);
3627 break;
3628 case NM_LSA:
3629 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2));
3630 break;
3631 case NM_EXTW:
3632 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
3633 break;
3634 case NM_POOL32AXF:
3635 gen_pool32axf_nanomips_insn(env, ctx);
3636 break;
3637 default:
3638 gen_reserved_instruction(ctx);
3639 break;
3640 }
3641 break;
3642 default:
3643 gen_reserved_instruction(ctx);
3644 break;
3645 }
3646 break;
3647 case NM_P_GP_W:
3648 switch (ctx->opcode & 0x03) {
3649 case NM_ADDIUGP_W:
3650 if (rt != 0) {
3651 offset = extract32(ctx->opcode, 0, 21);
3652 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
3653 }
3654 break;
3655 case NM_LWGP:
3656 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
3657 break;
3658 case NM_SWGP:
3659 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
3660 break;
3661 default:
3662 gen_reserved_instruction(ctx);
3663 break;
3664 }
3665 break;
3666 case NM_P48I:
3667 {
3668 insn = translator_lduw_end(env, &ctx->base, ctx->base.pc_next + 4,
3669 mo_endian(ctx));
3670 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
3671 switch (extract32(ctx->opcode, 16, 5)) {
3672 case NM_LI48:
3673 check_nms(ctx);
3674 if (rt != 0) {
3675 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
3676 }
3677 break;
3678 case NM_ADDIU48:
3679 check_nms(ctx);
3680 if (rt != 0) {
3681 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
3682 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3683 }
3684 break;
3685 case NM_ADDIUGP48:
3686 check_nms(ctx);
3687 if (rt != 0) {
3688 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
3689 }
3690 break;
3691 case NM_ADDIUPC48:
3692 check_nms(ctx);
3693 if (rt != 0) {
3694 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
3695 addr_off);
3696
3697 tcg_gen_movi_tl(cpu_gpr[rt], addr);
3698 }
3699 break;
3700 case NM_LWPC48:
3701 check_nms(ctx);
3702 if (rt != 0) {
3703 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
3704 addr_off);
3705
3706 tcg_gen_qemu_ld_tl(cpu_gpr[rt], tcg_constant_tl(addr),
3707 ctx->mem_idx,
3708 mo_endian(ctx) | MO_SL
3709 | ctx->default_tcg_memop_mask);
3710 }
3711 break;
3712 case NM_SWPC48:
3713 check_nms(ctx);
3714 {
3715 TCGv t1;
3716 t1 = tcg_temp_new();
3717
3718 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
3719 addr_off);
3720
3721 gen_load_gpr(t1, rt);
3722
3723 tcg_gen_qemu_st_tl(t1, tcg_constant_tl(addr), ctx->mem_idx,
3724 mo_endian(ctx) | MO_UL
3725 | ctx->default_tcg_memop_mask);
3726 }
3727 break;
3728 default:
3729 gen_reserved_instruction(ctx);
3730 break;
3731 }
3732 return 6;
3733 }
3734 case NM_P_U12:
3735 switch (extract32(ctx->opcode, 12, 4)) {
3736 case NM_ORI:
3737 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
3738 break;
3739 case NM_XORI:
3740 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
3741 break;
3742 case NM_ANDI:
3743 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
3744 break;
3745 case NM_P_SR:
3746 switch (extract32(ctx->opcode, 20, 1)) {
3747 case NM_PP_SR:
3748 switch (ctx->opcode & 3) {
3749 case NM_SAVE:
3750 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
3751 extract32(ctx->opcode, 2, 1),
3752 extract32(ctx->opcode, 3, 9) << 3);
3753 break;
3754 case NM_RESTORE:
3755 case NM_RESTORE_JRC:
3756 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
3757 extract32(ctx->opcode, 2, 1),
3758 extract32(ctx->opcode, 3, 9) << 3);
3759 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
3760 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
3761 }
3762 break;
3763 default:
3764 gen_reserved_instruction(ctx);
3765 break;
3766 }
3767 break;
3768 case NM_P_SR_F:
3769 gen_reserved_instruction(ctx);
3770 break;
3771 }
3772 break;
3773 case NM_SLTI:
3774 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
3775 break;
3776 case NM_SLTIU:
3777 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
3778 break;
3779 case NM_SEQI:
3780 {
3781 TCGv t0 = tcg_temp_new();
3782
3783 imm = extract32(ctx->opcode, 0, 12);
3784 gen_load_gpr(t0, rs);
3785 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
3786 gen_store_gpr(t0, rt);
3787 }
3788 break;
3789 case NM_ADDIUNEG:
3790 imm = (int16_t) extract32(ctx->opcode, 0, 12);
3791 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
3792 break;
3793 case NM_P_SHIFT:
3794 {
3795 int shift = extract32(ctx->opcode, 0, 5);
3796 switch (extract32(ctx->opcode, 5, 4)) {
3797 case NM_P_SLL:
3798 if (rt == 0 && shift == 0) {
3799 /* NOP */
3800 } else if (rt == 0 && shift == 3) {
3801 /* EHB - treat as NOP */
3802 } else if (rt == 0 && shift == 5) {
3803 /* PAUSE - treat as NOP */
3804 } else if (rt == 0 && shift == 6) {
3805 /* SYNC */
3806 gen_sync(extract32(ctx->opcode, 16, 5));
3807 } else {
3808 /* SLL */
3809 gen_shift_imm(ctx, OPC_SLL, rt, rs,
3810 extract32(ctx->opcode, 0, 5));
3811 }
3812 break;
3813 case NM_SRL:
3814 gen_shift_imm(ctx, OPC_SRL, rt, rs,
3815 extract32(ctx->opcode, 0, 5));
3816 break;
3817 case NM_SRA:
3818 gen_shift_imm(ctx, OPC_SRA, rt, rs,
3819 extract32(ctx->opcode, 0, 5));
3820 break;
3821 case NM_ROTR:
3822 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
3823 extract32(ctx->opcode, 0, 5));
3824 break;
3825 default:
3826 gen_reserved_instruction(ctx);
3827 break;
3828 }
3829 }
3830 break;
3831 case NM_P_ROTX:
3832 check_nms(ctx);
3833 if (rt != 0) {
3834 TCGv t0 = tcg_temp_new();
3835 TCGv_i32 shift =
3836 tcg_constant_i32(extract32(ctx->opcode, 0, 5));
3837 TCGv_i32 shiftx =
3838 tcg_constant_i32(extract32(ctx->opcode, 7, 4) << 1);
3839 TCGv_i32 stripe =
3840 tcg_constant_i32(extract32(ctx->opcode, 6, 1));
3841
3842 gen_load_gpr(t0, rs);
3843 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
3844 }
3845 break;
3846 case NM_P_INS:
3847 switch (((ctx->opcode >> 10) & 2) |
3848 (extract32(ctx->opcode, 5, 1))) {
3849 case NM_INS:
3850 check_nms(ctx);
3851 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
3852 extract32(ctx->opcode, 6, 5));
3853 break;
3854 default:
3855 gen_reserved_instruction(ctx);
3856 break;
3857 }
3858 break;
3859 case NM_P_EXT:
3860 switch (((ctx->opcode >> 10) & 2) |
3861 (extract32(ctx->opcode, 5, 1))) {
3862 case NM_EXT:
3863 check_nms(ctx);
3864 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
3865 extract32(ctx->opcode, 6, 5));
3866 break;
3867 default:
3868 gen_reserved_instruction(ctx);
3869 break;
3870 }
3871 break;
3872 default:
3873 gen_reserved_instruction(ctx);
3874 break;
3875 }
3876 break;
3877 case NM_POOL32F:
3878 gen_pool32f_nanomips_insn(ctx);
3879 break;
3880 case NM_POOL32S:
3881 break;
3882 case NM_P_LUI:
3883 switch (extract32(ctx->opcode, 1, 1)) {
3884 case NM_LUI:
3885 if (rt != 0) {
3886 tcg_gen_movi_tl(cpu_gpr[rt],
3887 sextract32(ctx->opcode, 0, 1) << 31 |
3888 extract32(ctx->opcode, 2, 10) << 21 |
3889 extract32(ctx->opcode, 12, 9) << 12);
3890 }
3891 break;
3892 case NM_ALUIPC:
3893 if (rt != 0) {
3894 offset = sextract32(ctx->opcode, 0, 1) << 31 |
3895 extract32(ctx->opcode, 2, 10) << 21 |
3896 extract32(ctx->opcode, 12, 9) << 12;
3897 target_long addr;
3898 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
3899 tcg_gen_movi_tl(cpu_gpr[rt], addr);
3900 }
3901 break;
3902 }
3903 break;
3904 case NM_P_GP_BH:
3905 {
3906 uint32_t u = extract32(ctx->opcode, 0, 18);
3907
3908 switch (extract32(ctx->opcode, 18, 3)) {
3909 case NM_LBGP:
3910 gen_ld(ctx, OPC_LB, rt, 28, u);
3911 break;
3912 case NM_SBGP:
3913 gen_st(ctx, OPC_SB, rt, 28, u);
3914 break;
3915 case NM_LBUGP:
3916 gen_ld(ctx, OPC_LBU, rt, 28, u);
3917 break;
3918 case NM_ADDIUGP_B:
3919 if (rt != 0) {
3920 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
3921 }
3922 break;
3923 case NM_P_GP_LH:
3924 u &= ~1;
3925 switch (ctx->opcode & 1) {
3926 case NM_LHGP:
3927 gen_ld(ctx, OPC_LH, rt, 28, u);
3928 break;
3929 case NM_LHUGP:
3930 gen_ld(ctx, OPC_LHU, rt, 28, u);
3931 break;
3932 }
3933 break;
3934 case NM_P_GP_SH:
3935 u &= ~1;
3936 switch (ctx->opcode & 1) {
3937 case NM_SHGP:
3938 gen_st(ctx, OPC_SH, rt, 28, u);
3939 break;
3940 default:
3941 gen_reserved_instruction(ctx);
3942 break;
3943 }
3944 break;
3945 case NM_P_GP_CP1:
3946 u &= ~0x3;
3947 switch (ctx->opcode & 0x3) {
3948 case NM_LWC1GP:
3949 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
3950 break;
3951 case NM_LDC1GP:
3952 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
3953 break;
3954 case NM_SWC1GP:
3955 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
3956 break;
3957 case NM_SDC1GP:
3958 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
3959 break;
3960 }
3961 break;
3962 default:
3963 gen_reserved_instruction(ctx);
3964 break;
3965 }
3966 }
3967 break;
3968 case NM_P_LS_U12:
3969 {
3970 uint32_t u = extract32(ctx->opcode, 0, 12);
3971
3972 switch (extract32(ctx->opcode, 12, 4)) {
3973 case NM_P_PREFU12:
3974 if (rt == 31) {
3975 /* SYNCI */
3976 /*
3977 * Break the TB to be able to sync copied instructions
3978 * immediately.
3979 */
3980 ctx->base.is_jmp = DISAS_STOP;
3981 } else {
3982 /* PREF */
3983 /* Treat as NOP. */
3984 }
3985 break;
3986 case NM_LB:
3987 gen_ld(ctx, OPC_LB, rt, rs, u);
3988 break;
3989 case NM_LH:
3990 gen_ld(ctx, OPC_LH, rt, rs, u);
3991 break;
3992 case NM_LW:
3993 gen_ld(ctx, OPC_LW, rt, rs, u);
3994 break;
3995 case NM_LBU:
3996 gen_ld(ctx, OPC_LBU, rt, rs, u);
3997 break;
3998 case NM_LHU:
3999 gen_ld(ctx, OPC_LHU, rt, rs, u);
4000 break;
4001 case NM_SB:
4002 gen_st(ctx, OPC_SB, rt, rs, u);
4003 break;
4004 case NM_SH:
4005 gen_st(ctx, OPC_SH, rt, rs, u);
4006 break;
4007 case NM_SW:
4008 gen_st(ctx, OPC_SW, rt, rs, u);
4009 break;
4010 case NM_LWC1:
4011 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
4012 break;
4013 case NM_LDC1:
4014 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
4015 break;
4016 case NM_SWC1:
4017 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
4018 break;
4019 case NM_SDC1:
4020 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
4021 break;
4022 default:
4023 gen_reserved_instruction(ctx);
4024 break;
4025 }
4026 }
4027 break;
4028 case NM_P_LS_S9:
4029 {
4030 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
4031 extract32(ctx->opcode, 0, 8);
4032
4033 switch (extract32(ctx->opcode, 8, 3)) {
4034 case NM_P_LS_S0:
4035 switch (extract32(ctx->opcode, 11, 4)) {
4036 case NM_LBS9:
4037 gen_ld(ctx, OPC_LB, rt, rs, s);
4038 break;
4039 case NM_LHS9:
4040 gen_ld(ctx, OPC_LH, rt, rs, s);
4041 break;
4042 case NM_LWS9:
4043 gen_ld(ctx, OPC_LW, rt, rs, s);
4044 break;
4045 case NM_LBUS9:
4046 gen_ld(ctx, OPC_LBU, rt, rs, s);
4047 break;
4048 case NM_LHUS9:
4049 gen_ld(ctx, OPC_LHU, rt, rs, s);
4050 break;
4051 case NM_SBS9:
4052 gen_st(ctx, OPC_SB, rt, rs, s);
4053 break;
4054 case NM_SHS9:
4055 gen_st(ctx, OPC_SH, rt, rs, s);
4056 break;
4057 case NM_SWS9:
4058 gen_st(ctx, OPC_SW, rt, rs, s);
4059 break;
4060 case NM_LWC1S9:
4061 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
4062 break;
4063 case NM_LDC1S9:
4064 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
4065 break;
4066 case NM_SWC1S9:
4067 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
4068 break;
4069 case NM_SDC1S9:
4070 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
4071 break;
4072 case NM_P_PREFS9:
4073 if (rt == 31) {
4074 /* SYNCI */
4075 /*
4076 * Break the TB to be able to sync copied instructions
4077 * immediately.
4078 */
4079 ctx->base.is_jmp = DISAS_STOP;
4080 } else {
4081 /* PREF */
4082 /* Treat as NOP. */
4083 }
4084 break;
4085 default:
4086 gen_reserved_instruction(ctx);
4087 break;
4088 }
4089 break;
4090 case NM_P_LS_S1:
4091 switch (extract32(ctx->opcode, 11, 4)) {
4092 case NM_UALH:
4093 case NM_UASH:
4094 check_nms(ctx);
4095 {
4096 TCGv t0 = tcg_temp_new();
4097 TCGv t1 = tcg_temp_new();
4098
4099 gen_base_offset_addr(ctx, t0, rs, s);
4100
4101 switch (extract32(ctx->opcode, 11, 4)) {
4102 case NM_UALH:
4103 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
4104 mo_endian(ctx) | MO_SW | MO_UNALN);
4105 gen_store_gpr(t0, rt);
4106 break;
4107 case NM_UASH:
4108 gen_load_gpr(t1, rt);
4109 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
4110 mo_endian(ctx) | MO_UW | MO_UNALN);
4111 break;
4112 }
4113 }
4114 break;
4115 case NM_P_LL:
4116 switch (ctx->opcode & 0x03) {
4117 case NM_LL:
4118 gen_ld(ctx, OPC_LL, rt, rs, s);
4119 break;
4120 case NM_LLWP:
4121 check_xnp(ctx);
4122 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
4123 break;
4124 default:
4125 gen_reserved_instruction(ctx);
4126 break;
4127 }
4128 break;
4129 case NM_P_SC:
4130 switch (ctx->opcode & 0x03) {
4131 case NM_SC:
4132 gen_st_cond(ctx, rt, rs, s, mo_endian(ctx) | MO_SL,
4133 false);
4134 break;
4135 case NM_SCWP:
4136 check_xnp(ctx);
4137 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
4138 false);
4139 break;
4140 default:
4141 gen_reserved_instruction(ctx);
4142 break;
4143 }
4144 break;
4145 case NM_CACHE:
4146 check_cp0_enabled(ctx);
4147 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
4148 gen_cache_operation(ctx, rt, rs, s);
4149 }
4150 break;
4151 default:
4152 gen_reserved_instruction(ctx);
4153 break;
4154 }
4155 break;
4156 case NM_P_LS_E0:
4157 switch (extract32(ctx->opcode, 11, 4)) {
4158 case NM_LBE:
4159 check_eva(ctx);
4160 check_cp0_enabled(ctx);
4161 gen_ld(ctx, OPC_LBE, rt, rs, s);
4162 break;
4163 case NM_SBE:
4164 check_eva(ctx);
4165 check_cp0_enabled(ctx);
4166 gen_st(ctx, OPC_SBE, rt, rs, s);
4167 break;
4168 case NM_LBUE:
4169 check_eva(ctx);
4170 check_cp0_enabled(ctx);
4171 gen_ld(ctx, OPC_LBUE, rt, rs, s);
4172 break;
4173 case NM_P_PREFE:
4174 if (rt == 31) {
4175 /* case NM_SYNCIE */
4176 check_eva(ctx);
4177 check_cp0_enabled(ctx);
4178 /*
4179 * Break the TB to be able to sync copied instructions
4180 * immediately.
4181 */
4182 ctx->base.is_jmp = DISAS_STOP;
4183 } else {
4184 /* case NM_PREFE */
4185 check_eva(ctx);
4186 check_cp0_enabled(ctx);
4187 /* Treat as NOP. */
4188 }
4189 break;
4190 case NM_LHE:
4191 check_eva(ctx);
4192 check_cp0_enabled(ctx);
4193 gen_ld(ctx, OPC_LHE, rt, rs, s);
4194 break;
4195 case NM_SHE:
4196 check_eva(ctx);
4197 check_cp0_enabled(ctx);
4198 gen_st(ctx, OPC_SHE, rt, rs, s);
4199 break;
4200 case NM_LHUE:
4201 check_eva(ctx);
4202 check_cp0_enabled(ctx);
4203 gen_ld(ctx, OPC_LHUE, rt, rs, s);
4204 break;
4205 case NM_CACHEE:
4206 check_eva(ctx);
4207 check_cp0_enabled(ctx);
4208 check_nms_dl_il_sl_tl_l2c(ctx);
4209 gen_cache_operation(ctx, rt, rs, s);
4210 break;
4211 case NM_LWE:
4212 check_eva(ctx);
4213 check_cp0_enabled(ctx);
4214 gen_ld(ctx, OPC_LWE, rt, rs, s);
4215 break;
4216 case NM_SWE:
4217 check_eva(ctx);
4218 check_cp0_enabled(ctx);
4219 gen_st(ctx, OPC_SWE, rt, rs, s);
4220 break;
4221 case NM_P_LLE:
4222 switch (extract32(ctx->opcode, 2, 2)) {
4223 case NM_LLE:
4224 check_xnp(ctx);
4225 check_eva(ctx);
4226 check_cp0_enabled(ctx);
4227 gen_ld(ctx, OPC_LLE, rt, rs, s);
4228 break;
4229 case NM_LLWPE:
4230 check_xnp(ctx);
4231 check_eva(ctx);
4232 check_cp0_enabled(ctx);
4233 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
4234 break;
4235 default:
4236 gen_reserved_instruction(ctx);
4237 break;
4238 }
4239 break;
4240 case NM_P_SCE:
4241 switch (extract32(ctx->opcode, 2, 2)) {
4242 case NM_SCE:
4243 check_xnp(ctx);
4244 check_eva(ctx);
4245 check_cp0_enabled(ctx);
4246 gen_st_cond(ctx, rt, rs, s, mo_endian(ctx) | MO_SL,
4247 true);
4248 break;
4249 case NM_SCWPE:
4250 check_xnp(ctx);
4251 check_eva(ctx);
4252 check_cp0_enabled(ctx);
4253 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
4254 true);
4255 break;
4256 default:
4257 gen_reserved_instruction(ctx);
4258 break;
4259 }
4260 break;
4261 default:
4262 gen_reserved_instruction(ctx);
4263 break;
4264 }
4265 break;
4266 case NM_P_LS_WM:
4267 case NM_P_LS_UAWM:
4268 check_nms(ctx);
4269 {
4270 int count = extract32(ctx->opcode, 12, 3);
4271 int counter = 0;
4272
4273 offset = sextract32(ctx->opcode, 15, 1) << 8 |
4274 extract32(ctx->opcode, 0, 8);
4275 TCGv va = tcg_temp_new();
4276 TCGv t1 = tcg_temp_new();
4277 MemOp memop = (extract32(ctx->opcode, 8, 3)) ==
4278 NM_P_LS_UAWM ? MO_UNALN : MO_ALIGN;
4279
4280 count = (count == 0) ? 8 : count;
4281 while (counter != count) {
4282 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
4283 int this_offset = offset + (counter << 2);
4284
4285 gen_base_offset_addr(ctx, va, rs, this_offset);
4286
4287 switch (extract32(ctx->opcode, 11, 1)) {
4288 case NM_LWM:
4289 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
4290 memop | mo_endian(ctx) | MO_SL);
4291 gen_store_gpr(t1, this_rt);
4292 if ((this_rt == rs) &&
4293 (counter != (count - 1))) {
4294 /* UNPREDICTABLE */
4295 }
4296 break;
4297 case NM_SWM:
4298 this_rt = (rt == 0) ? 0 : this_rt;
4299 gen_load_gpr(t1, this_rt);
4300 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
4301 memop | mo_endian(ctx) | MO_UL);
4302 break;
4303 }
4304 counter++;
4305 }
4306 }
4307 break;
4308 default:
4309 gen_reserved_instruction(ctx);
4310 break;
4311 }
4312 }
4313 break;
4314 case NM_MOVE_BALC:
4315 check_nms(ctx);
4316 {
4317 TCGv t0 = tcg_temp_new();
4318 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
4319 extract32(ctx->opcode, 1, 20) << 1;
4320 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
4321 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
4322 extract32(ctx->opcode, 21, 3));
4323 gen_load_gpr(t0, rt);
4324 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4325 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
4326 }
4327 break;
4328 case NM_P_BAL:
4329 {
4330 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
4331 extract32(ctx->opcode, 1, 24) << 1;
4332
4333 if ((extract32(ctx->opcode, 25, 1)) == 0) {
4334 /* BC */
4335 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
4336 } else {
4337 /* BALC */
4338 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
4339 }
4340 }
4341 break;
4342 case NM_P_J:
4343 switch (extract32(ctx->opcode, 12, 4)) {
4344 case NM_JALRC:
4345 case NM_JALRC_HB:
4346 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
4347 break;
4348 case NM_P_BALRSC:
4349 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
4350 break;
4351 default:
4352 gen_reserved_instruction(ctx);
4353 break;
4354 }
4355 break;
4356 case NM_P_BR1:
4357 {
4358 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
4359 extract32(ctx->opcode, 1, 13) << 1;
4360 switch (extract32(ctx->opcode, 14, 2)) {
4361 case NM_BEQC:
4362 check_nms(ctx);
4363 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
4364 break;
4365 case NM_P_BR3A:
4366 s = sextract32(ctx->opcode, 0, 1) << 14 |
4367 extract32(ctx->opcode, 1, 13) << 1;
4368 switch (extract32(ctx->opcode, 16, 5)) {
4369 case NM_BC1EQZC:
4370 check_cp1_enabled(ctx);
4371 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
4372 break;
4373 case NM_BC1NEZC:
4374 check_cp1_enabled(ctx);
4375 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
4376 break;
4377 case NM_BPOSGE32C:
4378 check_dsp_r3(ctx);
4379 {
4380 imm = extract32(ctx->opcode, 1, 13)
4381 | extract32(ctx->opcode, 0, 1) << 13;
4382
4383 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
4384 imm << 1);
4385 }
4386 break;
4387 default:
4388 gen_reserved_instruction(ctx);
4389 break;
4390 }
4391 break;
4392 case NM_BGEC:
4393 if (rs == rt) {
4394 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
4395 } else {
4396 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
4397 }
4398 break;
4399 case NM_BGEUC:
4400 if (rs == rt || rt == 0) {
4401 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
4402 } else if (rs == 0) {
4403 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
4404 } else {
4405 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
4406 }
4407 break;
4408 }
4409 }
4410 break;
4411 case NM_P_BR2:
4412 {
4413 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
4414 extract32(ctx->opcode, 1, 13) << 1;
4415 switch (extract32(ctx->opcode, 14, 2)) {
4416 case NM_BNEC:
4417 check_nms(ctx);
4418 if (rs == rt) {
4419 /* NOP */
4420 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
4421 } else {
4422 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
4423 }
4424 break;
4425 case NM_BLTC:
4426 if (rs != 0 && rt != 0 && rs == rt) {
4427 /* NOP */
4428 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
4429 } else {
4430 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
4431 }
4432 break;
4433 case NM_BLTUC:
4434 if (rs == 0 || rs == rt) {
4435 /* NOP */
4436 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
4437 } else {
4438 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
4439 }
4440 break;
4441 default:
4442 gen_reserved_instruction(ctx);
4443 break;
4444 }
4445 }
4446 break;
4447 case NM_P_BRI:
4448 {
4449 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
4450 extract32(ctx->opcode, 1, 10) << 1;
4451 uint32_t u = extract32(ctx->opcode, 11, 7);
4452
4453 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
4454 rt, u, s);
4455 }
4456 break;
4457 default:
4458 gen_reserved_instruction(ctx);
4459 break;
4460 }
4461 return 4;
4462 }
4463
4464 static int decode_isa_nanomips(CPUMIPSState *env, DisasContext *ctx)
4465 {
4466 uint32_t op;
4467 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
4468 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
4469 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
4470 int offset;
4471 int imm;
4472
4473 /* make sure instructions are on a halfword boundary */
4474 if (ctx->base.pc_next & 0x1) {
4475 TCGv tmp = tcg_constant_tl(ctx->base.pc_next);
4476 tcg_gen_st_tl(tmp, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4477 generate_exception_end(ctx, EXCP_AdEL);
4478 return 2;
4479 }
4480
4481 op = extract32(ctx->opcode, 10, 6);
4482 switch (op) {
4483 case NM_P16_MV:
4484 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
4485 if (rt != 0) {
4486 /* MOVE */
4487 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
4488 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
4489 } else {
4490 /* P16.RI */
4491 switch (extract32(ctx->opcode, 3, 2)) {
4492 case NM_P16_SYSCALL:
4493 if (extract32(ctx->opcode, 2, 1) == 0) {
4494 generate_exception_end(ctx, EXCP_SYSCALL);
4495 } else {
4496 gen_reserved_instruction(ctx);
4497 }
4498 break;
4499 case NM_BREAK16:
4500 generate_exception_end(ctx, EXCP_BREAK);
4501 break;
4502 case NM_SDBBP16:
4503 if (is_uhi(ctx, extract32(ctx->opcode, 0, 3))) {
4504 ctx->base.is_jmp = DISAS_SEMIHOST;
4505 } else {
4506 if (ctx->hflags & MIPS_HFLAG_SBRI) {
4507 gen_reserved_instruction(ctx);
4508 } else {
4509 generate_exception_end(ctx, EXCP_DBp);
4510 }
4511 }
4512 break;
4513 default:
4514 gen_reserved_instruction(ctx);
4515 break;
4516 }
4517 }
4518 break;
4519 case NM_P16_SHIFT:
4520 {
4521 int shift = extract32(ctx->opcode, 0, 3);
4522 uint32_t opc = 0;
4523 shift = (shift == 0) ? 8 : shift;
4524
4525 switch (extract32(ctx->opcode, 3, 1)) {
4526 case NM_SLL16:
4527 opc = OPC_SLL;
4528 break;
4529 case NM_SRL16:
4530 opc = OPC_SRL;
4531 break;
4532 }
4533 gen_shift_imm(ctx, opc, rt, rs, shift);
4534 }
4535 break;
4536 case NM_P16C:
4537 switch (ctx->opcode & 1) {
4538 case NM_POOL16C_0:
4539 gen_pool16c_nanomips_insn(ctx);
4540 break;
4541 case NM_LWXS16:
4542 gen_ldxs(ctx, rt, rs, rd);
4543 break;
4544 }
4545 break;
4546 case NM_P16_A1:
4547 switch (extract32(ctx->opcode, 6, 1)) {
4548 case NM_ADDIUR1SP:
4549 imm = extract32(ctx->opcode, 0, 6) << 2;
4550 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
4551 break;
4552 default:
4553 gen_reserved_instruction(ctx);
4554 break;
4555 }
4556 break;
4557 case NM_P16_A2:
4558 switch (extract32(ctx->opcode, 3, 1)) {
4559 case NM_ADDIUR2:
4560 imm = extract32(ctx->opcode, 0, 3) << 2;
4561 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
4562 break;
4563 case NM_P_ADDIURS5:
4564 rt = extract32(ctx->opcode, 5, 5);
4565 if (rt != 0) {
4566 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
4567 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
4568 (extract32(ctx->opcode, 0, 3));
4569 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
4570 }
4571 break;
4572 }
4573 break;
4574 case NM_P16_ADDU:
4575 switch (ctx->opcode & 0x1) {
4576 case NM_ADDU16:
4577 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
4578 break;
4579 case NM_SUBU16:
4580 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
4581 break;
4582 }
4583 break;
4584 case NM_P16_4X4:
4585 rt = (extract32(ctx->opcode, 9, 1) << 3) |
4586 extract32(ctx->opcode, 5, 3);
4587 rs = (extract32(ctx->opcode, 4, 1) << 3) |
4588 extract32(ctx->opcode, 0, 3);
4589 rt = decode_gpr_gpr4(rt);
4590 rs = decode_gpr_gpr4(rs);
4591 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
4592 (extract32(ctx->opcode, 3, 1))) {
4593 case NM_ADDU4X4:
4594 check_nms(ctx);
4595 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
4596 break;
4597 case NM_MUL4X4:
4598 check_nms(ctx);
4599 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
4600 break;
4601 default:
4602 gen_reserved_instruction(ctx);
4603 break;
4604 }
4605 break;
4606 case NM_LI16:
4607 {
4608 imm = extract32(ctx->opcode, 0, 7);
4609 imm = (imm == 0x7f ? -1 : imm);
4610 if (rt != 0) {
4611 tcg_gen_movi_tl(cpu_gpr[rt], imm);
4612 }
4613 }
4614 break;
4615 case NM_ANDI16:
4616 {
4617 uint32_t u = extract32(ctx->opcode, 0, 4);
4618 u = (u == 12) ? 0xff :
4619 (u == 13) ? 0xffff : u;
4620 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
4621 }
4622 break;
4623 case NM_P16_LB:
4624 offset = extract32(ctx->opcode, 0, 2);
4625 switch (extract32(ctx->opcode, 2, 2)) {
4626 case NM_LB16:
4627 gen_ld(ctx, OPC_LB, rt, rs, offset);
4628 break;
4629 case NM_SB16:
4630 rt = decode_gpr_gpr3_src_store(
4631 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4632 gen_st(ctx, OPC_SB, rt, rs, offset);
4633 break;
4634 case NM_LBU16:
4635 gen_ld(ctx, OPC_LBU, rt, rs, offset);
4636 break;
4637 default:
4638 gen_reserved_instruction(ctx);
4639 break;
4640 }
4641 break;
4642 case NM_P16_LH:
4643 offset = extract32(ctx->opcode, 1, 2) << 1;
4644 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
4645 case NM_LH16:
4646 gen_ld(ctx, OPC_LH, rt, rs, offset);
4647 break;
4648 case NM_SH16:
4649 rt = decode_gpr_gpr3_src_store(
4650 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4651 gen_st(ctx, OPC_SH, rt, rs, offset);
4652 break;
4653 case NM_LHU16:
4654 gen_ld(ctx, OPC_LHU, rt, rs, offset);
4655 break;
4656 default:
4657 gen_reserved_instruction(ctx);
4658 break;
4659 }
4660 break;
4661 case NM_LW16:
4662 offset = extract32(ctx->opcode, 0, 4) << 2;
4663 gen_ld(ctx, OPC_LW, rt, rs, offset);
4664 break;
4665 case NM_LWSP16:
4666 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
4667 offset = extract32(ctx->opcode, 0, 5) << 2;
4668 gen_ld(ctx, OPC_LW, rt, 29, offset);
4669 break;
4670 case NM_LW4X4:
4671 check_nms(ctx);
4672 rt = (extract32(ctx->opcode, 9, 1) << 3) |
4673 extract32(ctx->opcode, 5, 3);
4674 rs = (extract32(ctx->opcode, 4, 1) << 3) |
4675 extract32(ctx->opcode, 0, 3);
4676 offset = (extract32(ctx->opcode, 3, 1) << 3) |
4677 (extract32(ctx->opcode, 8, 1) << 2);
4678 rt = decode_gpr_gpr4(rt);
4679 rs = decode_gpr_gpr4(rs);
4680 gen_ld(ctx, OPC_LW, rt, rs, offset);
4681 break;
4682 case NM_SW4X4:
4683 check_nms(ctx);
4684 rt = (extract32(ctx->opcode, 9, 1) << 3) |
4685 extract32(ctx->opcode, 5, 3);
4686 rs = (extract32(ctx->opcode, 4, 1) << 3) |
4687 extract32(ctx->opcode, 0, 3);
4688 offset = (extract32(ctx->opcode, 3, 1) << 3) |
4689 (extract32(ctx->opcode, 8, 1) << 2);
4690 rt = decode_gpr_gpr4_zero(rt);
4691 rs = decode_gpr_gpr4(rs);
4692 gen_st(ctx, OPC_SW, rt, rs, offset);
4693 break;
4694 case NM_LWGP16:
4695 offset = extract32(ctx->opcode, 0, 7) << 2;
4696 gen_ld(ctx, OPC_LW, rt, 28, offset);
4697 break;
4698 case NM_SWSP16:
4699 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
4700 offset = extract32(ctx->opcode, 0, 5) << 2;
4701 gen_st(ctx, OPC_SW, rt, 29, offset);
4702 break;
4703 case NM_SW16:
4704 rt = decode_gpr_gpr3_src_store(
4705 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4706 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
4707 offset = extract32(ctx->opcode, 0, 4) << 2;
4708 gen_st(ctx, OPC_SW, rt, rs, offset);
4709 break;
4710 case NM_SWGP16:
4711 rt = decode_gpr_gpr3_src_store(
4712 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4713 offset = extract32(ctx->opcode, 0, 7) << 2;
4714 gen_st(ctx, OPC_SW, rt, 28, offset);
4715 break;
4716 case NM_BC16:
4717 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
4718 (sextract32(ctx->opcode, 0, 1) << 10) |
4719 (extract32(ctx->opcode, 1, 9) << 1));
4720 break;
4721 case NM_BALC16:
4722 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
4723 (sextract32(ctx->opcode, 0, 1) << 10) |
4724 (extract32(ctx->opcode, 1, 9) << 1));
4725 break;
4726 case NM_BEQZC16:
4727 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
4728 (sextract32(ctx->opcode, 0, 1) << 7) |
4729 (extract32(ctx->opcode, 1, 6) << 1));
4730 break;
4731 case NM_BNEZC16:
4732 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
4733 (sextract32(ctx->opcode, 0, 1) << 7) |
4734 (extract32(ctx->opcode, 1, 6) << 1));
4735 break;
4736 case NM_P16_BR:
4737 switch (ctx->opcode & 0xf) {
4738 case 0:
4739 /* P16.JRC */
4740 switch (extract32(ctx->opcode, 4, 1)) {
4741 case NM_JRC:
4742 gen_compute_branch_nm(ctx, OPC_JR, 2,
4743 extract32(ctx->opcode, 5, 5), 0, 0);
4744 break;
4745 case NM_JALRC16:
4746 gen_compute_branch_nm(ctx, OPC_JALR, 2,
4747 extract32(ctx->opcode, 5, 5), 31, 0);
4748 break;
4749 }
4750 break;
4751 default:
4752 {
4753 /* P16.BRI */
4754 uint32_t opc = extract32(ctx->opcode, 4, 3) <
4755 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
4756 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
4757 extract32(ctx->opcode, 0, 4) << 1);
4758 }
4759 break;
4760 }
4761 break;
4762 case NM_P16_SR:
4763 {
4764 int count = extract32(ctx->opcode, 0, 4);
4765 int u = extract32(ctx->opcode, 4, 4) << 4;
4766
4767 rt = 30 + extract32(ctx->opcode, 9, 1);
4768 switch (extract32(ctx->opcode, 8, 1)) {
4769 case NM_SAVE16:
4770 gen_save(ctx, rt, count, 0, u);
4771 break;
4772 case NM_RESTORE_JRC16:
4773 gen_restore(ctx, rt, count, 0, u);
4774 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
4775 break;
4776 }
4777 }
4778 break;
4779 case NM_MOVEP:
4780 case NM_MOVEPREV:
4781 check_nms(ctx);
4782 {
4783 static const int gpr2reg1[] = {4, 5, 6, 7};
4784 static const int gpr2reg2[] = {5, 6, 7, 8};
4785 int re;
4786 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
4787 extract32(ctx->opcode, 8, 1);
4788 int r1 = gpr2reg1[rd2];
4789 int r2 = gpr2reg2[rd2];
4790 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
4791 extract32(ctx->opcode, 0, 3);
4792 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
4793 extract32(ctx->opcode, 5, 3);
4794 TCGv t0 = tcg_temp_new();
4795 TCGv t1 = tcg_temp_new();
4796 if (op == NM_MOVEP) {
4797 rd = r1;
4798 re = r2;
4799 rs = decode_gpr_gpr4_zero(r3);
4800 rt = decode_gpr_gpr4_zero(r4);
4801 } else {
4802 rd = decode_gpr_gpr4(r3);
4803 re = decode_gpr_gpr4(r4);
4804 rs = r1;
4805 rt = r2;
4806 }
4807 gen_load_gpr(t0, rs);
4808 gen_load_gpr(t1, rt);
4809 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4810 tcg_gen_mov_tl(cpu_gpr[re], t1);
4811 }
4812 break;
4813 default:
4814 return decode_nanomips_32_48_opc(env, ctx);
4815 }
4816
4817 return 2;
4818 }