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