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