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