qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

nanomips_translate.c.inc (147084B)


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