cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

nanomips_translate.c.inc (145991B)


      1/*
      2 *  MIPS emulation for QEMU - nanoMIPS translation routines
      3 *
      4 *  Copyright (c) 2004-2005 Jocelyn Mayer
      5 *  Copyright (c) 2006 Marius Groeger (FPU operations)
      6 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
      7 *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
      8 *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
      9 *
     10 * SPDX-License-Identifier: LGPL-2.1-or-later
     11 */
     12
     13/* MAJOR, P16, and P32 pools opcodes */
     14enum {
     15    NM_P_ADDIU      = 0x00,
     16    NM_ADDIUPC      = 0x01,
     17    NM_MOVE_BALC    = 0x02,
     18    NM_P16_MV       = 0x04,
     19    NM_LW16         = 0x05,
     20    NM_BC16         = 0x06,
     21    NM_P16_SR       = 0x07,
     22
     23    NM_POOL32A      = 0x08,
     24    NM_P_BAL        = 0x0a,
     25    NM_P16_SHIFT    = 0x0c,
     26    NM_LWSP16       = 0x0d,
     27    NM_BALC16       = 0x0e,
     28    NM_P16_4X4      = 0x0f,
     29
     30    NM_P_GP_W       = 0x10,
     31    NM_P_GP_BH      = 0x11,
     32    NM_P_J          = 0x12,
     33    NM_P16C         = 0x14,
     34    NM_LWGP16       = 0x15,
     35    NM_P16_LB       = 0x17,
     36
     37    NM_P48I         = 0x18,
     38    NM_P16_A1       = 0x1c,
     39    NM_LW4X4        = 0x1d,
     40    NM_P16_LH       = 0x1f,
     41
     42    NM_P_U12        = 0x20,
     43    NM_P_LS_U12     = 0x21,
     44    NM_P_BR1        = 0x22,
     45    NM_P16_A2       = 0x24,
     46    NM_SW16         = 0x25,
     47    NM_BEQZC16      = 0x26,
     48
     49    NM_POOL32F      = 0x28,
     50    NM_P_LS_S9      = 0x29,
     51    NM_P_BR2        = 0x2a,
     52
     53    NM_P16_ADDU     = 0x2c,
     54    NM_SWSP16       = 0x2d,
     55    NM_BNEZC16      = 0x2e,
     56    NM_MOVEP        = 0x2f,
     57
     58    NM_POOL32S      = 0x30,
     59    NM_P_BRI        = 0x32,
     60    NM_LI16         = 0x34,
     61    NM_SWGP16       = 0x35,
     62    NM_P16_BR       = 0x36,
     63
     64    NM_P_LUI        = 0x38,
     65    NM_ANDI16       = 0x3c,
     66    NM_SW4X4        = 0x3d,
     67    NM_MOVEPREV     = 0x3f,
     68};
     69
     70/* POOL32A instruction pool */
     71enum {
     72    NM_POOL32A0    = 0x00,
     73    NM_SPECIAL2    = 0x01,
     74    NM_COP2_1      = 0x02,
     75    NM_UDI         = 0x03,
     76    NM_POOL32A5    = 0x05,
     77    NM_POOL32A7    = 0x07,
     78};
     79
     80/* P.GP.W instruction pool */
     81enum {
     82    NM_ADDIUGP_W = 0x00,
     83    NM_LWGP      = 0x02,
     84    NM_SWGP      = 0x03,
     85};
     86
     87/* P48I instruction pool */
     88enum {
     89    NM_LI48        = 0x00,
     90    NM_ADDIU48     = 0x01,
     91    NM_ADDIUGP48   = 0x02,
     92    NM_ADDIUPC48   = 0x03,
     93    NM_LWPC48      = 0x0b,
     94    NM_SWPC48      = 0x0f,
     95};
     96
     97/* P.U12 instruction pool */
     98enum {
     99    NM_ORI      = 0x00,
    100    NM_XORI     = 0x01,
    101    NM_ANDI     = 0x02,
    102    NM_P_SR     = 0x03,
    103    NM_SLTI     = 0x04,
    104    NM_SLTIU    = 0x05,
    105    NM_SEQI     = 0x06,
    106    NM_ADDIUNEG = 0x08,
    107    NM_P_SHIFT  = 0x0c,
    108    NM_P_ROTX   = 0x0d,
    109    NM_P_INS    = 0x0e,
    110    NM_P_EXT    = 0x0f,
    111};
    112
    113/* POOL32F instruction pool */
    114enum {
    115    NM_POOL32F_0   = 0x00,
    116    NM_POOL32F_3   = 0x03,
    117    NM_POOL32F_5   = 0x05,
    118};
    119
    120/* POOL32S instruction pool */
    121enum {
    122    NM_POOL32S_0   = 0x00,
    123    NM_POOL32S_4   = 0x04,
    124};
    125
    126/* P.LUI instruction pool */
    127enum {
    128    NM_LUI      = 0x00,
    129    NM_ALUIPC   = 0x01,
    130};
    131
    132/* P.GP.BH instruction pool */
    133enum {
    134    NM_LBGP      = 0x00,
    135    NM_SBGP      = 0x01,
    136    NM_LBUGP     = 0x02,
    137    NM_ADDIUGP_B = 0x03,
    138    NM_P_GP_LH   = 0x04,
    139    NM_P_GP_SH   = 0x05,
    140    NM_P_GP_CP1  = 0x06,
    141};
    142
    143/* P.LS.U12 instruction pool */
    144enum {
    145    NM_LB        = 0x00,
    146    NM_SB        = 0x01,
    147    NM_LBU       = 0x02,
    148    NM_P_PREFU12 = 0x03,
    149    NM_LH        = 0x04,
    150    NM_SH        = 0x05,
    151    NM_LHU       = 0x06,
    152    NM_LWU       = 0x07,
    153    NM_LW        = 0x08,
    154    NM_SW        = 0x09,
    155    NM_LWC1      = 0x0a,
    156    NM_SWC1      = 0x0b,
    157    NM_LDC1      = 0x0e,
    158    NM_SDC1      = 0x0f,
    159};
    160
    161/* P.LS.S9 instruction pool */
    162enum {
    163    NM_P_LS_S0         = 0x00,
    164    NM_P_LS_S1         = 0x01,
    165    NM_P_LS_E0         = 0x02,
    166    NM_P_LS_WM         = 0x04,
    167    NM_P_LS_UAWM       = 0x05,
    168};
    169
    170/* P.BAL instruction pool */
    171enum {
    172    NM_BC       = 0x00,
    173    NM_BALC     = 0x01,
    174};
    175
    176/* P.J instruction pool */
    177enum {
    178    NM_JALRC    = 0x00,
    179    NM_JALRC_HB = 0x01,
    180    NM_P_BALRSC = 0x08,
    181};
    182
    183/* P.BR1 instruction pool */
    184enum {
    185    NM_BEQC     = 0x00,
    186    NM_P_BR3A   = 0x01,
    187    NM_BGEC     = 0x02,
    188    NM_BGEUC    = 0x03,
    189};
    190
    191/* P.BR2 instruction pool */
    192enum {
    193    NM_BNEC     = 0x00,
    194    NM_BLTC     = 0x02,
    195    NM_BLTUC    = 0x03,
    196};
    197
    198/* P.BRI instruction pool */
    199enum {
    200    NM_BEQIC    = 0x00,
    201    NM_BBEQZC   = 0x01,
    202    NM_BGEIC    = 0x02,
    203    NM_BGEIUC   = 0x03,
    204    NM_BNEIC    = 0x04,
    205    NM_BBNEZC   = 0x05,
    206    NM_BLTIC    = 0x06,
    207    NM_BLTIUC   = 0x07,
    208};
    209
    210/* P16.SHIFT instruction pool */
    211enum {
    212    NM_SLL16    = 0x00,
    213    NM_SRL16    = 0x01,
    214};
    215
    216/* POOL16C instruction pool */
    217enum {
    218    NM_POOL16C_0  = 0x00,
    219    NM_LWXS16     = 0x01,
    220};
    221
    222/* P16.A1 instruction pool */
    223enum {
    224    NM_ADDIUR1SP = 0x01,
    225};
    226
    227/* P16.A2 instruction pool */
    228enum {
    229    NM_ADDIUR2  = 0x00,
    230    NM_P_ADDIURS5  = 0x01,
    231};
    232
    233/* P16.ADDU instruction pool */
    234enum {
    235    NM_ADDU16     = 0x00,
    236    NM_SUBU16     = 0x01,
    237};
    238
    239/* P16.SR instruction pool */
    240enum {
    241    NM_SAVE16        = 0x00,
    242    NM_RESTORE_JRC16 = 0x01,
    243};
    244
    245/* P16.4X4 instruction pool */
    246enum {
    247    NM_ADDU4X4      = 0x00,
    248    NM_MUL4X4       = 0x01,
    249};
    250
    251/* P16.LB instruction pool */
    252enum {
    253    NM_LB16       = 0x00,
    254    NM_SB16       = 0x01,
    255    NM_LBU16      = 0x02,
    256};
    257
    258/* P16.LH  instruction pool */
    259enum {
    260    NM_LH16     = 0x00,
    261    NM_SH16     = 0x01,
    262    NM_LHU16    = 0x02,
    263};
    264
    265/* P.RI instruction pool */
    266enum {
    267    NM_SIGRIE       = 0x00,
    268    NM_P_SYSCALL    = 0x01,
    269    NM_BREAK        = 0x02,
    270    NM_SDBBP        = 0x03,
    271};
    272
    273/* POOL32A0 instruction pool */
    274enum {
    275    NM_P_TRAP   = 0x00,
    276    NM_SEB      = 0x01,
    277    NM_SLLV     = 0x02,
    278    NM_MUL      = 0x03,
    279    NM_MFC0     = 0x06,
    280    NM_MFHC0    = 0x07,
    281    NM_SEH      = 0x09,
    282    NM_SRLV     = 0x0a,
    283    NM_MUH      = 0x0b,
    284    NM_MTC0     = 0x0e,
    285    NM_MTHC0    = 0x0f,
    286    NM_SRAV     = 0x12,
    287    NM_MULU     = 0x13,
    288    NM_ROTRV    = 0x1a,
    289    NM_MUHU     = 0x1b,
    290    NM_ADD      = 0x22,
    291    NM_DIV      = 0x23,
    292    NM_ADDU     = 0x2a,
    293    NM_MOD      = 0x2b,
    294    NM_SUB      = 0x32,
    295    NM_DIVU     = 0x33,
    296    NM_RDHWR    = 0x38,
    297    NM_SUBU     = 0x3a,
    298    NM_MODU     = 0x3b,
    299    NM_P_CMOVE  = 0x42,
    300    NM_FORK     = 0x45,
    301    NM_MFTR     = 0x46,
    302    NM_MFHTR    = 0x47,
    303    NM_AND      = 0x4a,
    304    NM_YIELD    = 0x4d,
    305    NM_MTTR     = 0x4e,
    306    NM_MTHTR    = 0x4f,
    307    NM_OR       = 0x52,
    308    NM_D_E_MT_VPE = 0x56,
    309    NM_NOR      = 0x5a,
    310    NM_XOR      = 0x62,
    311    NM_SLT      = 0x6a,
    312    NM_P_SLTU   = 0x72,
    313    NM_SOV      = 0x7a,
    314};
    315
    316/* CRC32 instruction pool */
    317enum {
    318    NM_CRC32B   = 0x00,
    319    NM_CRC32H   = 0x01,
    320    NM_CRC32W   = 0x02,
    321    NM_CRC32CB  = 0x04,
    322    NM_CRC32CH  = 0x05,
    323    NM_CRC32CW  = 0x06,
    324};
    325
    326/* POOL32A5 instruction pool */
    327enum {
    328    NM_CMP_EQ_PH        = 0x00,
    329    NM_CMP_LT_PH        = 0x08,
    330    NM_CMP_LE_PH        = 0x10,
    331    NM_CMPGU_EQ_QB      = 0x18,
    332    NM_CMPGU_LT_QB      = 0x20,
    333    NM_CMPGU_LE_QB      = 0x28,
    334    NM_CMPGDU_EQ_QB     = 0x30,
    335    NM_CMPGDU_LT_QB     = 0x38,
    336    NM_CMPGDU_LE_QB     = 0x40,
    337    NM_CMPU_EQ_QB       = 0x48,
    338    NM_CMPU_LT_QB       = 0x50,
    339    NM_CMPU_LE_QB       = 0x58,
    340    NM_ADDQ_S_W         = 0x60,
    341    NM_SUBQ_S_W         = 0x68,
    342    NM_ADDSC            = 0x70,
    343    NM_ADDWC            = 0x78,
    344
    345    NM_ADDQ_S_PH   = 0x01,
    346    NM_ADDQH_R_PH  = 0x09,
    347    NM_ADDQH_R_W   = 0x11,
    348    NM_ADDU_S_QB   = 0x19,
    349    NM_ADDU_S_PH   = 0x21,
    350    NM_ADDUH_R_QB  = 0x29,
    351    NM_SHRAV_R_PH  = 0x31,
    352    NM_SHRAV_R_QB  = 0x39,
    353    NM_SUBQ_S_PH   = 0x41,
    354    NM_SUBQH_R_PH  = 0x49,
    355    NM_SUBQH_R_W   = 0x51,
    356    NM_SUBU_S_QB   = 0x59,
    357    NM_SUBU_S_PH   = 0x61,
    358    NM_SUBUH_R_QB  = 0x69,
    359    NM_SHLLV_S_PH  = 0x71,
    360    NM_PRECR_SRA_R_PH_W = 0x79,
    361
    362    NM_MULEU_S_PH_QBL   = 0x12,
    363    NM_MULEU_S_PH_QBR   = 0x1a,
    364    NM_MULQ_RS_PH       = 0x22,
    365    NM_MULQ_S_PH        = 0x2a,
    366    NM_MULQ_RS_W        = 0x32,
    367    NM_MULQ_S_W         = 0x3a,
    368    NM_APPEND           = 0x42,
    369    NM_MODSUB           = 0x52,
    370    NM_SHRAV_R_W        = 0x5a,
    371    NM_SHRLV_PH         = 0x62,
    372    NM_SHRLV_QB         = 0x6a,
    373    NM_SHLLV_QB         = 0x72,
    374    NM_SHLLV_S_W        = 0x7a,
    375
    376    NM_SHILO            = 0x03,
    377
    378    NM_MULEQ_S_W_PHL    = 0x04,
    379    NM_MULEQ_S_W_PHR    = 0x0c,
    380
    381    NM_MUL_S_PH         = 0x05,
    382    NM_PRECR_QB_PH      = 0x0d,
    383    NM_PRECRQ_QB_PH     = 0x15,
    384    NM_PRECRQ_PH_W      = 0x1d,
    385    NM_PRECRQ_RS_PH_W   = 0x25,
    386    NM_PRECRQU_S_QB_PH  = 0x2d,
    387    NM_PACKRL_PH        = 0x35,
    388    NM_PICK_QB          = 0x3d,
    389    NM_PICK_PH          = 0x45,
    390
    391    NM_SHRA_R_W         = 0x5e,
    392    NM_SHRA_R_PH        = 0x66,
    393    NM_SHLL_S_PH        = 0x76,
    394    NM_SHLL_S_W         = 0x7e,
    395
    396    NM_REPL_PH          = 0x07
    397};
    398
    399/* POOL32A7 instruction pool */
    400enum {
    401    NM_P_LSX        = 0x00,
    402    NM_LSA          = 0x01,
    403    NM_EXTW         = 0x03,
    404    NM_POOL32AXF    = 0x07,
    405};
    406
    407/* P.SR instruction pool */
    408enum {
    409    NM_PP_SR           = 0x00,
    410    NM_P_SR_F          = 0x01,
    411};
    412
    413/* P.SHIFT instruction pool */
    414enum {
    415    NM_P_SLL        = 0x00,
    416    NM_SRL          = 0x02,
    417    NM_SRA          = 0x04,
    418    NM_ROTR         = 0x06,
    419};
    420
    421/* P.ROTX instruction pool */
    422enum {
    423    NM_ROTX         = 0x00,
    424};
    425
    426/* P.INS instruction pool */
    427enum {
    428    NM_INS          = 0x00,
    429};
    430
    431/* P.EXT instruction pool */
    432enum {
    433    NM_EXT          = 0x00,
    434};
    435
    436/* POOL32F_0 (fmt) instruction pool */
    437enum {
    438    NM_RINT_S              = 0x04,
    439    NM_RINT_D              = 0x44,
    440    NM_ADD_S               = 0x06,
    441    NM_SELEQZ_S            = 0x07,
    442    NM_SELEQZ_D            = 0x47,
    443    NM_CLASS_S             = 0x0c,
    444    NM_CLASS_D             = 0x4c,
    445    NM_SUB_S               = 0x0e,
    446    NM_SELNEZ_S            = 0x0f,
    447    NM_SELNEZ_D            = 0x4f,
    448    NM_MUL_S               = 0x16,
    449    NM_SEL_S               = 0x17,
    450    NM_SEL_D               = 0x57,
    451    NM_DIV_S               = 0x1e,
    452    NM_ADD_D               = 0x26,
    453    NM_SUB_D               = 0x2e,
    454    NM_MUL_D               = 0x36,
    455    NM_MADDF_S             = 0x37,
    456    NM_MADDF_D             = 0x77,
    457    NM_DIV_D               = 0x3e,
    458    NM_MSUBF_S             = 0x3f,
    459    NM_MSUBF_D             = 0x7f,
    460};
    461
    462/* POOL32F_3  instruction pool */
    463enum {
    464    NM_MIN_FMT         = 0x00,
    465    NM_MAX_FMT         = 0x01,
    466    NM_MINA_FMT        = 0x04,
    467    NM_MAXA_FMT        = 0x05,
    468    NM_POOL32FXF       = 0x07,
    469};
    470
    471/* POOL32F_5  instruction pool */
    472enum {
    473    NM_CMP_CONDN_S     = 0x00,
    474    NM_CMP_CONDN_D     = 0x02,
    475};
    476
    477/* P.GP.LH instruction pool */
    478enum {
    479    NM_LHGP    = 0x00,
    480    NM_LHUGP   = 0x01,
    481};
    482
    483/* P.GP.SH instruction pool */
    484enum {
    485    NM_SHGP    = 0x00,
    486};
    487
    488/* P.GP.CP1 instruction pool */
    489enum {
    490    NM_LWC1GP       = 0x00,
    491    NM_SWC1GP       = 0x01,
    492    NM_LDC1GP       = 0x02,
    493    NM_SDC1GP       = 0x03,
    494};
    495
    496/* P.LS.S0 instruction pool */
    497enum {
    498    NM_LBS9     = 0x00,
    499    NM_LHS9     = 0x04,
    500    NM_LWS9     = 0x08,
    501    NM_LDS9     = 0x0c,
    502
    503    NM_SBS9     = 0x01,
    504    NM_SHS9     = 0x05,
    505    NM_SWS9     = 0x09,
    506    NM_SDS9     = 0x0d,
    507
    508    NM_LBUS9    = 0x02,
    509    NM_LHUS9    = 0x06,
    510    NM_LWC1S9   = 0x0a,
    511    NM_LDC1S9   = 0x0e,
    512
    513    NM_P_PREFS9 = 0x03,
    514    NM_LWUS9    = 0x07,
    515    NM_SWC1S9   = 0x0b,
    516    NM_SDC1S9   = 0x0f,
    517};
    518
    519/* P.LS.S1 instruction pool */
    520enum {
    521    NM_ASET_ACLR = 0x02,
    522    NM_UALH      = 0x04,
    523    NM_UASH      = 0x05,
    524    NM_CACHE     = 0x07,
    525    NM_P_LL      = 0x0a,
    526    NM_P_SC      = 0x0b,
    527};
    528
    529/* P.LS.E0 instruction pool */
    530enum {
    531    NM_LBE      = 0x00,
    532    NM_SBE      = 0x01,
    533    NM_LBUE     = 0x02,
    534    NM_P_PREFE  = 0x03,
    535    NM_LHE      = 0x04,
    536    NM_SHE      = 0x05,
    537    NM_LHUE     = 0x06,
    538    NM_CACHEE   = 0x07,
    539    NM_LWE      = 0x08,
    540    NM_SWE      = 0x09,
    541    NM_P_LLE    = 0x0a,
    542    NM_P_SCE    = 0x0b,
    543};
    544
    545/* P.PREFE instruction pool */
    546enum {
    547    NM_SYNCIE   = 0x00,
    548    NM_PREFE    = 0x01,
    549};
    550
    551/* P.LLE instruction pool */
    552enum {
    553    NM_LLE      = 0x00,
    554    NM_LLWPE    = 0x01,
    555};
    556
    557/* P.SCE instruction pool */
    558enum {
    559    NM_SCE      = 0x00,
    560    NM_SCWPE    = 0x01,
    561};
    562
    563/* P.LS.WM instruction pool */
    564enum {
    565    NM_LWM       = 0x00,
    566    NM_SWM       = 0x01,
    567};
    568
    569/* P.LS.UAWM instruction pool */
    570enum {
    571    NM_UALWM       = 0x00,
    572    NM_UASWM       = 0x01,
    573};
    574
    575/* P.BR3A instruction pool */
    576enum {
    577    NM_BC1EQZC          = 0x00,
    578    NM_BC1NEZC          = 0x01,
    579    NM_BC2EQZC          = 0x02,
    580    NM_BC2NEZC          = 0x03,
    581    NM_BPOSGE32C        = 0x04,
    582};
    583
    584/* P16.RI instruction pool */
    585enum {
    586    NM_P16_SYSCALL  = 0x01,
    587    NM_BREAK16      = 0x02,
    588    NM_SDBBP16      = 0x03,
    589};
    590
    591/* POOL16C_0 instruction pool */
    592enum {
    593    NM_POOL16C_00      = 0x00,
    594};
    595
    596/* P16.JRC instruction pool */
    597enum {
    598    NM_JRC          = 0x00,
    599    NM_JALRC16      = 0x01,
    600};
    601
    602/* P.SYSCALL instruction pool */
    603enum {
    604    NM_SYSCALL      = 0x00,
    605    NM_HYPCALL      = 0x01,
    606};
    607
    608/* P.TRAP instruction pool */
    609enum {
    610    NM_TEQ          = 0x00,
    611    NM_TNE          = 0x01,
    612};
    613
    614/* P.CMOVE instruction pool */
    615enum {
    616    NM_MOVZ            = 0x00,
    617    NM_MOVN            = 0x01,
    618};
    619
    620/* POOL32Axf instruction pool */
    621enum {
    622    NM_POOL32AXF_1 = 0x01,
    623    NM_POOL32AXF_2 = 0x02,
    624    NM_POOL32AXF_4 = 0x04,
    625    NM_POOL32AXF_5 = 0x05,
    626    NM_POOL32AXF_7 = 0x07,
    627};
    628
    629/* POOL32Axf_1 instruction pool */
    630enum {
    631    NM_POOL32AXF_1_0 = 0x00,
    632    NM_POOL32AXF_1_1 = 0x01,
    633    NM_POOL32AXF_1_3 = 0x03,
    634    NM_POOL32AXF_1_4 = 0x04,
    635    NM_POOL32AXF_1_5 = 0x05,
    636    NM_POOL32AXF_1_7 = 0x07,
    637};
    638
    639/* POOL32Axf_2 instruction pool */
    640enum {
    641    NM_POOL32AXF_2_0_7     = 0x00,
    642    NM_POOL32AXF_2_8_15    = 0x01,
    643    NM_POOL32AXF_2_16_23   = 0x02,
    644    NM_POOL32AXF_2_24_31   = 0x03,
    645};
    646
    647/* POOL32Axf_7 instruction pool */
    648enum {
    649    NM_SHRA_R_QB    = 0x0,
    650    NM_SHRL_PH      = 0x1,
    651    NM_REPL_QB      = 0x2,
    652};
    653
    654/* POOL32Axf_1_0 instruction pool */
    655enum {
    656    NM_MFHI = 0x0,
    657    NM_MFLO = 0x1,
    658    NM_MTHI = 0x2,
    659    NM_MTLO = 0x3,
    660};
    661
    662/* POOL32Axf_1_1 instruction pool */
    663enum {
    664    NM_MTHLIP = 0x0,
    665    NM_SHILOV = 0x1,
    666};
    667
    668/* POOL32Axf_1_3 instruction pool */
    669enum {
    670    NM_RDDSP    = 0x0,
    671    NM_WRDSP    = 0x1,
    672    NM_EXTP     = 0x2,
    673    NM_EXTPDP   = 0x3,
    674};
    675
    676/* POOL32Axf_1_4 instruction pool */
    677enum {
    678    NM_SHLL_QB  = 0x0,
    679    NM_SHRL_QB  = 0x1,
    680};
    681
    682/* POOL32Axf_1_5 instruction pool */
    683enum {
    684    NM_MAQ_S_W_PHR   = 0x0,
    685    NM_MAQ_S_W_PHL   = 0x1,
    686    NM_MAQ_SA_W_PHR  = 0x2,
    687    NM_MAQ_SA_W_PHL  = 0x3,
    688};
    689
    690/* POOL32Axf_1_7 instruction pool */
    691enum {
    692    NM_EXTR_W       = 0x0,
    693    NM_EXTR_R_W     = 0x1,
    694    NM_EXTR_RS_W    = 0x2,
    695    NM_EXTR_S_H     = 0x3,
    696};
    697
    698/* POOL32Axf_2_0_7 instruction pool */
    699enum {
    700    NM_DPA_W_PH     = 0x0,
    701    NM_DPAQ_S_W_PH  = 0x1,
    702    NM_DPS_W_PH     = 0x2,
    703    NM_DPSQ_S_W_PH  = 0x3,
    704    NM_BALIGN       = 0x4,
    705    NM_MADD         = 0x5,
    706    NM_MULT         = 0x6,
    707    NM_EXTRV_W      = 0x7,
    708};
    709
    710/* POOL32Axf_2_8_15 instruction pool */
    711enum {
    712    NM_DPAX_W_PH    = 0x0,
    713    NM_DPAQ_SA_L_W  = 0x1,
    714    NM_DPSX_W_PH    = 0x2,
    715    NM_DPSQ_SA_L_W  = 0x3,
    716    NM_MADDU        = 0x5,
    717    NM_MULTU        = 0x6,
    718    NM_EXTRV_R_W    = 0x7,
    719};
    720
    721/* POOL32Axf_2_16_23 instruction pool */
    722enum {
    723    NM_DPAU_H_QBL       = 0x0,
    724    NM_DPAQX_S_W_PH     = 0x1,
    725    NM_DPSU_H_QBL       = 0x2,
    726    NM_DPSQX_S_W_PH     = 0x3,
    727    NM_EXTPV            = 0x4,
    728    NM_MSUB             = 0x5,
    729    NM_MULSA_W_PH       = 0x6,
    730    NM_EXTRV_RS_W       = 0x7,
    731};
    732
    733/* POOL32Axf_2_24_31 instruction pool */
    734enum {
    735    NM_DPAU_H_QBR       = 0x0,
    736    NM_DPAQX_SA_W_PH    = 0x1,
    737    NM_DPSU_H_QBR       = 0x2,
    738    NM_DPSQX_SA_W_PH    = 0x3,
    739    NM_EXTPDPV          = 0x4,
    740    NM_MSUBU            = 0x5,
    741    NM_MULSAQ_S_W_PH    = 0x6,
    742    NM_EXTRV_S_H        = 0x7,
    743};
    744
    745/* POOL32Axf_{4, 5} instruction pool */
    746enum {
    747    NM_CLO      = 0x25,
    748    NM_CLZ      = 0x2d,
    749
    750    NM_TLBP     = 0x01,
    751    NM_TLBR     = 0x09,
    752    NM_TLBWI    = 0x11,
    753    NM_TLBWR    = 0x19,
    754    NM_TLBINV   = 0x03,
    755    NM_TLBINVF  = 0x0b,
    756    NM_DI       = 0x23,
    757    NM_EI       = 0x2b,
    758    NM_RDPGPR   = 0x70,
    759    NM_WRPGPR   = 0x78,
    760    NM_WAIT     = 0x61,
    761    NM_DERET    = 0x71,
    762    NM_ERETX    = 0x79,
    763
    764    /* nanoMIPS DSP instructions */
    765    NM_ABSQ_S_QB        = 0x00,
    766    NM_ABSQ_S_PH        = 0x08,
    767    NM_ABSQ_S_W         = 0x10,
    768    NM_PRECEQ_W_PHL     = 0x28,
    769    NM_PRECEQ_W_PHR     = 0x30,
    770    NM_PRECEQU_PH_QBL   = 0x38,
    771    NM_PRECEQU_PH_QBR   = 0x48,
    772    NM_PRECEU_PH_QBL    = 0x58,
    773    NM_PRECEU_PH_QBR    = 0x68,
    774    NM_PRECEQU_PH_QBLA  = 0x39,
    775    NM_PRECEQU_PH_QBRA  = 0x49,
    776    NM_PRECEU_PH_QBLA   = 0x59,
    777    NM_PRECEU_PH_QBRA   = 0x69,
    778    NM_REPLV_PH         = 0x01,
    779    NM_REPLV_QB         = 0x09,
    780    NM_BITREV           = 0x18,
    781    NM_INSV             = 0x20,
    782    NM_RADDU_W_QB       = 0x78,
    783
    784    NM_BITSWAP          = 0x05,
    785    NM_WSBH             = 0x3d,
    786};
    787
    788/* PP.SR instruction pool */
    789enum {
    790    NM_SAVE         = 0x00,
    791    NM_RESTORE      = 0x02,
    792    NM_RESTORE_JRC  = 0x03,
    793};
    794
    795/* P.SR.F instruction pool */
    796enum {
    797    NM_SAVEF        = 0x00,
    798    NM_RESTOREF     = 0x01,
    799};
    800
    801/* P16.SYSCALL  instruction pool */
    802enum {
    803    NM_SYSCALL16     = 0x00,
    804    NM_HYPCALL16     = 0x01,
    805};
    806
    807/* POOL16C_00 instruction pool */
    808enum {
    809    NM_NOT16           = 0x00,
    810    NM_XOR16           = 0x01,
    811    NM_AND16           = 0x02,
    812    NM_OR16            = 0x03,
    813};
    814
    815/* PP.LSX and PP.LSXS instruction pool */
    816enum {
    817    NM_LBX      = 0x00,
    818    NM_LHX      = 0x04,
    819    NM_LWX      = 0x08,
    820    NM_LDX      = 0x0c,
    821
    822    NM_SBX      = 0x01,
    823    NM_SHX      = 0x05,
    824    NM_SWX      = 0x09,
    825    NM_SDX      = 0x0d,
    826
    827    NM_LBUX     = 0x02,
    828    NM_LHUX     = 0x06,
    829    NM_LWC1X    = 0x0a,
    830    NM_LDC1X    = 0x0e,
    831
    832    NM_LWUX     = 0x07,
    833    NM_SWC1X    = 0x0b,
    834    NM_SDC1X    = 0x0f,
    835
    836    NM_LHXS     = 0x04,
    837    NM_LWXS     = 0x08,
    838    NM_LDXS     = 0x0c,
    839
    840    NM_SHXS     = 0x05,
    841    NM_SWXS     = 0x09,
    842    NM_SDXS     = 0x0d,
    843
    844    NM_LHUXS    = 0x06,
    845    NM_LWC1XS   = 0x0a,
    846    NM_LDC1XS   = 0x0e,
    847
    848    NM_LWUXS    = 0x07,
    849    NM_SWC1XS   = 0x0b,
    850    NM_SDC1XS   = 0x0f,
    851};
    852
    853/* ERETx instruction pool */
    854enum {
    855    NM_ERET     = 0x00,
    856    NM_ERETNC   = 0x01,
    857};
    858
    859/* POOL32FxF_{0, 1} insturction pool */
    860enum {
    861    NM_CFC1     = 0x40,
    862    NM_CTC1     = 0x60,
    863    NM_MFC1     = 0x80,
    864    NM_MTC1     = 0xa0,
    865    NM_MFHC1    = 0xc0,
    866    NM_MTHC1    = 0xe0,
    867
    868    NM_CVT_S_PL = 0x84,
    869    NM_CVT_S_PU = 0xa4,
    870
    871    NM_CVT_L_S     = 0x004,
    872    NM_CVT_L_D     = 0x104,
    873    NM_CVT_W_S     = 0x024,
    874    NM_CVT_W_D     = 0x124,
    875
    876    NM_RSQRT_S     = 0x008,
    877    NM_RSQRT_D     = 0x108,
    878
    879    NM_SQRT_S      = 0x028,
    880    NM_SQRT_D      = 0x128,
    881
    882    NM_RECIP_S     = 0x048,
    883    NM_RECIP_D     = 0x148,
    884
    885    NM_FLOOR_L_S   = 0x00c,
    886    NM_FLOOR_L_D   = 0x10c,
    887
    888    NM_FLOOR_W_S   = 0x02c,
    889    NM_FLOOR_W_D   = 0x12c,
    890
    891    NM_CEIL_L_S    = 0x04c,
    892    NM_CEIL_L_D    = 0x14c,
    893    NM_CEIL_W_S    = 0x06c,
    894    NM_CEIL_W_D    = 0x16c,
    895    NM_TRUNC_L_S   = 0x08c,
    896    NM_TRUNC_L_D   = 0x18c,
    897    NM_TRUNC_W_S   = 0x0ac,
    898    NM_TRUNC_W_D   = 0x1ac,
    899    NM_ROUND_L_S   = 0x0cc,
    900    NM_ROUND_L_D   = 0x1cc,
    901    NM_ROUND_W_S   = 0x0ec,
    902    NM_ROUND_W_D   = 0x1ec,
    903
    904    NM_MOV_S       = 0x01,
    905    NM_MOV_D       = 0x81,
    906    NM_ABS_S       = 0x0d,
    907    NM_ABS_D       = 0x8d,
    908    NM_NEG_S       = 0x2d,
    909    NM_NEG_D       = 0xad,
    910    NM_CVT_D_S     = 0x04d,
    911    NM_CVT_D_W     = 0x0cd,
    912    NM_CVT_D_L     = 0x14d,
    913    NM_CVT_S_D     = 0x06d,
    914    NM_CVT_S_W     = 0x0ed,
    915    NM_CVT_S_L     = 0x16d,
    916};
    917
    918/* P.LL instruction pool */
    919enum {
    920    NM_LL       = 0x00,
    921    NM_LLWP     = 0x01,
    922};
    923
    924/* P.SC instruction pool */
    925enum {
    926    NM_SC       = 0x00,
    927    NM_SCWP     = 0x01,
    928};
    929
    930/* P.DVP instruction pool */
    931enum {
    932    NM_DVP      = 0x00,
    933    NM_EVP      = 0x01,
    934};
    935
    936
    937/*
    938 *
    939 * nanoMIPS decoding engine
    940 *
    941 */
    942
    943
    944/* extraction utilities */
    945
    946#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
    947#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
    948#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
    949#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
    950#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
    951
    952/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
    953static inline int decode_gpr_gpr3(int r)
    954{
    955    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
    956
    957    return map[r & 0x7];
    958}
    959
    960/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
    961static inline int decode_gpr_gpr3_src_store(int r)
    962{
    963    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
    964
    965    return map[r & 0x7];
    966}
    967
    968/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
    969static inline int decode_gpr_gpr4(int r)
    970{
    971    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
    972                               16, 17, 18, 19, 20, 21, 22, 23 };
    973
    974    return map[r & 0xf];
    975}
    976
    977/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
    978static inline int decode_gpr_gpr4_zero(int r)
    979{
    980    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
    981                               16, 17, 18, 19, 20, 21, 22, 23 };
    982
    983    return map[r & 0xf];
    984}
    985
    986static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
    987                    int shift)
    988{
    989    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
    990}
    991
    992static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
    993                    uint32_t reg1, uint32_t reg2)
    994{
    995    TCGv taddr = tcg_temp_new();
    996    TCGv_i64 tval = tcg_temp_new_i64();
    997    TCGv tmp1 = tcg_temp_new();
    998    TCGv tmp2 = tcg_temp_new();
    999
   1000    gen_base_offset_addr(ctx, taddr, base, offset);
   1001    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
   1002    if (cpu_is_bigendian(ctx)) {
   1003        tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
   1004    } else {
   1005        tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
   1006    }
   1007    gen_store_gpr(tmp1, reg1);
   1008    tcg_temp_free(tmp1);
   1009    gen_store_gpr(tmp2, reg2);
   1010    tcg_temp_free(tmp2);
   1011    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
   1012    tcg_temp_free_i64(tval);
   1013    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
   1014    tcg_temp_free(taddr);
   1015}
   1016
   1017static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
   1018                    uint32_t reg1, uint32_t reg2, bool eva)
   1019{
   1020    TCGv taddr = tcg_temp_local_new();
   1021    TCGv lladdr = tcg_temp_local_new();
   1022    TCGv_i64 tval = tcg_temp_new_i64();
   1023    TCGv_i64 llval = tcg_temp_new_i64();
   1024    TCGv_i64 val = tcg_temp_new_i64();
   1025    TCGv tmp1 = tcg_temp_new();
   1026    TCGv tmp2 = tcg_temp_new();
   1027    TCGLabel *lab_fail = gen_new_label();
   1028    TCGLabel *lab_done = gen_new_label();
   1029
   1030    gen_base_offset_addr(ctx, taddr, base, offset);
   1031
   1032    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
   1033    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
   1034
   1035    gen_load_gpr(tmp1, reg1);
   1036    gen_load_gpr(tmp2, reg2);
   1037
   1038    if (cpu_is_bigendian(ctx)) {
   1039        tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
   1040    } else {
   1041        tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
   1042    }
   1043
   1044    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
   1045    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
   1046                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
   1047    if (reg1 != 0) {
   1048        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
   1049    }
   1050    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
   1051
   1052    gen_set_label(lab_fail);
   1053
   1054    if (reg1 != 0) {
   1055        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
   1056    }
   1057    gen_set_label(lab_done);
   1058    tcg_gen_movi_tl(lladdr, -1);
   1059    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
   1060}
   1061
   1062static void gen_adjust_sp(DisasContext *ctx, int u)
   1063{
   1064    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
   1065}
   1066
   1067static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
   1068                     uint8_t gp, uint16_t u)
   1069{
   1070    int counter = 0;
   1071    TCGv va = tcg_temp_new();
   1072    TCGv t0 = tcg_temp_new();
   1073
   1074    while (counter != count) {
   1075        bool use_gp = gp && (counter == count - 1);
   1076        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
   1077        int this_offset = -((counter + 1) << 2);
   1078        gen_base_offset_addr(ctx, va, 29, this_offset);
   1079        gen_load_gpr(t0, this_rt);
   1080        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
   1081                           (MO_TEUL | ctx->default_tcg_memop_mask));
   1082        counter++;
   1083    }
   1084
   1085    /* adjust stack pointer */
   1086    gen_adjust_sp(ctx, -u);
   1087
   1088    tcg_temp_free(t0);
   1089    tcg_temp_free(va);
   1090}
   1091
   1092static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
   1093                        uint8_t gp, uint16_t u)
   1094{
   1095    int counter = 0;
   1096    TCGv va = tcg_temp_new();
   1097    TCGv t0 = tcg_temp_new();
   1098
   1099    while (counter != count) {
   1100        bool use_gp = gp && (counter == count - 1);
   1101        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
   1102        int this_offset = u - ((counter + 1) << 2);
   1103        gen_base_offset_addr(ctx, va, 29, this_offset);
   1104        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
   1105                        ctx->default_tcg_memop_mask);
   1106        tcg_gen_ext32s_tl(t0, t0);
   1107        gen_store_gpr(t0, this_rt);
   1108        counter++;
   1109    }
   1110
   1111    /* adjust stack pointer */
   1112    gen_adjust_sp(ctx, u);
   1113
   1114    tcg_temp_free(t0);
   1115    tcg_temp_free(va);
   1116}
   1117
   1118static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
   1119                                  int insn_bytes,
   1120                                  int rs, int rt, int32_t offset)
   1121{
   1122    target_ulong btgt = -1;
   1123    int bcond_compute = 0;
   1124    TCGv t0 = tcg_temp_new();
   1125    TCGv t1 = tcg_temp_new();
   1126
   1127    /* Load needed operands */
   1128    switch (opc) {
   1129    case OPC_BEQ:
   1130    case OPC_BNE:
   1131        /* Compare two registers */
   1132        if (rs != rt) {
   1133            gen_load_gpr(t0, rs);
   1134            gen_load_gpr(t1, rt);
   1135            bcond_compute = 1;
   1136        }
   1137        btgt = ctx->base.pc_next + insn_bytes + offset;
   1138        break;
   1139    case OPC_BGEZAL:
   1140        /* Compare to zero */
   1141        if (rs != 0) {
   1142            gen_load_gpr(t0, rs);
   1143            bcond_compute = 1;
   1144        }
   1145        btgt = ctx->base.pc_next + insn_bytes + offset;
   1146        break;
   1147    case OPC_BPOSGE32:
   1148        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
   1149        bcond_compute = 1;
   1150        btgt = ctx->base.pc_next + insn_bytes + offset;
   1151        break;
   1152    case OPC_JR:
   1153    case OPC_JALR:
   1154        /* Jump to register */
   1155        if (offset != 0 && offset != 16) {
   1156            /*
   1157             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
   1158             * others are reserved.
   1159             */
   1160            MIPS_INVAL("jump hint");
   1161            gen_reserved_instruction(ctx);
   1162            goto out;
   1163        }
   1164        gen_load_gpr(btarget, rs);
   1165        break;
   1166    default:
   1167        MIPS_INVAL("branch/jump");
   1168        gen_reserved_instruction(ctx);
   1169        goto out;
   1170    }
   1171    if (bcond_compute == 0) {
   1172        /* No condition to be computed */
   1173        switch (opc) {
   1174        case OPC_BEQ:     /* rx == rx        */
   1175            /* Always take */
   1176            ctx->hflags |= MIPS_HFLAG_B;
   1177            break;
   1178        case OPC_BGEZAL:  /* 0 >= 0          */
   1179            /* Always take and link */
   1180            tcg_gen_movi_tl(cpu_gpr[31],
   1181                            ctx->base.pc_next + insn_bytes);
   1182            ctx->hflags |= MIPS_HFLAG_B;
   1183            break;
   1184        case OPC_BNE:     /* rx != rx        */
   1185            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
   1186            /* Skip the instruction in the delay slot */
   1187            ctx->base.pc_next += 4;
   1188            goto out;
   1189        case OPC_JR:
   1190            ctx->hflags |= MIPS_HFLAG_BR;
   1191            break;
   1192        case OPC_JALR:
   1193            if (rt > 0) {
   1194                tcg_gen_movi_tl(cpu_gpr[rt],
   1195                                ctx->base.pc_next + insn_bytes);
   1196            }
   1197            ctx->hflags |= MIPS_HFLAG_BR;
   1198            break;
   1199        default:
   1200            MIPS_INVAL("branch/jump");
   1201            gen_reserved_instruction(ctx);
   1202            goto out;
   1203        }
   1204    } else {
   1205        switch (opc) {
   1206        case OPC_BEQ:
   1207            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
   1208            goto not_likely;
   1209        case OPC_BNE:
   1210            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
   1211            goto not_likely;
   1212        case OPC_BGEZAL:
   1213            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
   1214            tcg_gen_movi_tl(cpu_gpr[31],
   1215                            ctx->base.pc_next + insn_bytes);
   1216            goto not_likely;
   1217        case OPC_BPOSGE32:
   1218            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
   1219        not_likely:
   1220            ctx->hflags |= MIPS_HFLAG_BC;
   1221            break;
   1222        default:
   1223            MIPS_INVAL("conditional branch/jump");
   1224            gen_reserved_instruction(ctx);
   1225            goto out;
   1226        }
   1227    }
   1228
   1229    ctx->btarget = btgt;
   1230
   1231 out:
   1232    if (insn_bytes == 2) {
   1233        ctx->hflags |= MIPS_HFLAG_B16;
   1234    }
   1235    tcg_temp_free(t0);
   1236    tcg_temp_free(t1);
   1237}
   1238
   1239static void gen_pool16c_nanomips_insn(DisasContext *ctx)
   1240{
   1241    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
   1242    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
   1243
   1244    switch (extract32(ctx->opcode, 2, 2)) {
   1245    case NM_NOT16:
   1246        gen_logic(ctx, OPC_NOR, rt, rs, 0);
   1247        break;
   1248    case NM_AND16:
   1249        gen_logic(ctx, OPC_AND, rt, rt, rs);
   1250        break;
   1251    case NM_XOR16:
   1252        gen_logic(ctx, OPC_XOR, rt, rt, rs);
   1253        break;
   1254    case NM_OR16:
   1255        gen_logic(ctx, OPC_OR, rt, rt, rs);
   1256        break;
   1257    }
   1258}
   1259
   1260static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
   1261{
   1262    int rt = extract32(ctx->opcode, 21, 5);
   1263    int rs = extract32(ctx->opcode, 16, 5);
   1264    int rd = extract32(ctx->opcode, 11, 5);
   1265
   1266    switch (extract32(ctx->opcode, 3, 7)) {
   1267    case NM_P_TRAP:
   1268        switch (extract32(ctx->opcode, 10, 1)) {
   1269        case NM_TEQ:
   1270            check_nms(ctx);
   1271            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
   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();
   1372
   1373            gen_load_gpr(t1, rs);
   1374            gen_load_gpr(t2, rt);
   1375            tcg_gen_add_tl(t0, t1, t2);
   1376            tcg_gen_ext32s_tl(t0, t0);
   1377            tcg_gen_xor_tl(t1, t1, t2);
   1378            tcg_gen_xor_tl(t2, t0, t2);
   1379            tcg_gen_andc_tl(t1, t2, t1);
   1380
   1381            /* operands of same sign, result different sign */
   1382            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
   1383            gen_store_gpr(t0, rd);
   1384
   1385            tcg_temp_free(t0);
   1386            tcg_temp_free(t1);
   1387            tcg_temp_free(t2);
   1388        }
   1389        break;
   1390    case NM_MUL:
   1391        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
   1392        break;
   1393    case NM_MUH:
   1394        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
   1395        break;
   1396    case NM_MULU:
   1397        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
   1398        break;
   1399    case NM_MUHU:
   1400        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
   1401        break;
   1402    case NM_DIV:
   1403        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
   1404        break;
   1405    case NM_MOD:
   1406        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
   1407        break;
   1408    case NM_DIVU:
   1409        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
   1410        break;
   1411    case NM_MODU:
   1412        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
   1413        break;
   1414#ifndef CONFIG_USER_ONLY
   1415    case NM_MFC0:
   1416        check_cp0_enabled(ctx);
   1417        if (rt == 0) {
   1418            /* Treat as NOP. */
   1419            break;
   1420        }
   1421        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
   1422        break;
   1423    case NM_MTC0:
   1424        check_cp0_enabled(ctx);
   1425        {
   1426            TCGv t0 = tcg_temp_new();
   1427
   1428            gen_load_gpr(t0, rt);
   1429            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
   1430            tcg_temp_free(t0);
   1431        }
   1432        break;
   1433    case NM_D_E_MT_VPE:
   1434        {
   1435            uint8_t sc = extract32(ctx->opcode, 10, 1);
   1436            TCGv t0 = tcg_temp_new();
   1437
   1438            switch (sc) {
   1439            case 0:
   1440                if (rs == 1) {
   1441                    /* DMT */
   1442                    check_cp0_mt(ctx);
   1443                    gen_helper_dmt(t0);
   1444                    gen_store_gpr(t0, rt);
   1445                } else if (rs == 0) {
   1446                    /* DVPE */
   1447                    check_cp0_mt(ctx);
   1448                    gen_helper_dvpe(t0, cpu_env);
   1449                    gen_store_gpr(t0, rt);
   1450                } else {
   1451                    gen_reserved_instruction(ctx);
   1452                }
   1453                break;
   1454            case 1:
   1455                if (rs == 1) {
   1456                    /* EMT */
   1457                    check_cp0_mt(ctx);
   1458                    gen_helper_emt(t0);
   1459                    gen_store_gpr(t0, rt);
   1460                } else if (rs == 0) {
   1461                    /* EVPE */
   1462                    check_cp0_mt(ctx);
   1463                    gen_helper_evpe(t0, cpu_env);
   1464                    gen_store_gpr(t0, rt);
   1465                } else {
   1466                    gen_reserved_instruction(ctx);
   1467                }
   1468                break;
   1469            }
   1470
   1471            tcg_temp_free(t0);
   1472        }
   1473        break;
   1474    case NM_FORK:
   1475        check_mt(ctx);
   1476        {
   1477            TCGv t0 = tcg_temp_new();
   1478            TCGv t1 = tcg_temp_new();
   1479
   1480            gen_load_gpr(t0, rt);
   1481            gen_load_gpr(t1, rs);
   1482            gen_helper_fork(t0, t1);
   1483            tcg_temp_free(t0);
   1484            tcg_temp_free(t1);
   1485        }
   1486        break;
   1487    case NM_MFTR:
   1488    case NM_MFHTR:
   1489        check_cp0_enabled(ctx);
   1490        if (rd == 0) {
   1491            /* Treat as NOP. */
   1492            return;
   1493        }
   1494        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
   1495                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
   1496        break;
   1497    case NM_MTTR:
   1498    case NM_MTHTR:
   1499        check_cp0_enabled(ctx);
   1500        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
   1501                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
   1502        break;
   1503    case NM_YIELD:
   1504        check_mt(ctx);
   1505        {
   1506            TCGv t0 = tcg_temp_new();
   1507
   1508            gen_load_gpr(t0, rs);
   1509            gen_helper_yield(t0, cpu_env, t0);
   1510            gen_store_gpr(t0, rt);
   1511            tcg_temp_free(t0);
   1512        }
   1513        break;
   1514#endif
   1515    default:
   1516        gen_reserved_instruction(ctx);
   1517        break;
   1518    }
   1519}
   1520
   1521/* dsp */
   1522static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
   1523                                            int ret, int v1, int v2)
   1524{
   1525    TCGv_i32 t0;
   1526    TCGv v0_t;
   1527    TCGv v1_t;
   1528
   1529    t0 = tcg_temp_new_i32();
   1530
   1531    v0_t = tcg_temp_new();
   1532    v1_t = tcg_temp_new();
   1533
   1534    tcg_gen_movi_i32(t0, v2 >> 3);
   1535
   1536    gen_load_gpr(v0_t, ret);
   1537    gen_load_gpr(v1_t, v1);
   1538
   1539    switch (opc) {
   1540    case NM_MAQ_S_W_PHR:
   1541        check_dsp(ctx);
   1542        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
   1543        break;
   1544    case NM_MAQ_S_W_PHL:
   1545        check_dsp(ctx);
   1546        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
   1547        break;
   1548    case NM_MAQ_SA_W_PHR:
   1549        check_dsp(ctx);
   1550        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
   1551        break;
   1552    case NM_MAQ_SA_W_PHL:
   1553        check_dsp(ctx);
   1554        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
   1555        break;
   1556    default:
   1557        gen_reserved_instruction(ctx);
   1558        break;
   1559    }
   1560
   1561    tcg_temp_free_i32(t0);
   1562
   1563    tcg_temp_free(v0_t);
   1564    tcg_temp_free(v1_t);
   1565}
   1566
   1567
   1568static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
   1569                                    int ret, int v1, int v2)
   1570{
   1571    int16_t imm;
   1572    TCGv t0 = tcg_temp_new();
   1573    TCGv t1 = tcg_temp_new();
   1574    TCGv v0_t = tcg_temp_new();
   1575
   1576    gen_load_gpr(v0_t, v1);
   1577
   1578    switch (opc) {
   1579    case NM_POOL32AXF_1_0:
   1580        check_dsp(ctx);
   1581        switch (extract32(ctx->opcode, 12, 2)) {
   1582        case NM_MFHI:
   1583            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
   1584            break;
   1585        case NM_MFLO:
   1586            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
   1587            break;
   1588        case NM_MTHI:
   1589            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
   1590            break;
   1591        case NM_MTLO:
   1592            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
   1593            break;
   1594        }
   1595        break;
   1596    case NM_POOL32AXF_1_1:
   1597        check_dsp(ctx);
   1598        switch (extract32(ctx->opcode, 12, 2)) {
   1599        case NM_MTHLIP:
   1600            tcg_gen_movi_tl(t0, v2);
   1601            gen_helper_mthlip(t0, v0_t, cpu_env);
   1602            break;
   1603        case NM_SHILOV:
   1604            tcg_gen_movi_tl(t0, v2 >> 3);
   1605            gen_helper_shilo(t0, v0_t, cpu_env);
   1606            break;
   1607        default:
   1608            gen_reserved_instruction(ctx);
   1609            break;
   1610        }
   1611        break;
   1612    case NM_POOL32AXF_1_3:
   1613        check_dsp(ctx);
   1614        imm = extract32(ctx->opcode, 14, 7);
   1615        switch (extract32(ctx->opcode, 12, 2)) {
   1616        case NM_RDDSP:
   1617            tcg_gen_movi_tl(t0, imm);
   1618            gen_helper_rddsp(t0, t0, cpu_env);
   1619            gen_store_gpr(t0, ret);
   1620            break;
   1621        case NM_WRDSP:
   1622            gen_load_gpr(t0, ret);
   1623            tcg_gen_movi_tl(t1, imm);
   1624            gen_helper_wrdsp(t0, t1, cpu_env);
   1625            break;
   1626        case NM_EXTP:
   1627            tcg_gen_movi_tl(t0, v2 >> 3);
   1628            tcg_gen_movi_tl(t1, v1);
   1629            gen_helper_extp(t0, t0, t1, cpu_env);
   1630            gen_store_gpr(t0, ret);
   1631            break;
   1632        case NM_EXTPDP:
   1633            tcg_gen_movi_tl(t0, v2 >> 3);
   1634            tcg_gen_movi_tl(t1, v1);
   1635            gen_helper_extpdp(t0, t0, t1, cpu_env);
   1636            gen_store_gpr(t0, ret);
   1637            break;
   1638        }
   1639        break;
   1640    case NM_POOL32AXF_1_4:
   1641        check_dsp(ctx);
   1642        tcg_gen_movi_tl(t0, v2 >> 2);
   1643        switch (extract32(ctx->opcode, 12, 1)) {
   1644        case NM_SHLL_QB:
   1645            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
   1646            gen_store_gpr(t0, ret);
   1647            break;
   1648        case NM_SHRL_QB:
   1649            gen_helper_shrl_qb(t0, t0, v0_t);
   1650            gen_store_gpr(t0, ret);
   1651            break;
   1652        }
   1653        break;
   1654    case NM_POOL32AXF_1_5:
   1655        opc = extract32(ctx->opcode, 12, 2);
   1656        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
   1657        break;
   1658    case NM_POOL32AXF_1_7:
   1659        check_dsp(ctx);
   1660        tcg_gen_movi_tl(t0, v2 >> 3);
   1661        tcg_gen_movi_tl(t1, v1);
   1662        switch (extract32(ctx->opcode, 12, 2)) {
   1663        case NM_EXTR_W:
   1664            gen_helper_extr_w(t0, t0, t1, cpu_env);
   1665            gen_store_gpr(t0, ret);
   1666            break;
   1667        case NM_EXTR_R_W:
   1668            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
   1669            gen_store_gpr(t0, ret);
   1670            break;
   1671        case NM_EXTR_RS_W:
   1672            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
   1673            gen_store_gpr(t0, ret);
   1674            break;
   1675        case NM_EXTR_S_H:
   1676            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
   1677            gen_store_gpr(t0, ret);
   1678            break;
   1679        }
   1680        break;
   1681    default:
   1682        gen_reserved_instruction(ctx);
   1683        break;
   1684    }
   1685
   1686    tcg_temp_free(t0);
   1687    tcg_temp_free(t1);
   1688    tcg_temp_free(v0_t);
   1689}
   1690
   1691static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
   1692                                    TCGv v0, TCGv v1, int rd)
   1693{
   1694    TCGv_i32 t0;
   1695
   1696    t0 = tcg_temp_new_i32();
   1697
   1698    tcg_gen_movi_i32(t0, rd >> 3);
   1699
   1700    switch (opc) {
   1701    case NM_POOL32AXF_2_0_7:
   1702        switch (extract32(ctx->opcode, 9, 3)) {
   1703        case NM_DPA_W_PH:
   1704            check_dsp_r2(ctx);
   1705            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
   1706            break;
   1707        case NM_DPAQ_S_W_PH:
   1708            check_dsp(ctx);
   1709            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
   1710            break;
   1711        case NM_DPS_W_PH:
   1712            check_dsp_r2(ctx);
   1713            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
   1714            break;
   1715        case NM_DPSQ_S_W_PH:
   1716            check_dsp(ctx);
   1717            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
   1718            break;
   1719        default:
   1720            gen_reserved_instruction(ctx);
   1721            break;
   1722        }
   1723        break;
   1724    case NM_POOL32AXF_2_8_15:
   1725        switch (extract32(ctx->opcode, 9, 3)) {
   1726        case NM_DPAX_W_PH:
   1727            check_dsp_r2(ctx);
   1728            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
   1729            break;
   1730        case NM_DPAQ_SA_L_W:
   1731            check_dsp(ctx);
   1732            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
   1733            break;
   1734        case NM_DPSX_W_PH:
   1735            check_dsp_r2(ctx);
   1736            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
   1737            break;
   1738        case NM_DPSQ_SA_L_W:
   1739            check_dsp(ctx);
   1740            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
   1741            break;
   1742        default:
   1743            gen_reserved_instruction(ctx);
   1744            break;
   1745        }
   1746        break;
   1747    case NM_POOL32AXF_2_16_23:
   1748        switch (extract32(ctx->opcode, 9, 3)) {
   1749        case NM_DPAU_H_QBL:
   1750            check_dsp(ctx);
   1751            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
   1752            break;
   1753        case NM_DPAQX_S_W_PH:
   1754            check_dsp_r2(ctx);
   1755            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
   1756            break;
   1757        case NM_DPSU_H_QBL:
   1758            check_dsp(ctx);
   1759            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
   1760            break;
   1761        case NM_DPSQX_S_W_PH:
   1762            check_dsp_r2(ctx);
   1763            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
   1764            break;
   1765        case NM_MULSA_W_PH:
   1766            check_dsp_r2(ctx);
   1767            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
   1768            break;
   1769        default:
   1770            gen_reserved_instruction(ctx);
   1771            break;
   1772        }
   1773        break;
   1774    case NM_POOL32AXF_2_24_31:
   1775        switch (extract32(ctx->opcode, 9, 3)) {
   1776        case NM_DPAU_H_QBR:
   1777            check_dsp(ctx);
   1778            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
   1779            break;
   1780        case NM_DPAQX_SA_W_PH:
   1781            check_dsp_r2(ctx);
   1782            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
   1783            break;
   1784        case NM_DPSU_H_QBR:
   1785            check_dsp(ctx);
   1786            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
   1787            break;
   1788        case NM_DPSQX_SA_W_PH:
   1789            check_dsp_r2(ctx);
   1790            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
   1791            break;
   1792        case NM_MULSAQ_S_W_PH:
   1793            check_dsp(ctx);
   1794            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
   1795            break;
   1796        default:
   1797            gen_reserved_instruction(ctx);
   1798            break;
   1799        }
   1800        break;
   1801    default:
   1802        gen_reserved_instruction(ctx);
   1803        break;
   1804    }
   1805
   1806    tcg_temp_free_i32(t0);
   1807}
   1808
   1809static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
   1810                                          int rt, int rs, int rd)
   1811{
   1812    int ret = rt;
   1813    TCGv t0 = tcg_temp_new();
   1814    TCGv t1 = tcg_temp_new();
   1815    TCGv v0_t = tcg_temp_new();
   1816    TCGv v1_t = tcg_temp_new();
   1817
   1818    gen_load_gpr(v0_t, rt);
   1819    gen_load_gpr(v1_t, rs);
   1820
   1821    switch (opc) {
   1822    case NM_POOL32AXF_2_0_7:
   1823        switch (extract32(ctx->opcode, 9, 3)) {
   1824        case NM_DPA_W_PH:
   1825        case NM_DPAQ_S_W_PH:
   1826        case NM_DPS_W_PH:
   1827        case NM_DPSQ_S_W_PH:
   1828            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
   1829            break;
   1830        case NM_BALIGN:
   1831            check_dsp_r2(ctx);
   1832            if (rt != 0) {
   1833                gen_load_gpr(t0, rs);
   1834                rd &= 3;
   1835                if (rd != 0 && rd != 2) {
   1836                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
   1837                    tcg_gen_ext32u_tl(t0, t0);
   1838                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
   1839                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
   1840                }
   1841                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
   1842            }
   1843            break;
   1844        case NM_MADD:
   1845            check_dsp(ctx);
   1846            {
   1847                int acc = extract32(ctx->opcode, 14, 2);
   1848                TCGv_i64 t2 = tcg_temp_new_i64();
   1849                TCGv_i64 t3 = tcg_temp_new_i64();
   1850
   1851                gen_load_gpr(t0, rt);
   1852                gen_load_gpr(t1, rs);
   1853                tcg_gen_ext_tl_i64(t2, t0);
   1854                tcg_gen_ext_tl_i64(t3, t1);
   1855                tcg_gen_mul_i64(t2, t2, t3);
   1856                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
   1857                tcg_gen_add_i64(t2, t2, t3);
   1858                tcg_temp_free_i64(t3);
   1859                gen_move_low32(cpu_LO[acc], t2);
   1860                gen_move_high32(cpu_HI[acc], t2);
   1861                tcg_temp_free_i64(t2);
   1862            }
   1863            break;
   1864        case NM_MULT:
   1865            check_dsp(ctx);
   1866            {
   1867                int acc = extract32(ctx->opcode, 14, 2);
   1868                TCGv_i32 t2 = tcg_temp_new_i32();
   1869                TCGv_i32 t3 = tcg_temp_new_i32();
   1870
   1871                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();
   1905
   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();
   1927
   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();
   1971
   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();
   2014
   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    }
   2042
   2043    tcg_temp_free(t0);
   2044    tcg_temp_free(t1);
   2045
   2046    tcg_temp_free(v0_t);
   2047    tcg_temp_free(v1_t);
   2048}
   2049
   2050static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
   2051                                          int rt, int rs)
   2052{
   2053    int ret = rt;
   2054    TCGv t0 = tcg_temp_new();
   2055    TCGv v0_t = tcg_temp_new();
   2056
   2057    gen_load_gpr(v0_t, rs);
   2058
   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();
   2155
   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    }
   2185
   2186    tcg_temp_free(v0_t);
   2187    tcg_temp_free(t0);
   2188}
   2189
   2190static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
   2191                                          int rt, int rs, int rd)
   2192{
   2193    TCGv t0 = tcg_temp_new();
   2194    TCGv rs_t = tcg_temp_new();
   2195
   2196    gen_load_gpr(rs_t, rs);
   2197
   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);
   2242}
   2243
   2244
   2245static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
   2246{
   2247    int rt = extract32(ctx->opcode, 21, 5);
   2248    int rs = extract32(ctx->opcode, 16, 5);
   2249    int rd = extract32(ctx->opcode, 11, 5);
   2250
   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();
   2295
   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();
   2308
   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    }
   2350}
   2351
   2352/* Immediate Value Compact Branches */
   2353static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
   2354                                   int rt, int32_t imm, int32_t offset)
   2355{
   2356    TCGCond cond = TCG_COND_ALWAYS;
   2357    TCGv t0 = tcg_temp_new();
   2358    TCGv t1 = tcg_temp_new();
   2359
   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);
   2363
   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    }
   2433
   2434    /* branch completion */
   2435    clear_branch_hflags(ctx);
   2436    ctx->base.is_jmp = DISAS_NORETURN;
   2437
   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();
   2444
   2445        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
   2446
   2447        gen_goto_tb(ctx, 1, ctx->btarget);
   2448        gen_set_label(fs);
   2449
   2450        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
   2451    }
   2452
   2453out:
   2454    tcg_temp_free(t0);
   2455    tcg_temp_free(t1);
   2456}
   2457
   2458/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
   2459static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
   2460                                                int rt)
   2461{
   2462    TCGv t0 = tcg_temp_new();
   2463    TCGv t1 = tcg_temp_new();
   2464
   2465    /* load rs */
   2466    gen_load_gpr(t0, rs);
   2467
   2468    /* link */
   2469    if (rt != 0) {
   2470        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
   2471    }
   2472
   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);
   2477
   2478    /* branch completion */
   2479    clear_branch_hflags(ctx);
   2480    ctx->base.is_jmp = DISAS_NORETURN;
   2481
   2482    /* unconditional branch to register */
   2483    tcg_gen_mov_tl(cpu_PC, btarget);
   2484    tcg_gen_lookup_and_goto_ptr();
   2485
   2486    tcg_temp_free(t0);
   2487    tcg_temp_free(t1);
   2488}
   2489
   2490/* nanoMIPS Branches */
   2491static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
   2492                                       int rs, int rt, int32_t offset)
   2493{
   2494    int bcond_compute = 0;
   2495    TCGv t0 = tcg_temp_new();
   2496    TCGv t1 = tcg_temp_new();
   2497
   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();
   2533
   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    }
   2546
   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();
   2561
   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        }
   2619
   2620        /* branch completion */
   2621        clear_branch_hflags(ctx);
   2622        ctx->base.is_jmp = DISAS_NORETURN;
   2623
   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);
   2627
   2628        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
   2629    }
   2630
   2631out:
   2632    tcg_temp_free(t0);
   2633    tcg_temp_free(t1);
   2634}
   2635
   2636
   2637/* nanoMIPS CP1 Branches */
   2638static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
   2639                                   int32_t ft, int32_t offset)
   2640{
   2641    target_ulong btarget;
   2642    TCGv_i64 t0 = tcg_temp_new_i64();
   2643
   2644    gen_load_fpr64(ctx, t0, ft);
   2645    tcg_gen_andi_i64(t0, t0, 1);
   2646
   2647    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
   2648
   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    }
   2663
   2664    tcg_gen_trunc_i64_tl(bcond, t0);
   2665
   2666    ctx->btarget = btarget;
   2667
   2668out:
   2669    tcg_temp_free_i64(t0);
   2670}
   2671
   2672
   2673static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
   2674{
   2675    TCGv t0, t1;
   2676    t0 = tcg_temp_new();
   2677    t1 = tcg_temp_new();
   2678
   2679    gen_load_gpr(t0, rs);
   2680    gen_load_gpr(t1, rt);
   2681
   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);
   2707
   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    }
   2793
   2794    tcg_temp_free(t0);
   2795    tcg_temp_free(t1);
   2796}
   2797
   2798static void gen_pool32f_nanomips_insn(DisasContext *ctx)
   2799{
   2800    int rt, rs, rd;
   2801
   2802    rt = extract32(ctx->opcode, 21, 5);
   2803    rs = extract32(ctx->opcode, 16, 5);
   2804    rd = extract32(ctx->opcode, 11, 5);
   2805
   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    }
   3095}
   3096
   3097static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
   3098                                       int rd, int rs, int rt)
   3099{
   3100    int ret = rd;
   3101    TCGv t0 = tcg_temp_new();
   3102    TCGv v1_t = tcg_temp_new();
   3103    TCGv v2_t = tcg_temp_new();
   3104
   3105    gen_load_gpr(v1_t, rs);
   3106    gen_load_gpr(v2_t, rt);
   3107
   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);
   3525
   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    }
   3645
   3646    tcg_temp_free(v2_t);
   3647    tcg_temp_free(v1_t);
   3648    tcg_temp_free(t0);
   3649}
   3650
   3651static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
   3652{
   3653    uint16_t insn;
   3654    uint32_t op;
   3655    int rt, rs, rd;
   3656    int offset;
   3657    int imm;
   3658
   3659    insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
   3660    ctx->opcode = (ctx->opcode << 16) | insn;
   3661
   3662    rt = extract32(ctx->opcode, 21, 5);
   3663    rs = extract32(ctx->opcode, 16, 5);
   3664    rd = extract32(ctx->opcode, 11, 5);
   3665
   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, 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);
   3805
   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();
   3814
   3815                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
   3816                                                addr_off);
   3817
   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();
   3829
   3830                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
   3831                                                addr_off);
   3832
   3833                    tcg_gen_movi_tl(t0, addr);
   3834                    gen_load_gpr(t1, rt);
   3835
   3836                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
   3837
   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();
   3896
   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);
   3901
   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));
   3952
   3953                gen_load_gpr(t0, rs);
   3954                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
   3955                tcg_temp_free(t0);
   3956
   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);
   4023
   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);
   4087
   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);
   4148
   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();
   4214
   4215                        gen_base_offset_addr(ctx, t0, rs, s);
   4216
   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;
   4376
   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;
   4383
   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);
   4388
   4389                        gen_base_offset_addr(ctx, va, rs, this_offset);
   4390
   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;
   4439
   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;
   4488
   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);
   4553
   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;
   4563}
   4564
   4565static int decode_isa_nanomips(CPUMIPSState *env, DisasContext *ctx)
   4566{
   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;
   4573
   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    }
   4582
   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;
   4626
   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;
   4868
   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    }
   4920
   4921    return 2;
   4922}