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