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