qemu/target/mips/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS emulation for QEMU - main 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 * This library is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU Lesser General Public
  12 * License as published by the Free Software Foundation; either
  13 * version 2 of the License, or (at your option) any later version.
  14 *
  15 * This library is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * Lesser General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU Lesser General Public
  21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  22 */
  23
  24#include "qemu/osdep.h"
  25#include "cpu.h"
  26#include "internal.h"
  27#include "disas/disas.h"
  28#include "exec/exec-all.h"
  29#include "tcg-op.h"
  30#include "exec/cpu_ldst.h"
  31#include "hw/mips/cpudevs.h"
  32
  33#include "exec/helper-proto.h"
  34#include "exec/helper-gen.h"
  35#include "hw/semihosting/semihost.h"
  36
  37#include "target/mips/trace.h"
  38#include "trace-tcg.h"
  39#include "exec/translator.h"
  40#include "exec/log.h"
  41#include "qemu/qemu-print.h"
  42
  43#define MIPS_DEBUG_DISAS 0
  44
  45/* MIPS major opcodes */
  46#define MASK_OP_MAJOR(op)       (op & (0x3F << 26))
  47
  48enum {
  49    /* indirect opcode tables */
  50    OPC_SPECIAL  = (0x00 << 26),
  51    OPC_REGIMM   = (0x01 << 26),
  52    OPC_CP0      = (0x10 << 26),
  53    OPC_CP1      = (0x11 << 26),
  54    OPC_CP2      = (0x12 << 26),
  55    OPC_CP3      = (0x13 << 26),
  56    OPC_SPECIAL2 = (0x1C << 26),
  57    OPC_SPECIAL3 = (0x1F << 26),
  58    /* arithmetic with immediate */
  59    OPC_ADDI     = (0x08 << 26),
  60    OPC_ADDIU    = (0x09 << 26),
  61    OPC_SLTI     = (0x0A << 26),
  62    OPC_SLTIU    = (0x0B << 26),
  63    /* logic with immediate */
  64    OPC_ANDI     = (0x0C << 26),
  65    OPC_ORI      = (0x0D << 26),
  66    OPC_XORI     = (0x0E << 26),
  67    OPC_LUI      = (0x0F << 26),
  68    /* arithmetic with immediate */
  69    OPC_DADDI    = (0x18 << 26),
  70    OPC_DADDIU   = (0x19 << 26),
  71    /* Jump and branches */
  72    OPC_J        = (0x02 << 26),
  73    OPC_JAL      = (0x03 << 26),
  74    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  75    OPC_BEQL     = (0x14 << 26),
  76    OPC_BNE      = (0x05 << 26),
  77    OPC_BNEL     = (0x15 << 26),
  78    OPC_BLEZ     = (0x06 << 26),
  79    OPC_BLEZL    = (0x16 << 26),
  80    OPC_BGTZ     = (0x07 << 26),
  81    OPC_BGTZL    = (0x17 << 26),
  82    OPC_JALX     = (0x1D << 26),
  83    OPC_DAUI     = (0x1D << 26),
  84    /* Load and stores */
  85    OPC_LDL      = (0x1A << 26),
  86    OPC_LDR      = (0x1B << 26),
  87    OPC_LB       = (0x20 << 26),
  88    OPC_LH       = (0x21 << 26),
  89    OPC_LWL      = (0x22 << 26),
  90    OPC_LW       = (0x23 << 26),
  91    OPC_LWPC     = OPC_LW | 0x5,
  92    OPC_LBU      = (0x24 << 26),
  93    OPC_LHU      = (0x25 << 26),
  94    OPC_LWR      = (0x26 << 26),
  95    OPC_LWU      = (0x27 << 26),
  96    OPC_SB       = (0x28 << 26),
  97    OPC_SH       = (0x29 << 26),
  98    OPC_SWL      = (0x2A << 26),
  99    OPC_SW       = (0x2B << 26),
 100    OPC_SDL      = (0x2C << 26),
 101    OPC_SDR      = (0x2D << 26),
 102    OPC_SWR      = (0x2E << 26),
 103    OPC_LL       = (0x30 << 26),
 104    OPC_LLD      = (0x34 << 26),
 105    OPC_LD       = (0x37 << 26),
 106    OPC_LDPC     = OPC_LD | 0x5,
 107    OPC_SC       = (0x38 << 26),
 108    OPC_SCD      = (0x3C << 26),
 109    OPC_SD       = (0x3F << 26),
 110    /* Floating point load/store */
 111    OPC_LWC1     = (0x31 << 26),
 112    OPC_LWC2     = (0x32 << 26),
 113    OPC_LDC1     = (0x35 << 26),
 114    OPC_LDC2     = (0x36 << 26),
 115    OPC_SWC1     = (0x39 << 26),
 116    OPC_SWC2     = (0x3A << 26),
 117    OPC_SDC1     = (0x3D << 26),
 118    OPC_SDC2     = (0x3E << 26),
 119    /* Compact Branches */
 120    OPC_BLEZALC  = (0x06 << 26),
 121    OPC_BGEZALC  = (0x06 << 26),
 122    OPC_BGEUC    = (0x06 << 26),
 123    OPC_BGTZALC  = (0x07 << 26),
 124    OPC_BLTZALC  = (0x07 << 26),
 125    OPC_BLTUC    = (0x07 << 26),
 126    OPC_BOVC     = (0x08 << 26),
 127    OPC_BEQZALC  = (0x08 << 26),
 128    OPC_BEQC     = (0x08 << 26),
 129    OPC_BLEZC    = (0x16 << 26),
 130    OPC_BGEZC    = (0x16 << 26),
 131    OPC_BGEC     = (0x16 << 26),
 132    OPC_BGTZC    = (0x17 << 26),
 133    OPC_BLTZC    = (0x17 << 26),
 134    OPC_BLTC     = (0x17 << 26),
 135    OPC_BNVC     = (0x18 << 26),
 136    OPC_BNEZALC  = (0x18 << 26),
 137    OPC_BNEC     = (0x18 << 26),
 138    OPC_BC       = (0x32 << 26),
 139    OPC_BEQZC    = (0x36 << 26),
 140    OPC_JIC      = (0x36 << 26),
 141    OPC_BALC     = (0x3A << 26),
 142    OPC_BNEZC    = (0x3E << 26),
 143    OPC_JIALC    = (0x3E << 26),
 144    /* MDMX ASE specific */
 145    OPC_MDMX     = (0x1E << 26),
 146    /* MSA ASE, same as MDMX */
 147    OPC_MSA      = OPC_MDMX,
 148    /* Cache and prefetch */
 149    OPC_CACHE    = (0x2F << 26),
 150    OPC_PREF     = (0x33 << 26),
 151    /* PC-relative address computation / loads */
 152    OPC_PCREL    = (0x3B << 26),
 153};
 154
 155/* PC-relative address computation / loads  */
 156#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 157#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 158enum {
 159    /* Instructions determined by bits 19 and 20 */
 160    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 161    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 162    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 163
 164    /* Instructions determined by bits 16 ... 20 */
 165    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 166    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 167
 168    /* Other */
 169    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 170};
 171
 172/* MIPS special opcodes */
 173#define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
 174
 175enum {
 176    /* Shifts */
 177    OPC_SLL      = 0x00 | OPC_SPECIAL,
 178    /* NOP is SLL r0, r0, 0   */
 179    /* SSNOP is SLL r0, r0, 1 */
 180    /* EHB is SLL r0, r0, 3 */
 181    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 182    OPC_ROTR     = OPC_SRL | (1 << 21),
 183    OPC_SRA      = 0x03 | OPC_SPECIAL,
 184    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 185    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 186    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 187    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 188    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 189    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 190    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 191    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 192    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 193    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 194    OPC_DROTR    = OPC_DSRL | (1 << 21),
 195    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 196    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 197    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 198    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 199    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 200    /* Multiplication / division */
 201    OPC_MULT     = 0x18 | OPC_SPECIAL,
 202    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 203    OPC_DIV      = 0x1A | OPC_SPECIAL,
 204    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 205    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 206    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 207    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 208    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 209
 210    /* 2 registers arithmetic / logic */
 211    OPC_ADD      = 0x20 | OPC_SPECIAL,
 212    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 213    OPC_SUB      = 0x22 | OPC_SPECIAL,
 214    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 215    OPC_AND      = 0x24 | OPC_SPECIAL,
 216    OPC_OR       = 0x25 | OPC_SPECIAL,
 217    OPC_XOR      = 0x26 | OPC_SPECIAL,
 218    OPC_NOR      = 0x27 | OPC_SPECIAL,
 219    OPC_SLT      = 0x2A | OPC_SPECIAL,
 220    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 221    OPC_DADD     = 0x2C | OPC_SPECIAL,
 222    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 223    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 224    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 225    /* Jumps */
 226    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 227    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 228    /* Traps */
 229    OPC_TGE      = 0x30 | OPC_SPECIAL,
 230    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 231    OPC_TLT      = 0x32 | OPC_SPECIAL,
 232    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 233    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 234    OPC_TNE      = 0x36 | OPC_SPECIAL,
 235    /* HI / LO registers load & stores */
 236    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 237    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 238    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 239    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 240    /* Conditional moves */
 241    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 242    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 243
 244    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 245    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 246
 247    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 248
 249    /* Special */
 250    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 251    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 252    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 253    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 254    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 255
 256    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 257    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 258    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 259    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 260};
 261
 262/*
 263 * R6 Multiply and Divide instructions have the same opcode
 264 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
 265 */
 266#define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
 267
 268enum {
 269    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 270    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 271    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 272    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 273    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 274    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 275    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 276    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 277
 278    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 279    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 280    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 281    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 282    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 283    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 284    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 285    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 286
 287    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 288    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 289    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 290    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 291    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 292
 293    OPC_LSA  = 0x05 | OPC_SPECIAL,
 294    OPC_DLSA = 0x15 | OPC_SPECIAL,
 295};
 296
 297/* Multiplication variants of the vr54xx. */
 298#define MASK_MUL_VR54XX(op)         (MASK_SPECIAL(op) | (op & (0x1F << 6)))
 299
 300enum {
 301    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 302    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 303    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 304    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 305    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 306    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 307    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 308    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 309    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 310    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 311    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 312    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 313    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 314    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 315};
 316
 317/* REGIMM (rt field) opcodes */
 318#define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
 319
 320enum {
 321    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 322    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 323    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 324    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 325    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 326    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 327    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 328    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 329    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 330    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 331    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 332    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 333    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 334    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 335    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 336    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 337
 338    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 339    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 340};
 341
 342/* Special2 opcodes */
 343#define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 344
 345enum {
 346    /* Multiply & xxx operations */
 347    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 348    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 349    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 350    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 351    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 352    /* Loongson 2F */
 353    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 354    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 355    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 356    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 357    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 358    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 359    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 360    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 361    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 362    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 363    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 364    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 365    /* Misc */
 366    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 367    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 368    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 369    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 370    /* Special */
 371    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 372};
 373
 374/* Special3 opcodes */
 375#define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 376
 377enum {
 378    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 379    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 380    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 381    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 382    OPC_INS      = 0x04 | OPC_SPECIAL3,
 383    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 384    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 385    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 386    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 387    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 388    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 389    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 390    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 391
 392    /* Loongson 2E */
 393    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 394    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 395    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 396    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 397    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 398    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 399    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 400    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 401    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 402    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 403    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 404    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 405
 406    /* MIPS DSP Load */
 407    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 408    /* MIPS DSP Arithmetic */
 409    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 410    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 411    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 412    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 413    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 414    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 415    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 416    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 417    /* MIPS DSP GPR-Based Shift Sub-class */
 418    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 419    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 420    /* MIPS DSP Multiply Sub-class insns */
 421    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 422    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 423    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 424    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 425    /* DSP Bit/Manipulation Sub-class */
 426    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 427    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 428    /* MIPS DSP Append Sub-class */
 429    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 430    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 431    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 432    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 433    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 434
 435    /* EVA */
 436    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 437    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 438    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 439    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 440    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 441    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 442    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 443    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 444    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 445    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 446    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 447    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 448    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 449    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 450    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 451    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 452
 453    /* R6 */
 454    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 455    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 456    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 457    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 458    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 459    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 460};
 461
 462/* BSHFL opcodes */
 463#define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 464
 465enum {
 466    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 467    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 468    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 469    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 470    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 471    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 472    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 473    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 474};
 475
 476/* DBSHFL opcodes */
 477#define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 478
 479enum {
 480    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 481    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 482    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 483    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 484    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 485    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 486    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 487    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 488    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 489    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 490    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 491};
 492
 493/* MIPS DSP REGIMM opcodes */
 494enum {
 495    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 496    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 497};
 498
 499#define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 500/* MIPS DSP Load */
 501enum {
 502    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 503    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 504    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 505    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 506};
 507
 508#define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 509enum {
 510    /* MIPS DSP Arithmetic Sub-class */
 511    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 512    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 513    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 514    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 515    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 516    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 517    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 518    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 519    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 520    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 521    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 522    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 523    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 524    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 525    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 526    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 527    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 528    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 529    /* MIPS DSP Multiply Sub-class insns */
 530    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 531    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 532    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 533    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 534    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 535    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 536};
 537
 538#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 539#define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 540enum {
 541    /* MIPS DSP Arithmetic Sub-class */
 542    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 543    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 544    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 545    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 546    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 547    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 548    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 549    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 550    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 551    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 552    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 553    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 554    /* MIPS DSP Multiply Sub-class insns */
 555    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 556    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 557    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 558    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 559};
 560
 561#define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 562enum {
 563    /* MIPS DSP Arithmetic Sub-class */
 564    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 565    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 566    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 567    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 568    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 569    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 570    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 571    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 572    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 573    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 574    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 575    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 576    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 577    /* DSP Bit/Manipulation Sub-class */
 578    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 579    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 580    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 581    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 582    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 583};
 584
 585#define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 586enum {
 587    /* MIPS DSP Arithmetic Sub-class */
 588    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 589    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 590    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 591    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 592    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 593    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 594    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 595    /* DSP Compare-Pick Sub-class */
 596    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 597    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 598    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 599    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 600    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 601    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 602    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 603    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 604    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 605    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 606    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 607    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 608    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 609    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 610    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 611};
 612
 613#define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 614enum {
 615    /* MIPS DSP GPR-Based Shift Sub-class */
 616    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 617    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 618    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 619    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 620    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 621    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 622    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 623    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 624    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 625    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 626    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 627    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 628    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 629    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 630    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 631    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 632    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 633    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 634    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 635    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 636    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 637    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 638};
 639
 640#define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 641enum {
 642    /* MIPS DSP Multiply Sub-class insns */
 643    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 644    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 645    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 646    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 647    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 648    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 649    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 650    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 651    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 652    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 653    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 654    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 655    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 656    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 657    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 658    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 659    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 660    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 661    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 662    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 663    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 664    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 665};
 666
 667#define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 668enum {
 669    /* DSP Bit/Manipulation Sub-class */
 670    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 671};
 672
 673#define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 674enum {
 675    /* MIPS DSP Append Sub-class */
 676    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 677    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 678    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 679};
 680
 681#define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 682enum {
 683    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 684    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 685    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 686    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 687    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 688    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 689    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 690    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 691    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 692    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 693    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 694    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 695    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 696    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 697    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 698    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 699    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 700    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 701};
 702
 703#define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 704enum {
 705    /* MIPS DSP Arithmetic Sub-class */
 706    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 707    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 708    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 709    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 710    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 711    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 712    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 713    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 714    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 715    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 716    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 717    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 718    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 719    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 720    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 721    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 722    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 723    /* DSP Bit/Manipulation Sub-class */
 724    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 725    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 726    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 727    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 728    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 729    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 730};
 731
 732#define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 733enum {
 734    /* MIPS DSP Multiply Sub-class insns */
 735    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 736    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 737    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 738    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 739    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 740    /* MIPS DSP Arithmetic Sub-class */
 741    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 742    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 743    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 744    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 745    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 746    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 747    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 748    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 749    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 750    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 751    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 752    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 753    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 754    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 755    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 756    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 757    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 758    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 759    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 760    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 761    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 762};
 763
 764#define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 765enum {
 766    /* DSP Compare-Pick Sub-class */
 767    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 768    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 769    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 770    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 771    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 772    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 773    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 774    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 775    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 776    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 777    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 778    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 779    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 780    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 781    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 782    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 783    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 784    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 785    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 786    /* MIPS DSP Arithmetic Sub-class */
 787    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 788    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 789    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 790    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 792    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 793    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 794    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 795};
 796
 797#define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 798enum {
 799    /* DSP Append Sub-class */
 800    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 801    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 802    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 803    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 804};
 805
 806#define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 807enum {
 808    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 809    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 810    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 811    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 812    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 813    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 814    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 815    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 816    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 817    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 818    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 819    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 820    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 821    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 822    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 823    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 824    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 825    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 826    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 827    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 828    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 829    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 830};
 831
 832#define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 833enum {
 834    /* DSP Bit/Manipulation Sub-class */
 835    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 836};
 837
 838#define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 839enum {
 840    /* MIPS DSP Multiply Sub-class insns */
 841    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 842    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 843    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 844    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 845    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 846    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 847    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 848    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 849    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 850    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 851    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 852    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 853    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 854    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 855    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 856    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 857    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 858    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 859    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 860    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 861    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 862    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 863    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 864    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 865    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 866    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 867};
 868
 869#define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 870enum {
 871    /* MIPS DSP GPR-Based Shift Sub-class */
 872    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 873    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 874    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 875    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 876    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 877    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 878    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 879    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 880    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 881    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 882    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 883    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 884    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 885    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 886    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 887    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 888    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 889    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 890    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 891    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 892    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 893    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 894    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 895    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 896    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 897    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 898};
 899
 900/* Coprocessor 0 (rs field) */
 901#define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 902
 903enum {
 904    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 905    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 906    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 907    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 908    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 909    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 910    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 911    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 912    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 913    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 914    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 915    OPC_C0       = (0x10 << 21) | OPC_CP0,
 916    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 917    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 918    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 919    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 920    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 921    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 922    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 923    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 924    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 925    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 926    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 927    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 928    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 929    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 930    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 931};
 932
 933/* MFMC0 opcodes */
 934#define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
 935
 936enum {
 937    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 938    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 939    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 940    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 941    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 942    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 943    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 944    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 945};
 946
 947/* Coprocessor 0 (with rs == C0) */
 948#define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
 949
 950enum {
 951    OPC_TLBR     = 0x01 | OPC_C0,
 952    OPC_TLBWI    = 0x02 | OPC_C0,
 953    OPC_TLBINV   = 0x03 | OPC_C0,
 954    OPC_TLBINVF  = 0x04 | OPC_C0,
 955    OPC_TLBWR    = 0x06 | OPC_C0,
 956    OPC_TLBP     = 0x08 | OPC_C0,
 957    OPC_RFE      = 0x10 | OPC_C0,
 958    OPC_ERET     = 0x18 | OPC_C0,
 959    OPC_DERET    = 0x1F | OPC_C0,
 960    OPC_WAIT     = 0x20 | OPC_C0,
 961};
 962
 963/* Coprocessor 1 (rs field) */
 964#define MASK_CP1(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 965
 966/* Values for the fmt field in FP instructions */
 967enum {
 968    /* 0 - 15 are reserved */
 969    FMT_S = 16,          /* single fp */
 970    FMT_D = 17,          /* double fp */
 971    FMT_E = 18,          /* extended fp */
 972    FMT_Q = 19,          /* quad fp */
 973    FMT_W = 20,          /* 32-bit fixed */
 974    FMT_L = 21,          /* 64-bit fixed */
 975    FMT_PS = 22,         /* paired single fp */
 976    /* 23 - 31 are reserved */
 977};
 978
 979enum {
 980    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 981    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 982    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 983    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 984    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 985    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 986    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 987    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 988    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 989    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 990    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 991    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 992    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 993    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 994    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 995    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 996    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 997    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 998    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 999    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1000    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
1001    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
1002    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1003    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1004    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1005    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1006    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1007    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1008    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1009    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1010};
1011
1012#define MASK_CP1_FUNC(op)           (MASK_CP1(op) | (op & 0x3F))
1013#define MASK_BC1(op)                (MASK_CP1(op) | (op & (0x3 << 16)))
1014
1015enum {
1016    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1017    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1018    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1019    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1020};
1021
1022enum {
1023    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1024    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1025};
1026
1027enum {
1028    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1029    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1030};
1031
1032#define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1033
1034enum {
1035    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1036    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1037    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1038    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1039    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1040    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1041    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1042    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1043    OPC_BC2     = (0x08 << 21) | OPC_CP2,
1044    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1045    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1046};
1047
1048#define MASK_LMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1049
1050enum {
1051    OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1052    OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1053    OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1054    OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1055    OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1056    OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1057    OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1058    OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1059
1060    OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1061    OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1062    OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1063    OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1064    OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1065    OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1066    OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1067    OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1068
1069    OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1070    OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1071    OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1072    OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1073    OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1074    OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1075    OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1076    OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1077
1078    OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1079    OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1080    OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1081    OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1082    OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1083    OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1084    OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1085    OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1086
1087    OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1088    OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1089    OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1090    OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1091    OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1092    OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1093
1094    OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1095    OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1096    OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1097    OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1098    OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1099    OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1100
1101    OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1102    OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1103    OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1104    OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1105    OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1106    OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1107
1108    OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1109    OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1110    OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1111    OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1112    OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1113    OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1114
1115    OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1116    OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1117    OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1118    OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1119    OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1120    OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1121
1122    OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1123    OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1124    OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1125    OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1126    OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1127    OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1128
1129    OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1130    OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1131    OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1132    OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1133    OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1134    OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1135
1136    OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1137    OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1138    OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1139    OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1140    OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1141    OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1142};
1143
1144
1145#define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1146
1147enum {
1148    OPC_LWXC1       = 0x00 | OPC_CP3,
1149    OPC_LDXC1       = 0x01 | OPC_CP3,
1150    OPC_LUXC1       = 0x05 | OPC_CP3,
1151    OPC_SWXC1       = 0x08 | OPC_CP3,
1152    OPC_SDXC1       = 0x09 | OPC_CP3,
1153    OPC_SUXC1       = 0x0D | OPC_CP3,
1154    OPC_PREFX       = 0x0F | OPC_CP3,
1155    OPC_ALNV_PS     = 0x1E | OPC_CP3,
1156    OPC_MADD_S      = 0x20 | OPC_CP3,
1157    OPC_MADD_D      = 0x21 | OPC_CP3,
1158    OPC_MADD_PS     = 0x26 | OPC_CP3,
1159    OPC_MSUB_S      = 0x28 | OPC_CP3,
1160    OPC_MSUB_D      = 0x29 | OPC_CP3,
1161    OPC_MSUB_PS     = 0x2E | OPC_CP3,
1162    OPC_NMADD_S     = 0x30 | OPC_CP3,
1163    OPC_NMADD_D     = 0x31 | OPC_CP3,
1164    OPC_NMADD_PS    = 0x36 | OPC_CP3,
1165    OPC_NMSUB_S     = 0x38 | OPC_CP3,
1166    OPC_NMSUB_D     = 0x39 | OPC_CP3,
1167    OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1168};
1169
1170/* MSA Opcodes */
1171#define MASK_MSA_MINOR(op)          (MASK_OP_MAJOR(op) | (op & 0x3F))
1172enum {
1173    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1174    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1175    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1176    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1177    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1178    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1179    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1180    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1181    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1182    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1183    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1184    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1185    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1186    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1187    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1188    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1189    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1190    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1191    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1192    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1193    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1194
1195    /* MI10 instruction */
1196    OPC_LD_B        = (0x20) | OPC_MSA,
1197    OPC_LD_H        = (0x21) | OPC_MSA,
1198    OPC_LD_W        = (0x22) | OPC_MSA,
1199    OPC_LD_D        = (0x23) | OPC_MSA,
1200    OPC_ST_B        = (0x24) | OPC_MSA,
1201    OPC_ST_H        = (0x25) | OPC_MSA,
1202    OPC_ST_W        = (0x26) | OPC_MSA,
1203    OPC_ST_D        = (0x27) | OPC_MSA,
1204};
1205
1206enum {
1207    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1208    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1209    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1210    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1211    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1212    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1213    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1214    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1215    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1216    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1217    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1218    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1219    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1220
1221    /* I8 instruction */
1222    OPC_ANDI_B      = (0x0 << 24) | OPC_MSA_I8_00,
1223    OPC_BMNZI_B     = (0x0 << 24) | OPC_MSA_I8_01,
1224    OPC_SHF_B       = (0x0 << 24) | OPC_MSA_I8_02,
1225    OPC_ORI_B       = (0x1 << 24) | OPC_MSA_I8_00,
1226    OPC_BMZI_B      = (0x1 << 24) | OPC_MSA_I8_01,
1227    OPC_SHF_H       = (0x1 << 24) | OPC_MSA_I8_02,
1228    OPC_NORI_B      = (0x2 << 24) | OPC_MSA_I8_00,
1229    OPC_BSELI_B     = (0x2 << 24) | OPC_MSA_I8_01,
1230    OPC_SHF_W       = (0x2 << 24) | OPC_MSA_I8_02,
1231    OPC_XORI_B      = (0x3 << 24) | OPC_MSA_I8_00,
1232
1233    /* VEC/2R/2RF instruction */
1234    OPC_AND_V       = (0x00 << 21) | OPC_MSA_VEC,
1235    OPC_OR_V        = (0x01 << 21) | OPC_MSA_VEC,
1236    OPC_NOR_V       = (0x02 << 21) | OPC_MSA_VEC,
1237    OPC_XOR_V       = (0x03 << 21) | OPC_MSA_VEC,
1238    OPC_BMNZ_V      = (0x04 << 21) | OPC_MSA_VEC,
1239    OPC_BMZ_V       = (0x05 << 21) | OPC_MSA_VEC,
1240    OPC_BSEL_V      = (0x06 << 21) | OPC_MSA_VEC,
1241
1242    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1243    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1244
1245    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1246    OPC_FILL_df     = (0x00 << 18) | OPC_MSA_2R,
1247    OPC_PCNT_df     = (0x01 << 18) | OPC_MSA_2R,
1248    OPC_NLOC_df     = (0x02 << 18) | OPC_MSA_2R,
1249    OPC_NLZC_df     = (0x03 << 18) | OPC_MSA_2R,
1250
1251    /* 2RF instruction df(bit 16) = _w, _d */
1252    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1253    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1254    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1255    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1256    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1257    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1258    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1259    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1260    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1261    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1262    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1263    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1264    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1265    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1266    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1267    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1268
1269    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1270    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1271    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1272    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1273    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1274    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1275    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1276    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1277    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1278    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1279    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1280    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1281    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1282    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1283    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1284    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1285    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1286    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1287    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1288    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1289    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1290    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1291    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1292    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1293    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1294    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1295    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1296    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1297    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1298    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1299    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1300    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1301    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1302    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1303    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1304    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1305    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1306    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1307    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1308    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1309    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1310    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1311    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1312    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1313    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1314    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1315    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1316    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1317    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1318    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1319    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1320    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1321    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1322    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1323    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1324    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1325    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1326    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1327    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1328    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1329    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1330    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1331    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1332    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1333
1334    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1335    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1336    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1337    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1338    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1339    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1341    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1342    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1343    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1344
1345    /* 3RF instruction _df(bit 21) = _w, _d */
1346    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1347    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1348    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1349    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1350    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1351    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1352    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1353    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1354    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1355    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1356    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1357    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1358    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1359    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1360    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1361    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1362    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1363    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1364    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1365    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1366    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1367    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1368    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1369    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1370    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1371    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1372    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1373    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1374    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1375    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1376    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1377    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1378    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1379    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1380    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1381    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1382    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1383    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1384    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1385    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1386    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1387
1388    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1389    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1390    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1391    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1392    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1393    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1394    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1395    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1396    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1397    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1398    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1399    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1400    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1401};
1402
1403
1404/*
1405 *
1406 *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1407 *       ============================================
1408 *
1409 *
1410 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1411 * instructions set. It is designed to fit the needs of signal, graphical and
1412 * video processing applications. MXU instruction set is used in Xburst family
1413 * of microprocessors by Ingenic.
1414 *
1415 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1416 * the control register.
1417 *
1418 *
1419 *     The notation used in MXU assembler mnemonics
1420 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1421 *
1422 *  Register operands:
1423 *
1424 *   XRa, XRb, XRc, XRd - MXU registers
1425 *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1426 *
1427 *  Non-register operands:
1428 *
1429 *   aptn1 - 1-bit accumulate add/subtract pattern
1430 *   aptn2 - 2-bit accumulate add/subtract pattern
1431 *   eptn2 - 2-bit execute add/subtract pattern
1432 *   optn2 - 2-bit operand pattern
1433 *   optn3 - 3-bit operand pattern
1434 *   sft4  - 4-bit shift amount
1435 *   strd2 - 2-bit stride amount
1436 *
1437 *  Prefixes:
1438 *
1439 *   Level of parallelism:                Operand size:
1440 *    S - single operation at a time       32 - word
1441 *    D - two operations in parallel       16 - half word
1442 *    Q - four operations in parallel       8 - byte
1443 *
1444 *  Operations:
1445 *
1446 *   ADD   - Add or subtract
1447 *   ADDC  - Add with carry-in
1448 *   ACC   - Accumulate
1449 *   ASUM  - Sum together then accumulate (add or subtract)
1450 *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1451 *   AVG   - Average between 2 operands
1452 *   ABD   - Absolute difference
1453 *   ALN   - Align data
1454 *   AND   - Logical bitwise 'and' operation
1455 *   CPS   - Copy sign
1456 *   EXTR  - Extract bits
1457 *   I2M   - Move from GPR register to MXU register
1458 *   LDD   - Load data from memory to XRF
1459 *   LDI   - Load data from memory to XRF (and increase the address base)
1460 *   LUI   - Load unsigned immediate
1461 *   MUL   - Multiply
1462 *   MULU  - Unsigned multiply
1463 *   MADD  - 64-bit operand add 32x32 product
1464 *   MSUB  - 64-bit operand subtract 32x32 product
1465 *   MAC   - Multiply and accumulate (add or subtract)
1466 *   MAD   - Multiply and add or subtract
1467 *   MAX   - Maximum between 2 operands
1468 *   MIN   - Minimum between 2 operands
1469 *   M2I   - Move from MXU register to GPR register
1470 *   MOVZ  - Move if zero
1471 *   MOVN  - Move if non-zero
1472 *   NOR   - Logical bitwise 'nor' operation
1473 *   OR    - Logical bitwise 'or' operation
1474 *   STD   - Store data from XRF to memory
1475 *   SDI   - Store data from XRF to memory (and increase the address base)
1476 *   SLT   - Set of less than comparison
1477 *   SAD   - Sum of absolute differences
1478 *   SLL   - Logical shift left
1479 *   SLR   - Logical shift right
1480 *   SAR   - Arithmetic shift right
1481 *   SAT   - Saturation
1482 *   SFL   - Shuffle
1483 *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1484 *   XOR   - Logical bitwise 'exclusive or' operation
1485 *
1486 *  Suffixes:
1487 *
1488 *   E - Expand results
1489 *   F - Fixed point multiplication
1490 *   L - Low part result
1491 *   R - Doing rounding
1492 *   V - Variable instead of immediate
1493 *   W - Combine above L and V
1494 *
1495 *
1496 *     The list of MXU instructions grouped by functionality
1497 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1498 *
1499 * Load/Store instructions           Multiplication instructions
1500 * -----------------------           ---------------------------
1501 *
1502 *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1503 *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1504 *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1505 *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1506 *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1507 *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1508 *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1509 *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1510 *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1511 *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1512 *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1513 *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1514 *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1515 *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1516 *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1517 *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1518 *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1519 *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1520 *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1521 *  S16SDI XRa, Rb, s10, eptn2
1522 *  S8LDD XRa, Rb, s8, eptn3
1523 *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1524 *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1525 *  S8SDI XRa, Rb, s8, eptn3
1526 *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1527 *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1528 *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1529 *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1530 *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1531 *                                    S32CPS XRa, XRb, XRc
1532 *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1533 * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1534 * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1535 *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1536 *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1537 *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1538 *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1539 *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1540 *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1541 *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1542 *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1543 *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1544 *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1545 *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1546 *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1547 *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1548 *  Q8SLT XRa, XRb, XRc
1549 *  Q8SLTU XRa, XRb, XRc
1550 *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1551 *  Q8MOVN XRa, XRb, XRc             ------------------
1552 *
1553 *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1554 * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1555 * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1556 *                                    D32SARL XRa, XRb, XRc, sft4
1557 *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1558 *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1559 *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1560 *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1561 *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1562 *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1563 * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1564 * -------------------------          Q16SLLV XRa, XRb, Rb
1565 *                                    Q16SLRV XRa, XRb, Rb
1566 *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1567 *  S32ALN XRa, XRb, XRc, Rb
1568 *  S32ALNI XRa, XRb, XRc, s3
1569 *  S32LUI XRa, s8, optn3            Move instructions
1570 *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1571 *  S32EXTRV XRa, XRb, Rs, Rt
1572 *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1573 *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1574 *
1575 *
1576 *     The opcode organization of MXU instructions
1577 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1578 *
1579 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1580 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1581 * other bits up to the instruction level is as follows:
1582 *
1583 *              bits
1584 *             05..00
1585 *
1586 *          ┌─ 000000 ─ OPC_MXU_S32MADD
1587 *          ├─ 000001 ─ OPC_MXU_S32MADDU
1588 *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
1589 *          │
1590 *          │                               20..18
1591 *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1592 *          │                            ├─ 001 ─ OPC_MXU_S32MIN
1593 *          │                            ├─ 010 ─ OPC_MXU_D16MAX
1594 *          │                            ├─ 011 ─ OPC_MXU_D16MIN
1595 *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
1596 *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
1597 *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
1598 *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
1599 *          ├─ 000100 ─ OPC_MXU_S32MSUB
1600 *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
1601 *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1602 *          │                            ├─ 001 ─ OPC_MXU_D16SLT
1603 *          │                            ├─ 010 ─ OPC_MXU_D16AVG
1604 *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
1605 *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
1606 *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
1607 *          │                            └─ 111 ─ OPC_MXU_Q8ADD
1608 *          │
1609 *          │                               20..18
1610 *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1611 *          │                            ├─ 010 ─ OPC_MXU_D16CPS
1612 *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
1613 *          │                            └─ 110 ─ OPC_MXU_Q16SAT
1614 *          ├─ 001000 ─ OPC_MXU_D16MUL
1615 *          │                               25..24
1616 *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1617 *          │                            └─ 01 ─ OPC_MXU_D16MULE
1618 *          ├─ 001010 ─ OPC_MXU_D16MAC
1619 *          ├─ 001011 ─ OPC_MXU_D16MACF
1620 *          ├─ 001100 ─ OPC_MXU_D16MADL
1621 *          ├─ 001101 ─ OPC_MXU_S16MAD
1622 *          ├─ 001110 ─ OPC_MXU_Q16ADD
1623 *          ├─ 001111 ─ OPC_MXU_D16MACE     23
1624 *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
1625 *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1626 *          │
1627 *          │                               23
1628 *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1629 *          │                            └─ 1 ─ OPC_MXU_S32STDR
1630 *          │
1631 *          │                               13..10
1632 *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1633 *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
1634 *          │
1635 *          │                               13..10
1636 *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1637 *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
1638 *          │
1639 *          │                               23
1640 *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1641 *          │                            └─ 1 ─ OPC_MXU_S32LDIR
1642 *          │
1643 *          │                               23
1644 *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1645 *          │                            └─ 1 ─ OPC_MXU_S32SDIR
1646 *          │
1647 *          │                               13..10
1648 *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1649 *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
1650 *          │
1651 *          │                               13..10
1652 *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1653 *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
1654 *          ├─ 011000 ─ OPC_MXU_D32ADD
1655 *          │                               23..22
1656 *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1657 * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
1658 *          │                            └─ 10 ─ OPC_MXU_D32ASUM
1659 *          ├─ 011010 ─ <not assigned>
1660 *          │                               23..22
1661 *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1662 *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
1663 *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
1664 *          │
1665 *          │                               23..22
1666 *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1667 *          │                            ├─ 01 ─ OPC_MXU_D8SUM
1668 *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
1669 *          ├─ 011110 ─ <not assigned>
1670 *          ├─ 011111 ─ <not assigned>
1671 *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
1672 *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
1673 *          ├─ 100010 ─ OPC_MXU_S8LDD
1674 *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
1675 *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
1676 *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
1677 *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
1678 *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1679 *          │
1680 *          │                               20..18
1681 *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1682 *          │                            ├─ 001 ─ OPC_MXU_S32ALN
1683 *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
1684 *          │                            ├─ 011 ─ OPC_MXU_S32LUI
1685 *          │                            ├─ 100 ─ OPC_MXU_S32NOR
1686 *          │                            ├─ 101 ─ OPC_MXU_S32AND
1687 *          │                            ├─ 110 ─ OPC_MXU_S32OR
1688 *          │                            └─ 111 ─ OPC_MXU_S32XOR
1689 *          │
1690 *          │                               7..5
1691 *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1692 *          │                            ├─ 001 ─ OPC_MXU_LXH
1693 *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
1694 *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
1695 *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
1696 *          ├─ 101100 ─ OPC_MXU_S16LDI
1697 *          ├─ 101101 ─ OPC_MXU_S16SDI
1698 *          ├─ 101110 ─ OPC_MXU_S32M2I
1699 *          ├─ 101111 ─ OPC_MXU_S32I2M
1700 *          ├─ 110000 ─ OPC_MXU_D32SLL
1701 *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
1702 *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
1703 *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
1704 *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
1705 *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
1706 *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
1707 *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1708 *          │
1709 *          ├─ 110111 ─ OPC_MXU_Q16SAR
1710 *          │                               23..22
1711 *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1712 *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
1713 *          │
1714 *          │                               20..18
1715 *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1716 *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
1717 *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
1718 *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
1719 *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
1720 *          │                            └─ 101 ─ OPC_MXU_S32MOVN
1721 *          │
1722 *          │                               23..22
1723 *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1724 *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
1725 *          ├─ 111011 ─ OPC_MXU_Q16SCOP
1726 *          ├─ 111100 ─ OPC_MXU_Q8MADL
1727 *          ├─ 111101 ─ OPC_MXU_S32SFL
1728 *          ├─ 111110 ─ OPC_MXU_Q8SAD
1729 *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
1730 *
1731 *
1732 * Compiled after:
1733 *
1734 *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1735 *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1736 */
1737
1738enum {
1739    OPC_MXU_S32MADD  = 0x00,
1740    OPC_MXU_S32MADDU = 0x01,
1741    OPC__MXU_MUL     = 0x02,
1742    OPC_MXU__POOL00  = 0x03,
1743    OPC_MXU_S32MSUB  = 0x04,
1744    OPC_MXU_S32MSUBU = 0x05,
1745    OPC_MXU__POOL01  = 0x06,
1746    OPC_MXU__POOL02  = 0x07,
1747    OPC_MXU_D16MUL   = 0x08,
1748    OPC_MXU__POOL03  = 0x09,
1749    OPC_MXU_D16MAC   = 0x0A,
1750    OPC_MXU_D16MACF  = 0x0B,
1751    OPC_MXU_D16MADL  = 0x0C,
1752    OPC_MXU_S16MAD   = 0x0D,
1753    OPC_MXU_Q16ADD   = 0x0E,
1754    OPC_MXU_D16MACE  = 0x0F,
1755    OPC_MXU__POOL04  = 0x10,
1756    OPC_MXU__POOL05  = 0x11,
1757    OPC_MXU__POOL06  = 0x12,
1758    OPC_MXU__POOL07  = 0x13,
1759    OPC_MXU__POOL08  = 0x14,
1760    OPC_MXU__POOL09  = 0x15,
1761    OPC_MXU__POOL10  = 0x16,
1762    OPC_MXU__POOL11  = 0x17,
1763    OPC_MXU_D32ADD   = 0x18,
1764    OPC_MXU__POOL12  = 0x19,
1765    /* not assigned 0x1A */
1766    OPC_MXU__POOL13  = 0x1B,
1767    OPC_MXU__POOL14  = 0x1C,
1768    OPC_MXU_Q8ACCE   = 0x1D,
1769    /* not assigned 0x1E */
1770    /* not assigned 0x1F */
1771    /* not assigned 0x20 */
1772    /* not assigned 0x21 */
1773    OPC_MXU_S8LDD    = 0x22,
1774    OPC_MXU_S8STD    = 0x23,
1775    OPC_MXU_S8LDI    = 0x24,
1776    OPC_MXU_S8SDI    = 0x25,
1777    OPC_MXU__POOL15  = 0x26,
1778    OPC_MXU__POOL16  = 0x27,
1779    OPC_MXU__POOL17  = 0x28,
1780    /* not assigned 0x29 */
1781    OPC_MXU_S16LDD   = 0x2A,
1782    OPC_MXU_S16STD   = 0x2B,
1783    OPC_MXU_S16LDI   = 0x2C,
1784    OPC_MXU_S16SDI   = 0x2D,
1785    OPC_MXU_S32M2I   = 0x2E,
1786    OPC_MXU_S32I2M   = 0x2F,
1787    OPC_MXU_D32SLL   = 0x30,
1788    OPC_MXU_D32SLR   = 0x31,
1789    OPC_MXU_D32SARL  = 0x32,
1790    OPC_MXU_D32SAR   = 0x33,
1791    OPC_MXU_Q16SLL   = 0x34,
1792    OPC_MXU_Q16SLR   = 0x35,
1793    OPC_MXU__POOL18  = 0x36,
1794    OPC_MXU_Q16SAR   = 0x37,
1795    OPC_MXU__POOL19  = 0x38,
1796    OPC_MXU__POOL20  = 0x39,
1797    OPC_MXU__POOL21  = 0x3A,
1798    OPC_MXU_Q16SCOP  = 0x3B,
1799    OPC_MXU_Q8MADL   = 0x3C,
1800    OPC_MXU_S32SFL   = 0x3D,
1801    OPC_MXU_Q8SAD    = 0x3E,
1802    /* not assigned 0x3F */
1803};
1804
1805
1806/*
1807 * MXU pool 00
1808 */
1809enum {
1810    OPC_MXU_S32MAX   = 0x00,
1811    OPC_MXU_S32MIN   = 0x01,
1812    OPC_MXU_D16MAX   = 0x02,
1813    OPC_MXU_D16MIN   = 0x03,
1814    OPC_MXU_Q8MAX    = 0x04,
1815    OPC_MXU_Q8MIN    = 0x05,
1816    OPC_MXU_Q8SLT    = 0x06,
1817    OPC_MXU_Q8SLTU   = 0x07,
1818};
1819
1820/*
1821 * MXU pool 01
1822 */
1823enum {
1824    OPC_MXU_S32SLT   = 0x00,
1825    OPC_MXU_D16SLT   = 0x01,
1826    OPC_MXU_D16AVG   = 0x02,
1827    OPC_MXU_D16AVGR  = 0x03,
1828    OPC_MXU_Q8AVG    = 0x04,
1829    OPC_MXU_Q8AVGR   = 0x05,
1830    OPC_MXU_Q8ADD    = 0x07,
1831};
1832
1833/*
1834 * MXU pool 02
1835 */
1836enum {
1837    OPC_MXU_S32CPS   = 0x00,
1838    OPC_MXU_D16CPS   = 0x02,
1839    OPC_MXU_Q8ABD    = 0x04,
1840    OPC_MXU_Q16SAT   = 0x06,
1841};
1842
1843/*
1844 * MXU pool 03
1845 */
1846enum {
1847    OPC_MXU_D16MULF  = 0x00,
1848    OPC_MXU_D16MULE  = 0x01,
1849};
1850
1851/*
1852 * MXU pool 04
1853 */
1854enum {
1855    OPC_MXU_S32LDD   = 0x00,
1856    OPC_MXU_S32LDDR  = 0x01,
1857};
1858
1859/*
1860 * MXU pool 05
1861 */
1862enum {
1863    OPC_MXU_S32STD   = 0x00,
1864    OPC_MXU_S32STDR  = 0x01,
1865};
1866
1867/*
1868 * MXU pool 06
1869 */
1870enum {
1871    OPC_MXU_S32LDDV  = 0x00,
1872    OPC_MXU_S32LDDVR = 0x01,
1873};
1874
1875/*
1876 * MXU pool 07
1877 */
1878enum {
1879    OPC_MXU_S32STDV  = 0x00,
1880    OPC_MXU_S32STDVR = 0x01,
1881};
1882
1883/*
1884 * MXU pool 08
1885 */
1886enum {
1887    OPC_MXU_S32LDI   = 0x00,
1888    OPC_MXU_S32LDIR  = 0x01,
1889};
1890
1891/*
1892 * MXU pool 09
1893 */
1894enum {
1895    OPC_MXU_S32SDI   = 0x00,
1896    OPC_MXU_S32SDIR  = 0x01,
1897};
1898
1899/*
1900 * MXU pool 10
1901 */
1902enum {
1903    OPC_MXU_S32LDIV  = 0x00,
1904    OPC_MXU_S32LDIVR = 0x01,
1905};
1906
1907/*
1908 * MXU pool 11
1909 */
1910enum {
1911    OPC_MXU_S32SDIV  = 0x00,
1912    OPC_MXU_S32SDIVR = 0x01,
1913};
1914
1915/*
1916 * MXU pool 12
1917 */
1918enum {
1919    OPC_MXU_D32ACC   = 0x00,
1920    OPC_MXU_D32ACCM  = 0x01,
1921    OPC_MXU_D32ASUM  = 0x02,
1922};
1923
1924/*
1925 * MXU pool 13
1926 */
1927enum {
1928    OPC_MXU_Q16ACC   = 0x00,
1929    OPC_MXU_Q16ACCM  = 0x01,
1930    OPC_MXU_Q16ASUM  = 0x02,
1931};
1932
1933/*
1934 * MXU pool 14
1935 */
1936enum {
1937    OPC_MXU_Q8ADDE   = 0x00,
1938    OPC_MXU_D8SUM    = 0x01,
1939    OPC_MXU_D8SUMC   = 0x02,
1940};
1941
1942/*
1943 * MXU pool 15
1944 */
1945enum {
1946    OPC_MXU_S32MUL   = 0x00,
1947    OPC_MXU_S32MULU  = 0x01,
1948    OPC_MXU_S32EXTR  = 0x02,
1949    OPC_MXU_S32EXTRV = 0x03,
1950};
1951
1952/*
1953 * MXU pool 16
1954 */
1955enum {
1956    OPC_MXU_D32SARW  = 0x00,
1957    OPC_MXU_S32ALN   = 0x01,
1958    OPC_MXU_S32ALNI  = 0x02,
1959    OPC_MXU_S32LUI   = 0x03,
1960    OPC_MXU_S32NOR   = 0x04,
1961    OPC_MXU_S32AND   = 0x05,
1962    OPC_MXU_S32OR    = 0x06,
1963    OPC_MXU_S32XOR   = 0x07,
1964};
1965
1966/*
1967 * MXU pool 17
1968 */
1969enum {
1970    OPC_MXU_LXB      = 0x00,
1971    OPC_MXU_LXH      = 0x01,
1972    OPC_MXU_LXW      = 0x03,
1973    OPC_MXU_LXBU     = 0x04,
1974    OPC_MXU_LXHU     = 0x05,
1975};
1976
1977/*
1978 * MXU pool 18
1979 */
1980enum {
1981    OPC_MXU_D32SLLV  = 0x00,
1982    OPC_MXU_D32SLRV  = 0x01,
1983    OPC_MXU_D32SARV  = 0x03,
1984    OPC_MXU_Q16SLLV  = 0x04,
1985    OPC_MXU_Q16SLRV  = 0x05,
1986    OPC_MXU_Q16SARV  = 0x07,
1987};
1988
1989/*
1990 * MXU pool 19
1991 */
1992enum {
1993    OPC_MXU_Q8MUL    = 0x00,
1994    OPC_MXU_Q8MULSU  = 0x01,
1995};
1996
1997/*
1998 * MXU pool 20
1999 */
2000enum {
2001    OPC_MXU_Q8MOVZ   = 0x00,
2002    OPC_MXU_Q8MOVN   = 0x01,
2003    OPC_MXU_D16MOVZ  = 0x02,
2004    OPC_MXU_D16MOVN  = 0x03,
2005    OPC_MXU_S32MOVZ  = 0x04,
2006    OPC_MXU_S32MOVN  = 0x05,
2007};
2008
2009/*
2010 * MXU pool 21
2011 */
2012enum {
2013    OPC_MXU_Q8MAC    = 0x00,
2014    OPC_MXU_Q8MACSU  = 0x01,
2015};
2016
2017/*
2018 *     Overview of the TX79-specific instruction set
2019 *     =============================================
2020 *
2021 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2022 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2023 * instructions and certain multimedia instructions (MMIs). These MMIs
2024 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2025 * or sixteen 8-bit paths.
2026 *
2027 * Reference:
2028 *
2029 * The Toshiba TX System RISC TX79 Core Architecture manual,
2030 * https://wiki.qemu.org/File:C790.pdf
2031 *
2032 *     Three-Operand Multiply and Multiply-Add (4 instructions)
2033 *     --------------------------------------------------------
2034 * MADD    [rd,] rs, rt      Multiply/Add
2035 * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
2036 * MULT    [rd,] rs, rt      Multiply (3-operand)
2037 * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2038 *
2039 *     Multiply Instructions for Pipeline 1 (10 instructions)
2040 *     ------------------------------------------------------
2041 * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2042 * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2043 * DIV1    rs, rt            Divide Pipeline 1
2044 * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2045 * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2046 * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2047 * MFHI1   rd                Move From HI1 Register
2048 * MFLO1   rd                Move From LO1 Register
2049 * MTHI1   rs                Move To HI1 Register
2050 * MTLO1   rs                Move To LO1 Register
2051 *
2052 *     Arithmetic (19 instructions)
2053 *     ----------------------------
2054 * PADDB   rd, rs, rt        Parallel Add Byte
2055 * PSUBB   rd, rs, rt        Parallel Subtract Byte
2056 * PADDH   rd, rs, rt        Parallel Add Halfword
2057 * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2058 * PADDW   rd, rs, rt        Parallel Add Word
2059 * PSUBW   rd, rs, rt        Parallel Subtract Word
2060 * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2061 * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2062 * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2063 * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2064 * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2065 * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2066 * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2067 * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2068 * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2069 * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2070 * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2071 * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2072 * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2073 *
2074 *     Min/Max (4 instructions)
2075 *     ------------------------
2076 * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2077 * PMINH   rd, rs, rt        Parallel Minimum Halfword
2078 * PMAXW   rd, rs, rt        Parallel Maximum Word
2079 * PMINW   rd, rs, rt        Parallel Minimum Word
2080 *
2081 *     Absolute (2 instructions)
2082 *     -------------------------
2083 * PABSH   rd, rt            Parallel Absolute Halfword
2084 * PABSW   rd, rt            Parallel Absolute Word
2085 *
2086 *     Logical (4 instructions)
2087 *     ------------------------
2088 * PAND    rd, rs, rt        Parallel AND
2089 * POR     rd, rs, rt        Parallel OR
2090 * PXOR    rd, rs, rt        Parallel XOR
2091 * PNOR    rd, rs, rt        Parallel NOR
2092 *
2093 *     Shift (9 instructions)
2094 *     ----------------------
2095 * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2096 * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2097 * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2098 * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2099 * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2100 * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2101 * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2102 * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2103 * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2104 *
2105 *     Compare (6 instructions)
2106 *     ------------------------
2107 * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2108 * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2109 * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2110 * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2111 * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2112 * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2113 *
2114 *     LZC (1 instruction)
2115 *     -------------------
2116 * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2117 *
2118 *     Quadword Load and Store (2 instructions)
2119 *     ----------------------------------------
2120 * LQ      rt, offset(base)  Load Quadword
2121 * SQ      rt, offset(base)  Store Quadword
2122 *
2123 *     Multiply and Divide (19 instructions)
2124 *     -------------------------------------
2125 * PMULTW  rd, rs, rt        Parallel Multiply Word
2126 * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2127 * PDIVW   rs, rt            Parallel Divide Word
2128 * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2129 * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2130 * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2131 * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2132 * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2133 * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2134 * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2135 * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2136 * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2137 * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2138 * PMFHI   rd                Parallel Move From HI Register
2139 * PMFLO   rd                Parallel Move From LO Register
2140 * PMTHI   rs                Parallel Move To HI Register
2141 * PMTLO   rs                Parallel Move To LO Register
2142 * PMFHL   rd                Parallel Move From HI/LO Register
2143 * PMTHL   rs                Parallel Move To HI/LO Register
2144 *
2145 *     Pack/Extend (11 instructions)
2146 *     -----------------------------
2147 * PPAC5   rd, rt            Parallel Pack to 5 bits
2148 * PPACB   rd, rs, rt        Parallel Pack to Byte
2149 * PPACH   rd, rs, rt        Parallel Pack to Halfword
2150 * PPACW   rd, rs, rt        Parallel Pack to Word
2151 * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2152 * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2153 * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2154 * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2155 * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2156 * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2157 * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2158 *
2159 *     Others (16 instructions)
2160 *     ------------------------
2161 * PCPYH   rd, rt            Parallel Copy Halfword
2162 * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2163 * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2164 * PREVH   rd, rt            Parallel Reverse Halfword
2165 * PINTH   rd, rs, rt        Parallel Interleave Halfword
2166 * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2167 * PEXEH   rd, rt            Parallel Exchange Even Halfword
2168 * PEXCH   rd, rt            Parallel Exchange Center Halfword
2169 * PEXEW   rd, rt            Parallel Exchange Even Word
2170 * PEXCW   rd, rt            Parallel Exchange Center Word
2171 * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2172 * MFSA    rd                Move from Shift Amount Register
2173 * MTSA    rs                Move to Shift Amount Register
2174 * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2175 * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2176 * PROT3W  rd, rt            Parallel Rotate 3 Words
2177 *
2178 *     MMI (MultiMedia Instruction) encodings
2179 *     ======================================
2180 *
2181 * MMI instructions encoding table keys:
2182 *
2183 *     *   This code is reserved for future use. An attempt to execute it
2184 *         causes a Reserved Instruction exception.
2185 *     %   This code indicates an instruction class. The instruction word
2186 *         must be further decoded by examining additional tables that show
2187 *         the values for other instruction fields.
2188 *     #   This code is reserved for the unsupported instructions DMULT,
2189 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2190 *         to execute it causes a Reserved Instruction exception.
2191 *
2192 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2193 *
2194 *  31    26                                        0
2195 * +--------+----------------------------------------+
2196 * | opcode |                                        |
2197 * +--------+----------------------------------------+
2198 *
2199 *   opcode  bits 28..26
2200 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2201 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2202 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2203 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2204 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2205 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2206 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2207 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2208 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2209 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2210 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2211 */
2212
2213enum {
2214    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2215    MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2216    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2217};
2218
2219/*
2220 * MMI instructions with opcode field = MMI:
2221 *
2222 *  31    26                                 5      0
2223 * +--------+-------------------------------+--------+
2224 * |   MMI  |                               |function|
2225 * +--------+-------------------------------+--------+
2226 *
2227 * function  bits 2..0
2228 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2229 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2230 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2231 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2232 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2233 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2234 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2235 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2236 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2237 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2238 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2239 */
2240
2241#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2242enum {
2243    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2244    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2245    MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2246    MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2247    MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2248    MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2249    MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2250    MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2251    MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2252    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2253    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2254    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2255    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2256    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2257    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2258    MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2259    MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2260    MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2261    MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2262    MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2263    MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2264    MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2265    MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2266    MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2267    MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2268};
2269
2270/*
2271 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2272 *
2273 *  31    26                        10     6 5      0
2274 * +--------+----------------------+--------+--------+
2275 * |   MMI  |                      |function|  MMI0  |
2276 * +--------+----------------------+--------+--------+
2277 *
2278 * function  bits 7..6
2279 *     bits |   0   |   1   |   2   |   3
2280 *    10..8 |   00  |   01  |   10  |   11
2281 *   -------+-------+-------+-------+-------
2282 *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2283 *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2284 *    2 010 | PADDB | PSUBB | PCGTB |   *
2285 *    3 011 |   *   |   *   |   *   |   *
2286 *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2287 *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2288 *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2289 *    7 111 |   *   |   *   | PEXT5 | PPAC5
2290 */
2291
2292#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2293enum {
2294    MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2295    MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2296    MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2297    MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2298    MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2299    MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2300    MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2301    MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2302    MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2303    MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2304    MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2305    MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2306    MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2307    MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2308    MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2309    MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2310    MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2311    MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2312    MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2313    MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2314    MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2315    MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2316    MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2317    MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2318    MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2319};
2320
2321/*
2322 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2323 *
2324 *  31    26                        10     6 5      0
2325 * +--------+----------------------+--------+--------+
2326 * |   MMI  |                      |function|  MMI1  |
2327 * +--------+----------------------+--------+--------+
2328 *
2329 * function  bits 7..6
2330 *     bits |   0   |   1   |   2   |   3
2331 *    10..8 |   00  |   01  |   10  |   11
2332 *   -------+-------+-------+-------+-------
2333 *    0 000 |   *   | PABSW | PCEQW | PMINW
2334 *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2335 *    2 010 |   *   |   *   | PCEQB |   *
2336 *    3 011 |   *   |   *   |   *   |   *
2337 *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2338 *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2339 *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2340 *    7 111 |   *   |   *   |   *   |   *
2341 */
2342
2343#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2344enum {
2345    MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2346    MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2347    MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2348    MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2349    MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2350    MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2351    MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2352    MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2353    MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2354    MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2355    MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2356    MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2357    MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2358    MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2359    MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2360    MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2361    MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2362    MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2363};
2364
2365/*
2366 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2367 *
2368 *  31    26                        10     6 5      0
2369 * +--------+----------------------+--------+--------+
2370 * |   MMI  |                      |function|  MMI2  |
2371 * +--------+----------------------+--------+--------+
2372 *
2373 * function  bits 7..6
2374 *     bits |   0   |   1   |   2   |   3
2375 *    10..8 |   00  |   01  |   10  |   11
2376 *   -------+-------+-------+-------+-------
2377 *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2378 *    1 001 | PMSUBW|   *   |   *   |   *
2379 *    2 010 | PMFHI | PMFLO | PINTH |   *
2380 *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2381 *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2382 *    5 101 | PMSUBH| PHMSBH|   *   |   *
2383 *    6 110 |   *   |   *   | PEXEH | PREVH
2384 *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2385 */
2386
2387#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2388enum {
2389    MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2390    MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2391    MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2392    MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2393    MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2394    MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2395    MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2396    MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2397    MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2398    MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2399    MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2400    MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2401    MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2402    MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2403    MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2404    MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2405    MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2406    MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2407    MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2408    MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2409    MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2410    MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2411};
2412
2413/*
2414 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2415 *
2416 *  31    26                        10     6 5      0
2417 * +--------+----------------------+--------+--------+
2418 * |   MMI  |                      |function|  MMI3  |
2419 * +--------+----------------------+--------+--------+
2420 *
2421 * function  bits 7..6
2422 *     bits |   0   |   1   |   2   |   3
2423 *    10..8 |   00  |   01  |   10  |   11
2424 *   -------+-------+-------+-------+-------
2425 *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2426 *    1 001 |   *   |   *   |   *   |   *
2427 *    2 010 | PMTHI | PMTLO | PINTEH|   *
2428 *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2429 *    4 100 |   *   |   *   |  POR  |  PNOR
2430 *    5 101 |   *   |   *   |   *   |   *
2431 *    6 110 |   *   |   *   | PEXCH | PCPYH
2432 *    7 111 |   *   |   *   | PEXCW |   *
2433 */
2434
2435#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2436enum {
2437    MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2438    MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2439    MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2440    MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2441    MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2442    MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2443    MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2444    MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2445    MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2446    MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2447    MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2448    MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2449    MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2450};
2451
2452/* global register indices */
2453static TCGv cpu_gpr[32], cpu_PC;
2454static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2455static TCGv cpu_dspctrl, btarget, bcond;
2456static TCGv cpu_lladdr, cpu_llval;
2457static TCGv_i32 hflags;
2458static TCGv_i32 fpu_fcr0, fpu_fcr31;
2459static TCGv_i64 fpu_f64[32];
2460static TCGv_i64 msa_wr_d[64];
2461
2462#if defined(TARGET_MIPS64)
2463/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2464static TCGv_i64 cpu_mmr[32];
2465#endif
2466
2467#if !defined(TARGET_MIPS64)
2468/* MXU registers */
2469static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2470static TCGv mxu_CR;
2471#endif
2472
2473#include "exec/gen-icount.h"
2474
2475#define gen_helper_0e0i(name, arg) do {                           \
2476    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2477    gen_helper_##name(cpu_env, helper_tmp);                       \
2478    tcg_temp_free_i32(helper_tmp);                                \
2479    } while (0)
2480
2481#define gen_helper_0e1i(name, arg1, arg2) do {                    \
2482    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2483    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2484    tcg_temp_free_i32(helper_tmp);                                \
2485    } while (0)
2486
2487#define gen_helper_1e0i(name, ret, arg1) do {                     \
2488    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2489    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2490    tcg_temp_free_i32(helper_tmp);                                \
2491    } while (0)
2492
2493#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2494    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2495    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2496    tcg_temp_free_i32(helper_tmp);                                \
2497    } while (0)
2498
2499#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2500    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2501    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2502    tcg_temp_free_i32(helper_tmp);                                \
2503    } while (0)
2504
2505#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2506    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2507    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2508    tcg_temp_free_i32(helper_tmp);                                \
2509    } while (0)
2510
2511#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2512    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2513    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2514    tcg_temp_free_i32(helper_tmp);                                \
2515    } while (0)
2516
2517typedef struct DisasContext {
2518    DisasContextBase base;
2519    target_ulong saved_pc;
2520    target_ulong page_start;
2521    uint32_t opcode;
2522    uint64_t insn_flags;
2523    int32_t CP0_Config1;
2524    int32_t CP0_Config2;
2525    int32_t CP0_Config3;
2526    int32_t CP0_Config5;
2527    /* Routine used to access memory */
2528    int mem_idx;
2529    MemOp default_tcg_memop_mask;
2530    uint32_t hflags, saved_hflags;
2531    target_ulong btarget;
2532    bool ulri;
2533    int kscrexist;
2534    bool rxi;
2535    int ie;
2536    bool bi;
2537    bool bp;
2538    uint64_t PAMask;
2539    bool mvh;
2540    bool eva;
2541    bool sc;
2542    int CP0_LLAddr_shift;
2543    bool ps;
2544    bool vp;
2545    bool cmgcr;
2546    bool mrp;
2547    bool nan2008;
2548    bool abs2008;
2549    bool saar;
2550} DisasContext;
2551
2552#define DISAS_STOP       DISAS_TARGET_0
2553#define DISAS_EXIT       DISAS_TARGET_1
2554
2555static const char * const regnames[] = {
2556    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2557    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2558    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2559    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2560};
2561
2562static const char * const regnames_HI[] = {
2563    "HI0", "HI1", "HI2", "HI3",
2564};
2565
2566static const char * const regnames_LO[] = {
2567    "LO0", "LO1", "LO2", "LO3",
2568};
2569
2570static const char * const fregnames[] = {
2571    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2572    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2573    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2574    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2575};
2576
2577static const char * const msaregnames[] = {
2578    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2579    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2580    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2581    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2582    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2583    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2584    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2585    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2586    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2587    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2588    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2589    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2590    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2591    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2592    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2593    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2594};
2595
2596#if !defined(TARGET_MIPS64)
2597static const char * const mxuregnames[] = {
2598    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2599    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2600};
2601#endif
2602
2603#define LOG_DISAS(...)                                                        \
2604    do {                                                                      \
2605        if (MIPS_DEBUG_DISAS) {                                               \
2606            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2607        }                                                                     \
2608    } while (0)
2609
2610#define MIPS_INVAL(op)                                                        \
2611    do {                                                                      \
2612        if (MIPS_DEBUG_DISAS) {                                               \
2613            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2614                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2615                          ctx->base.pc_next, ctx->opcode, op,                 \
2616                          ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2617                          ((ctx->opcode >> 16) & 0x1F));                      \
2618        }                                                                     \
2619    } while (0)
2620
2621/* General purpose registers moves. */
2622static inline void gen_load_gpr(TCGv t, int reg)
2623{
2624    if (reg == 0) {
2625        tcg_gen_movi_tl(t, 0);
2626    } else {
2627        tcg_gen_mov_tl(t, cpu_gpr[reg]);
2628    }
2629}
2630
2631static inline void gen_store_gpr(TCGv t, int reg)
2632{
2633    if (reg != 0) {
2634        tcg_gen_mov_tl(cpu_gpr[reg], t);
2635    }
2636}
2637
2638/* Moves to/from shadow registers. */
2639static inline void gen_load_srsgpr(int from, int to)
2640{
2641    TCGv t0 = tcg_temp_new();
2642
2643    if (from == 0) {
2644        tcg_gen_movi_tl(t0, 0);
2645    } else {
2646        TCGv_i32 t2 = tcg_temp_new_i32();
2647        TCGv_ptr addr = tcg_temp_new_ptr();
2648
2649        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2650        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2651        tcg_gen_andi_i32(t2, t2, 0xf);
2652        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2653        tcg_gen_ext_i32_ptr(addr, t2);
2654        tcg_gen_add_ptr(addr, cpu_env, addr);
2655
2656        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2657        tcg_temp_free_ptr(addr);
2658        tcg_temp_free_i32(t2);
2659    }
2660    gen_store_gpr(t0, to);
2661    tcg_temp_free(t0);
2662}
2663
2664static inline void gen_store_srsgpr(int from, int to)
2665{
2666    if (to != 0) {
2667        TCGv t0 = tcg_temp_new();
2668        TCGv_i32 t2 = tcg_temp_new_i32();
2669        TCGv_ptr addr = tcg_temp_new_ptr();
2670
2671        gen_load_gpr(t0, from);
2672        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2673        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2674        tcg_gen_andi_i32(t2, t2, 0xf);
2675        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2676        tcg_gen_ext_i32_ptr(addr, t2);
2677        tcg_gen_add_ptr(addr, cpu_env, addr);
2678
2679        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2680        tcg_temp_free_ptr(addr);
2681        tcg_temp_free_i32(t2);
2682        tcg_temp_free(t0);
2683    }
2684}
2685
2686#if !defined(TARGET_MIPS64)
2687/* MXU General purpose registers moves. */
2688static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2689{
2690    if (reg == 0) {
2691        tcg_gen_movi_tl(t, 0);
2692    } else if (reg <= 15) {
2693        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2694    }
2695}
2696
2697static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2698{
2699    if (reg > 0 && reg <= 15) {
2700        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2701    }
2702}
2703
2704/* MXU control register moves. */
2705static inline void gen_load_mxu_cr(TCGv t)
2706{
2707    tcg_gen_mov_tl(t, mxu_CR);
2708}
2709
2710static inline void gen_store_mxu_cr(TCGv t)
2711{
2712    /* TODO: Add handling of RW rules for MXU_CR. */
2713    tcg_gen_mov_tl(mxu_CR, t);
2714}
2715#endif
2716
2717
2718/* Tests */
2719static inline void gen_save_pc(target_ulong pc)
2720{
2721    tcg_gen_movi_tl(cpu_PC, pc);
2722}
2723
2724static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2725{
2726    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2727    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2728        gen_save_pc(ctx->base.pc_next);
2729        ctx->saved_pc = ctx->base.pc_next;
2730    }
2731    if (ctx->hflags != ctx->saved_hflags) {
2732        tcg_gen_movi_i32(hflags, ctx->hflags);
2733        ctx->saved_hflags = ctx->hflags;
2734        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2735        case MIPS_HFLAG_BR:
2736            break;
2737        case MIPS_HFLAG_BC:
2738        case MIPS_HFLAG_BL:
2739        case MIPS_HFLAG_B:
2740            tcg_gen_movi_tl(btarget, ctx->btarget);
2741            break;
2742        }
2743    }
2744}
2745
2746static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2747{
2748    ctx->saved_hflags = ctx->hflags;
2749    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2750    case MIPS_HFLAG_BR:
2751        break;
2752    case MIPS_HFLAG_BC:
2753    case MIPS_HFLAG_BL:
2754    case MIPS_HFLAG_B:
2755        ctx->btarget = env->btarget;
2756        break;
2757    }
2758}
2759
2760static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2761{
2762    TCGv_i32 texcp = tcg_const_i32(excp);
2763    TCGv_i32 terr = tcg_const_i32(err);
2764    save_cpu_state(ctx, 1);
2765    gen_helper_raise_exception_err(cpu_env, texcp, terr);
2766    tcg_temp_free_i32(terr);
2767    tcg_temp_free_i32(texcp);
2768    ctx->base.is_jmp = DISAS_NORETURN;
2769}
2770
2771static inline void generate_exception(DisasContext *ctx, int excp)
2772{
2773    gen_helper_0e0i(raise_exception, excp);
2774}
2775
2776static inline void generate_exception_end(DisasContext *ctx, int excp)
2777{
2778    generate_exception_err(ctx, excp, 0);
2779}
2780
2781/* Floating point register moves. */
2782static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2783{
2784    if (ctx->hflags & MIPS_HFLAG_FRE) {
2785        generate_exception(ctx, EXCP_RI);
2786    }
2787    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2788}
2789
2790static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2791{
2792    TCGv_i64 t64;
2793    if (ctx->hflags & MIPS_HFLAG_FRE) {
2794        generate_exception(ctx, EXCP_RI);
2795    }
2796    t64 = tcg_temp_new_i64();
2797    tcg_gen_extu_i32_i64(t64, t);
2798    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2799    tcg_temp_free_i64(t64);
2800}
2801
2802static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2803{
2804    if (ctx->hflags & MIPS_HFLAG_F64) {
2805        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2806    } else {
2807        gen_load_fpr32(ctx, t, reg | 1);
2808    }
2809}
2810
2811static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2812{
2813    if (ctx->hflags & MIPS_HFLAG_F64) {
2814        TCGv_i64 t64 = tcg_temp_new_i64();
2815        tcg_gen_extu_i32_i64(t64, t);
2816        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2817        tcg_temp_free_i64(t64);
2818    } else {
2819        gen_store_fpr32(ctx, t, reg | 1);
2820    }
2821}
2822
2823static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2824{
2825    if (ctx->hflags & MIPS_HFLAG_F64) {
2826        tcg_gen_mov_i64(t, fpu_f64[reg]);
2827    } else {
2828        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2829    }
2830}
2831
2832static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2833{
2834    if (ctx->hflags & MIPS_HFLAG_F64) {
2835        tcg_gen_mov_i64(fpu_f64[reg], t);
2836    } else {
2837        TCGv_i64 t0;
2838        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2839        t0 = tcg_temp_new_i64();
2840        tcg_gen_shri_i64(t0, t, 32);
2841        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2842        tcg_temp_free_i64(t0);
2843    }
2844}
2845
2846static inline int get_fp_bit(int cc)
2847{
2848    if (cc) {
2849        return 24 + cc;
2850    } else {
2851        return 23;
2852    }
2853}
2854
2855/* Addresses computation */
2856static inline void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0,
2857                                   TCGv arg1)
2858{
2859    tcg_gen_add_tl(ret, arg0, arg1);
2860
2861#if defined(TARGET_MIPS64)
2862    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2863        tcg_gen_ext32s_i64(ret, ret);
2864    }
2865#endif
2866}
2867
2868static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2869                                    target_long ofs)
2870{
2871    tcg_gen_addi_tl(ret, base, ofs);
2872
2873#if defined(TARGET_MIPS64)
2874    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2875        tcg_gen_ext32s_i64(ret, ret);
2876    }
2877#endif
2878}
2879
2880/* Addresses computation (translation time) */
2881static target_long addr_add(DisasContext *ctx, target_long base,
2882                            target_long offset)
2883{
2884    target_long sum = base + offset;
2885
2886#if defined(TARGET_MIPS64)
2887    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2888        sum = (int32_t)sum;
2889    }
2890#endif
2891    return sum;
2892}
2893
2894/* Sign-extract the low 32-bits to a target_long.  */
2895static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2896{
2897#if defined(TARGET_MIPS64)
2898    tcg_gen_ext32s_i64(ret, arg);
2899#else
2900    tcg_gen_extrl_i64_i32(ret, arg);
2901#endif
2902}
2903
2904/* Sign-extract the high 32-bits to a target_long.  */
2905static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2906{
2907#if defined(TARGET_MIPS64)
2908    tcg_gen_sari_i64(ret, arg, 32);
2909#else
2910    tcg_gen_extrh_i64_i32(ret, arg);
2911#endif
2912}
2913
2914static inline void check_cp0_enabled(DisasContext *ctx)
2915{
2916    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2917        generate_exception_err(ctx, EXCP_CpU, 0);
2918    }
2919}
2920
2921static inline void check_cp1_enabled(DisasContext *ctx)
2922{
2923    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
2924        generate_exception_err(ctx, EXCP_CpU, 1);
2925    }
2926}
2927
2928/*
2929 * Verify that the processor is running with COP1X instructions enabled.
2930 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2931 * opcode tables.
2932 */
2933static inline void check_cop1x(DisasContext *ctx)
2934{
2935    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
2936        generate_exception_end(ctx, EXCP_RI);
2937    }
2938}
2939
2940/*
2941 * Verify that the processor is running with 64-bit floating-point
2942 * operations enabled.
2943 */
2944static inline void check_cp1_64bitmode(DisasContext *ctx)
2945{
2946    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
2947        generate_exception_end(ctx, EXCP_RI);
2948    }
2949}
2950
2951/*
2952 * Verify if floating point register is valid; an operation is not defined
2953 * if bit 0 of any register specification is set and the FR bit in the
2954 * Status register equals zero, since the register numbers specify an
2955 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2956 * in the Status register equals one, both even and odd register numbers
2957 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2958 *
2959 * Multiple 64 bit wide registers can be checked by calling
2960 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2961 */
2962static inline void check_cp1_registers(DisasContext *ctx, int regs)
2963{
2964    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
2965        generate_exception_end(ctx, EXCP_RI);
2966    }
2967}
2968
2969/*
2970 * Verify that the processor is running with DSP instructions enabled.
2971 * This is enabled by CP0 Status register MX(24) bit.
2972 */
2973static inline void check_dsp(DisasContext *ctx)
2974{
2975    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2976        if (ctx->insn_flags & ASE_DSP) {
2977            generate_exception_end(ctx, EXCP_DSPDIS);
2978        } else {
2979            generate_exception_end(ctx, EXCP_RI);
2980        }
2981    }
2982}
2983
2984static inline void check_dsp_r2(DisasContext *ctx)
2985{
2986    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2987        if (ctx->insn_flags & ASE_DSP) {
2988            generate_exception_end(ctx, EXCP_DSPDIS);
2989        } else {
2990            generate_exception_end(ctx, EXCP_RI);
2991        }
2992    }
2993}
2994
2995static inline void check_dsp_r3(DisasContext *ctx)
2996{
2997    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2998        if (ctx->insn_flags & ASE_DSP) {
2999            generate_exception_end(ctx, EXCP_DSPDIS);
3000        } else {
3001            generate_exception_end(ctx, EXCP_RI);
3002        }
3003    }
3004}
3005
3006/*
3007 * This code generates a "reserved instruction" exception if the
3008 * CPU does not support the instruction set corresponding to flags.
3009 */
3010static inline void check_insn(DisasContext *ctx, uint64_t flags)
3011{
3012    if (unlikely(!(ctx->insn_flags & flags))) {
3013        generate_exception_end(ctx, EXCP_RI);
3014    }
3015}
3016
3017/*
3018 * This code generates a "reserved instruction" exception if the
3019 * CPU has corresponding flag set which indicates that the instruction
3020 * has been removed.
3021 */
3022static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3023{
3024    if (unlikely(ctx->insn_flags & flags)) {
3025        generate_exception_end(ctx, EXCP_RI);
3026    }
3027}
3028
3029/*
3030 * The Linux kernel traps certain reserved instruction exceptions to
3031 * emulate the corresponding instructions. QEMU is the kernel in user
3032 * mode, so those traps are emulated by accepting the instructions.
3033 *
3034 * A reserved instruction exception is generated for flagged CPUs if
3035 * QEMU runs in system mode.
3036 */
3037static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3038{
3039#ifndef CONFIG_USER_ONLY
3040    check_insn_opc_removed(ctx, flags);
3041#endif
3042}
3043
3044/*
3045 * This code generates a "reserved instruction" exception if the
3046 * CPU does not support 64-bit paired-single (PS) floating point data type.
3047 */
3048static inline void check_ps(DisasContext *ctx)
3049{
3050    if (unlikely(!ctx->ps)) {
3051        generate_exception(ctx, EXCP_RI);
3052    }
3053    check_cp1_64bitmode(ctx);
3054}
3055
3056#ifdef TARGET_MIPS64
3057/*
3058 * This code generates a "reserved instruction" exception if 64-bit
3059 * instructions are not enabled.
3060 */
3061static inline void check_mips_64(DisasContext *ctx)
3062{
3063    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
3064        generate_exception_end(ctx, EXCP_RI);
3065    }
3066}
3067#endif
3068
3069#ifndef CONFIG_USER_ONLY
3070static inline void check_mvh(DisasContext *ctx)
3071{
3072    if (unlikely(!ctx->mvh)) {
3073        generate_exception(ctx, EXCP_RI);
3074    }
3075}
3076#endif
3077
3078/*
3079 * This code generates a "reserved instruction" exception if the
3080 * Config5 XNP bit is set.
3081 */
3082static inline void check_xnp(DisasContext *ctx)
3083{
3084    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3085        generate_exception_end(ctx, EXCP_RI);
3086    }
3087}
3088
3089#ifndef CONFIG_USER_ONLY
3090/*
3091 * This code generates a "reserved instruction" exception if the
3092 * Config3 PW bit is NOT set.
3093 */
3094static inline void check_pw(DisasContext *ctx)
3095{
3096    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3097        generate_exception_end(ctx, EXCP_RI);
3098    }
3099}
3100#endif
3101
3102/*
3103 * This code generates a "reserved instruction" exception if the
3104 * Config3 MT bit is NOT set.
3105 */
3106static inline void check_mt(DisasContext *ctx)
3107{
3108    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3109        generate_exception_end(ctx, EXCP_RI);
3110    }
3111}
3112
3113#ifndef CONFIG_USER_ONLY
3114/*
3115 * This code generates a "coprocessor unusable" exception if CP0 is not
3116 * available, and, if that is not the case, generates a "reserved instruction"
3117 * exception if the Config5 MT bit is NOT set. This is needed for availability
3118 * control of some of MT ASE instructions.
3119 */
3120static inline void check_cp0_mt(DisasContext *ctx)
3121{
3122    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3123        generate_exception_err(ctx, EXCP_CpU, 0);
3124    } else {
3125        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3126            generate_exception_err(ctx, EXCP_RI, 0);
3127        }
3128    }
3129}
3130#endif
3131
3132/*
3133 * This code generates a "reserved instruction" exception if the
3134 * Config5 NMS bit is set.
3135 */
3136static inline void check_nms(DisasContext *ctx)
3137{
3138    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3139        generate_exception_end(ctx, EXCP_RI);
3140    }
3141}
3142
3143/*
3144 * This code generates a "reserved instruction" exception if the
3145 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3146 * Config2 TL, and Config5 L2C are unset.
3147 */
3148static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3149{
3150    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3151                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3152                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3153                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3154                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3155                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
3156        generate_exception_end(ctx, EXCP_RI);
3157    }
3158}
3159
3160/*
3161 * This code generates a "reserved instruction" exception if the
3162 * Config5 EVA bit is NOT set.
3163 */
3164static inline void check_eva(DisasContext *ctx)
3165{
3166    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3167        generate_exception_end(ctx, EXCP_RI);
3168    }
3169}
3170
3171
3172/*
3173 * Define small wrappers for gen_load_fpr* so that we have a uniform
3174 * calling interface for 32 and 64-bit FPRs.  No sense in changing
3175 * all callers for gen_load_fpr32 when we need the CTX parameter for
3176 * this one use.
3177 */
3178#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3179#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3180#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3181static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3182                                               int ft, int fs, int cc)        \
3183{                                                                             \
3184    TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
3185    TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
3186    switch (ifmt) {                                                           \
3187    case FMT_PS:                                                              \
3188        check_ps(ctx);                                                        \
3189        break;                                                                \
3190    case FMT_D:                                                               \
3191        if (abs) {                                                            \
3192            check_cop1x(ctx);                                                 \
3193        }                                                                     \
3194        check_cp1_registers(ctx, fs | ft);                                    \
3195        break;                                                                \
3196    case FMT_S:                                                               \
3197        if (abs) {                                                            \
3198            check_cop1x(ctx);                                                 \
3199        }                                                                     \
3200        break;                                                                \
3201    }                                                                         \
3202    gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
3203    gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
3204    switch (n) {                                                              \
3205    case  0:                                                                  \
3206        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
3207    break;                                                                    \
3208    case  1:                                                                  \
3209        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
3210    break;                                                                    \
3211    case  2:                                                                  \
3212        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
3213    break;                                                                    \
3214    case  3:                                                                  \
3215        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
3216    break;                                                                    \
3217    case  4:                                                                  \
3218        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
3219    break;                                                                    \
3220    case  5:                                                                  \
3221        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
3222    break;                                                                    \
3223    case  6:                                                                  \
3224        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
3225    break;                                                                    \
3226    case  7:                                                                  \
3227        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
3228    break;                                                                    \
3229    case  8:                                                                  \
3230        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
3231    break;                                                                    \
3232    case  9:                                                                  \
3233        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
3234    break;                                                                    \
3235    case 10:                                                                  \
3236        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
3237    break;                                                                    \
3238    case 11:                                                                  \
3239        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
3240    break;                                                                    \
3241    case 12:                                                                  \
3242        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
3243    break;                                                                    \
3244    case 13:                                                                  \
3245        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
3246    break;                                                                    \
3247    case 14:                                                                  \
3248        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
3249    break;                                                                    \
3250    case 15:                                                                  \
3251        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
3252    break;                                                                    \
3253    default:                                                                  \
3254        abort();                                                              \
3255    }                                                                         \
3256    tcg_temp_free_i##bits(fp0);                                               \
3257    tcg_temp_free_i##bits(fp1);                                               \
3258}
3259
3260FOP_CONDS(, 0, d, FMT_D, 64)
3261FOP_CONDS(abs, 1, d, FMT_D, 64)
3262FOP_CONDS(, 0, s, FMT_S, 32)
3263FOP_CONDS(abs, 1, s, FMT_S, 32)
3264FOP_CONDS(, 0, ps, FMT_PS, 64)
3265FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3266#undef FOP_CONDS
3267
3268#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3269static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
3270                                      int ft, int fs, int fd)           \
3271{                                                                       \
3272    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3273    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3274    if (ifmt == FMT_D) {                                                \
3275        check_cp1_registers(ctx, fs | ft | fd);                         \
3276    }                                                                   \
3277    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3278    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3279    switch (n) {                                                        \
3280    case  0:                                                            \
3281        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3282        break;                                                          \
3283    case  1:                                                            \
3284        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3285        break;                                                          \
3286    case  2:                                                            \
3287        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3288        break;                                                          \
3289    case  3:                                                            \
3290        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3291        break;                                                          \
3292    case  4:                                                            \
3293        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3294        break;                                                          \
3295    case  5:                                                            \
3296        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3297        break;                                                          \
3298    case  6:                                                            \
3299        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3300        break;                                                          \
3301    case  7:                                                            \
3302        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3303        break;                                                          \
3304    case  8:                                                            \
3305        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3306        break;                                                          \
3307    case  9:                                                            \
3308        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3309        break;                                                          \
3310    case 10:                                                            \
3311        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3312        break;                                                          \
3313    case 11:                                                            \
3314        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3315        break;                                                          \
3316    case 12:                                                            \
3317        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3318        break;                                                          \
3319    case 13:                                                            \
3320        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3321        break;                                                          \
3322    case 14:                                                            \
3323        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3324        break;                                                          \
3325    case 15:                                                            \
3326        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3327        break;                                                          \
3328    case 17:                                                            \
3329        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3330        break;                                                          \
3331    case 18:                                                            \
3332        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3333        break;                                                          \
3334    case 19:                                                            \
3335        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3336        break;                                                          \
3337    case 25:                                                            \
3338        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3339        break;                                                          \
3340    case 26:                                                            \
3341        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3342        break;                                                          \
3343    case 27:                                                            \
3344        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3345        break;                                                          \
3346    default:                                                            \
3347        abort();                                                        \
3348    }                                                                   \
3349    STORE;                                                              \
3350    tcg_temp_free_i ## bits(fp0);                                       \
3351    tcg_temp_free_i ## bits(fp1);                                       \
3352}
3353
3354FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3355FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3356#undef FOP_CONDNS
3357#undef gen_ldcmp_fpr32
3358#undef gen_ldcmp_fpr64
3359
3360/* load/store instructions. */
3361#ifdef CONFIG_USER_ONLY
3362#define OP_LD_ATOMIC(insn, fname)                                          \
3363static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3364                                DisasContext *ctx)                         \
3365{                                                                          \
3366    TCGv t0 = tcg_temp_new();                                              \
3367    tcg_gen_mov_tl(t0, arg1);                                              \
3368    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3369    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
3370    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
3371    tcg_temp_free(t0);                                                     \
3372}
3373#else
3374#define OP_LD_ATOMIC(insn, fname)                                          \
3375static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3376                                DisasContext *ctx)                         \
3377{                                                                          \
3378    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3379}
3380#endif
3381OP_LD_ATOMIC(ll, ld32s);
3382#if defined(TARGET_MIPS64)
3383OP_LD_ATOMIC(lld, ld64);
3384#endif
3385#undef OP_LD_ATOMIC
3386
3387static void gen_base_offset_addr(DisasContext *ctx, TCGv addr,
3388                                 int base, int offset)
3389{
3390    if (base == 0) {
3391        tcg_gen_movi_tl(addr, offset);
3392    } else if (offset == 0) {
3393        gen_load_gpr(addr, base);
3394    } else {
3395        tcg_gen_movi_tl(addr, offset);
3396        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3397    }
3398}
3399
3400static target_ulong pc_relative_pc(DisasContext *ctx)
3401{
3402    target_ulong pc = ctx->base.pc_next;
3403
3404    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3405        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3406
3407        pc -= branch_bytes;
3408    }
3409
3410    pc &= ~(target_ulong)3;
3411    return pc;
3412}
3413
3414/* Load */
3415static void gen_ld(DisasContext *ctx, uint32_t opc,
3416                   int rt, int base, int offset)
3417{
3418    TCGv t0, t1, t2;
3419    int mem_idx = ctx->mem_idx;
3420
3421    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3422        /*
3423         * Loongson CPU uses a load to zero register for prefetch.
3424         * We emulate it as a NOP. On other CPU we must perform the
3425         * actual memory access.
3426         */
3427        return;
3428    }
3429
3430    t0 = tcg_temp_new();
3431    gen_base_offset_addr(ctx, t0, base, offset);
3432
3433    switch (opc) {
3434#if defined(TARGET_MIPS64)
3435    case OPC_LWU:
3436        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3437                           ctx->default_tcg_memop_mask);
3438        gen_store_gpr(t0, rt);
3439        break;
3440    case OPC_LD:
3441        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3442                           ctx->default_tcg_memop_mask);
3443        gen_store_gpr(t0, rt);
3444        break;
3445    case OPC_LLD:
3446    case R6_OPC_LLD:
3447        op_ld_lld(t0, t0, mem_idx, ctx);
3448        gen_store_gpr(t0, rt);
3449        break;
3450    case OPC_LDL:
3451        t1 = tcg_temp_new();
3452        /*
3453         * Do a byte access to possibly trigger a page
3454         * fault with the unaligned address.
3455         */
3456        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3457        tcg_gen_andi_tl(t1, t0, 7);
3458#ifndef TARGET_WORDS_BIGENDIAN
3459        tcg_gen_xori_tl(t1, t1, 7);
3460#endif
3461        tcg_gen_shli_tl(t1, t1, 3);
3462        tcg_gen_andi_tl(t0, t0, ~7);
3463        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3464        tcg_gen_shl_tl(t0, t0, t1);
3465        t2 = tcg_const_tl(-1);
3466        tcg_gen_shl_tl(t2, t2, t1);
3467        gen_load_gpr(t1, rt);
3468        tcg_gen_andc_tl(t1, t1, t2);
3469        tcg_temp_free(t2);
3470        tcg_gen_or_tl(t0, t0, t1);
3471        tcg_temp_free(t1);
3472        gen_store_gpr(t0, rt);
3473        break;
3474    case OPC_LDR:
3475        t1 = tcg_temp_new();
3476        /*
3477         * Do a byte access to possibly trigger a page
3478         * fault with the unaligned address.
3479         */
3480        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3481        tcg_gen_andi_tl(t1, t0, 7);
3482#ifdef TARGET_WORDS_BIGENDIAN
3483        tcg_gen_xori_tl(t1, t1, 7);
3484#endif
3485        tcg_gen_shli_tl(t1, t1, 3);
3486        tcg_gen_andi_tl(t0, t0, ~7);
3487        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3488        tcg_gen_shr_tl(t0, t0, t1);
3489        tcg_gen_xori_tl(t1, t1, 63);
3490        t2 = tcg_const_tl(0xfffffffffffffffeull);
3491        tcg_gen_shl_tl(t2, t2, t1);
3492        gen_load_gpr(t1, rt);
3493        tcg_gen_and_tl(t1, t1, t2);
3494        tcg_temp_free(t2);
3495        tcg_gen_or_tl(t0, t0, t1);
3496        tcg_temp_free(t1);
3497        gen_store_gpr(t0, rt);
3498        break;
3499    case OPC_LDPC:
3500        t1 = tcg_const_tl(pc_relative_pc(ctx));
3501        gen_op_addr_add(ctx, t0, t0, t1);
3502        tcg_temp_free(t1);
3503        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3504        gen_store_gpr(t0, rt);
3505        break;
3506#endif
3507    case OPC_LWPC:
3508        t1 = tcg_const_tl(pc_relative_pc(ctx));
3509        gen_op_addr_add(ctx, t0, t0, t1);
3510        tcg_temp_free(t1);
3511        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3512        gen_store_gpr(t0, rt);
3513        break;
3514    case OPC_LWE:
3515        mem_idx = MIPS_HFLAG_UM;
3516        /* fall through */
3517    case OPC_LW:
3518        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3519                           ctx->default_tcg_memop_mask);
3520        gen_store_gpr(t0, rt);
3521        break;
3522    case OPC_LHE:
3523        mem_idx = MIPS_HFLAG_UM;
3524        /* fall through */
3525    case OPC_LH:
3526        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3527                           ctx->default_tcg_memop_mask);
3528        gen_store_gpr(t0, rt);
3529        break;
3530    case OPC_LHUE:
3531        mem_idx = MIPS_HFLAG_UM;
3532        /* fall through */
3533    case OPC_LHU:
3534        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3535                           ctx->default_tcg_memop_mask);
3536        gen_store_gpr(t0, rt);
3537        break;
3538    case OPC_LBE:
3539        mem_idx = MIPS_HFLAG_UM;
3540        /* fall through */
3541    case OPC_LB:
3542        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3543        gen_store_gpr(t0, rt);
3544        break;
3545    case OPC_LBUE:
3546        mem_idx = MIPS_HFLAG_UM;
3547        /* fall through */
3548    case OPC_LBU:
3549        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3550        gen_store_gpr(t0, rt);
3551        break;
3552    case OPC_LWLE:
3553        mem_idx = MIPS_HFLAG_UM;
3554        /* fall through */
3555    case OPC_LWL:
3556        t1 = tcg_temp_new();
3557        /*
3558         * Do a byte access to possibly trigger a page
3559         * fault with the unaligned address.
3560         */
3561        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3562        tcg_gen_andi_tl(t1, t0, 3);
3563#ifndef TARGET_WORDS_BIGENDIAN
3564        tcg_gen_xori_tl(t1, t1, 3);
3565#endif
3566        tcg_gen_shli_tl(t1, t1, 3);
3567        tcg_gen_andi_tl(t0, t0, ~3);
3568        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3569        tcg_gen_shl_tl(t0, t0, t1);
3570        t2 = tcg_const_tl(-1);
3571        tcg_gen_shl_tl(t2, t2, t1);
3572        gen_load_gpr(t1, rt);
3573        tcg_gen_andc_tl(t1, t1, t2);
3574        tcg_temp_free(t2);
3575        tcg_gen_or_tl(t0, t0, t1);
3576        tcg_temp_free(t1);
3577        tcg_gen_ext32s_tl(t0, t0);
3578        gen_store_gpr(t0, rt);
3579        break;
3580    case OPC_LWRE:
3581        mem_idx = MIPS_HFLAG_UM;
3582        /* fall through */
3583    case OPC_LWR:
3584        t1 = tcg_temp_new();
3585        /*
3586         * Do a byte access to possibly trigger a page
3587         * fault with the unaligned address.
3588         */
3589        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3590        tcg_gen_andi_tl(t1, t0, 3);
3591#ifdef TARGET_WORDS_BIGENDIAN
3592        tcg_gen_xori_tl(t1, t1, 3);
3593#endif
3594        tcg_gen_shli_tl(t1, t1, 3);
3595        tcg_gen_andi_tl(t0, t0, ~3);
3596        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3597        tcg_gen_shr_tl(t0, t0, t1);
3598        tcg_gen_xori_tl(t1, t1, 31);
3599        t2 = tcg_const_tl(0xfffffffeull);
3600        tcg_gen_shl_tl(t2, t2, t1);
3601        gen_load_gpr(t1, rt);
3602        tcg_gen_and_tl(t1, t1, t2);
3603        tcg_temp_free(t2);
3604        tcg_gen_or_tl(t0, t0, t1);
3605        tcg_temp_free(t1);
3606        tcg_gen_ext32s_tl(t0, t0);
3607        gen_store_gpr(t0, rt);
3608        break;
3609    case OPC_LLE:
3610        mem_idx = MIPS_HFLAG_UM;
3611        /* fall through */
3612    case OPC_LL:
3613    case R6_OPC_LL:
3614        op_ld_ll(t0, t0, mem_idx, ctx);
3615        gen_store_gpr(t0, rt);
3616        break;
3617    }
3618    tcg_temp_free(t0);
3619}
3620
3621static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3622                    uint32_t reg1, uint32_t reg2)
3623{
3624    TCGv taddr = tcg_temp_new();
3625    TCGv_i64 tval = tcg_temp_new_i64();
3626    TCGv tmp1 = tcg_temp_new();
3627    TCGv tmp2 = tcg_temp_new();
3628
3629    gen_base_offset_addr(ctx, taddr, base, offset);
3630    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3631#ifdef TARGET_WORDS_BIGENDIAN
3632    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3633#else
3634    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3635#endif
3636    gen_store_gpr(tmp1, reg1);
3637    tcg_temp_free(tmp1);
3638    gen_store_gpr(tmp2, reg2);
3639    tcg_temp_free(tmp2);
3640    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3641    tcg_temp_free_i64(tval);
3642    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3643    tcg_temp_free(taddr);
3644}
3645
3646/* Store */
3647static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3648                   int base, int offset)
3649{
3650    TCGv t0 = tcg_temp_new();
3651    TCGv t1 = tcg_temp_new();
3652    int mem_idx = ctx->mem_idx;
3653
3654    gen_base_offset_addr(ctx, t0, base, offset);
3655    gen_load_gpr(t1, rt);
3656    switch (opc) {
3657#if defined(TARGET_MIPS64)
3658    case OPC_SD:
3659        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3660                           ctx->default_tcg_memop_mask);
3661        break;
3662    case OPC_SDL:
3663        gen_helper_0e2i(sdl, t1, t0, mem_idx);
3664        break;
3665    case OPC_SDR:
3666        gen_helper_0e2i(sdr, t1, t0, mem_idx);
3667        break;
3668#endif
3669    case OPC_SWE:
3670        mem_idx = MIPS_HFLAG_UM;
3671        /* fall through */
3672    case OPC_SW:
3673        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3674                           ctx->default_tcg_memop_mask);
3675        break;
3676    case OPC_SHE:
3677        mem_idx = MIPS_HFLAG_UM;
3678        /* fall through */
3679    case OPC_SH:
3680        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3681                           ctx->default_tcg_memop_mask);
3682        break;
3683    case OPC_SBE:
3684        mem_idx = MIPS_HFLAG_UM;
3685        /* fall through */
3686    case OPC_SB:
3687        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3688        break;
3689    case OPC_SWLE:
3690        mem_idx = MIPS_HFLAG_UM;
3691        /* fall through */
3692    case OPC_SWL:
3693        gen_helper_0e2i(swl, t1, t0, mem_idx);
3694        break;
3695    case OPC_SWRE:
3696        mem_idx = MIPS_HFLAG_UM;
3697        /* fall through */
3698    case OPC_SWR:
3699        gen_helper_0e2i(swr, t1, t0, mem_idx);
3700        break;
3701    }
3702    tcg_temp_free(t0);
3703    tcg_temp_free(t1);
3704}
3705
3706
3707/* Store conditional */
3708static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3709                        MemOp tcg_mo, bool eva)
3710{
3711    TCGv addr, t0, val;
3712    TCGLabel *l1 = gen_new_label();
3713    TCGLabel *done = gen_new_label();
3714
3715    t0 = tcg_temp_new();
3716    addr = tcg_temp_new();
3717    /* compare the address against that of the preceeding LL */
3718    gen_base_offset_addr(ctx, addr, base, offset);
3719    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3720    tcg_temp_free(addr);
3721    tcg_gen_movi_tl(t0, 0);
3722    gen_store_gpr(t0, rt);
3723    tcg_gen_br(done);
3724
3725    gen_set_label(l1);
3726    /* generate cmpxchg */
3727    val = tcg_temp_new();
3728    gen_load_gpr(val, rt);
3729    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3730                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3731    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3732    gen_store_gpr(t0, rt);
3733    tcg_temp_free(val);
3734
3735    gen_set_label(done);
3736    tcg_temp_free(t0);
3737}
3738
3739
3740static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3741                    uint32_t reg1, uint32_t reg2, bool eva)
3742{
3743    TCGv taddr = tcg_temp_local_new();
3744    TCGv lladdr = tcg_temp_local_new();
3745    TCGv_i64 tval = tcg_temp_new_i64();
3746    TCGv_i64 llval = tcg_temp_new_i64();
3747    TCGv_i64 val = tcg_temp_new_i64();
3748    TCGv tmp1 = tcg_temp_new();
3749    TCGv tmp2 = tcg_temp_new();
3750    TCGLabel *lab_fail = gen_new_label();
3751    TCGLabel *lab_done = gen_new_label();
3752
3753    gen_base_offset_addr(ctx, taddr, base, offset);
3754
3755    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3756    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3757
3758    gen_load_gpr(tmp1, reg1);
3759    gen_load_gpr(tmp2, reg2);
3760
3761#ifdef TARGET_WORDS_BIGENDIAN
3762    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3763#else
3764    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3765#endif
3766
3767    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3768    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3769                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3770    if (reg1 != 0) {
3771        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3772    }
3773    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3774
3775    gen_set_label(lab_fail);
3776
3777    if (reg1 != 0) {
3778        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3779    }
3780    gen_set_label(lab_done);
3781    tcg_gen_movi_tl(lladdr, -1);
3782    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3783}
3784
3785/* Load and store */
3786static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3787                         TCGv t0)
3788{
3789    /*
3790     * Don't do NOP if destination is zero: we must perform the actual
3791     * memory access.
3792     */
3793    switch (opc) {
3794    case OPC_LWC1:
3795        {
3796            TCGv_i32 fp0 = tcg_temp_new_i32();
3797            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3798                                ctx->default_tcg_memop_mask);
3799            gen_store_fpr32(ctx, fp0, ft);
3800            tcg_temp_free_i32(fp0);
3801        }
3802        break;
3803    case OPC_SWC1:
3804        {
3805            TCGv_i32 fp0 = tcg_temp_new_i32();
3806            gen_load_fpr32(ctx, fp0, ft);
3807            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3808                                ctx->default_tcg_memop_mask);
3809            tcg_temp_free_i32(fp0);
3810        }
3811        break;
3812    case OPC_LDC1:
3813        {
3814            TCGv_i64 fp0 = tcg_temp_new_i64();
3815            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3816                                ctx->default_tcg_memop_mask);
3817            gen_store_fpr64(ctx, fp0, ft);
3818            tcg_temp_free_i64(fp0);
3819        }
3820        break;
3821    case OPC_SDC1:
3822        {
3823            TCGv_i64 fp0 = tcg_temp_new_i64();
3824            gen_load_fpr64(ctx, fp0, ft);
3825            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3826                                ctx->default_tcg_memop_mask);
3827            tcg_temp_free_i64(fp0);
3828        }
3829        break;
3830    default:
3831        MIPS_INVAL("flt_ldst");
3832        generate_exception_end(ctx, EXCP_RI);
3833        break;
3834    }
3835}
3836
3837static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3838                          int rs, int16_t imm)
3839{
3840    TCGv t0 = tcg_temp_new();
3841
3842    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3843        check_cp1_enabled(ctx);
3844        switch (op) {
3845        case OPC_LDC1:
3846        case OPC_SDC1:
3847            check_insn(ctx, ISA_MIPS2);
3848            /* Fallthrough */
3849        default:
3850            gen_base_offset_addr(ctx, t0, rs, imm);
3851            gen_flt_ldst(ctx, op, rt, t0);
3852        }
3853    } else {
3854        generate_exception_err(ctx, EXCP_CpU, 1);
3855    }
3856    tcg_temp_free(t0);
3857}
3858
3859/* Arithmetic with immediate operand */
3860static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3861                          int rt, int rs, int imm)
3862{
3863    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3864
3865    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3866        /*
3867         * If no destination, treat it as a NOP.
3868         * For addi, we must generate the overflow exception when needed.
3869         */
3870        return;
3871    }
3872    switch (opc) {
3873    case OPC_ADDI:
3874        {
3875            TCGv t0 = tcg_temp_local_new();
3876            TCGv t1 = tcg_temp_new();
3877            TCGv t2 = tcg_temp_new();
3878            TCGLabel *l1 = gen_new_label();
3879
3880            gen_load_gpr(t1, rs);
3881            tcg_gen_addi_tl(t0, t1, uimm);
3882            tcg_gen_ext32s_tl(t0, t0);
3883
3884            tcg_gen_xori_tl(t1, t1, ~uimm);
3885            tcg_gen_xori_tl(t2, t0, uimm);
3886            tcg_gen_and_tl(t1, t1, t2);
3887            tcg_temp_free(t2);
3888            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3889            tcg_temp_free(t1);
3890            /* operands of same sign, result different sign */
3891            generate_exception(ctx, EXCP_OVERFLOW);
3892            gen_set_label(l1);
3893            tcg_gen_ext32s_tl(t0, t0);
3894            gen_store_gpr(t0, rt);
3895            tcg_temp_free(t0);
3896        }
3897        break;
3898    case OPC_ADDIU:
3899        if (rs != 0) {
3900            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3901            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3902        } else {
3903            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3904        }
3905        break;
3906#if defined(TARGET_MIPS64)
3907    case OPC_DADDI:
3908        {
3909            TCGv t0 = tcg_temp_local_new();
3910            TCGv t1 = tcg_temp_new();
3911            TCGv t2 = tcg_temp_new();
3912            TCGLabel *l1 = gen_new_label();
3913
3914            gen_load_gpr(t1, rs);
3915            tcg_gen_addi_tl(t0, t1, uimm);
3916
3917            tcg_gen_xori_tl(t1, t1, ~uimm);
3918            tcg_gen_xori_tl(t2, t0, uimm);
3919            tcg_gen_and_tl(t1, t1, t2);
3920            tcg_temp_free(t2);
3921            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3922            tcg_temp_free(t1);
3923            /* operands of same sign, result different sign */
3924            generate_exception(ctx, EXCP_OVERFLOW);
3925            gen_set_label(l1);
3926            gen_store_gpr(t0, rt);
3927            tcg_temp_free(t0);
3928        }
3929        break;
3930    case OPC_DADDIU:
3931        if (rs != 0) {
3932            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3933        } else {
3934            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3935        }
3936        break;
3937#endif
3938    }
3939}
3940
3941/* Logic with immediate operand */
3942static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3943                          int rt, int rs, int16_t imm)
3944{
3945    target_ulong uimm;
3946
3947    if (rt == 0) {
3948        /* If no destination, treat it as a NOP. */
3949        return;
3950    }
3951    uimm = (uint16_t)imm;
3952    switch (opc) {
3953    case OPC_ANDI:
3954        if (likely(rs != 0)) {
3955            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3956        } else {
3957            tcg_gen_movi_tl(cpu_gpr[rt], 0);
3958        }
3959        break;
3960    case OPC_ORI:
3961        if (rs != 0) {
3962            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3963        } else {
3964            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3965        }
3966        break;
3967    case OPC_XORI:
3968        if (likely(rs != 0)) {
3969            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3970        } else {
3971            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3972        }
3973        break;
3974    case OPC_LUI:
3975        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3976            /* OPC_AUI */
3977            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3978            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3979        } else {
3980            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3981        }
3982        break;
3983
3984    default:
3985        break;
3986    }
3987}
3988
3989/* Set on less than with immediate operand */
3990static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3991                        int rt, int rs, int16_t imm)
3992{
3993    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3994    TCGv t0;
3995
3996    if (rt == 0) {
3997        /* If no destination, treat it as a NOP. */
3998        return;
3999    }
4000    t0 = tcg_temp_new();
4001    gen_load_gpr(t0, rs);
4002    switch (opc) {
4003    case OPC_SLTI:
4004        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
4005        break;
4006    case OPC_SLTIU:
4007        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
4008        break;
4009    }
4010    tcg_temp_free(t0);
4011}
4012
4013/* Shifts with immediate operand */
4014static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
4015                          int rt, int rs, int16_t imm)
4016{
4017    target_ulong uimm = ((uint16_t)imm) & 0x1f;
4018    TCGv t0;
4019
4020    if (rt == 0) {
4021        /* If no destination, treat it as a NOP. */
4022        return;
4023    }
4024
4025    t0 = tcg_temp_new();
4026    gen_load_gpr(t0, rs);
4027    switch (opc) {
4028    case OPC_SLL:
4029        tcg_gen_shli_tl(t0, t0, uimm);
4030        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4031        break;
4032    case OPC_SRA:
4033        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4034        break;
4035    case OPC_SRL:
4036        if (uimm != 0) {
4037            tcg_gen_ext32u_tl(t0, t0);
4038            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4039        } else {
4040            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4041        }
4042        break;
4043    case OPC_ROTR:
4044        if (uimm != 0) {
4045            TCGv_i32 t1 = tcg_temp_new_i32();
4046
4047            tcg_gen_trunc_tl_i32(t1, t0);
4048            tcg_gen_rotri_i32(t1, t1, uimm);
4049            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4050            tcg_temp_free_i32(t1);
4051        } else {
4052            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4053        }
4054        break;
4055#if defined(TARGET_MIPS64)
4056    case OPC_DSLL:
4057        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4058        break;
4059    case OPC_DSRA:
4060        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4061        break;
4062    case OPC_DSRL:
4063        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4064        break;
4065    case OPC_DROTR:
4066        if (uimm != 0) {
4067            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4068        } else {
4069            tcg_gen_mov_tl(cpu_gpr[rt], t0);
4070        }
4071        break;
4072    case OPC_DSLL32:
4073        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4074        break;
4075    case OPC_DSRA32:
4076        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4077        break;
4078    case OPC_DSRL32:
4079        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4080        break;
4081    case OPC_DROTR32:
4082        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4083        break;
4084#endif
4085    }
4086    tcg_temp_free(t0);
4087}
4088
4089/* Arithmetic */
4090static void gen_arith(DisasContext *ctx, uint32_t opc,
4091                      int rd, int rs, int rt)
4092{
4093    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4094       && opc != OPC_DADD && opc != OPC_DSUB) {
4095        /*
4096         * If no destination, treat it as a NOP.
4097         * For add & sub, we must generate the overflow exception when needed.
4098         */
4099        return;
4100    }
4101
4102    switch (opc) {
4103    case OPC_ADD:
4104        {
4105            TCGv t0 = tcg_temp_local_new();
4106            TCGv t1 = tcg_temp_new();
4107            TCGv t2 = tcg_temp_new();
4108            TCGLabel *l1 = gen_new_label();
4109
4110            gen_load_gpr(t1, rs);
4111            gen_load_gpr(t2, rt);
4112            tcg_gen_add_tl(t0, t1, t2);
4113            tcg_gen_ext32s_tl(t0, t0);
4114            tcg_gen_xor_tl(t1, t1, t2);
4115            tcg_gen_xor_tl(t2, t0, t2);
4116            tcg_gen_andc_tl(t1, t2, t1);
4117            tcg_temp_free(t2);
4118            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4119            tcg_temp_free(t1);
4120            /* operands of same sign, result different sign */
4121            generate_exception(ctx, EXCP_OVERFLOW);
4122            gen_set_label(l1);
4123            gen_store_gpr(t0, rd);
4124            tcg_temp_free(t0);
4125        }
4126        break;
4127    case OPC_ADDU:
4128        if (rs != 0 && rt != 0) {
4129            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4130            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4131        } else if (rs == 0 && rt != 0) {
4132            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4133        } else if (rs != 0 && rt == 0) {
4134            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4135        } else {
4136            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4137        }
4138        break;
4139    case OPC_SUB:
4140        {
4141            TCGv t0 = tcg_temp_local_new();
4142            TCGv t1 = tcg_temp_new();
4143            TCGv t2 = tcg_temp_new();
4144            TCGLabel *l1 = gen_new_label();
4145
4146            gen_load_gpr(t1, rs);
4147            gen_load_gpr(t2, rt);
4148            tcg_gen_sub_tl(t0, t1, t2);
4149            tcg_gen_ext32s_tl(t0, t0);
4150            tcg_gen_xor_tl(t2, t1, t2);
4151            tcg_gen_xor_tl(t1, t0, t1);
4152            tcg_gen_and_tl(t1, t1, t2);
4153            tcg_temp_free(t2);
4154            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4155            tcg_temp_free(t1);
4156            /*
4157             * operands of different sign, first operand and the result
4158             * of different sign
4159             */
4160            generate_exception(ctx, EXCP_OVERFLOW);
4161            gen_set_label(l1);
4162            gen_store_gpr(t0, rd);
4163            tcg_temp_free(t0);
4164        }
4165        break;
4166    case OPC_SUBU:
4167        if (rs != 0 && rt != 0) {
4168            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4169            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4170        } else if (rs == 0 && rt != 0) {
4171            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4172            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4173        } else if (rs != 0 && rt == 0) {
4174            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4175        } else {
4176            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4177        }
4178        break;
4179#if defined(TARGET_MIPS64)
4180    case OPC_DADD:
4181        {
4182            TCGv t0 = tcg_temp_local_new();
4183            TCGv t1 = tcg_temp_new();
4184            TCGv t2 = tcg_temp_new();
4185            TCGLabel *l1 = gen_new_label();
4186
4187            gen_load_gpr(t1, rs);
4188            gen_load_gpr(t2, rt);
4189            tcg_gen_add_tl(t0, t1, t2);
4190            tcg_gen_xor_tl(t1, t1, t2);
4191            tcg_gen_xor_tl(t2, t0, t2);
4192            tcg_gen_andc_tl(t1, t2, t1);
4193            tcg_temp_free(t2);
4194            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4195            tcg_temp_free(t1);
4196            /* operands of same sign, result different sign */
4197            generate_exception(ctx, EXCP_OVERFLOW);
4198            gen_set_label(l1);
4199            gen_store_gpr(t0, rd);
4200            tcg_temp_free(t0);
4201        }
4202        break;
4203    case OPC_DADDU:
4204        if (rs != 0 && rt != 0) {
4205            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4206        } else if (rs == 0 && rt != 0) {
4207            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4208        } else if (rs != 0 && rt == 0) {
4209            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4210        } else {
4211            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4212        }
4213        break;
4214    case OPC_DSUB:
4215        {
4216            TCGv t0 = tcg_temp_local_new();
4217            TCGv t1 = tcg_temp_new();
4218            TCGv t2 = tcg_temp_new();
4219            TCGLabel *l1 = gen_new_label();
4220
4221            gen_load_gpr(t1, rs);
4222            gen_load_gpr(t2, rt);
4223            tcg_gen_sub_tl(t0, t1, t2);
4224            tcg_gen_xor_tl(t2, t1, t2);
4225            tcg_gen_xor_tl(t1, t0, t1);
4226            tcg_gen_and_tl(t1, t1, t2);
4227            tcg_temp_free(t2);
4228            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4229            tcg_temp_free(t1);
4230            /*
4231             * Operands of different sign, first operand and result different
4232             * sign.
4233             */
4234            generate_exception(ctx, EXCP_OVERFLOW);
4235            gen_set_label(l1);
4236            gen_store_gpr(t0, rd);
4237            tcg_temp_free(t0);
4238        }
4239        break;
4240    case OPC_DSUBU:
4241        if (rs != 0 && rt != 0) {
4242            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4243        } else if (rs == 0 && rt != 0) {
4244            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4245        } else if (rs != 0 && rt == 0) {
4246            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4247        } else {
4248            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4249        }
4250        break;
4251#endif
4252    case OPC_MUL:
4253        if (likely(rs != 0 && rt != 0)) {
4254            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4255            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4256        } else {
4257            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4258        }
4259        break;
4260    }
4261}
4262
4263/* Conditional move */
4264static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4265                          int rd, int rs, int rt)
4266{
4267    TCGv t0, t1, t2;
4268
4269    if (rd == 0) {
4270        /* If no destination, treat it as a NOP. */
4271        return;
4272    }
4273
4274    t0 = tcg_temp_new();
4275    gen_load_gpr(t0, rt);
4276    t1 = tcg_const_tl(0);
4277    t2 = tcg_temp_new();
4278    gen_load_gpr(t2, rs);
4279    switch (opc) {
4280    case OPC_MOVN:
4281        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4282        break;
4283    case OPC_MOVZ:
4284        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4285        break;
4286    case OPC_SELNEZ:
4287        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4288        break;
4289    case OPC_SELEQZ:
4290        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4291        break;
4292    }
4293    tcg_temp_free(t2);
4294    tcg_temp_free(t1);
4295    tcg_temp_free(t0);
4296}
4297
4298/* Logic */
4299static void gen_logic(DisasContext *ctx, uint32_t opc,
4300                      int rd, int rs, int rt)
4301{
4302    if (rd == 0) {
4303        /* If no destination, treat it as a NOP. */
4304        return;
4305    }
4306
4307    switch (opc) {
4308    case OPC_AND:
4309        if (likely(rs != 0 && rt != 0)) {
4310            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4311        } else {
4312            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4313        }
4314        break;
4315    case OPC_NOR:
4316        if (rs != 0 && rt != 0) {
4317            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4318        } else if (rs == 0 && rt != 0) {
4319            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4320        } else if (rs != 0 && rt == 0) {
4321            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4322        } else {
4323            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4324        }
4325        break;
4326    case OPC_OR:
4327        if (likely(rs != 0 && rt != 0)) {
4328            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4329        } else if (rs == 0 && rt != 0) {
4330            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4331        } else if (rs != 0 && rt == 0) {
4332            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4333        } else {
4334            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4335        }
4336        break;
4337    case OPC_XOR:
4338        if (likely(rs != 0 && rt != 0)) {
4339            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4340        } else if (rs == 0 && rt != 0) {
4341            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4342        } else if (rs != 0 && rt == 0) {
4343            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4344        } else {
4345            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4346        }
4347        break;
4348    }
4349}
4350
4351/* Set on lower than */
4352static void gen_slt(DisasContext *ctx, uint32_t opc,
4353                    int rd, int rs, int rt)
4354{
4355    TCGv t0, t1;
4356
4357    if (rd == 0) {
4358        /* If no destination, treat it as a NOP. */
4359        return;
4360    }
4361
4362    t0 = tcg_temp_new();
4363    t1 = tcg_temp_new();
4364    gen_load_gpr(t0, rs);
4365    gen_load_gpr(t1, rt);
4366    switch (opc) {
4367    case OPC_SLT:
4368        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4369        break;
4370    case OPC_SLTU:
4371        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4372        break;
4373    }
4374    tcg_temp_free(t0);
4375    tcg_temp_free(t1);
4376}
4377
4378/* Shifts */
4379static void gen_shift(DisasContext *ctx, uint32_t opc,
4380                      int rd, int rs, int rt)
4381{
4382    TCGv t0, t1;
4383
4384    if (rd == 0) {
4385        /*
4386         * If no destination, treat it as a NOP.
4387         * For add & sub, we must generate the overflow exception when needed.
4388         */
4389        return;
4390    }
4391
4392    t0 = tcg_temp_new();
4393    t1 = tcg_temp_new();
4394    gen_load_gpr(t0, rs);
4395    gen_load_gpr(t1, rt);
4396    switch (opc) {
4397    case OPC_SLLV:
4398        tcg_gen_andi_tl(t0, t0, 0x1f);
4399        tcg_gen_shl_tl(t0, t1, t0);
4400        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4401        break;
4402    case OPC_SRAV:
4403        tcg_gen_andi_tl(t0, t0, 0x1f);
4404        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4405        break;
4406    case OPC_SRLV:
4407        tcg_gen_ext32u_tl(t1, t1);
4408        tcg_gen_andi_tl(t0, t0, 0x1f);
4409        tcg_gen_shr_tl(t0, t1, t0);
4410        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4411        break;
4412    case OPC_ROTRV:
4413        {
4414            TCGv_i32 t2 = tcg_temp_new_i32();
4415            TCGv_i32 t3 = tcg_temp_new_i32();
4416
4417            tcg_gen_trunc_tl_i32(t2, t0);
4418            tcg_gen_trunc_tl_i32(t3, t1);
4419            tcg_gen_andi_i32(t2, t2, 0x1f);
4420            tcg_gen_rotr_i32(t2, t3, t2);
4421            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4422            tcg_temp_free_i32(t2);
4423            tcg_temp_free_i32(t3);
4424        }
4425        break;
4426#if defined(TARGET_MIPS64)
4427    case OPC_DSLLV:
4428        tcg_gen_andi_tl(t0, t0, 0x3f);
4429        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4430        break;
4431    case OPC_DSRAV:
4432        tcg_gen_andi_tl(t0, t0, 0x3f);
4433        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4434        break;
4435    case OPC_DSRLV:
4436        tcg_gen_andi_tl(t0, t0, 0x3f);
4437        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4438        break;
4439    case OPC_DROTRV:
4440        tcg_gen_andi_tl(t0, t0, 0x3f);
4441        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4442        break;
4443#endif
4444    }
4445    tcg_temp_free(t0);
4446    tcg_temp_free(t1);
4447}
4448
4449#if defined(TARGET_MIPS64)
4450/* Copy GPR to and from TX79 HI1/LO1 register. */
4451static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4452{
4453    if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4454        /* Treat as NOP. */
4455        return;
4456    }
4457
4458    switch (opc) {
4459    case MMI_OPC_MFHI1:
4460        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4461        break;
4462    case MMI_OPC_MFLO1:
4463        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4464        break;
4465    case MMI_OPC_MTHI1:
4466        if (reg != 0) {
4467            tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4468        } else {
4469            tcg_gen_movi_tl(cpu_HI[1], 0);
4470        }
4471        break;
4472    case MMI_OPC_MTLO1:
4473        if (reg != 0) {
4474            tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4475        } else {
4476            tcg_gen_movi_tl(cpu_LO[1], 0);
4477        }
4478        break;
4479    default:
4480        MIPS_INVAL("mfthilo1 TX79");
4481        generate_exception_end(ctx, EXCP_RI);
4482        break;
4483    }
4484}
4485#endif
4486
4487/* Arithmetic on HI/LO registers */
4488static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4489{
4490    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4491        /* Treat as NOP. */
4492        return;
4493    }
4494
4495    if (acc != 0) {
4496        check_dsp(ctx);
4497    }
4498
4499    switch (opc) {
4500    case OPC_MFHI:
4501#if defined(TARGET_MIPS64)
4502        if (acc != 0) {
4503            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4504        } else
4505#endif
4506        {
4507            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4508        }
4509        break;
4510    case OPC_MFLO:
4511#if defined(TARGET_MIPS64)
4512        if (acc != 0) {
4513            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4514        } else
4515#endif
4516        {
4517            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4518        }
4519        break;
4520    case OPC_MTHI:
4521        if (reg != 0) {
4522#if defined(TARGET_MIPS64)
4523            if (acc != 0) {
4524                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4525            } else
4526#endif
4527            {
4528                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4529            }
4530        } else {
4531            tcg_gen_movi_tl(cpu_HI[acc], 0);
4532        }
4533        break;
4534    case OPC_MTLO:
4535        if (reg != 0) {
4536#if defined(TARGET_MIPS64)
4537            if (acc != 0) {
4538                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4539            } else
4540#endif
4541            {
4542                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4543            }
4544        } else {
4545            tcg_gen_movi_tl(cpu_LO[acc], 0);
4546        }
4547        break;
4548    }
4549}
4550
4551static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4552                             MemOp memop)
4553{
4554    TCGv t0 = tcg_const_tl(addr);
4555    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4556    gen_store_gpr(t0, reg);
4557    tcg_temp_free(t0);
4558}
4559
4560static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4561                             int rs)
4562{
4563    target_long offset;
4564    target_long addr;
4565
4566    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4567    case OPC_ADDIUPC:
4568        if (rs != 0) {
4569            offset = sextract32(ctx->opcode << 2, 0, 21);
4570            addr = addr_add(ctx, pc, offset);
4571            tcg_gen_movi_tl(cpu_gpr[rs], addr);
4572        }
4573        break;
4574    case R6_OPC_LWPC:
4575        offset = sextract32(ctx->opcode << 2, 0, 21);
4576        addr = addr_add(ctx, pc, offset);
4577        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4578        break;
4579#if defined(TARGET_MIPS64)
4580    case OPC_LWUPC:
4581        check_mips_64(ctx);
4582        offset = sextract32(ctx->opcode << 2, 0, 21);
4583        addr = addr_add(ctx, pc, offset);
4584        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4585        break;
4586#endif
4587    default:
4588        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4589        case OPC_AUIPC:
4590            if (rs != 0) {
4591                offset = sextract32(ctx->opcode, 0, 16) << 16;
4592                addr = addr_add(ctx, pc, offset);
4593                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4594            }
4595            break;
4596        case OPC_ALUIPC:
4597            if (rs != 0) {
4598                offset = sextract32(ctx->opcode, 0, 16) << 16;
4599                addr = ~0xFFFF & addr_add(ctx, pc, offset);
4600                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4601            }
4602            break;
4603#if defined(TARGET_MIPS64)
4604        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4605        case R6_OPC_LDPC + (1 << 16):
4606        case R6_OPC_LDPC + (2 << 16):
4607        case R6_OPC_LDPC + (3 << 16):
4608            check_mips_64(ctx);
4609            offset = sextract32(ctx->opcode << 3, 0, 21);
4610            addr = addr_add(ctx, (pc & ~0x7), offset);
4611            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4612            break;
4613#endif
4614        default:
4615            MIPS_INVAL("OPC_PCREL");
4616            generate_exception_end(ctx, EXCP_RI);
4617            break;
4618        }
4619        break;
4620    }
4621}
4622
4623static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4624{
4625    TCGv t0, t1;
4626
4627    if (rd == 0) {
4628        /* Treat as NOP. */
4629        return;
4630    }
4631
4632    t0 = tcg_temp_new();
4633    t1 = tcg_temp_new();
4634
4635    gen_load_gpr(t0, rs);
4636    gen_load_gpr(t1, rt);
4637
4638    switch (opc) {
4639    case R6_OPC_DIV:
4640        {
4641            TCGv t2 = tcg_temp_new();
4642            TCGv t3 = tcg_temp_new();
4643            tcg_gen_ext32s_tl(t0, t0);
4644            tcg_gen_ext32s_tl(t1, t1);
4645            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4646            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4647            tcg_gen_and_tl(t2, t2, t3);
4648            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4649            tcg_gen_or_tl(t2, t2, t3);
4650            tcg_gen_movi_tl(t3, 0);
4651            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4652            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4653            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4654            tcg_temp_free(t3);
4655            tcg_temp_free(t2);
4656        }
4657        break;
4658    case R6_OPC_MOD:
4659        {
4660            TCGv t2 = tcg_temp_new();
4661            TCGv t3 = tcg_temp_new();
4662            tcg_gen_ext32s_tl(t0, t0);
4663            tcg_gen_ext32s_tl(t1, t1);
4664            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4665            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4666            tcg_gen_and_tl(t2, t2, t3);
4667            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4668            tcg_gen_or_tl(t2, t2, t3);
4669            tcg_gen_movi_tl(t3, 0);
4670            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4671            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4672            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4673            tcg_temp_free(t3);
4674            tcg_temp_free(t2);
4675        }
4676        break;
4677    case R6_OPC_DIVU:
4678        {
4679            TCGv t2 = tcg_const_tl(0);
4680            TCGv t3 = tcg_const_tl(1);
4681            tcg_gen_ext32u_tl(t0, t0);
4682            tcg_gen_ext32u_tl(t1, t1);
4683            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4684            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4685            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4686            tcg_temp_free(t3);
4687            tcg_temp_free(t2);
4688        }
4689        break;
4690    case R6_OPC_MODU:
4691        {
4692            TCGv t2 = tcg_const_tl(0);
4693            TCGv t3 = tcg_const_tl(1);
4694            tcg_gen_ext32u_tl(t0, t0);
4695            tcg_gen_ext32u_tl(t1, t1);
4696            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4697            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4698            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4699            tcg_temp_free(t3);
4700            tcg_temp_free(t2);
4701        }
4702        break;
4703    case R6_OPC_MUL:
4704        {
4705            TCGv_i32 t2 = tcg_temp_new_i32();
4706            TCGv_i32 t3 = tcg_temp_new_i32();
4707            tcg_gen_trunc_tl_i32(t2, t0);
4708            tcg_gen_trunc_tl_i32(t3, t1);
4709            tcg_gen_mul_i32(t2, t2, t3);
4710            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4711            tcg_temp_free_i32(t2);
4712            tcg_temp_free_i32(t3);
4713        }
4714        break;
4715    case R6_OPC_MUH:
4716        {
4717            TCGv_i32 t2 = tcg_temp_new_i32();
4718            TCGv_i32 t3 = tcg_temp_new_i32();
4719            tcg_gen_trunc_tl_i32(t2, t0);
4720            tcg_gen_trunc_tl_i32(t3, t1);
4721            tcg_gen_muls2_i32(t2, t3, t2, t3);
4722            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4723            tcg_temp_free_i32(t2);
4724            tcg_temp_free_i32(t3);
4725        }
4726        break;
4727    case R6_OPC_MULU:
4728        {
4729            TCGv_i32 t2 = tcg_temp_new_i32();
4730            TCGv_i32 t3 = tcg_temp_new_i32();
4731            tcg_gen_trunc_tl_i32(t2, t0);
4732            tcg_gen_trunc_tl_i32(t3, t1);
4733            tcg_gen_mul_i32(t2, t2, t3);
4734            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4735            tcg_temp_free_i32(t2);
4736            tcg_temp_free_i32(t3);
4737        }
4738        break;
4739    case R6_OPC_MUHU:
4740        {
4741            TCGv_i32 t2 = tcg_temp_new_i32();
4742            TCGv_i32 t3 = tcg_temp_new_i32();
4743            tcg_gen_trunc_tl_i32(t2, t0);
4744            tcg_gen_trunc_tl_i32(t3, t1);
4745            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4746            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4747            tcg_temp_free_i32(t2);
4748            tcg_temp_free_i32(t3);
4749        }
4750        break;
4751#if defined(TARGET_MIPS64)
4752    case R6_OPC_DDIV:
4753        {
4754            TCGv t2 = tcg_temp_new();
4755            TCGv t3 = tcg_temp_new();
4756            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4757            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4758            tcg_gen_and_tl(t2, t2, t3);
4759            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4760            tcg_gen_or_tl(t2, t2, t3);
4761            tcg_gen_movi_tl(t3, 0);
4762            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4763            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4764            tcg_temp_free(t3);
4765            tcg_temp_free(t2);
4766        }
4767        break;
4768    case R6_OPC_DMOD:
4769        {
4770            TCGv t2 = tcg_temp_new();
4771            TCGv t3 = tcg_temp_new();
4772            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4773            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4774            tcg_gen_and_tl(t2, t2, t3);
4775            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4776            tcg_gen_or_tl(t2, t2, t3);
4777            tcg_gen_movi_tl(t3, 0);
4778            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4779            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4780            tcg_temp_free(t3);
4781            tcg_temp_free(t2);
4782        }
4783        break;
4784    case R6_OPC_DDIVU:
4785        {
4786            TCGv t2 = tcg_const_tl(0);
4787            TCGv t3 = tcg_const_tl(1);
4788            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4789            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4790            tcg_temp_free(t3);
4791            tcg_temp_free(t2);
4792        }
4793        break;
4794    case R6_OPC_DMODU:
4795        {
4796            TCGv t2 = tcg_const_tl(0);
4797            TCGv t3 = tcg_const_tl(1);
4798            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4799            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4800            tcg_temp_free(t3);
4801            tcg_temp_free(t2);
4802        }
4803        break;
4804    case R6_OPC_DMUL:
4805        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4806        break;
4807    case R6_OPC_DMUH:
4808        {
4809            TCGv t2 = tcg_temp_new();
4810            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4811            tcg_temp_free(t2);
4812        }
4813        break;
4814    case R6_OPC_DMULU:
4815        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4816        break;
4817    case R6_OPC_DMUHU:
4818        {
4819            TCGv t2 = tcg_temp_new();
4820            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4821            tcg_temp_free(t2);
4822        }
4823        break;
4824#endif
4825    default:
4826        MIPS_INVAL("r6 mul/div");
4827        generate_exception_end(ctx, EXCP_RI);
4828        goto out;
4829    }
4830 out:
4831    tcg_temp_free(t0);
4832    tcg_temp_free(t1);
4833}
4834
4835#if defined(TARGET_MIPS64)
4836static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4837{
4838    TCGv t0, t1;
4839
4840    t0 = tcg_temp_new();
4841    t1 = tcg_temp_new();
4842
4843    gen_load_gpr(t0, rs);
4844    gen_load_gpr(t1, rt);
4845
4846    switch (opc) {
4847    case MMI_OPC_DIV1:
4848        {
4849            TCGv t2 = tcg_temp_new();
4850            TCGv t3 = tcg_temp_new();
4851            tcg_gen_ext32s_tl(t0, t0);
4852            tcg_gen_ext32s_tl(t1, t1);
4853            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4854            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4855            tcg_gen_and_tl(t2, t2, t3);
4856            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4857            tcg_gen_or_tl(t2, t2, t3);
4858            tcg_gen_movi_tl(t3, 0);
4859            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4860            tcg_gen_div_tl(cpu_LO[1], t0, t1);
4861            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4862            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4863            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4864            tcg_temp_free(t3);
4865            tcg_temp_free(t2);
4866        }
4867        break;
4868    case MMI_OPC_DIVU1:
4869        {
4870            TCGv t2 = tcg_const_tl(0);
4871            TCGv t3 = tcg_const_tl(1);
4872            tcg_gen_ext32u_tl(t0, t0);
4873            tcg_gen_ext32u_tl(t1, t1);
4874            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4875            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4876            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4877            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4878            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4879            tcg_temp_free(t3);
4880            tcg_temp_free(t2);
4881        }
4882        break;
4883    default:
4884        MIPS_INVAL("div1 TX79");
4885        generate_exception_end(ctx, EXCP_RI);
4886        goto out;
4887    }
4888 out:
4889    tcg_temp_free(t0);
4890    tcg_temp_free(t1);
4891}
4892#endif
4893
4894static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4895                       int acc, int rs, int rt)
4896{
4897    TCGv t0, t1;
4898
4899    t0 = tcg_temp_new();
4900    t1 = tcg_temp_new();
4901
4902    gen_load_gpr(t0, rs);
4903    gen_load_gpr(t1, rt);
4904
4905    if (acc != 0) {
4906        check_dsp(ctx);
4907    }
4908
4909    switch (opc) {
4910    case OPC_DIV:
4911        {
4912            TCGv t2 = tcg_temp_new();
4913            TCGv t3 = tcg_temp_new();
4914            tcg_gen_ext32s_tl(t0, t0);
4915            tcg_gen_ext32s_tl(t1, t1);
4916            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4917            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4918            tcg_gen_and_tl(t2, t2, t3);
4919            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4920            tcg_gen_or_tl(t2, t2, t3);
4921            tcg_gen_movi_tl(t3, 0);
4922            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4923            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4924            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4925            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4926            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4927            tcg_temp_free(t3);
4928            tcg_temp_free(t2);
4929        }
4930        break;
4931    case OPC_DIVU:
4932        {
4933            TCGv t2 = tcg_const_tl(0);
4934            TCGv t3 = tcg_const_tl(1);
4935            tcg_gen_ext32u_tl(t0, t0);
4936            tcg_gen_ext32u_tl(t1, t1);
4937            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4938            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4939            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4940            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4941            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4942            tcg_temp_free(t3);
4943            tcg_temp_free(t2);
4944        }
4945        break;
4946    case OPC_MULT:
4947        {
4948            TCGv_i32 t2 = tcg_temp_new_i32();
4949            TCGv_i32 t3 = tcg_temp_new_i32();
4950            tcg_gen_trunc_tl_i32(t2, t0);
4951            tcg_gen_trunc_tl_i32(t3, t1);
4952            tcg_gen_muls2_i32(t2, t3, t2, t3);
4953            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4954            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4955            tcg_temp_free_i32(t2);
4956            tcg_temp_free_i32(t3);
4957        }
4958        break;
4959    case OPC_MULTU:
4960        {
4961            TCGv_i32 t2 = tcg_temp_new_i32();
4962            TCGv_i32 t3 = tcg_temp_new_i32();
4963            tcg_gen_trunc_tl_i32(t2, t0);
4964            tcg_gen_trunc_tl_i32(t3, t1);
4965            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4966            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4967            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4968            tcg_temp_free_i32(t2);
4969            tcg_temp_free_i32(t3);
4970        }
4971        break;
4972#if defined(TARGET_MIPS64)
4973    case OPC_DDIV:
4974        {
4975            TCGv t2 = tcg_temp_new();
4976            TCGv t3 = tcg_temp_new();
4977            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4978            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4979            tcg_gen_and_tl(t2, t2, t3);
4980            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4981            tcg_gen_or_tl(t2, t2, t3);
4982            tcg_gen_movi_tl(t3, 0);
4983            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4984            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4985            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4986            tcg_temp_free(t3);
4987            tcg_temp_free(t2);
4988        }
4989        break;
4990    case OPC_DDIVU:
4991        {
4992            TCGv t2 = tcg_const_tl(0);
4993            TCGv t3 = tcg_const_tl(1);
4994            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4995            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4996            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4997            tcg_temp_free(t3);
4998            tcg_temp_free(t2);
4999        }
5000        break;
5001    case OPC_DMULT:
5002        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5003        break;
5004    case OPC_DMULTU:
5005        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
5006        break;
5007#endif
5008    case OPC_MADD:
5009        {
5010            TCGv_i64 t2 = tcg_temp_new_i64();
5011            TCGv_i64 t3 = tcg_temp_new_i64();
5012
5013            tcg_gen_ext_tl_i64(t2, t0);
5014            tcg_gen_ext_tl_i64(t3, t1);
5015            tcg_gen_mul_i64(t2, t2, t3);
5016            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5017            tcg_gen_add_i64(t2, t2, t3);
5018            tcg_temp_free_i64(t3);
5019            gen_move_low32(cpu_LO[acc], t2);
5020            gen_move_high32(cpu_HI[acc], t2);
5021            tcg_temp_free_i64(t2);
5022        }
5023        break;
5024    case OPC_MADDU:
5025        {
5026            TCGv_i64 t2 = tcg_temp_new_i64();
5027            TCGv_i64 t3 = tcg_temp_new_i64();
5028
5029            tcg_gen_ext32u_tl(t0, t0);
5030            tcg_gen_ext32u_tl(t1, t1);
5031            tcg_gen_extu_tl_i64(t2, t0);
5032            tcg_gen_extu_tl_i64(t3, t1);
5033            tcg_gen_mul_i64(t2, t2, t3);
5034            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5035            tcg_gen_add_i64(t2, t2, t3);
5036            tcg_temp_free_i64(t3);
5037            gen_move_low32(cpu_LO[acc], t2);
5038            gen_move_high32(cpu_HI[acc], t2);
5039            tcg_temp_free_i64(t2);
5040        }
5041        break;
5042    case OPC_MSUB:
5043        {
5044            TCGv_i64 t2 = tcg_temp_new_i64();
5045            TCGv_i64 t3 = tcg_temp_new_i64();
5046
5047            tcg_gen_ext_tl_i64(t2, t0);
5048            tcg_gen_ext_tl_i64(t3, t1);
5049            tcg_gen_mul_i64(t2, t2, t3);
5050            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5051            tcg_gen_sub_i64(t2, t3, t2);
5052            tcg_temp_free_i64(t3);
5053            gen_move_low32(cpu_LO[acc], t2);
5054            gen_move_high32(cpu_HI[acc], t2);
5055            tcg_temp_free_i64(t2);
5056        }
5057        break;
5058    case OPC_MSUBU:
5059        {
5060            TCGv_i64 t2 = tcg_temp_new_i64();
5061            TCGv_i64 t3 = tcg_temp_new_i64();
5062
5063            tcg_gen_ext32u_tl(t0, t0);
5064            tcg_gen_ext32u_tl(t1, t1);
5065            tcg_gen_extu_tl_i64(t2, t0);
5066            tcg_gen_extu_tl_i64(t3, t1);
5067            tcg_gen_mul_i64(t2, t2, t3);
5068            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5069            tcg_gen_sub_i64(t2, t3, t2);
5070            tcg_temp_free_i64(t3);
5071            gen_move_low32(cpu_LO[acc], t2);
5072            gen_move_high32(cpu_HI[acc], t2);
5073            tcg_temp_free_i64(t2);
5074        }
5075        break;
5076    default:
5077        MIPS_INVAL("mul/div");
5078        generate_exception_end(ctx, EXCP_RI);
5079        goto out;
5080    }
5081 out:
5082    tcg_temp_free(t0);
5083    tcg_temp_free(t1);
5084}
5085
5086/*
5087 * These MULT[U] and MADD[U] instructions implemented in for example
5088 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5089 * architectures are special three-operand variants with the syntax
5090 *
5091 *     MULT[U][1] rd, rs, rt
5092 *
5093 * such that
5094 *
5095 *     (rd, LO, HI) <- rs * rt
5096 *
5097 * and
5098 *
5099 *     MADD[U][1] rd, rs, rt
5100 *
5101 * such that
5102 *
5103 *     (rd, LO, HI) <- (LO, HI) + rs * rt
5104 *
5105 * where the low-order 32-bits of the result is placed into both the
5106 * GPR rd and the special register LO. The high-order 32-bits of the
5107 * result is placed into the special register HI.
5108 *
5109 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5110 * which is the zero register that always reads as 0.
5111 */
5112static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5113                         int rd, int rs, int rt)
5114{
5115    TCGv t0 = tcg_temp_new();
5116    TCGv t1 = tcg_temp_new();
5117    int acc = 0;
5118
5119    gen_load_gpr(t0, rs);
5120    gen_load_gpr(t1, rt);
5121
5122    switch (opc) {
5123    case MMI_OPC_MULT1:
5124        acc = 1;
5125        /* Fall through */
5126    case OPC_MULT:
5127        {
5128            TCGv_i32 t2 = tcg_temp_new_i32();
5129            TCGv_i32 t3 = tcg_temp_new_i32();
5130            tcg_gen_trunc_tl_i32(t2, t0);
5131            tcg_gen_trunc_tl_i32(t3, t1);
5132            tcg_gen_muls2_i32(t2, t3, t2, t3);
5133            if (rd) {
5134                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5135            }
5136            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5137            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5138            tcg_temp_free_i32(t2);
5139            tcg_temp_free_i32(t3);
5140        }
5141        break;
5142    case MMI_OPC_MULTU1:
5143        acc = 1;
5144        /* Fall through */
5145    case OPC_MULTU:
5146        {
5147            TCGv_i32 t2 = tcg_temp_new_i32();
5148            TCGv_i32 t3 = tcg_temp_new_i32();
5149            tcg_gen_trunc_tl_i32(t2, t0);
5150            tcg_gen_trunc_tl_i32(t3, t1);
5151            tcg_gen_mulu2_i32(t2, t3, t2, t3);
5152            if (rd) {
5153                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5154            }
5155            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5156            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5157            tcg_temp_free_i32(t2);
5158            tcg_temp_free_i32(t3);
5159        }
5160        break;
5161    case MMI_OPC_MADD1:
5162        acc = 1;
5163        /* Fall through */
5164    case MMI_OPC_MADD:
5165        {
5166            TCGv_i64 t2 = tcg_temp_new_i64();
5167            TCGv_i64 t3 = tcg_temp_new_i64();
5168
5169            tcg_gen_ext_tl_i64(t2, t0);
5170            tcg_gen_ext_tl_i64(t3, t1);
5171            tcg_gen_mul_i64(t2, t2, t3);
5172            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5173            tcg_gen_add_i64(t2, t2, t3);
5174            tcg_temp_free_i64(t3);
5175            gen_move_low32(cpu_LO[acc], t2);
5176            gen_move_high32(cpu_HI[acc], t2);
5177            if (rd) {
5178                gen_move_low32(cpu_gpr[rd], t2);
5179            }
5180            tcg_temp_free_i64(t2);
5181        }
5182        break;
5183    case MMI_OPC_MADDU1:
5184        acc = 1;
5185        /* Fall through */
5186    case MMI_OPC_MADDU:
5187        {
5188            TCGv_i64 t2 = tcg_temp_new_i64();
5189            TCGv_i64 t3 = tcg_temp_new_i64();
5190
5191            tcg_gen_ext32u_tl(t0, t0);
5192            tcg_gen_ext32u_tl(t1, t1);
5193            tcg_gen_extu_tl_i64(t2, t0);
5194            tcg_gen_extu_tl_i64(t3, t1);
5195            tcg_gen_mul_i64(t2, t2, t3);
5196            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5197            tcg_gen_add_i64(t2, t2, t3);
5198            tcg_temp_free_i64(t3);
5199            gen_move_low32(cpu_LO[acc], t2);
5200            gen_move_high32(cpu_HI[acc], t2);
5201            if (rd) {
5202                gen_move_low32(cpu_gpr[rd], t2);
5203            }
5204            tcg_temp_free_i64(t2);
5205        }
5206        break;
5207    default:
5208        MIPS_INVAL("mul/madd TXx9");
5209        generate_exception_end(ctx, EXCP_RI);
5210        goto out;
5211    }
5212
5213 out:
5214    tcg_temp_free(t0);
5215    tcg_temp_free(t1);
5216}
5217
5218static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
5219                           int rd, int rs, int rt)
5220{
5221    TCGv t0 = tcg_temp_new();
5222    TCGv t1 = tcg_temp_new();
5223
5224    gen_load_gpr(t0, rs);
5225    gen_load_gpr(t1, rt);
5226
5227    switch (opc) {
5228    case OPC_VR54XX_MULS:
5229        gen_helper_muls(t0, cpu_env, t0, t1);
5230        break;
5231    case OPC_VR54XX_MULSU:
5232        gen_helper_mulsu(t0, cpu_env, t0, t1);
5233        break;
5234    case OPC_VR54XX_MACC:
5235        gen_helper_macc(t0, cpu_env, t0, t1);
5236        break;
5237    case OPC_VR54XX_MACCU:
5238        gen_helper_maccu(t0, cpu_env, t0, t1);
5239        break;
5240    case OPC_VR54XX_MSAC:
5241        gen_helper_msac(t0, cpu_env, t0, t1);
5242        break;
5243    case OPC_VR54XX_MSACU:
5244        gen_helper_msacu(t0, cpu_env, t0, t1);
5245        break;
5246    case OPC_VR54XX_MULHI:
5247        gen_helper_mulhi(t0, cpu_env, t0, t1);
5248        break;
5249    case OPC_VR54XX_MULHIU:
5250        gen_helper_mulhiu(t0, cpu_env, t0, t1);
5251        break;
5252    case OPC_VR54XX_MULSHI:
5253        gen_helper_mulshi(t0, cpu_env, t0, t1);
5254        break;
5255    case OPC_VR54XX_MULSHIU:
5256        gen_helper_mulshiu(t0, cpu_env, t0, t1);
5257        break;
5258    case OPC_VR54XX_MACCHI:
5259        gen_helper_macchi(t0, cpu_env, t0, t1);
5260        break;
5261    case OPC_VR54XX_MACCHIU:
5262        gen_helper_macchiu(t0, cpu_env, t0, t1);
5263        break;
5264    case OPC_VR54XX_MSACHI:
5265        gen_helper_msachi(t0, cpu_env, t0, t1);
5266        break;
5267    case OPC_VR54XX_MSACHIU:
5268        gen_helper_msachiu(t0, cpu_env, t0, t1);
5269        break;
5270    default:
5271        MIPS_INVAL("mul vr54xx");
5272        generate_exception_end(ctx, EXCP_RI);
5273        goto out;
5274    }
5275    gen_store_gpr(t0, rd);
5276
5277 out:
5278    tcg_temp_free(t0);
5279    tcg_temp_free(t1);
5280}
5281
5282static void gen_cl(DisasContext *ctx, uint32_t opc,
5283                   int rd, int rs)
5284{
5285    TCGv t0;
5286
5287    if (rd == 0) {
5288        /* Treat as NOP. */
5289        return;
5290    }
5291    t0 = cpu_gpr[rd];
5292    gen_load_gpr(t0, rs);
5293
5294    switch (opc) {
5295    case OPC_CLO:
5296    case R6_OPC_CLO:
5297#if defined(TARGET_MIPS64)
5298    case OPC_DCLO:
5299    case R6_OPC_DCLO:
5300#endif
5301        tcg_gen_not_tl(t0, t0);
5302        break;
5303    }
5304
5305    switch (opc) {
5306    case OPC_CLO:
5307    case R6_OPC_CLO:
5308    case OPC_CLZ:
5309    case R6_OPC_CLZ:
5310        tcg_gen_ext32u_tl(t0, t0);
5311        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5312        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5313        break;
5314#if defined(TARGET_MIPS64)
5315    case OPC_DCLO:
5316    case R6_OPC_DCLO:
5317    case OPC_DCLZ:
5318    case R6_OPC_DCLZ:
5319        tcg_gen_clzi_i64(t0, t0, 64);
5320        break;
5321#endif
5322    }
5323}
5324
5325/* Godson integer instructions */
5326static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5327                                 int rd, int rs, int rt)
5328{
5329    TCGv t0, t1;
5330
5331    if (rd == 0) {
5332        /* Treat as NOP. */
5333        return;
5334    }
5335
5336    switch (opc) {
5337    case OPC_MULT_G_2E:
5338    case OPC_MULT_G_2F:
5339    case OPC_MULTU_G_2E:
5340    case OPC_MULTU_G_2F:
5341#if defined(TARGET_MIPS64)
5342    case OPC_DMULT_G_2E:
5343    case OPC_DMULT_G_2F:
5344    case OPC_DMULTU_G_2E:
5345    case OPC_DMULTU_G_2F:
5346#endif
5347        t0 = tcg_temp_new();
5348        t1 = tcg_temp_new();
5349        break;
5350    default:
5351        t0 = tcg_temp_local_new();
5352        t1 = tcg_temp_local_new();
5353        break;
5354    }
5355
5356    gen_load_gpr(t0, rs);
5357    gen_load_gpr(t1, rt);
5358
5359    switch (opc) {
5360    case OPC_MULT_G_2E:
5361    case OPC_MULT_G_2F:
5362        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5363        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5364        break;
5365    case OPC_MULTU_G_2E:
5366    case OPC_MULTU_G_2F:
5367        tcg_gen_ext32u_tl(t0, t0);
5368        tcg_gen_ext32u_tl(t1, t1);
5369        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5370        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5371        break;
5372    case OPC_DIV_G_2E:
5373    case OPC_DIV_G_2F:
5374        {
5375            TCGLabel *l1 = gen_new_label();
5376            TCGLabel *l2 = gen_new_label();
5377            TCGLabel *l3 = gen_new_label();
5378            tcg_gen_ext32s_tl(t0, t0);
5379            tcg_gen_ext32s_tl(t1, t1);
5380            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5381            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5382            tcg_gen_br(l3);
5383            gen_set_label(l1);
5384            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5385            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5386            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5387            tcg_gen_br(l3);
5388            gen_set_label(l2);
5389            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5390            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5391            gen_set_label(l3);
5392        }
5393        break;
5394    case OPC_DIVU_G_2E:
5395    case OPC_DIVU_G_2F:
5396        {
5397            TCGLabel *l1 = gen_new_label();
5398            TCGLabel *l2 = gen_new_label();
5399            tcg_gen_ext32u_tl(t0, t0);
5400            tcg_gen_ext32u_tl(t1, t1);
5401            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5402            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5403            tcg_gen_br(l2);
5404            gen_set_label(l1);
5405            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5406            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5407            gen_set_label(l2);
5408        }
5409        break;
5410    case OPC_MOD_G_2E:
5411    case OPC_MOD_G_2F:
5412        {
5413            TCGLabel *l1 = gen_new_label();
5414            TCGLabel *l2 = gen_new_label();
5415            TCGLabel *l3 = gen_new_label();
5416            tcg_gen_ext32u_tl(t0, t0);
5417            tcg_gen_ext32u_tl(t1, t1);
5418            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5419            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5420            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5421            gen_set_label(l1);
5422            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5423            tcg_gen_br(l3);
5424            gen_set_label(l2);
5425            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5426            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5427            gen_set_label(l3);
5428        }
5429        break;
5430    case OPC_MODU_G_2E:
5431    case OPC_MODU_G_2F:
5432        {
5433            TCGLabel *l1 = gen_new_label();
5434            TCGLabel *l2 = gen_new_label();
5435            tcg_gen_ext32u_tl(t0, t0);
5436            tcg_gen_ext32u_tl(t1, t1);
5437            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5438            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5439            tcg_gen_br(l2);
5440            gen_set_label(l1);
5441            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5442            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5443            gen_set_label(l2);
5444        }
5445        break;
5446#if defined(TARGET_MIPS64)
5447    case OPC_DMULT_G_2E:
5448    case OPC_DMULT_G_2F:
5449        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5450        break;
5451    case OPC_DMULTU_G_2E:
5452    case OPC_DMULTU_G_2F:
5453        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5454        break;
5455    case OPC_DDIV_G_2E:
5456    case OPC_DDIV_G_2F:
5457        {
5458            TCGLabel *l1 = gen_new_label();
5459            TCGLabel *l2 = gen_new_label();
5460            TCGLabel *l3 = gen_new_label();
5461            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5462            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5463            tcg_gen_br(l3);
5464            gen_set_label(l1);
5465            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5466            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5467            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5468            tcg_gen_br(l3);
5469            gen_set_label(l2);
5470            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5471            gen_set_label(l3);
5472        }
5473        break;
5474    case OPC_DDIVU_G_2E:
5475    case OPC_DDIVU_G_2F:
5476        {
5477            TCGLabel *l1 = gen_new_label();
5478            TCGLabel *l2 = gen_new_label();
5479            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5480            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5481            tcg_gen_br(l2);
5482            gen_set_label(l1);
5483            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5484            gen_set_label(l2);
5485        }
5486        break;
5487    case OPC_DMOD_G_2E:
5488    case OPC_DMOD_G_2F:
5489        {
5490            TCGLabel *l1 = gen_new_label();
5491            TCGLabel *l2 = gen_new_label();
5492            TCGLabel *l3 = gen_new_label();
5493            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5494            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5495            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5496            gen_set_label(l1);
5497            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5498            tcg_gen_br(l3);
5499            gen_set_label(l2);
5500            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5501            gen_set_label(l3);
5502        }
5503        break;
5504    case OPC_DMODU_G_2E:
5505    case OPC_DMODU_G_2F:
5506        {
5507            TCGLabel *l1 = gen_new_label();
5508            TCGLabel *l2 = gen_new_label();
5509            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5510            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5511            tcg_gen_br(l2);
5512            gen_set_label(l1);
5513            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5514            gen_set_label(l2);
5515        }
5516        break;
5517#endif
5518    }
5519
5520    tcg_temp_free(t0);
5521    tcg_temp_free(t1);
5522}
5523
5524/* Loongson multimedia instructions */
5525static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5526{
5527    uint32_t opc, shift_max;
5528    TCGv_i64 t0, t1;
5529
5530    opc = MASK_LMI(ctx->opcode);
5531    switch (opc) {
5532    case OPC_ADD_CP2:
5533    case OPC_SUB_CP2:
5534    case OPC_DADD_CP2:
5535    case OPC_DSUB_CP2:
5536        t0 = tcg_temp_local_new_i64();
5537        t1 = tcg_temp_local_new_i64();
5538        break;
5539    default:
5540        t0 = tcg_temp_new_i64();
5541        t1 = tcg_temp_new_i64();
5542        break;
5543    }
5544
5545    check_cp1_enabled(ctx);
5546    gen_load_fpr64(ctx, t0, rs);
5547    gen_load_fpr64(ctx, t1, rt);
5548
5549    switch (opc) {
5550    case OPC_PADDSH:
5551        gen_helper_paddsh(t0, t0, t1);
5552        break;
5553    case OPC_PADDUSH:
5554        gen_helper_paddush(t0, t0, t1);
5555        break;
5556    case OPC_PADDH:
5557        gen_helper_paddh(t0, t0, t1);
5558        break;
5559    case OPC_PADDW:
5560        gen_helper_paddw(t0, t0, t1);
5561        break;
5562    case OPC_PADDSB:
5563        gen_helper_paddsb(t0, t0, t1);
5564        break;
5565    case OPC_PADDUSB:
5566        gen_helper_paddusb(t0, t0, t1);
5567        break;
5568    case OPC_PADDB:
5569        gen_helper_paddb(t0, t0, t1);
5570        break;
5571
5572    case OPC_PSUBSH:
5573        gen_helper_psubsh(t0, t0, t1);
5574        break;
5575    case OPC_PSUBUSH:
5576        gen_helper_psubush(t0, t0, t1);
5577        break;
5578    case OPC_PSUBH:
5579        gen_helper_psubh(t0, t0, t1);
5580        break;
5581    case OPC_PSUBW:
5582        gen_helper_psubw(t0, t0, t1);
5583        break;
5584    case OPC_PSUBSB:
5585        gen_helper_psubsb(t0, t0, t1);
5586        break;
5587    case OPC_PSUBUSB:
5588        gen_helper_psubusb(t0, t0, t1);
5589        break;
5590    case OPC_PSUBB:
5591        gen_helper_psubb(t0, t0, t1);
5592        break;
5593
5594    case OPC_PSHUFH:
5595        gen_helper_pshufh(t0, t0, t1);
5596        break;
5597    case OPC_PACKSSWH:
5598        gen_helper_packsswh(t0, t0, t1);
5599        break;
5600    case OPC_PACKSSHB:
5601        gen_helper_packsshb(t0, t0, t1);
5602        break;
5603    case OPC_PACKUSHB:
5604        gen_helper_packushb(t0, t0, t1);
5605        break;
5606
5607    case OPC_PUNPCKLHW:
5608        gen_helper_punpcklhw(t0, t0, t1);
5609        break;
5610    case OPC_PUNPCKHHW:
5611        gen_helper_punpckhhw(t0, t0, t1);
5612        break;
5613    case OPC_PUNPCKLBH:
5614        gen_helper_punpcklbh(t0, t0, t1);
5615        break;
5616    case OPC_PUNPCKHBH:
5617        gen_helper_punpckhbh(t0, t0, t1);
5618        break;
5619    case OPC_PUNPCKLWD:
5620        gen_helper_punpcklwd(t0, t0, t1);
5621        break;
5622    case OPC_PUNPCKHWD:
5623        gen_helper_punpckhwd(t0, t0, t1);
5624        break;
5625
5626    case OPC_PAVGH:
5627        gen_helper_pavgh(t0, t0, t1);
5628        break;
5629    case OPC_PAVGB:
5630        gen_helper_pavgb(t0, t0, t1);
5631        break;
5632    case OPC_PMAXSH:
5633        gen_helper_pmaxsh(t0, t0, t1);
5634        break;
5635    case OPC_PMINSH:
5636        gen_helper_pminsh(t0, t0, t1);
5637        break;
5638    case OPC_PMAXUB:
5639        gen_helper_pmaxub(t0, t0, t1);
5640        break;
5641    case OPC_PMINUB:
5642        gen_helper_pminub(t0, t0, t1);
5643        break;
5644
5645    case OPC_PCMPEQW:
5646        gen_helper_pcmpeqw(t0, t0, t1);
5647        break;
5648    case OPC_PCMPGTW:
5649        gen_helper_pcmpgtw(t0, t0, t1);
5650        break;
5651    case OPC_PCMPEQH:
5652        gen_helper_pcmpeqh(t0, t0, t1);
5653        break;
5654    case OPC_PCMPGTH:
5655        gen_helper_pcmpgth(t0, t0, t1);
5656        break;
5657    case OPC_PCMPEQB:
5658        gen_helper_pcmpeqb(t0, t0, t1);
5659        break;
5660    case OPC_PCMPGTB:
5661        gen_helper_pcmpgtb(t0, t0, t1);
5662        break;
5663
5664    case OPC_PSLLW:
5665        gen_helper_psllw(t0, t0, t1);
5666        break;
5667    case OPC_PSLLH:
5668        gen_helper_psllh(t0, t0, t1);
5669        break;
5670    case OPC_PSRLW:
5671        gen_helper_psrlw(t0, t0, t1);
5672        break;
5673    case OPC_PSRLH:
5674        gen_helper_psrlh(t0, t0, t1);
5675        break;
5676    case OPC_PSRAW:
5677        gen_helper_psraw(t0, t0, t1);
5678        break;
5679    case OPC_PSRAH:
5680        gen_helper_psrah(t0, t0, t1);
5681        break;
5682
5683    case OPC_PMULLH:
5684        gen_helper_pmullh(t0, t0, t1);
5685        break;
5686    case OPC_PMULHH:
5687        gen_helper_pmulhh(t0, t0, t1);
5688        break;
5689    case OPC_PMULHUH:
5690        gen_helper_pmulhuh(t0, t0, t1);
5691        break;
5692    case OPC_PMADDHW:
5693        gen_helper_pmaddhw(t0, t0, t1);
5694        break;
5695
5696    case OPC_PASUBUB:
5697        gen_helper_pasubub(t0, t0, t1);
5698        break;
5699    case OPC_BIADD:
5700        gen_helper_biadd(t0, t0);
5701        break;
5702    case OPC_PMOVMSKB:
5703        gen_helper_pmovmskb(t0, t0);
5704        break;
5705
5706    case OPC_PADDD:
5707        tcg_gen_add_i64(t0, t0, t1);
5708        break;
5709    case OPC_PSUBD:
5710        tcg_gen_sub_i64(t0, t0, t1);
5711        break;
5712    case OPC_XOR_CP2:
5713        tcg_gen_xor_i64(t0, t0, t1);
5714        break;
5715    case OPC_NOR_CP2:
5716        tcg_gen_nor_i64(t0, t0, t1);
5717        break;
5718    case OPC_AND_CP2:
5719        tcg_gen_and_i64(t0, t0, t1);
5720        break;
5721    case OPC_OR_CP2:
5722        tcg_gen_or_i64(t0, t0, t1);
5723        break;
5724
5725    case OPC_PANDN:
5726        tcg_gen_andc_i64(t0, t1, t0);
5727        break;
5728
5729    case OPC_PINSRH_0:
5730        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5731        break;
5732    case OPC_PINSRH_1:
5733        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5734        break;
5735    case OPC_PINSRH_2:
5736        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5737        break;
5738    case OPC_PINSRH_3:
5739        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5740        break;
5741
5742    case OPC_PEXTRH:
5743        tcg_gen_andi_i64(t1, t1, 3);
5744        tcg_gen_shli_i64(t1, t1, 4);
5745        tcg_gen_shr_i64(t0, t0, t1);
5746        tcg_gen_ext16u_i64(t0, t0);
5747        break;
5748
5749    case OPC_ADDU_CP2:
5750        tcg_gen_add_i64(t0, t0, t1);
5751        tcg_gen_ext32s_i64(t0, t0);
5752        break;
5753    case OPC_SUBU_CP2:
5754        tcg_gen_sub_i64(t0, t0, t1);
5755        tcg_gen_ext32s_i64(t0, t0);
5756        break;
5757
5758    case OPC_SLL_CP2:
5759        shift_max = 32;
5760        goto do_shift;
5761    case OPC_SRL_CP2:
5762        shift_max = 32;
5763        goto do_shift;
5764    case OPC_SRA_CP2:
5765        shift_max = 32;
5766        goto do_shift;
5767    case OPC_DSLL_CP2:
5768        shift_max = 64;
5769        goto do_shift;
5770    case OPC_DSRL_CP2:
5771        shift_max = 64;
5772        goto do_shift;
5773    case OPC_DSRA_CP2:
5774        shift_max = 64;
5775        goto do_shift;
5776    do_shift:
5777        /* Make sure shift count isn't TCG undefined behaviour.  */
5778        tcg_gen_andi_i64(t1, t1, shift_max - 1);
5779
5780        switch (opc) {
5781        case OPC_SLL_CP2:
5782        case OPC_DSLL_CP2:
5783            tcg_gen_shl_i64(t0, t0, t1);
5784            break;
5785        case OPC_SRA_CP2:
5786        case OPC_DSRA_CP2:
5787            /*
5788             * Since SRA is UndefinedResult without sign-extended inputs,
5789             * we can treat SRA and DSRA the same.
5790             */
5791            tcg_gen_sar_i64(t0, t0, t1);
5792            break;
5793        case OPC_SRL_CP2:
5794            /* We want to shift in zeros for SRL; zero-extend first.  */
5795            tcg_gen_ext32u_i64(t0, t0);
5796            /* FALLTHRU */
5797        case OPC_DSRL_CP2:
5798            tcg_gen_shr_i64(t0, t0, t1);
5799            break;
5800        }
5801
5802        if (shift_max == 32) {
5803            tcg_gen_ext32s_i64(t0, t0);
5804        }
5805
5806        /* Shifts larger than MAX produce zero.  */
5807        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5808        tcg_gen_neg_i64(t1, t1);
5809        tcg_gen_and_i64(t0, t0, t1);
5810        break;
5811
5812    case OPC_ADD_CP2:
5813    case OPC_DADD_CP2:
5814        {
5815            TCGv_i64 t2 = tcg_temp_new_i64();
5816            TCGLabel *lab = gen_new_label();
5817
5818            tcg_gen_mov_i64(t2, t0);
5819            tcg_gen_add_i64(t0, t1, t2);
5820            if (opc == OPC_ADD_CP2) {
5821                tcg_gen_ext32s_i64(t0, t0);
5822            }
5823            tcg_gen_xor_i64(t1, t1, t2);
5824            tcg_gen_xor_i64(t2, t2, t0);
5825            tcg_gen_andc_i64(t1, t2, t1);
5826            tcg_temp_free_i64(t2);
5827            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5828            generate_exception(ctx, EXCP_OVERFLOW);
5829            gen_set_label(lab);
5830            break;
5831        }
5832
5833    case OPC_SUB_CP2:
5834    case OPC_DSUB_CP2:
5835        {
5836            TCGv_i64 t2 = tcg_temp_new_i64();
5837            TCGLabel *lab = gen_new_label();
5838
5839            tcg_gen_mov_i64(t2, t0);
5840            tcg_gen_sub_i64(t0, t1, t2);
5841            if (opc == OPC_SUB_CP2) {
5842                tcg_gen_ext32s_i64(t0, t0);
5843            }
5844            tcg_gen_xor_i64(t1, t1, t2);
5845            tcg_gen_xor_i64(t2, t2, t0);
5846            tcg_gen_and_i64(t1, t1, t2);
5847            tcg_temp_free_i64(t2);
5848            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5849            generate_exception(ctx, EXCP_OVERFLOW);
5850            gen_set_label(lab);
5851            break;
5852        }
5853
5854    case OPC_PMULUW:
5855        tcg_gen_ext32u_i64(t0, t0);
5856        tcg_gen_ext32u_i64(t1, t1);
5857        tcg_gen_mul_i64(t0, t0, t1);
5858        break;
5859
5860    case OPC_SEQU_CP2:
5861    case OPC_SEQ_CP2:
5862    case OPC_SLTU_CP2:
5863    case OPC_SLT_CP2:
5864    case OPC_SLEU_CP2:
5865    case OPC_SLE_CP2:
5866        /*
5867         * ??? Document is unclear: Set FCC[CC].  Does that mean the
5868         * FD field is the CC field?
5869         */
5870    default:
5871        MIPS_INVAL("loongson_cp2");
5872        generate_exception_end(ctx, EXCP_RI);
5873        return;
5874    }
5875
5876    gen_store_fpr64(ctx, t0, rd);
5877
5878    tcg_temp_free_i64(t0);
5879    tcg_temp_free_i64(t1);
5880}
5881
5882/* Traps */
5883static void gen_trap(DisasContext *ctx, uint32_t opc,
5884                     int rs, int rt, int16_t imm)
5885{
5886    int cond;
5887    TCGv t0 = tcg_temp_new();
5888    TCGv t1 = tcg_temp_new();
5889
5890    cond = 0;
5891    /* Load needed operands */
5892    switch (opc) {
5893    case OPC_TEQ:
5894    case OPC_TGE:
5895    case OPC_TGEU:
5896    case OPC_TLT:
5897    case OPC_TLTU:
5898    case OPC_TNE:
5899        /* Compare two registers */
5900        if (rs != rt) {
5901            gen_load_gpr(t0, rs);
5902            gen_load_gpr(t1, rt);
5903            cond = 1;
5904        }
5905        break;
5906    case OPC_TEQI:
5907    case OPC_TGEI:
5908    case OPC_TGEIU:
5909    case OPC_TLTI:
5910    case OPC_TLTIU:
5911    case OPC_TNEI:
5912        /* Compare register to immediate */
5913        if (rs != 0 || imm != 0) {
5914            gen_load_gpr(t0, rs);
5915            tcg_gen_movi_tl(t1, (int32_t)imm);
5916            cond = 1;
5917        }
5918        break;
5919    }
5920    if (cond == 0) {
5921        switch (opc) {
5922        case OPC_TEQ:   /* rs == rs */
5923        case OPC_TEQI:  /* r0 == 0  */
5924        case OPC_TGE:   /* rs >= rs */
5925        case OPC_TGEI:  /* r0 >= 0  */
5926        case OPC_TGEU:  /* rs >= rs unsigned */
5927        case OPC_TGEIU: /* r0 >= 0  unsigned */
5928            /* Always trap */
5929            generate_exception_end(ctx, EXCP_TRAP);
5930            break;
5931        case OPC_TLT:   /* rs < rs           */
5932        case OPC_TLTI:  /* r0 < 0            */
5933        case OPC_TLTU:  /* rs < rs unsigned  */
5934        case OPC_TLTIU: /* r0 < 0  unsigned  */
5935        case OPC_TNE:   /* rs != rs          */
5936        case OPC_TNEI:  /* r0 != 0           */
5937            /* Never trap: treat as NOP. */
5938            break;
5939        }
5940    } else {
5941        TCGLabel *l1 = gen_new_label();
5942
5943        switch (opc) {
5944        case OPC_TEQ:
5945        case OPC_TEQI:
5946            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5947            break;
5948        case OPC_TGE:
5949        case OPC_TGEI:
5950            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5951            break;
5952        case OPC_TGEU:
5953        case OPC_TGEIU:
5954            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5955            break;
5956        case OPC_TLT:
5957        case OPC_TLTI:
5958            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5959            break;
5960        case OPC_TLTU:
5961        case OPC_TLTIU:
5962            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5963            break;
5964        case OPC_TNE:
5965        case OPC_TNEI:
5966            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5967            break;
5968        }
5969        generate_exception(ctx, EXCP_TRAP);
5970        gen_set_label(l1);
5971    }
5972    tcg_temp_free(t0);
5973    tcg_temp_free(t1);
5974}
5975
5976static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5977{
5978    if (unlikely(ctx->base.singlestep_enabled)) {
5979        return false;
5980    }
5981
5982#ifndef CONFIG_USER_ONLY
5983    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5984#else
5985    return true;
5986#endif
5987}
5988
5989static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5990{
5991    if (use_goto_tb(ctx, dest)) {
5992        tcg_gen_goto_tb(n);
5993        gen_save_pc(dest);
5994        tcg_gen_exit_tb(ctx->base.tb, n);
5995    } else {
5996        gen_save_pc(dest);
5997        if (ctx->base.singlestep_enabled) {
5998            save_cpu_state(ctx, 0);
5999            gen_helper_raise_exception_debug(cpu_env);
6000        }
6001        tcg_gen_lookup_and_goto_ptr();
6002    }
6003}
6004
6005/* Branches (before delay slot) */
6006static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
6007                               int insn_bytes,
6008                               int rs, int rt, int32_t offset,
6009                               int delayslot_size)
6010{
6011    target_ulong btgt = -1;
6012    int blink = 0;
6013    int bcond_compute = 0;
6014    TCGv t0 = tcg_temp_new();
6015    TCGv t1 = tcg_temp_new();
6016
6017    if (ctx->hflags & MIPS_HFLAG_BMASK) {
6018#ifdef MIPS_DEBUG_DISAS
6019        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6020                  TARGET_FMT_lx "\n", ctx->base.pc_next);
6021#endif
6022        generate_exception_end(ctx, EXCP_RI);
6023        goto out;
6024    }
6025
6026    /* Load needed operands */
6027    switch (opc) {
6028    case OPC_BEQ:
6029    case OPC_BEQL:
6030    case OPC_BNE:
6031    case OPC_BNEL:
6032        /* Compare two registers */
6033        if (rs != rt) {
6034            gen_load_gpr(t0, rs);
6035            gen_load_gpr(t1, rt);
6036            bcond_compute = 1;
6037        }
6038        btgt = ctx->base.pc_next + insn_bytes + offset;
6039        break;
6040    case OPC_BGEZ:
6041    case OPC_BGEZAL:
6042    case OPC_BGEZALL:
6043    case OPC_BGEZL:
6044    case OPC_BGTZ:
6045    case OPC_BGTZL:
6046    case OPC_BLEZ:
6047    case OPC_BLEZL:
6048    case OPC_BLTZ:
6049    case OPC_BLTZAL:
6050    case OPC_BLTZALL:
6051    case OPC_BLTZL:
6052        /* Compare to zero */
6053        if (rs != 0) {
6054            gen_load_gpr(t0, rs);
6055            bcond_compute = 1;
6056        }
6057        btgt = ctx->base.pc_next + insn_bytes + offset;
6058        break;
6059    case OPC_BPOSGE32:
6060#if defined(TARGET_MIPS64)
6061    case OPC_BPOSGE64:
6062        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
6063#else
6064        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6065#endif
6066        bcond_compute = 1;
6067        btgt = ctx->base.pc_next + insn_bytes + offset;
6068        break;
6069    case OPC_J:
6070    case OPC_JAL:
6071    case OPC_JALX:
6072        /* Jump to immediate */
6073        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
6074            (uint32_t)offset;
6075        break;
6076    case OPC_JR:
6077    case OPC_JALR:
6078        /* Jump to register */
6079        if (offset != 0 && offset != 16) {
6080            /*
6081             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6082             * others are reserved.
6083             */
6084            MIPS_INVAL("jump hint");
6085            generate_exception_end(ctx, EXCP_RI);
6086            goto out;
6087        }
6088        gen_load_gpr(btarget, rs);
6089        break;
6090    default:
6091        MIPS_INVAL("branch/jump");
6092        generate_exception_end(ctx, EXCP_RI);
6093        goto out;
6094    }
6095    if (bcond_compute == 0) {
6096        /* No condition to be computed */
6097        switch (opc) {
6098        case OPC_BEQ:     /* rx == rx        */
6099        case OPC_BEQL:    /* rx == rx likely */
6100        case OPC_BGEZ:    /* 0 >= 0          */
6101        case OPC_BGEZL:   /* 0 >= 0 likely   */
6102        case OPC_BLEZ:    /* 0 <= 0          */
6103        case OPC_BLEZL:   /* 0 <= 0 likely   */
6104            /* Always take */
6105            ctx->hflags |= MIPS_HFLAG_B;
6106            break;
6107        case OPC_BGEZAL:  /* 0 >= 0          */
6108        case OPC_BGEZALL: /* 0 >= 0 likely   */
6109            /* Always take and link */
6110            blink = 31;
6111            ctx->hflags |= MIPS_HFLAG_B;
6112            break;
6113        case OPC_BNE:     /* rx != rx        */
6114        case OPC_BGTZ:    /* 0 > 0           */
6115        case OPC_BLTZ:    /* 0 < 0           */
6116            /* Treat as NOP. */
6117            goto out;
6118        case OPC_BLTZAL:  /* 0 < 0           */
6119            /*
6120             * Handle as an unconditional branch to get correct delay
6121             * slot checking.
6122             */
6123            blink = 31;
6124            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
6125            ctx->hflags |= MIPS_HFLAG_B;
6126            break;
6127        case OPC_BLTZALL: /* 0 < 0 likely */
6128            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6129            /* Skip the instruction in the delay slot */
6130            ctx->base.pc_next += 4;
6131            goto out;
6132        case OPC_BNEL:    /* rx != rx likely */
6133        case OPC_BGTZL:   /* 0 > 0 likely */
6134        case OPC_BLTZL:   /* 0 < 0 likely */
6135            /* Skip the instruction in the delay slot */
6136            ctx->base.pc_next += 4;
6137            goto out;
6138        case OPC_J:
6139            ctx->hflags |= MIPS_HFLAG_B;
6140            break;
6141        case OPC_JALX:
6142            ctx->hflags |= MIPS_HFLAG_BX;
6143            /* Fallthrough */
6144        case OPC_JAL:
6145            blink = 31;
6146            ctx->hflags |= MIPS_HFLAG_B;
6147            break;
6148        case OPC_JR:
6149            ctx->hflags |= MIPS_HFLAG_BR;
6150            break;
6151        case OPC_JALR:
6152            blink = rt;
6153            ctx->hflags |= MIPS_HFLAG_BR;
6154            break;
6155        default:
6156            MIPS_INVAL("branch/jump");
6157            generate_exception_end(ctx, EXCP_RI);
6158            goto out;
6159        }
6160    } else {
6161        switch (opc) {
6162        case OPC_BEQ:
6163            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6164            goto not_likely;
6165        case OPC_BEQL:
6166            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6167            goto likely;
6168        case OPC_BNE:
6169            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6170            goto not_likely;
6171        case OPC_BNEL:
6172            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6173            goto likely;
6174        case OPC_BGEZ:
6175            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6176            goto not_likely;
6177        case OPC_BGEZL:
6178            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6179            goto likely;
6180        case OPC_BGEZAL:
6181            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6182            blink = 31;
6183            goto not_likely;
6184        case OPC_BGEZALL:
6185            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6186            blink = 31;
6187            goto likely;
6188        case OPC_BGTZ:
6189            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6190            goto not_likely;
6191        case OPC_BGTZL:
6192            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6193            goto likely;
6194        case OPC_BLEZ:
6195            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6196            goto not_likely;
6197        case OPC_BLEZL:
6198            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6199            goto likely;
6200        case OPC_BLTZ:
6201            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6202            goto not_likely;
6203        case OPC_BLTZL:
6204            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6205            goto likely;
6206        case OPC_BPOSGE32:
6207            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6208            goto not_likely;
6209#if defined(TARGET_MIPS64)
6210        case OPC_BPOSGE64:
6211            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6212            goto not_likely;
6213#endif
6214        case OPC_BLTZAL:
6215            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6216            blink = 31;
6217        not_likely:
6218            ctx->hflags |= MIPS_HFLAG_BC;
6219            break;
6220        case OPC_BLTZALL:
6221            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6222            blink = 31;
6223        likely:
6224            ctx->hflags |= MIPS_HFLAG_BL;
6225            break;
6226        default:
6227            MIPS_INVAL("conditional branch/jump");
6228            generate_exception_end(ctx, EXCP_RI);
6229            goto out;
6230        }
6231    }
6232
6233    ctx->btarget = btgt;
6234
6235    switch (delayslot_size) {
6236    case 2:
6237        ctx->hflags |= MIPS_HFLAG_BDS16;
6238        break;
6239    case 4:
6240        ctx->hflags |= MIPS_HFLAG_BDS32;
6241        break;
6242    }
6243
6244    if (blink > 0) {
6245        int post_delay = insn_bytes + delayslot_size;
6246        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6247
6248        tcg_gen_movi_tl(cpu_gpr[blink],
6249                        ctx->base.pc_next + post_delay + lowbit);
6250    }
6251
6252 out:
6253    if (insn_bytes == 2) {
6254        ctx->hflags |= MIPS_HFLAG_B16;
6255    }
6256    tcg_temp_free(t0);
6257    tcg_temp_free(t1);
6258}
6259
6260
6261/* nanoMIPS Branches */
6262static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6263                                int insn_bytes,
6264                                int rs, int rt, int32_t offset)
6265{
6266    target_ulong btgt = -1;
6267    int bcond_compute = 0;
6268    TCGv t0 = tcg_temp_new();
6269    TCGv t1 = tcg_temp_new();
6270
6271    /* Load needed operands */
6272    switch (opc) {
6273    case OPC_BEQ:
6274    case OPC_BNE:
6275        /* Compare two registers */
6276        if (rs != rt) {
6277            gen_load_gpr(t0, rs);
6278            gen_load_gpr(t1, rt);
6279            bcond_compute = 1;
6280        }
6281        btgt = ctx->base.pc_next + insn_bytes + offset;
6282        break;
6283    case OPC_BGEZAL:
6284        /* Compare to zero */
6285        if (rs != 0) {
6286            gen_load_gpr(t0, rs);
6287            bcond_compute = 1;
6288        }
6289        btgt = ctx->base.pc_next + insn_bytes + offset;
6290        break;
6291    case OPC_BPOSGE32:
6292        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6293        bcond_compute = 1;
6294        btgt = ctx->base.pc_next + insn_bytes + offset;
6295        break;
6296    case OPC_JR:
6297    case OPC_JALR:
6298        /* Jump to register */
6299        if (offset != 0 && offset != 16) {
6300            /*
6301             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6302             * others are reserved.
6303             */
6304            MIPS_INVAL("jump hint");
6305            generate_exception_end(ctx, EXCP_RI);
6306            goto out;
6307        }
6308        gen_load_gpr(btarget, rs);
6309        break;
6310    default:
6311        MIPS_INVAL("branch/jump");
6312        generate_exception_end(ctx, EXCP_RI);
6313        goto out;
6314    }
6315    if (bcond_compute == 0) {
6316        /* No condition to be computed */
6317        switch (opc) {
6318        case OPC_BEQ:     /* rx == rx        */
6319            /* Always take */
6320            ctx->hflags |= MIPS_HFLAG_B;
6321            break;
6322        case OPC_BGEZAL:  /* 0 >= 0          */
6323            /* Always take and link */
6324            tcg_gen_movi_tl(cpu_gpr[31],
6325                            ctx->base.pc_next + insn_bytes);
6326            ctx->hflags |= MIPS_HFLAG_B;
6327            break;
6328        case OPC_BNE:     /* rx != rx        */
6329            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6330            /* Skip the instruction in the delay slot */
6331            ctx->base.pc_next += 4;
6332            goto out;
6333        case OPC_JR:
6334            ctx->hflags |= MIPS_HFLAG_BR;
6335            break;
6336        case OPC_JALR:
6337            if (rt > 0) {
6338                tcg_gen_movi_tl(cpu_gpr[rt],
6339                                ctx->base.pc_next + insn_bytes);
6340            }
6341            ctx->hflags |= MIPS_HFLAG_BR;
6342            break;
6343        default:
6344            MIPS_INVAL("branch/jump");
6345            generate_exception_end(ctx, EXCP_RI);
6346            goto out;
6347        }
6348    } else {
6349        switch (opc) {
6350        case OPC_BEQ:
6351            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6352            goto not_likely;
6353        case OPC_BNE:
6354            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6355            goto not_likely;
6356        case OPC_BGEZAL:
6357            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6358            tcg_gen_movi_tl(cpu_gpr[31],
6359                            ctx->base.pc_next + insn_bytes);
6360            goto not_likely;
6361        case OPC_BPOSGE32:
6362            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6363        not_likely:
6364            ctx->hflags |= MIPS_HFLAG_BC;
6365            break;
6366        default:
6367            MIPS_INVAL("conditional branch/jump");
6368            generate_exception_end(ctx, EXCP_RI);
6369            goto out;
6370        }
6371    }
6372
6373    ctx->btarget = btgt;
6374
6375 out:
6376    if (insn_bytes == 2) {
6377        ctx->hflags |= MIPS_HFLAG_B16;
6378    }
6379    tcg_temp_free(t0);
6380    tcg_temp_free(t1);
6381}
6382
6383
6384/* special3 bitfield operations */
6385static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
6386                       int rs, int lsb, int msb)
6387{
6388    TCGv t0 = tcg_temp_new();
6389    TCGv t1 = tcg_temp_new();
6390
6391    gen_load_gpr(t1, rs);
6392    switch (opc) {
6393    case OPC_EXT:
6394        if (lsb + msb > 31) {
6395            goto fail;
6396        }
6397        if (msb != 31) {
6398            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6399        } else {
6400            /*
6401             * The two checks together imply that lsb == 0,
6402             * so this is a simple sign-extension.
6403             */
6404            tcg_gen_ext32s_tl(t0, t1);
6405        }
6406        break;
6407#if defined(TARGET_MIPS64)
6408    case OPC_DEXTU:
6409        lsb += 32;
6410        goto do_dext;
6411    case OPC_DEXTM:
6412        msb += 32;
6413        goto do_dext;
6414    case OPC_DEXT:
6415    do_dext:
6416        if (lsb + msb > 63) {
6417            goto fail;
6418        }
6419        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6420        break;
6421#endif
6422    case OPC_INS:
6423        if (lsb > msb) {
6424            goto fail;
6425        }
6426        gen_load_gpr(t0, rt);
6427        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6428        tcg_gen_ext32s_tl(t0, t0);
6429        break;
6430#if defined(TARGET_MIPS64)
6431    case OPC_DINSU:
6432        lsb += 32;
6433        /* FALLTHRU */
6434    case OPC_DINSM:
6435        msb += 32;
6436        /* FALLTHRU */
6437    case OPC_DINS:
6438        if (lsb > msb) {
6439            goto fail;
6440        }
6441        gen_load_gpr(t0, rt);
6442        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6443        break;
6444#endif
6445    default:
6446fail:
6447        MIPS_INVAL("bitops");
6448        generate_exception_end(ctx, EXCP_RI);
6449        tcg_temp_free(t0);
6450        tcg_temp_free(t1);
6451        return;
6452    }
6453    gen_store_gpr(t0, rt);
6454    tcg_temp_free(t0);
6455    tcg_temp_free(t1);
6456}
6457
6458static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
6459{
6460    TCGv t0;
6461
6462    if (rd == 0) {
6463        /* If no destination, treat it as a NOP. */
6464        return;
6465    }
6466
6467    t0 = tcg_temp_new();
6468    gen_load_gpr(t0, rt);
6469    switch (op2) {
6470    case OPC_WSBH:
6471        {
6472            TCGv t1 = tcg_temp_new();
6473            TCGv t2 = tcg_const_tl(0x00FF00FF);
6474
6475            tcg_gen_shri_tl(t1, t0, 8);
6476            tcg_gen_and_tl(t1, t1, t2);
6477            tcg_gen_and_tl(t0, t0, t2);
6478            tcg_gen_shli_tl(t0, t0, 8);
6479            tcg_gen_or_tl(t0, t0, t1);
6480            tcg_temp_free(t2);
6481            tcg_temp_free(t1);
6482            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6483        }
6484        break;
6485    case OPC_SEB:
6486        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6487        break;
6488    case OPC_SEH:
6489        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6490        break;
6491#if defined(TARGET_MIPS64)
6492    case OPC_DSBH:
6493        {
6494            TCGv t1 = tcg_temp_new();
6495            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6496
6497            tcg_gen_shri_tl(t1, t0, 8);
6498            tcg_gen_and_tl(t1, t1, t2);
6499            tcg_gen_and_tl(t0, t0, t2);
6500            tcg_gen_shli_tl(t0, t0, 8);
6501            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6502            tcg_temp_free(t2);
6503            tcg_temp_free(t1);
6504        }
6505        break;
6506    case OPC_DSHD:
6507        {
6508            TCGv t1 = tcg_temp_new();
6509            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6510
6511            tcg_gen_shri_tl(t1, t0, 16);
6512            tcg_gen_and_tl(t1, t1, t2);
6513            tcg_gen_and_tl(t0, t0, t2);
6514            tcg_gen_shli_tl(t0, t0, 16);
6515            tcg_gen_or_tl(t0, t0, t1);
6516            tcg_gen_shri_tl(t1, t0, 32);
6517            tcg_gen_shli_tl(t0, t0, 32);
6518            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6519            tcg_temp_free(t2);
6520            tcg_temp_free(t1);
6521        }
6522        break;
6523#endif
6524    default:
6525        MIPS_INVAL("bsfhl");
6526        generate_exception_end(ctx, EXCP_RI);
6527        tcg_temp_free(t0);
6528        return;
6529    }
6530    tcg_temp_free(t0);
6531}
6532
6533static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6534                    int imm2)
6535{
6536    TCGv t0;
6537    TCGv t1;
6538    if (rd == 0) {
6539        /* Treat as NOP. */
6540        return;
6541    }
6542    t0 = tcg_temp_new();
6543    t1 = tcg_temp_new();
6544    gen_load_gpr(t0, rs);
6545    gen_load_gpr(t1, rt);
6546    tcg_gen_shli_tl(t0, t0, imm2 + 1);
6547    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6548    if (opc == OPC_LSA) {
6549        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6550    }
6551
6552    tcg_temp_free(t1);
6553    tcg_temp_free(t0);
6554
6555    return;
6556}
6557
6558static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6559                           int rt, int bits)
6560{
6561    TCGv t0;
6562    if (rd == 0) {
6563        /* Treat as NOP. */
6564        return;
6565    }
6566    t0 = tcg_temp_new();
6567    if (bits == 0 || bits == wordsz) {
6568        if (bits == 0) {
6569            gen_load_gpr(t0, rt);
6570        } else {
6571            gen_load_gpr(t0, rs);
6572        }
6573        switch (wordsz) {
6574        case 32:
6575            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6576            break;
6577#if defined(TARGET_MIPS64)
6578        case 64:
6579            tcg_gen_mov_tl(cpu_gpr[rd], t0);
6580            break;
6581#endif
6582        }
6583    } else {
6584        TCGv t1 = tcg_temp_new();
6585        gen_load_gpr(t0, rt);
6586        gen_load_gpr(t1, rs);
6587        switch (wordsz) {
6588        case 32:
6589            {
6590                TCGv_i64 t2 = tcg_temp_new_i64();
6591                tcg_gen_concat_tl_i64(t2, t1, t0);
6592                tcg_gen_shri_i64(t2, t2, 32 - bits);
6593                gen_move_low32(cpu_gpr[rd], t2);
6594                tcg_temp_free_i64(t2);
6595            }
6596            break;
6597#if defined(TARGET_MIPS64)
6598        case 64:
6599            tcg_gen_shli_tl(t0, t0, bits);
6600            tcg_gen_shri_tl(t1, t1, 64 - bits);
6601            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6602            break;
6603#endif
6604        }
6605        tcg_temp_free(t1);
6606    }
6607
6608    tcg_temp_free(t0);
6609}
6610
6611static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6612                      int bp)
6613{
6614    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6615}
6616
6617static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6618                    int shift)
6619{
6620    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6621}
6622
6623static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6624{
6625    TCGv t0;
6626    if (rd == 0) {
6627        /* Treat as NOP. */
6628        return;
6629    }
6630    t0 = tcg_temp_new();
6631    gen_load_gpr(t0, rt);
6632    switch (opc) {
6633    case OPC_BITSWAP:
6634        gen_helper_bitswap(cpu_gpr[rd], t0);
6635        break;
6636#if defined(TARGET_MIPS64)
6637    case OPC_DBITSWAP:
6638        gen_helper_dbitswap(cpu_gpr[rd], t0);
6639        break;
6640#endif
6641    }
6642    tcg_temp_free(t0);
6643}
6644
6645#ifndef CONFIG_USER_ONLY
6646/* CP0 (MMU and control) */
6647static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6648{
6649    TCGv_i64 t0 = tcg_temp_new_i64();
6650    TCGv_i64 t1 = tcg_temp_new_i64();
6651
6652    tcg_gen_ext_tl_i64(t0, arg);
6653    tcg_gen_ld_i64(t1, cpu_env, off);
6654#if defined(TARGET_MIPS64)
6655    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6656#else
6657    tcg_gen_concat32_i64(t1, t1, t0);
6658#endif
6659    tcg_gen_st_i64(t1, cpu_env, off);
6660    tcg_temp_free_i64(t1);
6661    tcg_temp_free_i64(t0);
6662}
6663
6664static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6665{
6666    TCGv_i64 t0 = tcg_temp_new_i64();
6667    TCGv_i64 t1 = tcg_temp_new_i64();
6668
6669    tcg_gen_ext_tl_i64(t0, arg);
6670    tcg_gen_ld_i64(t1, cpu_env, off);
6671    tcg_gen_concat32_i64(t1, t1, t0);
6672    tcg_gen_st_i64(t1, cpu_env, off);
6673    tcg_temp_free_i64(t1);
6674    tcg_temp_free_i64(t0);
6675}
6676
6677static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6678{
6679    TCGv_i64 t0 = tcg_temp_new_i64();
6680
6681    tcg_gen_ld_i64(t0, cpu_env, off);
6682#if defined(TARGET_MIPS64)
6683    tcg_gen_shri_i64(t0, t0, 30);
6684#else
6685    tcg_gen_shri_i64(t0, t0, 32);
6686#endif
6687    gen_move_low32(arg, t0);
6688    tcg_temp_free_i64(t0);
6689}
6690
6691static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6692{
6693    TCGv_i64 t0 = tcg_temp_new_i64();
6694
6695    tcg_gen_ld_i64(t0, cpu_env, off);
6696    tcg_gen_shri_i64(t0, t0, 32 + shift);
6697    gen_move_low32(arg, t0);
6698    tcg_temp_free_i64(t0);
6699}
6700
6701static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
6702{
6703    TCGv_i32 t0 = tcg_temp_new_i32();
6704
6705    tcg_gen_ld_i32(t0, cpu_env, off);
6706    tcg_gen_ext_i32_tl(arg, t0);
6707    tcg_temp_free_i32(t0);
6708}
6709
6710static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
6711{
6712    tcg_gen_ld_tl(arg, cpu_env, off);
6713    tcg_gen_ext32s_tl(arg, arg);
6714}
6715
6716static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
6717{
6718    TCGv_i32 t0 = tcg_temp_new_i32();
6719
6720    tcg_gen_trunc_tl_i32(t0, arg);
6721    tcg_gen_st_i32(t0, cpu_env, off);
6722    tcg_temp_free_i32(t0);
6723}
6724
6725#define CP0_CHECK(c)                            \
6726    do {                                        \
6727        if (!(c)) {                             \
6728            goto cp0_unimplemented;             \
6729        }                                       \
6730    } while (0)
6731
6732static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6733{
6734    const char *register_name = "invalid";
6735
6736    switch (reg) {
6737    case CP0_REGISTER_02:
6738        switch (sel) {
6739        case 0:
6740            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6741            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6742            register_name = "EntryLo0";
6743            break;
6744        default:
6745            goto cp0_unimplemented;
6746        }
6747        break;
6748    case CP0_REGISTER_03:
6749        switch (sel) {
6750        case CP0_REG03__ENTRYLO1:
6751            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6752            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6753            register_name = "EntryLo1";
6754            break;
6755        default:
6756            goto cp0_unimplemented;
6757        }
6758        break;
6759    case CP0_REGISTER_09:
6760        switch (sel) {
6761        case CP0_REG09__SAAR:
6762            CP0_CHECK(ctx->saar);
6763            gen_helper_mfhc0_saar(arg, cpu_env);
6764            register_name = "SAAR";
6765            break;
6766        default:
6767            goto cp0_unimplemented;
6768        }
6769        break;
6770    case CP0_REGISTER_17:
6771        switch (sel) {
6772        case CP0_REG17__LLADDR:
6773            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6774                             ctx->CP0_LLAddr_shift);
6775            register_name = "LLAddr";
6776            break;
6777        case CP0_REG17__MAAR:
6778            CP0_CHECK(ctx->mrp);
6779            gen_helper_mfhc0_maar(arg, cpu_env);
6780            register_name = "MAAR";
6781            break;
6782        default:
6783            goto cp0_unimplemented;
6784        }
6785        break;
6786    case CP0_REGISTER_28:
6787        switch (sel) {
6788        case 0:
6789        case 2:
6790        case 4:
6791        case 6:
6792            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6793            register_name = "TagLo";
6794            break;
6795        default:
6796            goto cp0_unimplemented;
6797        }
6798        break;
6799    default:
6800        goto cp0_unimplemented;
6801    }
6802    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6803    return;
6804
6805cp0_unimplemented:
6806    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6807                  register_name, reg, sel);
6808    tcg_gen_movi_tl(arg, 0);
6809}
6810
6811static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6812{
6813    const char *register_name = "invalid";
6814    uint64_t mask = ctx->PAMask >> 36;
6815
6816    switch (reg) {
6817    case CP0_REGISTER_02:
6818        switch (sel) {
6819        case 0:
6820            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6821            tcg_gen_andi_tl(arg, arg, mask);
6822            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6823            register_name = "EntryLo0";
6824            break;
6825        default:
6826            goto cp0_unimplemented;
6827        }
6828        break;
6829    case CP0_REGISTER_03:
6830        switch (sel) {
6831        case CP0_REG03__ENTRYLO1:
6832            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6833            tcg_gen_andi_tl(arg, arg, mask);
6834            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6835            register_name = "EntryLo1";
6836            break;
6837        default:
6838            goto cp0_unimplemented;
6839        }
6840        break;
6841    case CP0_REGISTER_09:
6842        switch (sel) {
6843        case CP0_REG09__SAAR:
6844            CP0_CHECK(ctx->saar);
6845            gen_helper_mthc0_saar(cpu_env, arg);
6846            register_name = "SAAR";
6847            break;
6848        default:
6849            goto cp0_unimplemented;
6850        }
6851        break;
6852    case CP0_REGISTER_17:
6853        switch (sel) {
6854        case CP0_REG17__LLADDR:
6855            /*
6856             * LLAddr is read-only (the only exception is bit 0 if LLB is
6857             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6858             * relevant for modern MIPS cores supporting MTHC0, therefore
6859             * treating MTHC0 to LLAddr as NOP.
6860             */
6861            register_name = "LLAddr";
6862            break;
6863        case CP0_REG17__MAAR:
6864            CP0_CHECK(ctx->mrp);
6865            gen_helper_mthc0_maar(cpu_env, arg);
6866            register_name = "MAAR";
6867            break;
6868        default:
6869            goto cp0_unimplemented;
6870        }
6871        break;
6872    case CP0_REGISTER_28:
6873        switch (sel) {
6874        case 0:
6875        case 2:
6876        case 4:
6877        case 6:
6878            tcg_gen_andi_tl(arg, arg, mask);
6879            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6880            register_name = "TagLo";
6881            break;
6882        default:
6883            goto cp0_unimplemented;
6884        }
6885        break;
6886    default:
6887        goto cp0_unimplemented;
6888    }
6889    trace_mips_translate_c0("mthc0", register_name, reg, sel);
6890
6891cp0_unimplemented:
6892    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6893                  register_name, reg, sel);
6894}
6895
6896static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6897{
6898    if (ctx->insn_flags & ISA_MIPS32R6) {
6899        tcg_gen_movi_tl(arg, 0);
6900    } else {
6901        tcg_gen_movi_tl(arg, ~0);
6902    }
6903}
6904
6905static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6906{
6907    const char *register_name = "invalid";
6908
6909    if (sel != 0) {
6910        check_insn(ctx, ISA_MIPS32);
6911    }
6912
6913    switch (reg) {
6914    case CP0_REGISTER_00:
6915        switch (sel) {
6916        case CP0_REG00__INDEX:
6917            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6918            register_name = "Index";
6919            break;
6920        case CP0_REG00__MVPCONTROL:
6921            CP0_CHECK(ctx->insn_flags & ASE_MT);
6922            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6923            register_name = "MVPControl";
6924            break;
6925        case CP0_REG00__MVPCONF0:
6926            CP0_CHECK(ctx->insn_flags & ASE_MT);
6927            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6928            register_name = "MVPConf0";
6929            break;
6930        case CP0_REG00__MVPCONF1:
6931            CP0_CHECK(ctx->insn_flags & ASE_MT);
6932            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6933            register_name = "MVPConf1";
6934            break;
6935        case CP0_REG00__VPCONTROL:
6936            CP0_CHECK(ctx->vp);
6937            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6938            register_name = "VPControl";
6939            break;
6940        default:
6941            goto cp0_unimplemented;
6942        }
6943        break;
6944    case CP0_REGISTER_01:
6945        switch (sel) {
6946        case CP0_REG01__RANDOM:
6947            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6948            gen_helper_mfc0_random(arg, cpu_env);
6949            register_name = "Random";
6950            break;
6951        case CP0_REG01__VPECONTROL:
6952            CP0_CHECK(ctx->insn_flags & ASE_MT);
6953            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6954            register_name = "VPEControl";
6955            break;
6956        case CP0_REG01__VPECONF0:
6957            CP0_CHECK(ctx->insn_flags & ASE_MT);
6958            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6959            register_name = "VPEConf0";
6960            break;
6961        case CP0_REG01__VPECONF1:
6962            CP0_CHECK(ctx->insn_flags & ASE_MT);
6963            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6964            register_name = "VPEConf1";
6965            break;
6966        case CP0_REG01__YQMASK:
6967            CP0_CHECK(ctx->insn_flags & ASE_MT);
6968            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6969            register_name = "YQMask";
6970            break;
6971        case CP0_REG01__VPESCHEDULE:
6972            CP0_CHECK(ctx->insn_flags & ASE_MT);
6973            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6974            register_name = "VPESchedule";
6975            break;
6976        case CP0_REG01__VPESCHEFBACK:
6977            CP0_CHECK(ctx->insn_flags & ASE_MT);
6978            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6979            register_name = "VPEScheFBack";
6980            break;
6981        case CP0_REG01__VPEOPT:
6982            CP0_CHECK(ctx->insn_flags & ASE_MT);
6983            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6984            register_name = "VPEOpt";
6985            break;
6986        default:
6987            goto cp0_unimplemented;
6988        }
6989        break;
6990    case CP0_REGISTER_02:
6991        switch (sel) {
6992        case CP0_REG02__ENTRYLO0:
6993            {
6994                TCGv_i64 tmp = tcg_temp_new_i64();
6995                tcg_gen_ld_i64(tmp, cpu_env,
6996                               offsetof(CPUMIPSState, CP0_EntryLo0));
6997#if defined(TARGET_MIPS64)
6998                if (ctx->rxi) {
6999                    /* Move RI/XI fields to bits 31:30 */
7000                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7001                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7002                }
7003#endif
7004                gen_move_low32(arg, tmp);
7005                tcg_temp_free_i64(tmp);
7006            }
7007            register_name = "EntryLo0";
7008            break;
7009        case CP0_REG02__TCSTATUS:
7010            CP0_CHECK(ctx->insn_flags & ASE_MT);
7011            gen_helper_mfc0_tcstatus(arg, cpu_env);
7012            register_name = "TCStatus";
7013            break;
7014        case CP0_REG02__TCBIND:
7015            CP0_CHECK(ctx->insn_flags & ASE_MT);
7016            gen_helper_mfc0_tcbind(arg, cpu_env);
7017            register_name = "TCBind";
7018            break;
7019        case CP0_REG02__TCRESTART:
7020            CP0_CHECK(ctx->insn_flags & ASE_MT);
7021            gen_helper_mfc0_tcrestart(arg, cpu_env);
7022            register_name = "TCRestart";
7023            break;
7024        case CP0_REG02__TCHALT:
7025            CP0_CHECK(ctx->insn_flags & ASE_MT);
7026            gen_helper_mfc0_tchalt(arg, cpu_env);
7027            register_name = "TCHalt";
7028            break;
7029        case CP0_REG02__TCCONTEXT:
7030            CP0_CHECK(ctx->insn_flags & ASE_MT);
7031            gen_helper_mfc0_tccontext(arg, cpu_env);
7032            register_name = "TCContext";
7033            break;
7034        case CP0_REG02__TCSCHEDULE:
7035            CP0_CHECK(ctx->insn_flags & ASE_MT);
7036            gen_helper_mfc0_tcschedule(arg, cpu_env);
7037            register_name = "TCSchedule";
7038            break;
7039        case CP0_REG02__TCSCHEFBACK:
7040            CP0_CHECK(ctx->insn_flags & ASE_MT);
7041            gen_helper_mfc0_tcschefback(arg, cpu_env);
7042            register_name = "TCScheFBack";
7043            break;
7044        default:
7045            goto cp0_unimplemented;
7046        }
7047        break;
7048    case CP0_REGISTER_03:
7049        switch (sel) {
7050        case CP0_REG03__ENTRYLO1:
7051            {
7052                TCGv_i64 tmp = tcg_temp_new_i64();
7053                tcg_gen_ld_i64(tmp, cpu_env,
7054                               offsetof(CPUMIPSState, CP0_EntryLo1));
7055#if defined(TARGET_MIPS64)
7056                if (ctx->rxi) {
7057                    /* Move RI/XI fields to bits 31:30 */
7058                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
7059                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
7060                }
7061#endif
7062                gen_move_low32(arg, tmp);
7063                tcg_temp_free_i64(tmp);
7064            }
7065            register_name = "EntryLo1";
7066            break;
7067        case CP0_REG03__GLOBALNUM:
7068            CP0_CHECK(ctx->vp);
7069            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7070            register_name = "GlobalNumber";
7071            break;
7072        default:
7073            goto cp0_unimplemented;
7074        }
7075        break;
7076    case CP0_REGISTER_04:
7077        switch (sel) {
7078        case CP0_REG04__CONTEXT:
7079            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7080            tcg_gen_ext32s_tl(arg, arg);
7081            register_name = "Context";
7082            break;
7083        case CP0_REG04__CONTEXTCONFIG:
7084            /* SmartMIPS ASE */
7085            /* gen_helper_mfc0_contextconfig(arg); */
7086            register_name = "ContextConfig";
7087            goto cp0_unimplemented;
7088        case CP0_REG04__USERLOCAL:
7089            CP0_CHECK(ctx->ulri);
7090            tcg_gen_ld_tl(arg, cpu_env,
7091                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7092            tcg_gen_ext32s_tl(arg, arg);
7093            register_name = "UserLocal";
7094            break;
7095        default:
7096            goto cp0_unimplemented;
7097        }
7098        break;
7099    case CP0_REGISTER_05:
7100        switch (sel) {
7101        case CP0_REG05__PAGEMASK:
7102            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7103            register_name = "PageMask";
7104            break;
7105        case CP0_REG05__PAGEGRAIN:
7106            check_insn(ctx, ISA_MIPS32R2);
7107            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7108            register_name = "PageGrain";
7109            break;
7110        case CP0_REG05__SEGCTL0:
7111            CP0_CHECK(ctx->sc);
7112            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7113            tcg_gen_ext32s_tl(arg, arg);
7114            register_name = "SegCtl0";
7115            break;
7116        case CP0_REG05__SEGCTL1:
7117            CP0_CHECK(ctx->sc);
7118            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7119            tcg_gen_ext32s_tl(arg, arg);
7120            register_name = "SegCtl1";
7121            break;
7122        case CP0_REG05__SEGCTL2:
7123            CP0_CHECK(ctx->sc);
7124            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7125            tcg_gen_ext32s_tl(arg, arg);
7126            register_name = "SegCtl2";
7127            break;
7128        case CP0_REG05__PWBASE:
7129            check_pw(ctx);
7130            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7131            register_name = "PWBase";
7132            break;
7133        case CP0_REG05__PWFIELD:
7134            check_pw(ctx);
7135            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
7136            register_name = "PWField";
7137            break;
7138        case CP0_REG05__PWSIZE:
7139            check_pw(ctx);
7140            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
7141            register_name = "PWSize";
7142            break;
7143        default:
7144            goto cp0_unimplemented;
7145        }
7146        break;
7147    case CP0_REGISTER_06:
7148        switch (sel) {
7149        case CP0_REG06__WIRED:
7150            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7151            register_name = "Wired";
7152            break;
7153        case CP0_REG06__SRSCONF0:
7154            check_insn(ctx, ISA_MIPS32R2);
7155            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7156            register_name = "SRSConf0";
7157            break;
7158        case CP0_REG06__SRSCONF1:
7159            check_insn(ctx, ISA_MIPS32R2);
7160            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7161            register_name = "SRSConf1";
7162            break;
7163        case CP0_REG06__SRSCONF2:
7164            check_insn(ctx, ISA_MIPS32R2);
7165            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7166            register_name = "SRSConf2";
7167            break;
7168        case CP0_REG06__SRSCONF3:
7169            check_insn(ctx, ISA_MIPS32R2);
7170            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7171            register_name = "SRSConf3";
7172            break;
7173        case CP0_REG06__SRSCONF4:
7174            check_insn(ctx, ISA_MIPS32R2);
7175            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7176            register_name = "SRSConf4";
7177            break;
7178        case CP0_REG06__PWCTL:
7179            check_pw(ctx);
7180            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7181            register_name = "PWCtl";
7182            break;
7183        default:
7184            goto cp0_unimplemented;
7185        }
7186        break;
7187    case CP0_REGISTER_07:
7188        switch (sel) {
7189        case CP0_REG07__HWRENA:
7190            check_insn(ctx, ISA_MIPS32R2);
7191            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7192            register_name = "HWREna";
7193            break;
7194        default:
7195            goto cp0_unimplemented;
7196        }
7197        break;
7198    case CP0_REGISTER_08:
7199        switch (sel) {
7200        case CP0_REG08__BADVADDR:
7201            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7202            tcg_gen_ext32s_tl(arg, arg);
7203            register_name = "BadVAddr";
7204            break;
7205        case CP0_REG08__BADINSTR:
7206            CP0_CHECK(ctx->bi);
7207            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7208            register_name = "BadInstr";
7209            break;
7210        case CP0_REG08__BADINSTRP:
7211            CP0_CHECK(ctx->bp);
7212            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7213            register_name = "BadInstrP";
7214            break;
7215        case CP0_REG08__BADINSTRX:
7216            CP0_CHECK(ctx->bi);
7217            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7218            tcg_gen_andi_tl(arg, arg, ~0xffff);
7219            register_name = "BadInstrX";
7220            break;
7221        default:
7222            goto cp0_unimplemented;
7223        }
7224        break;
7225    case CP0_REGISTER_09:
7226        switch (sel) {
7227        case CP0_REG09__COUNT:
7228            /* Mark as an IO operation because we read the time.  */
7229            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7230                gen_io_start();
7231            }
7232            gen_helper_mfc0_count(arg, cpu_env);
7233            /*
7234             * Break the TB to be able to take timer interrupts immediately
7235             * after reading count. DISAS_STOP isn't sufficient, we need to
7236             * ensure we break completely out of translated code.
7237             */
7238            gen_save_pc(ctx->base.pc_next + 4);
7239            ctx->base.is_jmp = DISAS_EXIT;
7240            register_name = "Count";
7241            break;
7242        case CP0_REG09__SAARI:
7243            CP0_CHECK(ctx->saar);
7244            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7245            register_name = "SAARI";
7246            break;
7247        case CP0_REG09__SAAR:
7248            CP0_CHECK(ctx->saar);
7249            gen_helper_mfc0_saar(arg, cpu_env);
7250            register_name = "SAAR";
7251            break;
7252        default:
7253            goto cp0_unimplemented;
7254        }
7255        break;
7256    case CP0_REGISTER_10:
7257        switch (sel) {
7258        case CP0_REG10__ENTRYHI:
7259            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7260            tcg_gen_ext32s_tl(arg, arg);
7261            register_name = "EntryHi";
7262            break;
7263        default:
7264            goto cp0_unimplemented;
7265        }
7266        break;
7267    case CP0_REGISTER_11:
7268        switch (sel) {
7269        case CP0_REG11__COMPARE:
7270            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7271            register_name = "Compare";
7272            break;
7273        /* 6,7 are implementation dependent */
7274        default:
7275            goto cp0_unimplemented;
7276        }
7277        break;
7278    case CP0_REGISTER_12:
7279        switch (sel) {
7280        case CP0_REG12__STATUS:
7281            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7282            register_name = "Status";
7283            break;
7284        case CP0_REG12__INTCTL:
7285            check_insn(ctx, ISA_MIPS32R2);
7286            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7287            register_name = "IntCtl";
7288            break;
7289        case CP0_REG12__SRSCTL:
7290            check_insn(ctx, ISA_MIPS32R2);
7291            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7292            register_name = "SRSCtl";
7293            break;
7294        case CP0_REG12__SRSMAP:
7295            check_insn(ctx, ISA_MIPS32R2);
7296            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7297            register_name = "SRSMap";
7298            break;
7299        default:
7300            goto cp0_unimplemented;
7301       }
7302        break;
7303    case CP0_REGISTER_13:
7304        switch (sel) {
7305        case CP0_REG13__CAUSE:
7306            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7307            register_name = "Cause";
7308            break;
7309        default:
7310            goto cp0_unimplemented;
7311       }
7312        break;
7313    case CP0_REGISTER_14:
7314        switch (sel) {
7315        case CP0_REG14__EPC:
7316            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7317            tcg_gen_ext32s_tl(arg, arg);
7318            register_name = "EPC";
7319            break;
7320        default:
7321            goto cp0_unimplemented;
7322        }
7323        break;
7324    case CP0_REGISTER_15:
7325        switch (sel) {
7326        case CP0_REG15__PRID:
7327            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7328            register_name = "PRid";
7329            break;
7330        case CP0_REG15__EBASE:
7331            check_insn(ctx, ISA_MIPS32R2);
7332            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7333            tcg_gen_ext32s_tl(arg, arg);
7334            register_name = "EBase";
7335            break;
7336        case CP0_REG15__CMGCRBASE:
7337            check_insn(ctx, ISA_MIPS32R2);
7338            CP0_CHECK(ctx->cmgcr);
7339            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7340            tcg_gen_ext32s_tl(arg, arg);
7341            register_name = "CMGCRBase";
7342            break;
7343        default:
7344            goto cp0_unimplemented;
7345       }
7346        break;
7347    case CP0_REGISTER_16:
7348        switch (sel) {
7349        case CP0_REG16__CONFIG:
7350            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7351            register_name = "Config";
7352            break;
7353        case CP0_REG16__CONFIG1:
7354            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7355            register_name = "Config1";
7356            break;
7357        case CP0_REG16__CONFIG2:
7358            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7359            register_name = "Config2";
7360            break;
7361        case CP0_REG16__CONFIG3:
7362            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7363            register_name = "Config3";
7364            break;
7365        case CP0_REG16__CONFIG4:
7366            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7367            register_name = "Config4";
7368            break;
7369        case CP0_REG16__CONFIG5:
7370            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7371            register_name = "Config5";
7372            break;
7373        /* 6,7 are implementation dependent */
7374        case CP0_REG16__CONFIG6:
7375            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7376            register_name = "Config6";
7377            break;
7378        case CP0_REG16__CONFIG7:
7379            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7380            register_name = "Config7";
7381            break;
7382        default:
7383            goto cp0_unimplemented;
7384        }
7385        break;
7386    case CP0_REGISTER_17:
7387        switch (sel) {
7388        case CP0_REG17__LLADDR:
7389            gen_helper_mfc0_lladdr(arg, cpu_env);
7390            register_name = "LLAddr";
7391            break;
7392        case CP0_REG17__MAAR:
7393            CP0_CHECK(ctx->mrp);
7394            gen_helper_mfc0_maar(arg, cpu_env);
7395            register_name = "MAAR";
7396            break;
7397        case CP0_REG17__MAARI:
7398            CP0_CHECK(ctx->mrp);
7399            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7400            register_name = "MAARI";
7401            break;
7402        default:
7403            goto cp0_unimplemented;
7404        }
7405        break;
7406    case CP0_REGISTER_18:
7407        switch (sel) {
7408        case CP0_REG18__WATCHLO0:
7409        case CP0_REG18__WATCHLO1:
7410        case CP0_REG18__WATCHLO2:
7411        case CP0_REG18__WATCHLO3:
7412        case CP0_REG18__WATCHLO4:
7413        case CP0_REG18__WATCHLO5:
7414        case CP0_REG18__WATCHLO6:
7415        case CP0_REG18__WATCHLO7:
7416            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7417            gen_helper_1e0i(mfc0_watchlo, arg, sel);
7418            register_name = "WatchLo";
7419            break;
7420        default:
7421            goto cp0_unimplemented;
7422        }
7423        break;
7424    case CP0_REGISTER_19:
7425        switch (sel) {
7426        case CP0_REG19__WATCHHI0:
7427        case CP0_REG19__WATCHHI1:
7428        case CP0_REG19__WATCHHI2:
7429        case CP0_REG19__WATCHHI3:
7430        case CP0_REG19__WATCHHI4:
7431        case CP0_REG19__WATCHHI5:
7432        case CP0_REG19__WATCHHI6:
7433        case CP0_REG19__WATCHHI7:
7434            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7435            gen_helper_1e0i(mfc0_watchhi, arg, sel);
7436            register_name = "WatchHi";
7437            break;
7438        default:
7439            goto cp0_unimplemented;
7440        }
7441        break;
7442    case CP0_REGISTER_20:
7443        switch (sel) {
7444        case CP0_REG20__XCONTEXT:
7445#if defined(TARGET_MIPS64)
7446            check_insn(ctx, ISA_MIPS3);
7447            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7448            tcg_gen_ext32s_tl(arg, arg);
7449            register_name = "XContext";
7450            break;
7451#endif
7452        default:
7453            goto cp0_unimplemented;
7454        }
7455        break;
7456    case CP0_REGISTER_21:
7457       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7458        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7459        switch (sel) {
7460        case 0:
7461            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7462            register_name = "Framemask";
7463            break;
7464        default:
7465            goto cp0_unimplemented;
7466        }
7467        break;
7468    case CP0_REGISTER_22:
7469        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7470        register_name = "'Diagnostic"; /* implementation dependent */
7471        break;
7472    case CP0_REGISTER_23:
7473        switch (sel) {
7474        case CP0_REG23__DEBUG:
7475            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7476            register_name = "Debug";
7477            break;
7478        case CP0_REG23__TRACECONTROL:
7479            /* PDtrace support */
7480            /* gen_helper_mfc0_tracecontrol(arg);  */
7481            register_name = "TraceControl";
7482            goto cp0_unimplemented;
7483        case CP0_REG23__TRACECONTROL2:
7484            /* PDtrace support */
7485            /* gen_helper_mfc0_tracecontrol2(arg); */
7486            register_name = "TraceControl2";
7487            goto cp0_unimplemented;
7488        case CP0_REG23__USERTRACEDATA1:
7489            /* PDtrace support */
7490            /* gen_helper_mfc0_usertracedata1(arg);*/
7491            register_name = "UserTraceData1";
7492            goto cp0_unimplemented;
7493        case CP0_REG23__TRACEIBPC:
7494            /* PDtrace support */
7495            /* gen_helper_mfc0_traceibpc(arg);     */
7496            register_name = "TraceIBPC";
7497            goto cp0_unimplemented;
7498        case CP0_REG23__TRACEDBPC:
7499            /* PDtrace support */
7500            /* gen_helper_mfc0_tracedbpc(arg);     */
7501            register_name = "TraceDBPC";
7502            goto cp0_unimplemented;
7503        default:
7504            goto cp0_unimplemented;
7505        }
7506        break;
7507    case CP0_REGISTER_24:
7508        switch (sel) {
7509        case CP0_REG24__DEPC:
7510            /* EJTAG support */
7511            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7512            tcg_gen_ext32s_tl(arg, arg);
7513            register_name = "DEPC";
7514            break;
7515        default:
7516            goto cp0_unimplemented;
7517        }
7518        break;
7519    case CP0_REGISTER_25:
7520        switch (sel) {
7521        case CP0_REG25__PERFCTL0:
7522            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7523            register_name = "Performance0";
7524            break;
7525        case CP0_REG25__PERFCNT0:
7526            /* gen_helper_mfc0_performance1(arg); */
7527            register_name = "Performance1";
7528            goto cp0_unimplemented;
7529        case CP0_REG25__PERFCTL1:
7530            /* gen_helper_mfc0_performance2(arg); */
7531            register_name = "Performance2";
7532            goto cp0_unimplemented;
7533        case CP0_REG25__PERFCNT1:
7534            /* gen_helper_mfc0_performance3(arg); */
7535            register_name = "Performance3";
7536            goto cp0_unimplemented;
7537        case CP0_REG25__PERFCTL2:
7538            /* gen_helper_mfc0_performance4(arg); */
7539            register_name = "Performance4";
7540            goto cp0_unimplemented;
7541        case CP0_REG25__PERFCNT2:
7542            /* gen_helper_mfc0_performance5(arg); */
7543            register_name = "Performance5";
7544            goto cp0_unimplemented;
7545        case CP0_REG25__PERFCTL3:
7546            /* gen_helper_mfc0_performance6(arg); */
7547            register_name = "Performance6";
7548            goto cp0_unimplemented;
7549        case CP0_REG25__PERFCNT3:
7550            /* gen_helper_mfc0_performance7(arg); */
7551            register_name = "Performance7";
7552            goto cp0_unimplemented;
7553        default:
7554            goto cp0_unimplemented;
7555        }
7556        break;
7557    case CP0_REGISTER_26:
7558        switch (sel) {
7559        case CP0_REG26__ERRCTL:
7560            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7561            register_name = "ErrCtl";
7562            break;
7563        default:
7564            goto cp0_unimplemented;
7565        }
7566        break;
7567    case CP0_REGISTER_27:
7568        switch (sel) {
7569        case CP0_REG27__CACHERR:
7570            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7571            register_name = "CacheErr";
7572            break;
7573        default:
7574            goto cp0_unimplemented;
7575        }
7576        break;
7577    case CP0_REGISTER_28:
7578        switch (sel) {
7579        case CP0_REG28__TAGLO:
7580        case CP0_REG28__TAGLO1:
7581        case CP0_REG28__TAGLO2:
7582        case CP0_REG28__TAGLO3:
7583            {
7584                TCGv_i64 tmp = tcg_temp_new_i64();
7585                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7586                gen_move_low32(arg, tmp);
7587                tcg_temp_free_i64(tmp);
7588            }
7589            register_name = "TagLo";
7590            break;
7591        case CP0_REG28__DATALO:
7592        case CP0_REG28__DATALO1:
7593        case CP0_REG28__DATALO2:
7594        case CP0_REG28__DATALO3:
7595            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7596            register_name = "DataLo";
7597            break;
7598        default:
7599            goto cp0_unimplemented;
7600        }
7601        break;
7602    case CP0_REGISTER_29:
7603        switch (sel) {
7604        case CP0_REG29__TAGHI:
7605        case CP0_REG29__TAGHI1:
7606        case CP0_REG29__TAGHI2:
7607        case CP0_REG29__TAGHI3:
7608            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7609            register_name = "TagHi";
7610            break;
7611        case CP0_REG29__DATAHI:
7612        case CP0_REG29__DATAHI1:
7613        case CP0_REG29__DATAHI2:
7614        case CP0_REG29__DATAHI3:
7615            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7616            register_name = "DataHi";
7617            break;
7618        default:
7619            goto cp0_unimplemented;
7620        }
7621        break;
7622    case CP0_REGISTER_30:
7623        switch (sel) {
7624        case CP0_REG30__ERROREPC:
7625            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7626            tcg_gen_ext32s_tl(arg, arg);
7627            register_name = "ErrorEPC";
7628            break;
7629        default:
7630            goto cp0_unimplemented;
7631        }
7632        break;
7633    case CP0_REGISTER_31:
7634        switch (sel) {
7635        case CP0_REG31__DESAVE:
7636            /* EJTAG support */
7637            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7638            register_name = "DESAVE";
7639            break;
7640        case CP0_REG31__KSCRATCH1:
7641        case CP0_REG31__KSCRATCH2:
7642        case CP0_REG31__KSCRATCH3:
7643        case CP0_REG31__KSCRATCH4:
7644        case CP0_REG31__KSCRATCH5:
7645        case CP0_REG31__KSCRATCH6:
7646            CP0_CHECK(ctx->kscrexist & (1 << sel));
7647            tcg_gen_ld_tl(arg, cpu_env,
7648                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7649            tcg_gen_ext32s_tl(arg, arg);
7650            register_name = "KScratch";
7651            break;
7652        default:
7653            goto cp0_unimplemented;
7654        }
7655        break;
7656    default:
7657       goto cp0_unimplemented;
7658    }
7659    trace_mips_translate_c0("mfc0", register_name, reg, sel);
7660    return;
7661
7662cp0_unimplemented:
7663    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7664                  register_name, reg, sel);
7665    gen_mfc0_unimplemented(ctx, arg);
7666}
7667
7668static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7669{
7670    const char *register_name = "invalid";
7671
7672    if (sel != 0) {
7673        check_insn(ctx, ISA_MIPS32);
7674    }
7675
7676    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7677        gen_io_start();
7678    }
7679
7680    switch (reg) {
7681    case CP0_REGISTER_00:
7682        switch (sel) {
7683        case CP0_REG00__INDEX:
7684            gen_helper_mtc0_index(cpu_env, arg);
7685            register_name = "Index";
7686            break;
7687        case CP0_REG00__MVPCONTROL:
7688            CP0_CHECK(ctx->insn_flags & ASE_MT);
7689            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7690            register_name = "MVPControl";
7691            break;
7692        case CP0_REG00__MVPCONF0:
7693            CP0_CHECK(ctx->insn_flags & ASE_MT);
7694            /* ignored */
7695            register_name = "MVPConf0";
7696            break;
7697        case CP0_REG00__MVPCONF1:
7698            CP0_CHECK(ctx->insn_flags & ASE_MT);
7699            /* ignored */
7700            register_name = "MVPConf1";
7701            break;
7702        case CP0_REG00__VPCONTROL:
7703            CP0_CHECK(ctx->vp);
7704            /* ignored */
7705            register_name = "VPControl";
7706            break;
7707        default:
7708            goto cp0_unimplemented;
7709        }
7710        break;
7711    case CP0_REGISTER_01:
7712        switch (sel) {
7713        case CP0_REG01__RANDOM:
7714            /* ignored */
7715            register_name = "Random";
7716            break;
7717        case CP0_REG01__VPECONTROL:
7718            CP0_CHECK(ctx->insn_flags & ASE_MT);
7719            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7720            register_name = "VPEControl";
7721            break;
7722        case CP0_REG01__VPECONF0:
7723            CP0_CHECK(ctx->insn_flags & ASE_MT);
7724            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7725            register_name = "VPEConf0";
7726            break;
7727        case CP0_REG01__VPECONF1:
7728            CP0_CHECK(ctx->insn_flags & ASE_MT);
7729            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7730            register_name = "VPEConf1";
7731            break;
7732        case CP0_REG01__YQMASK:
7733            CP0_CHECK(ctx->insn_flags & ASE_MT);
7734            gen_helper_mtc0_yqmask(cpu_env, arg);
7735            register_name = "YQMask";
7736            break;
7737        case CP0_REG01__VPESCHEDULE:
7738            CP0_CHECK(ctx->insn_flags & ASE_MT);
7739            tcg_gen_st_tl(arg, cpu_env,
7740                          offsetof(CPUMIPSState, CP0_VPESchedule));
7741            register_name = "VPESchedule";
7742            break;
7743        case CP0_REG01__VPESCHEFBACK:
7744            CP0_CHECK(ctx->insn_flags & ASE_MT);
7745            tcg_gen_st_tl(arg, cpu_env,
7746                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7747            register_name = "VPEScheFBack";
7748            break;
7749        case CP0_REG01__VPEOPT:
7750            CP0_CHECK(ctx->insn_flags & ASE_MT);
7751            gen_helper_mtc0_vpeopt(cpu_env, arg);
7752            register_name = "VPEOpt";
7753            break;
7754        default:
7755            goto cp0_unimplemented;
7756        }
7757        break;
7758    case CP0_REGISTER_02:
7759        switch (sel) {
7760        case CP0_REG02__ENTRYLO0:
7761            gen_helper_mtc0_entrylo0(cpu_env, arg);
7762            register_name = "EntryLo0";
7763            break;
7764        case CP0_REG02__TCSTATUS:
7765            CP0_CHECK(ctx->insn_flags & ASE_MT);
7766            gen_helper_mtc0_tcstatus(cpu_env, arg);
7767            register_name = "TCStatus";
7768            break;
7769        case CP0_REG02__TCBIND:
7770            CP0_CHECK(ctx->insn_flags & ASE_MT);
7771            gen_helper_mtc0_tcbind(cpu_env, arg);
7772            register_name = "TCBind";
7773            break;
7774        case CP0_REG02__TCRESTART:
7775            CP0_CHECK(ctx->insn_flags & ASE_MT);
7776            gen_helper_mtc0_tcrestart(cpu_env, arg);
7777            register_name = "TCRestart";
7778            break;
7779        case CP0_REG02__TCHALT:
7780            CP0_CHECK(ctx->insn_flags & ASE_MT);
7781            gen_helper_mtc0_tchalt(cpu_env, arg);
7782            register_name = "TCHalt";
7783            break;
7784        case CP0_REG02__TCCONTEXT:
7785            CP0_CHECK(ctx->insn_flags & ASE_MT);
7786            gen_helper_mtc0_tccontext(cpu_env, arg);
7787            register_name = "TCContext";
7788            break;
7789        case CP0_REG02__TCSCHEDULE:
7790            CP0_CHECK(ctx->insn_flags & ASE_MT);
7791            gen_helper_mtc0_tcschedule(cpu_env, arg);
7792            register_name = "TCSchedule";
7793            break;
7794        case CP0_REG02__TCSCHEFBACK:
7795            CP0_CHECK(ctx->insn_flags & ASE_MT);
7796            gen_helper_mtc0_tcschefback(cpu_env, arg);
7797            register_name = "TCScheFBack";
7798            break;
7799        default:
7800            goto cp0_unimplemented;
7801        }
7802        break;
7803    case CP0_REGISTER_03:
7804        switch (sel) {
7805        case CP0_REG03__ENTRYLO1:
7806            gen_helper_mtc0_entrylo1(cpu_env, arg);
7807            register_name = "EntryLo1";
7808            break;
7809        case CP0_REG03__GLOBALNUM:
7810            CP0_CHECK(ctx->vp);
7811            /* ignored */
7812            register_name = "GlobalNumber";
7813            break;
7814        default:
7815            goto cp0_unimplemented;
7816        }
7817        break;
7818    case CP0_REGISTER_04:
7819        switch (sel) {
7820        case CP0_REG04__CONTEXT:
7821            gen_helper_mtc0_context(cpu_env, arg);
7822            register_name = "Context";
7823            break;
7824        case CP0_REG04__CONTEXTCONFIG:
7825            /* SmartMIPS ASE */
7826            /* gen_helper_mtc0_contextconfig(arg); */
7827            register_name = "ContextConfig";
7828            goto cp0_unimplemented;
7829        case CP0_REG04__USERLOCAL:
7830            CP0_CHECK(ctx->ulri);
7831            tcg_gen_st_tl(arg, cpu_env,
7832                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7833            register_name = "UserLocal";
7834            break;
7835        default:
7836            goto cp0_unimplemented;
7837        }
7838        break;
7839    case CP0_REGISTER_05:
7840        switch (sel) {
7841        case CP0_REG05__PAGEMASK:
7842            gen_helper_mtc0_pagemask(cpu_env, arg);
7843            register_name = "PageMask";
7844            break;
7845        case CP0_REG05__PAGEGRAIN:
7846            check_insn(ctx, ISA_MIPS32R2);
7847            gen_helper_mtc0_pagegrain(cpu_env, arg);
7848            register_name = "PageGrain";
7849            ctx->base.is_jmp = DISAS_STOP;
7850            break;
7851        case CP0_REG05__SEGCTL0:
7852            CP0_CHECK(ctx->sc);
7853            gen_helper_mtc0_segctl0(cpu_env, arg);
7854            register_name = "SegCtl0";
7855            break;
7856        case CP0_REG05__SEGCTL1:
7857            CP0_CHECK(ctx->sc);
7858            gen_helper_mtc0_segctl1(cpu_env, arg);
7859            register_name = "SegCtl1";
7860            break;
7861        case CP0_REG05__SEGCTL2:
7862            CP0_CHECK(ctx->sc);
7863            gen_helper_mtc0_segctl2(cpu_env, arg);
7864            register_name = "SegCtl2";
7865            break;
7866        case CP0_REG05__PWBASE:
7867            check_pw(ctx);
7868            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7869            register_name = "PWBase";
7870            break;
7871        case CP0_REG05__PWFIELD:
7872            check_pw(ctx);
7873            gen_helper_mtc0_pwfield(cpu_env, arg);
7874            register_name = "PWField";
7875            break;
7876        case CP0_REG05__PWSIZE:
7877            check_pw(ctx);
7878            gen_helper_mtc0_pwsize(cpu_env, arg);
7879            register_name = "PWSize";
7880            break;
7881        default:
7882            goto cp0_unimplemented;
7883        }
7884        break;
7885    case CP0_REGISTER_06:
7886        switch (sel) {
7887        case CP0_REG06__WIRED:
7888            gen_helper_mtc0_wired(cpu_env, arg);
7889            register_name = "Wired";
7890            break;
7891        case CP0_REG06__SRSCONF0:
7892            check_insn(ctx, ISA_MIPS32R2);
7893            gen_helper_mtc0_srsconf0(cpu_env, arg);
7894            register_name = "SRSConf0";
7895            break;
7896        case CP0_REG06__SRSCONF1:
7897            check_insn(ctx, ISA_MIPS32R2);
7898            gen_helper_mtc0_srsconf1(cpu_env, arg);
7899            register_name = "SRSConf1";
7900            break;
7901        case CP0_REG06__SRSCONF2:
7902            check_insn(ctx, ISA_MIPS32R2);
7903            gen_helper_mtc0_srsconf2(cpu_env, arg);
7904            register_name = "SRSConf2";
7905            break;
7906        case CP0_REG06__SRSCONF3:
7907            check_insn(ctx, ISA_MIPS32R2);
7908            gen_helper_mtc0_srsconf3(cpu_env, arg);
7909            register_name = "SRSConf3";
7910            break;
7911        case CP0_REG06__SRSCONF4:
7912            check_insn(ctx, ISA_MIPS32R2);
7913            gen_helper_mtc0_srsconf4(cpu_env, arg);
7914            register_name = "SRSConf4";
7915            break;
7916        case CP0_REG06__PWCTL:
7917            check_pw(ctx);
7918            gen_helper_mtc0_pwctl(cpu_env, arg);
7919            register_name = "PWCtl";
7920            break;
7921        default:
7922            goto cp0_unimplemented;
7923        }
7924        break;
7925    case CP0_REGISTER_07:
7926        switch (sel) {
7927        case CP0_REG07__HWRENA:
7928            check_insn(ctx, ISA_MIPS32R2);
7929            gen_helper_mtc0_hwrena(cpu_env, arg);
7930            ctx->base.is_jmp = DISAS_STOP;
7931            register_name = "HWREna";
7932            break;
7933        default:
7934            goto cp0_unimplemented;
7935        }
7936        break;
7937    case CP0_REGISTER_08:
7938        switch (sel) {
7939        case CP0_REG08__BADVADDR:
7940            /* ignored */
7941            register_name = "BadVAddr";
7942            break;
7943        case CP0_REG08__BADINSTR:
7944            /* ignored */
7945            register_name = "BadInstr";
7946            break;
7947        case CP0_REG08__BADINSTRP:
7948            /* ignored */
7949            register_name = "BadInstrP";
7950            break;
7951        case CP0_REG08__BADINSTRX:
7952            /* ignored */
7953            register_name = "BadInstrX";
7954            break;
7955        default:
7956            goto cp0_unimplemented;
7957        }
7958        break;
7959    case CP0_REGISTER_09:
7960        switch (sel) {
7961        case CP0_REG09__COUNT:
7962            gen_helper_mtc0_count(cpu_env, arg);
7963            register_name = "Count";
7964            break;
7965        case CP0_REG09__SAARI:
7966            CP0_CHECK(ctx->saar);
7967            gen_helper_mtc0_saari(cpu_env, arg);
7968            register_name = "SAARI";
7969            break;
7970        case CP0_REG09__SAAR:
7971            CP0_CHECK(ctx->saar);
7972            gen_helper_mtc0_saar(cpu_env, arg);
7973            register_name = "SAAR";
7974            break;
7975        default:
7976            goto cp0_unimplemented;
7977        }
7978        break;
7979    case CP0_REGISTER_10:
7980        switch (sel) {
7981        case CP0_REG10__ENTRYHI:
7982            gen_helper_mtc0_entryhi(cpu_env, arg);
7983            register_name = "EntryHi";
7984            break;
7985        default:
7986            goto cp0_unimplemented;
7987        }
7988        break;
7989    case CP0_REGISTER_11:
7990        switch (sel) {
7991        case CP0_REG11__COMPARE:
7992            gen_helper_mtc0_compare(cpu_env, arg);
7993            register_name = "Compare";
7994            break;
7995        /* 6,7 are implementation dependent */
7996        default:
7997            goto cp0_unimplemented;
7998        }
7999        break;
8000    case CP0_REGISTER_12:
8001        switch (sel) {
8002        case CP0_REG12__STATUS:
8003            save_cpu_state(ctx, 1);
8004            gen_helper_mtc0_status(cpu_env, arg);
8005            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8006            gen_save_pc(ctx->base.pc_next + 4);
8007            ctx->base.is_jmp = DISAS_EXIT;
8008            register_name = "Status";
8009            break;
8010        case CP0_REG12__INTCTL:
8011            check_insn(ctx, ISA_MIPS32R2);
8012            gen_helper_mtc0_intctl(cpu_env, arg);
8013            /* Stop translation as we may have switched the execution mode */
8014            ctx->base.is_jmp = DISAS_STOP;
8015            register_name = "IntCtl";
8016            break;
8017        case CP0_REG12__SRSCTL:
8018            check_insn(ctx, ISA_MIPS32R2);
8019            gen_helper_mtc0_srsctl(cpu_env, arg);
8020            /* Stop translation as we may have switched the execution mode */
8021            ctx->base.is_jmp = DISAS_STOP;
8022            register_name = "SRSCtl";
8023            break;
8024        case CP0_REG12__SRSMAP:
8025            check_insn(ctx, ISA_MIPS32R2);
8026            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8027            /* Stop translation as we may have switched the execution mode */
8028            ctx->base.is_jmp = DISAS_STOP;
8029            register_name = "SRSMap";
8030            break;
8031        default:
8032            goto cp0_unimplemented;
8033        }
8034        break;
8035    case CP0_REGISTER_13:
8036        switch (sel) {
8037        case CP0_REG13__CAUSE:
8038            save_cpu_state(ctx, 1);
8039            gen_helper_mtc0_cause(cpu_env, arg);
8040            /*
8041             * Stop translation as we may have triggered an interrupt.
8042             * DISAS_STOP isn't sufficient, we need to ensure we break out of
8043             * translated code to check for pending interrupts.
8044             */
8045            gen_save_pc(ctx->base.pc_next + 4);
8046            ctx->base.is_jmp = DISAS_EXIT;
8047            register_name = "Cause";
8048            break;
8049        default:
8050            goto cp0_unimplemented;
8051        }
8052        break;
8053    case CP0_REGISTER_14:
8054        switch (sel) {
8055        case CP0_REG14__EPC:
8056            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8057            register_name = "EPC";
8058            break;
8059        default:
8060            goto cp0_unimplemented;
8061        }
8062        break;
8063    case CP0_REGISTER_15:
8064        switch (sel) {
8065        case CP0_REG15__PRID:
8066            /* ignored */
8067            register_name = "PRid";
8068            break;
8069        case CP0_REG15__EBASE:
8070            check_insn(ctx, ISA_MIPS32R2);
8071            gen_helper_mtc0_ebase(cpu_env, arg);
8072            register_name = "EBase";
8073            break;
8074        default:
8075            goto cp0_unimplemented;
8076        }
8077        break;
8078    case CP0_REGISTER_16:
8079        switch (sel) {
8080        case CP0_REG16__CONFIG:
8081            gen_helper_mtc0_config0(cpu_env, arg);
8082            register_name = "Config";
8083            /* Stop translation as we may have switched the execution mode */
8084            ctx->base.is_jmp = DISAS_STOP;
8085            break;
8086        case CP0_REG16__CONFIG1:
8087            /* ignored, read only */
8088            register_name = "Config1";
8089            break;
8090        case CP0_REG16__CONFIG2:
8091            gen_helper_mtc0_config2(cpu_env, arg);
8092            register_name = "Config2";
8093            /* Stop translation as we may have switched the execution mode */
8094            ctx->base.is_jmp = DISAS_STOP;
8095            break;
8096        case CP0_REG16__CONFIG3:
8097            gen_helper_mtc0_config3(cpu_env, arg);
8098            register_name = "Config3";
8099            /* Stop translation as we may have switched the execution mode */
8100            ctx->base.is_jmp = DISAS_STOP;
8101            break;
8102        case CP0_REG16__CONFIG4:
8103            gen_helper_mtc0_config4(cpu_env, arg);
8104            register_name = "Config4";
8105            ctx->base.is_jmp = DISAS_STOP;
8106            break;
8107        case CP0_REG16__CONFIG5:
8108            gen_helper_mtc0_config5(cpu_env, arg);
8109            register_name = "Config5";
8110            /* Stop translation as we may have switched the execution mode */
8111            ctx->base.is_jmp = DISAS_STOP;
8112            break;
8113        /* 6,7 are implementation dependent */
8114        case CP0_REG16__CONFIG6:
8115            /* ignored */
8116            register_name = "Config6";
8117            break;
8118        case CP0_REG16__CONFIG7:
8119            /* ignored */
8120            register_name = "Config7";
8121            break;
8122        default:
8123            register_name = "Invalid config selector";
8124            goto cp0_unimplemented;
8125        }
8126        break;
8127    case CP0_REGISTER_17:
8128        switch (sel) {
8129        case CP0_REG17__LLADDR:
8130            gen_helper_mtc0_lladdr(cpu_env, arg);
8131            register_name = "LLAddr";
8132            break;
8133        case CP0_REG17__MAAR:
8134            CP0_CHECK(ctx->mrp);
8135            gen_helper_mtc0_maar(cpu_env, arg);
8136            register_name = "MAAR";
8137            break;
8138        case CP0_REG17__MAARI:
8139            CP0_CHECK(ctx->mrp);
8140            gen_helper_mtc0_maari(cpu_env, arg);
8141            register_name = "MAARI";
8142            break;
8143        default:
8144            goto cp0_unimplemented;
8145        }
8146        break;
8147    case CP0_REGISTER_18:
8148        switch (sel) {
8149        case CP0_REG18__WATCHLO0:
8150        case CP0_REG18__WATCHLO1:
8151        case CP0_REG18__WATCHLO2:
8152        case CP0_REG18__WATCHLO3:
8153        case CP0_REG18__WATCHLO4:
8154        case CP0_REG18__WATCHLO5:
8155        case CP0_REG18__WATCHLO6:
8156        case CP0_REG18__WATCHLO7:
8157            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8158            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8159            register_name = "WatchLo";
8160            break;
8161        default:
8162            goto cp0_unimplemented;
8163        }
8164        break;
8165    case CP0_REGISTER_19:
8166        switch (sel) {
8167        case CP0_REG19__WATCHHI0:
8168        case CP0_REG19__WATCHHI1:
8169        case CP0_REG19__WATCHHI2:
8170        case CP0_REG19__WATCHHI3:
8171        case CP0_REG19__WATCHHI4:
8172        case CP0_REG19__WATCHHI5:
8173        case CP0_REG19__WATCHHI6:
8174        case CP0_REG19__WATCHHI7:
8175            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8176            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8177            register_name = "WatchHi";
8178            break;
8179        default:
8180            goto cp0_unimplemented;
8181        }
8182        break;
8183    case CP0_REGISTER_20:
8184        switch (sel) {
8185        case CP0_REG20__XCONTEXT:
8186#if defined(TARGET_MIPS64)
8187            check_insn(ctx, ISA_MIPS3);
8188            gen_helper_mtc0_xcontext(cpu_env, arg);
8189            register_name = "XContext";
8190            break;
8191#endif
8192        default:
8193            goto cp0_unimplemented;
8194        }
8195        break;
8196    case CP0_REGISTER_21:
8197       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8198        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8199        switch (sel) {
8200        case 0:
8201            gen_helper_mtc0_framemask(cpu_env, arg);
8202            register_name = "Framemask";
8203            break;
8204        default:
8205            goto cp0_unimplemented;
8206        }
8207        break;
8208    case CP0_REGISTER_22:
8209        /* ignored */
8210        register_name = "Diagnostic"; /* implementation dependent */
8211        break;
8212    case CP0_REGISTER_23:
8213        switch (sel) {
8214        case CP0_REG23__DEBUG:
8215            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8216            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8217            gen_save_pc(ctx->base.pc_next + 4);
8218            ctx->base.is_jmp = DISAS_EXIT;
8219            register_name = "Debug";
8220            break;
8221        case CP0_REG23__TRACECONTROL:
8222            /* PDtrace support */
8223            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8224            register_name = "TraceControl";
8225            /* Stop translation as we may have switched the execution mode */
8226            ctx->base.is_jmp = DISAS_STOP;
8227            goto cp0_unimplemented;
8228        case CP0_REG23__TRACECONTROL2:
8229            /* PDtrace support */
8230            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8231            register_name = "TraceControl2";
8232            /* Stop translation as we may have switched the execution mode */
8233            ctx->base.is_jmp = DISAS_STOP;
8234            goto cp0_unimplemented;
8235        case CP0_REG23__USERTRACEDATA1:
8236            /* Stop translation as we may have switched the execution mode */
8237            ctx->base.is_jmp = DISAS_STOP;
8238            /* PDtrace support */
8239            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8240            register_name = "UserTraceData";
8241            /* Stop translation as we may have switched the execution mode */
8242            ctx->base.is_jmp = DISAS_STOP;
8243            goto cp0_unimplemented;
8244        case CP0_REG23__TRACEIBPC:
8245            /* PDtrace support */
8246            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8247            /* Stop translation as we may have switched the execution mode */
8248            ctx->base.is_jmp = DISAS_STOP;
8249            register_name = "TraceIBPC";
8250            goto cp0_unimplemented;
8251        case CP0_REG23__TRACEDBPC:
8252            /* PDtrace support */
8253            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8254            /* Stop translation as we may have switched the execution mode */
8255            ctx->base.is_jmp = DISAS_STOP;
8256            register_name = "TraceDBPC";
8257            goto cp0_unimplemented;
8258        default:
8259            goto cp0_unimplemented;
8260        }
8261        break;
8262    case CP0_REGISTER_24:
8263        switch (sel) {
8264        case CP0_REG24__DEPC:
8265            /* EJTAG support */
8266            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8267            register_name = "DEPC";
8268            break;
8269        default:
8270            goto cp0_unimplemented;
8271        }
8272        break;
8273    case CP0_REGISTER_25:
8274        switch (sel) {
8275        case CP0_REG25__PERFCTL0:
8276            gen_helper_mtc0_performance0(cpu_env, arg);
8277            register_name = "Performance0";
8278            break;
8279        case CP0_REG25__PERFCNT0:
8280            /* gen_helper_mtc0_performance1(arg); */
8281            register_name = "Performance1";
8282            goto cp0_unimplemented;
8283        case CP0_REG25__PERFCTL1:
8284            /* gen_helper_mtc0_performance2(arg); */
8285            register_name = "Performance2";
8286            goto cp0_unimplemented;
8287        case CP0_REG25__PERFCNT1:
8288            /* gen_helper_mtc0_performance3(arg); */
8289            register_name = "Performance3";
8290            goto cp0_unimplemented;
8291        case CP0_REG25__PERFCTL2:
8292            /* gen_helper_mtc0_performance4(arg); */
8293            register_name = "Performance4";
8294            goto cp0_unimplemented;
8295        case CP0_REG25__PERFCNT2:
8296            /* gen_helper_mtc0_performance5(arg); */
8297            register_name = "Performance5";
8298            goto cp0_unimplemented;
8299        case CP0_REG25__PERFCTL3:
8300            /* gen_helper_mtc0_performance6(arg); */
8301            register_name = "Performance6";
8302            goto cp0_unimplemented;
8303        case CP0_REG25__PERFCNT3:
8304            /* gen_helper_mtc0_performance7(arg); */
8305            register_name = "Performance7";
8306            goto cp0_unimplemented;
8307        default:
8308            goto cp0_unimplemented;
8309        }
8310       break;
8311    case CP0_REGISTER_26:
8312        switch (sel) {
8313        case CP0_REG26__ERRCTL:
8314            gen_helper_mtc0_errctl(cpu_env, arg);
8315            ctx->base.is_jmp = DISAS_STOP;
8316            register_name = "ErrCtl";
8317            break;
8318        default:
8319            goto cp0_unimplemented;
8320        }
8321        break;
8322    case CP0_REGISTER_27:
8323        switch (sel) {
8324        case CP0_REG27__CACHERR:
8325            /* ignored */
8326            register_name = "CacheErr";
8327            break;
8328        default:
8329            goto cp0_unimplemented;
8330        }
8331       break;
8332    case CP0_REGISTER_28:
8333        switch (sel) {
8334        case CP0_REG28__TAGLO:
8335        case CP0_REG28__TAGLO1:
8336        case CP0_REG28__TAGLO2:
8337        case CP0_REG28__TAGLO3:
8338            gen_helper_mtc0_taglo(cpu_env, arg);
8339            register_name = "TagLo";
8340            break;
8341        case CP0_REG28__DATALO:
8342        case CP0_REG28__DATALO1:
8343        case CP0_REG28__DATALO2:
8344        case CP0_REG28__DATALO3:
8345            gen_helper_mtc0_datalo(cpu_env, arg);
8346            register_name = "DataLo";
8347            break;
8348        default:
8349            goto cp0_unimplemented;
8350        }
8351        break;
8352    case CP0_REGISTER_29:
8353        switch (sel) {
8354        case CP0_REG29__TAGHI:
8355        case CP0_REG29__TAGHI1:
8356        case CP0_REG29__TAGHI2:
8357        case CP0_REG29__TAGHI3:
8358            gen_helper_mtc0_taghi(cpu_env, arg);
8359            register_name = "TagHi";
8360            break;
8361        case CP0_REG29__DATAHI:
8362        case CP0_REG29__DATAHI1:
8363        case CP0_REG29__DATAHI2:
8364        case CP0_REG29__DATAHI3:
8365            gen_helper_mtc0_datahi(cpu_env, arg);
8366            register_name = "DataHi";
8367            break;
8368        default:
8369            register_name = "invalid sel";
8370            goto cp0_unimplemented;
8371        }
8372       break;
8373    case CP0_REGISTER_30:
8374        switch (sel) {
8375        case CP0_REG30__ERROREPC:
8376            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8377            register_name = "ErrorEPC";
8378            break;
8379        default:
8380            goto cp0_unimplemented;
8381        }
8382        break;
8383    case CP0_REGISTER_31:
8384        switch (sel) {
8385        case CP0_REG31__DESAVE:
8386            /* EJTAG support */
8387            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8388            register_name = "DESAVE";
8389            break;
8390        case CP0_REG31__KSCRATCH1:
8391        case CP0_REG31__KSCRATCH2:
8392        case CP0_REG31__KSCRATCH3:
8393        case CP0_REG31__KSCRATCH4:
8394        case CP0_REG31__KSCRATCH5:
8395        case CP0_REG31__KSCRATCH6:
8396            CP0_CHECK(ctx->kscrexist & (1 << sel));
8397            tcg_gen_st_tl(arg, cpu_env,
8398                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8399            register_name = "KScratch";
8400            break;
8401        default:
8402            goto cp0_unimplemented;
8403        }
8404        break;
8405    default:
8406       goto cp0_unimplemented;
8407    }
8408    trace_mips_translate_c0("mtc0", register_name, reg, sel);
8409
8410    /* For simplicity assume that all writes can cause interrupts.  */
8411    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8412        /*
8413         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8414         * translated code to check for pending interrupts.
8415         */
8416        gen_save_pc(ctx->base.pc_next + 4);
8417        ctx->base.is_jmp = DISAS_EXIT;
8418    }
8419    return;
8420
8421cp0_unimplemented:
8422    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8423                  register_name, reg, sel);
8424}
8425
8426#if defined(TARGET_MIPS64)
8427static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8428{
8429    const char *register_name = "invalid";
8430
8431    if (sel != 0) {
8432        check_insn(ctx, ISA_MIPS64);
8433    }
8434
8435    switch (reg) {
8436    case CP0_REGISTER_00:
8437        switch (sel) {
8438        case CP0_REG00__INDEX:
8439            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8440            register_name = "Index";
8441            break;
8442        case CP0_REG00__MVPCONTROL:
8443            CP0_CHECK(ctx->insn_flags & ASE_MT);
8444            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8445            register_name = "MVPControl";
8446            break;
8447        case CP0_REG00__MVPCONF0:
8448            CP0_CHECK(ctx->insn_flags & ASE_MT);
8449            gen_helper_mfc0_mvpconf0(arg, cpu_env);
8450            register_name = "MVPConf0";
8451            break;
8452        case CP0_REG00__MVPCONF1:
8453            CP0_CHECK(ctx->insn_flags & ASE_MT);
8454            gen_helper_mfc0_mvpconf1(arg, cpu_env);
8455            register_name = "MVPConf1";
8456            break;
8457        case CP0_REG00__VPCONTROL:
8458            CP0_CHECK(ctx->vp);
8459            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8460            register_name = "VPControl";
8461            break;
8462        default:
8463            goto cp0_unimplemented;
8464        }
8465        break;
8466    case CP0_REGISTER_01:
8467        switch (sel) {
8468        case CP0_REG01__RANDOM:
8469            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8470            gen_helper_mfc0_random(arg, cpu_env);
8471            register_name = "Random";
8472            break;
8473        case CP0_REG01__VPECONTROL:
8474            CP0_CHECK(ctx->insn_flags & ASE_MT);
8475            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8476            register_name = "VPEControl";
8477            break;
8478        case CP0_REG01__VPECONF0:
8479            CP0_CHECK(ctx->insn_flags & ASE_MT);
8480            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8481            register_name = "VPEConf0";
8482            break;
8483        case CP0_REG01__VPECONF1:
8484            CP0_CHECK(ctx->insn_flags & ASE_MT);
8485            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8486            register_name = "VPEConf1";
8487            break;
8488        case CP0_REG01__YQMASK:
8489            CP0_CHECK(ctx->insn_flags & ASE_MT);
8490            tcg_gen_ld_tl(arg, cpu_env,
8491                          offsetof(CPUMIPSState, CP0_YQMask));
8492            register_name = "YQMask";
8493            break;
8494        case CP0_REG01__VPESCHEDULE:
8495            CP0_CHECK(ctx->insn_flags & ASE_MT);
8496            tcg_gen_ld_tl(arg, cpu_env,
8497                          offsetof(CPUMIPSState, CP0_VPESchedule));
8498            register_name = "VPESchedule";
8499            break;
8500        case CP0_REG01__VPESCHEFBACK:
8501            CP0_CHECK(ctx->insn_flags & ASE_MT);
8502            tcg_gen_ld_tl(arg, cpu_env,
8503                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
8504            register_name = "VPEScheFBack";
8505            break;
8506        case CP0_REG01__VPEOPT:
8507            CP0_CHECK(ctx->insn_flags & ASE_MT);
8508            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8509            register_name = "VPEOpt";
8510            break;
8511        default:
8512            goto cp0_unimplemented;
8513        }
8514        break;
8515    case CP0_REGISTER_02:
8516        switch (sel) {
8517        case CP0_REG02__ENTRYLO0:
8518            tcg_gen_ld_tl(arg, cpu_env,
8519                          offsetof(CPUMIPSState, CP0_EntryLo0));
8520            register_name = "EntryLo0";
8521            break;
8522        case CP0_REG02__TCSTATUS:
8523            CP0_CHECK(ctx->insn_flags & ASE_MT);
8524            gen_helper_mfc0_tcstatus(arg, cpu_env);
8525            register_name = "TCStatus";
8526            break;
8527        case CP0_REG02__TCBIND:
8528            CP0_CHECK(ctx->insn_flags & ASE_MT);
8529            gen_helper_mfc0_tcbind(arg, cpu_env);
8530            register_name = "TCBind";
8531            break;
8532        case CP0_REG02__TCRESTART:
8533            CP0_CHECK(ctx->insn_flags & ASE_MT);
8534            gen_helper_dmfc0_tcrestart(arg, cpu_env);
8535            register_name = "TCRestart";
8536            break;
8537        case CP0_REG02__TCHALT:
8538            CP0_CHECK(ctx->insn_flags & ASE_MT);
8539            gen_helper_dmfc0_tchalt(arg, cpu_env);
8540            register_name = "TCHalt";
8541            break;
8542        case CP0_REG02__TCCONTEXT:
8543            CP0_CHECK(ctx->insn_flags & ASE_MT);
8544            gen_helper_dmfc0_tccontext(arg, cpu_env);
8545            register_name = "TCContext";
8546            break;
8547        case CP0_REG02__TCSCHEDULE:
8548            CP0_CHECK(ctx->insn_flags & ASE_MT);
8549            gen_helper_dmfc0_tcschedule(arg, cpu_env);
8550            register_name = "TCSchedule";
8551            break;
8552        case CP0_REG02__TCSCHEFBACK:
8553            CP0_CHECK(ctx->insn_flags & ASE_MT);
8554            gen_helper_dmfc0_tcschefback(arg, cpu_env);
8555            register_name = "TCScheFBack";
8556            break;
8557        default:
8558            goto cp0_unimplemented;
8559        }
8560        break;
8561    case CP0_REGISTER_03:
8562        switch (sel) {
8563        case CP0_REG03__ENTRYLO1:
8564            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8565            register_name = "EntryLo1";
8566            break;
8567        case CP0_REG03__GLOBALNUM:
8568            CP0_CHECK(ctx->vp);
8569            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8570            register_name = "GlobalNumber";
8571            break;
8572        default:
8573            goto cp0_unimplemented;
8574        }
8575        break;
8576    case CP0_REGISTER_04:
8577        switch (sel) {
8578        case CP0_REG04__CONTEXT:
8579            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8580            register_name = "Context";
8581            break;
8582        case CP0_REG04__CONTEXTCONFIG:
8583            /* SmartMIPS ASE */
8584            /* gen_helper_dmfc0_contextconfig(arg); */
8585            register_name = "ContextConfig";
8586            goto cp0_unimplemented;
8587        case CP0_REG04__USERLOCAL:
8588            CP0_CHECK(ctx->ulri);
8589            tcg_gen_ld_tl(arg, cpu_env,
8590                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8591            register_name = "UserLocal";
8592            break;
8593        default:
8594            goto cp0_unimplemented;
8595        }
8596        break;
8597    case CP0_REGISTER_05:
8598        switch (sel) {
8599        case CP0_REG05__PAGEMASK:
8600            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8601            register_name = "PageMask";
8602            break;
8603        case CP0_REG05__PAGEGRAIN:
8604            check_insn(ctx, ISA_MIPS32R2);
8605            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8606            register_name = "PageGrain";
8607            break;
8608        case CP0_REG05__SEGCTL0:
8609            CP0_CHECK(ctx->sc);
8610            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8611            register_name = "SegCtl0";
8612            break;
8613        case CP0_REG05__SEGCTL1:
8614            CP0_CHECK(ctx->sc);
8615            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8616            register_name = "SegCtl1";
8617            break;
8618        case CP0_REG05__SEGCTL2:
8619            CP0_CHECK(ctx->sc);
8620            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8621            register_name = "SegCtl2";
8622            break;
8623        case CP0_REG05__PWBASE:
8624            check_pw(ctx);
8625            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8626            register_name = "PWBase";
8627            break;
8628        case CP0_REG05__PWFIELD:
8629            check_pw(ctx);
8630            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8631            register_name = "PWField";
8632            break;
8633        case CP0_REG05__PWSIZE:
8634            check_pw(ctx);
8635            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8636            register_name = "PWSize";
8637            break;
8638        default:
8639            goto cp0_unimplemented;
8640        }
8641        break;
8642    case CP0_REGISTER_06:
8643        switch (sel) {
8644        case CP0_REG06__WIRED:
8645            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8646            register_name = "Wired";
8647            break;
8648        case CP0_REG06__SRSCONF0:
8649            check_insn(ctx, ISA_MIPS32R2);
8650            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8651            register_name = "SRSConf0";
8652            break;
8653        case CP0_REG06__SRSCONF1:
8654            check_insn(ctx, ISA_MIPS32R2);
8655            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8656            register_name = "SRSConf1";
8657            break;
8658        case CP0_REG06__SRSCONF2:
8659            check_insn(ctx, ISA_MIPS32R2);
8660            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8661            register_name = "SRSConf2";
8662            break;
8663        case CP0_REG06__SRSCONF3:
8664            check_insn(ctx, ISA_MIPS32R2);
8665            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8666            register_name = "SRSConf3";
8667            break;
8668        case CP0_REG06__SRSCONF4:
8669            check_insn(ctx, ISA_MIPS32R2);
8670            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8671            register_name = "SRSConf4";
8672            break;
8673        case CP0_REG06__PWCTL:
8674            check_pw(ctx);
8675            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8676            register_name = "PWCtl";
8677            break;
8678        default:
8679            goto cp0_unimplemented;
8680        }
8681        break;
8682    case CP0_REGISTER_07:
8683        switch (sel) {
8684        case CP0_REG07__HWRENA:
8685            check_insn(ctx, ISA_MIPS32R2);
8686            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8687            register_name = "HWREna";
8688            break;
8689        default:
8690            goto cp0_unimplemented;
8691        }
8692        break;
8693    case CP0_REGISTER_08:
8694        switch (sel) {
8695        case CP0_REG08__BADVADDR:
8696            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8697            register_name = "BadVAddr";
8698            break;
8699        case CP0_REG08__BADINSTR:
8700            CP0_CHECK(ctx->bi);
8701            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8702            register_name = "BadInstr";
8703            break;
8704        case CP0_REG08__BADINSTRP:
8705            CP0_CHECK(ctx->bp);
8706            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8707            register_name = "BadInstrP";
8708            break;
8709        case CP0_REG08__BADINSTRX:
8710            CP0_CHECK(ctx->bi);
8711            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8712            tcg_gen_andi_tl(arg, arg, ~0xffff);
8713            register_name = "BadInstrX";
8714            break;
8715        default:
8716            goto cp0_unimplemented;
8717        }
8718        break;
8719    case CP0_REGISTER_09:
8720        switch (sel) {
8721        case CP0_REG09__COUNT:
8722            /* Mark as an IO operation because we read the time.  */
8723            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8724                gen_io_start();
8725            }
8726            gen_helper_mfc0_count(arg, cpu_env);
8727            /*
8728             * Break the TB to be able to take timer interrupts immediately
8729             * after reading count. DISAS_STOP isn't sufficient, we need to
8730             * ensure we break completely out of translated code.
8731             */
8732            gen_save_pc(ctx->base.pc_next + 4);
8733            ctx->base.is_jmp = DISAS_EXIT;
8734            register_name = "Count";
8735            break;
8736        case CP0_REG09__SAARI:
8737            CP0_CHECK(ctx->saar);
8738            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8739            register_name = "SAARI";
8740            break;
8741        case CP0_REG09__SAAR:
8742            CP0_CHECK(ctx->saar);
8743            gen_helper_dmfc0_saar(arg, cpu_env);
8744            register_name = "SAAR";
8745            break;
8746        default:
8747            goto cp0_unimplemented;
8748        }
8749        break;
8750    case CP0_REGISTER_10:
8751        switch (sel) {
8752        case CP0_REG10__ENTRYHI:
8753            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8754            register_name = "EntryHi";
8755            break;
8756        default:
8757            goto cp0_unimplemented;
8758        }
8759        break;
8760    case CP0_REGISTER_11:
8761        switch (sel) {
8762        case CP0_REG11__COMPARE:
8763            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8764            register_name = "Compare";
8765            break;
8766        /* 6,7 are implementation dependent */
8767        default:
8768            goto cp0_unimplemented;
8769        }
8770        break;
8771    case CP0_REGISTER_12:
8772        switch (sel) {
8773        case CP0_REG12__STATUS:
8774            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8775            register_name = "Status";
8776            break;
8777        case CP0_REG12__INTCTL:
8778            check_insn(ctx, ISA_MIPS32R2);
8779            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8780            register_name = "IntCtl";
8781            break;
8782        case CP0_REG12__SRSCTL:
8783            check_insn(ctx, ISA_MIPS32R2);
8784            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8785            register_name = "SRSCtl";
8786            break;
8787        case CP0_REG12__SRSMAP:
8788            check_insn(ctx, ISA_MIPS32R2);
8789            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8790            register_name = "SRSMap";
8791            break;
8792        default:
8793            goto cp0_unimplemented;
8794        }
8795        break;
8796    case CP0_REGISTER_13:
8797        switch (sel) {
8798        case CP0_REG13__CAUSE:
8799            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8800            register_name = "Cause";
8801            break;
8802        default:
8803            goto cp0_unimplemented;
8804        }
8805        break;
8806    case CP0_REGISTER_14:
8807        switch (sel) {
8808        case CP0_REG14__EPC:
8809            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8810            register_name = "EPC";
8811            break;
8812        default:
8813            goto cp0_unimplemented;
8814        }
8815        break;
8816    case CP0_REGISTER_15:
8817        switch (sel) {
8818        case CP0_REG15__PRID:
8819            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8820            register_name = "PRid";
8821            break;
8822        case CP0_REG15__EBASE:
8823            check_insn(ctx, ISA_MIPS32R2);
8824            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8825            register_name = "EBase";
8826            break;
8827        case CP0_REG15__CMGCRBASE:
8828            check_insn(ctx, ISA_MIPS32R2);
8829            CP0_CHECK(ctx->cmgcr);
8830            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8831            register_name = "CMGCRBase";
8832            break;
8833        default:
8834            goto cp0_unimplemented;
8835        }
8836        break;
8837    case CP0_REGISTER_16:
8838        switch (sel) {
8839        case CP0_REG16__CONFIG:
8840            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8841            register_name = "Config";
8842            break;
8843        case CP0_REG16__CONFIG1:
8844            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8845            register_name = "Config1";
8846            break;
8847        case CP0_REG16__CONFIG2:
8848            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8849            register_name = "Config2";
8850            break;
8851        case CP0_REG16__CONFIG3:
8852            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8853            register_name = "Config3";
8854            break;
8855        case CP0_REG16__CONFIG4:
8856            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8857            register_name = "Config4";
8858            break;
8859        case CP0_REG16__CONFIG5:
8860            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8861            register_name = "Config5";
8862            break;
8863        /* 6,7 are implementation dependent */
8864        case CP0_REG16__CONFIG6:
8865            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8866            register_name = "Config6";
8867            break;
8868        case CP0_REG16__CONFIG7:
8869            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8870            register_name = "Config7";
8871            break;
8872        default:
8873            goto cp0_unimplemented;
8874        }
8875        break;
8876    case CP0_REGISTER_17:
8877        switch (sel) {
8878        case CP0_REG17__LLADDR:
8879            gen_helper_dmfc0_lladdr(arg, cpu_env);
8880            register_name = "LLAddr";
8881            break;
8882        case CP0_REG17__MAAR:
8883            CP0_CHECK(ctx->mrp);
8884            gen_helper_dmfc0_maar(arg, cpu_env);
8885            register_name = "MAAR";
8886            break;
8887        case CP0_REG17__MAARI:
8888            CP0_CHECK(ctx->mrp);
8889            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8890            register_name = "MAARI";
8891            break;
8892        default:
8893            goto cp0_unimplemented;
8894        }
8895        break;
8896    case CP0_REGISTER_18:
8897        switch (sel) {
8898        case CP0_REG18__WATCHLO0:
8899        case CP0_REG18__WATCHLO1:
8900        case CP0_REG18__WATCHLO2:
8901        case CP0_REG18__WATCHLO3:
8902        case CP0_REG18__WATCHLO4:
8903        case CP0_REG18__WATCHLO5:
8904        case CP0_REG18__WATCHLO6:
8905        case CP0_REG18__WATCHLO7:
8906            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8907            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8908            register_name = "WatchLo";
8909            break;
8910        default:
8911            goto cp0_unimplemented;
8912        }
8913        break;
8914    case CP0_REGISTER_19:
8915        switch (sel) {
8916        case CP0_REG19__WATCHHI0:
8917        case CP0_REG19__WATCHHI1:
8918        case CP0_REG19__WATCHHI2:
8919        case CP0_REG19__WATCHHI3:
8920        case CP0_REG19__WATCHHI4:
8921        case CP0_REG19__WATCHHI5:
8922        case CP0_REG19__WATCHHI6:
8923        case CP0_REG19__WATCHHI7:
8924            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8925            gen_helper_1e0i(mfc0_watchhi, arg, sel);
8926            register_name = "WatchHi";
8927            break;
8928        default:
8929            goto cp0_unimplemented;
8930        }
8931        break;
8932    case CP0_REGISTER_20:
8933        switch (sel) {
8934        case CP0_REG20__XCONTEXT:
8935            check_insn(ctx, ISA_MIPS3);
8936            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8937            register_name = "XContext";
8938            break;
8939        default:
8940            goto cp0_unimplemented;
8941        }
8942        break;
8943    case CP0_REGISTER_21:
8944        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8945        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8946        switch (sel) {
8947        case 0:
8948            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8949            register_name = "Framemask";
8950            break;
8951        default:
8952            goto cp0_unimplemented;
8953        }
8954        break;
8955    case CP0_REGISTER_22:
8956        tcg_gen_movi_tl(arg, 0); /* unimplemented */
8957        register_name = "'Diagnostic"; /* implementation dependent */
8958        break;
8959    case CP0_REGISTER_23:
8960        switch (sel) {
8961        case CP0_REG23__DEBUG:
8962            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8963            register_name = "Debug";
8964            break;
8965        case CP0_REG23__TRACECONTROL:
8966            /* PDtrace support */
8967            /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
8968            register_name = "TraceControl";
8969            goto cp0_unimplemented;
8970        case CP0_REG23__TRACECONTROL2:
8971            /* PDtrace support */
8972            /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8973            register_name = "TraceControl2";
8974            goto cp0_unimplemented;
8975        case CP0_REG23__USERTRACEDATA1:
8976            /* PDtrace support */
8977            /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8978            register_name = "UserTraceData1";
8979            goto cp0_unimplemented;
8980        case CP0_REG23__TRACEIBPC:
8981            /* PDtrace support */
8982            /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
8983            register_name = "TraceIBPC";
8984            goto cp0_unimplemented;
8985        case CP0_REG23__TRACEDBPC:
8986            /* PDtrace support */
8987            /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
8988            register_name = "TraceDBPC";
8989            goto cp0_unimplemented;
8990        default:
8991            goto cp0_unimplemented;
8992        }
8993        break;
8994    case CP0_REGISTER_24:
8995        switch (sel) {
8996        case CP0_REG24__DEPC:
8997            /* EJTAG support */
8998            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8999            register_name = "DEPC";
9000            break;
9001        default:
9002            goto cp0_unimplemented;
9003        }
9004        break;
9005    case CP0_REGISTER_25:
9006        switch (sel) {
9007        case CP0_REG25__PERFCTL0:
9008            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
9009            register_name = "Performance0";
9010            break;
9011        case CP0_REG25__PERFCNT0:
9012            /* gen_helper_dmfc0_performance1(arg); */
9013            register_name = "Performance1";
9014            goto cp0_unimplemented;
9015        case CP0_REG25__PERFCTL1:
9016            /* gen_helper_dmfc0_performance2(arg); */
9017            register_name = "Performance2";
9018            goto cp0_unimplemented;
9019        case CP0_REG25__PERFCNT1:
9020            /* gen_helper_dmfc0_performance3(arg); */
9021            register_name = "Performance3";
9022            goto cp0_unimplemented;
9023        case CP0_REG25__PERFCTL2:
9024            /* gen_helper_dmfc0_performance4(arg); */
9025            register_name = "Performance4";
9026            goto cp0_unimplemented;
9027        case CP0_REG25__PERFCNT2:
9028            /* gen_helper_dmfc0_performance5(arg); */
9029            register_name = "Performance5";
9030            goto cp0_unimplemented;
9031        case CP0_REG25__PERFCTL3:
9032            /* gen_helper_dmfc0_performance6(arg); */
9033            register_name = "Performance6";
9034            goto cp0_unimplemented;
9035        case CP0_REG25__PERFCNT3:
9036            /* gen_helper_dmfc0_performance7(arg); */
9037            register_name = "Performance7";
9038            goto cp0_unimplemented;
9039        default:
9040            goto cp0_unimplemented;
9041        }
9042        break;
9043    case CP0_REGISTER_26:
9044        switch (sel) {
9045        case CP0_REG26__ERRCTL:
9046            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
9047            register_name = "ErrCtl";
9048            break;
9049        default:
9050            goto cp0_unimplemented;
9051        }
9052        break;
9053    case CP0_REGISTER_27:
9054        switch (sel) {
9055        /* ignored */
9056        case CP0_REG27__CACHERR:
9057            tcg_gen_movi_tl(arg, 0); /* unimplemented */
9058            register_name = "CacheErr";
9059            break;
9060        default:
9061            goto cp0_unimplemented;
9062        }
9063        break;
9064    case CP0_REGISTER_28:
9065        switch (sel) {
9066        case CP0_REG28__TAGLO:
9067        case CP0_REG28__TAGLO1:
9068        case CP0_REG28__TAGLO2:
9069        case CP0_REG28__TAGLO3:
9070            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9071            register_name = "TagLo";
9072            break;
9073        case CP0_REG28__DATALO:
9074        case CP0_REG28__DATALO1:
9075        case CP0_REG28__DATALO2:
9076        case CP0_REG28__DATALO3:
9077            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9078            register_name = "DataLo";
9079            break;
9080        default:
9081            goto cp0_unimplemented;
9082        }
9083        break;
9084    case CP0_REGISTER_29:
9085        switch (sel) {
9086        case CP0_REG29__TAGHI:
9087        case CP0_REG29__TAGHI1:
9088        case CP0_REG29__TAGHI2:
9089        case CP0_REG29__TAGHI3:
9090            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9091            register_name = "TagHi";
9092            break;
9093        case CP0_REG29__DATAHI:
9094        case CP0_REG29__DATAHI1:
9095        case CP0_REG29__DATAHI2:
9096        case CP0_REG29__DATAHI3:
9097            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9098            register_name = "DataHi";
9099            break;
9100        default:
9101            goto cp0_unimplemented;
9102        }
9103        break;
9104    case CP0_REGISTER_30:
9105        switch (sel) {
9106        case CP0_REG30__ERROREPC:
9107            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9108            register_name = "ErrorEPC";
9109            break;
9110        default:
9111            goto cp0_unimplemented;
9112        }
9113        break;
9114    case CP0_REGISTER_31:
9115        switch (sel) {
9116        case CP0_REG31__DESAVE:
9117            /* EJTAG support */
9118            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9119            register_name = "DESAVE";
9120            break;
9121        case CP0_REG31__KSCRATCH1:
9122        case CP0_REG31__KSCRATCH2:
9123        case CP0_REG31__KSCRATCH3:
9124        case CP0_REG31__KSCRATCH4:
9125        case CP0_REG31__KSCRATCH5:
9126        case CP0_REG31__KSCRATCH6:
9127            CP0_CHECK(ctx->kscrexist & (1 << sel));
9128            tcg_gen_ld_tl(arg, cpu_env,
9129                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
9130            register_name = "KScratch";
9131            break;
9132        default:
9133            goto cp0_unimplemented;
9134        }
9135        break;
9136    default:
9137        goto cp0_unimplemented;
9138    }
9139    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
9140    return;
9141
9142cp0_unimplemented:
9143    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
9144                  register_name, reg, sel);
9145    gen_mfc0_unimplemented(ctx, arg);
9146}
9147
9148static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9149{
9150    const char *register_name = "invalid";
9151
9152    if (sel != 0) {
9153        check_insn(ctx, ISA_MIPS64);
9154    }
9155
9156    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9157        gen_io_start();
9158    }
9159
9160    switch (reg) {
9161    case CP0_REGISTER_00:
9162        switch (sel) {
9163        case CP0_REG00__INDEX:
9164            gen_helper_mtc0_index(cpu_env, arg);
9165            register_name = "Index";
9166            break;
9167        case CP0_REG00__MVPCONTROL:
9168            CP0_CHECK(ctx->insn_flags & ASE_MT);
9169            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9170            register_name = "MVPControl";
9171            break;
9172        case CP0_REG00__MVPCONF0:
9173            CP0_CHECK(ctx->insn_flags & ASE_MT);
9174            /* ignored */
9175            register_name = "MVPConf0";
9176            break;
9177        case CP0_REG00__MVPCONF1:
9178            CP0_CHECK(ctx->insn_flags & ASE_MT);
9179            /* ignored */
9180            register_name = "MVPConf1";
9181            break;
9182        case CP0_REG00__VPCONTROL:
9183            CP0_CHECK(ctx->vp);
9184            /* ignored */
9185            register_name = "VPControl";
9186            break;
9187        default:
9188            goto cp0_unimplemented;
9189        }
9190        break;
9191    case CP0_REGISTER_01:
9192        switch (sel) {
9193        case CP0_REG01__RANDOM:
9194            /* ignored */
9195            register_name = "Random";
9196            break;
9197        case CP0_REG01__VPECONTROL:
9198            CP0_CHECK(ctx->insn_flags & ASE_MT);
9199            gen_helper_mtc0_vpecontrol(cpu_env, arg);
9200            register_name = "VPEControl";
9201            break;
9202        case CP0_REG01__VPECONF0:
9203            CP0_CHECK(ctx->insn_flags & ASE_MT);
9204            gen_helper_mtc0_vpeconf0(cpu_env, arg);
9205            register_name = "VPEConf0";
9206            break;
9207        case CP0_REG01__VPECONF1:
9208            CP0_CHECK(ctx->insn_flags & ASE_MT);
9209            gen_helper_mtc0_vpeconf1(cpu_env, arg);
9210            register_name = "VPEConf1";
9211            break;
9212        case CP0_REG01__YQMASK:
9213            CP0_CHECK(ctx->insn_flags & ASE_MT);
9214            gen_helper_mtc0_yqmask(cpu_env, arg);
9215            register_name = "YQMask";
9216            break;
9217        case CP0_REG01__VPESCHEDULE:
9218            CP0_CHECK(ctx->insn_flags & ASE_MT);
9219            tcg_gen_st_tl(arg, cpu_env,
9220                          offsetof(CPUMIPSState, CP0_VPESchedule));
9221            register_name = "VPESchedule";
9222            break;
9223        case CP0_REG01__VPESCHEFBACK:
9224            CP0_CHECK(ctx->insn_flags & ASE_MT);
9225            tcg_gen_st_tl(arg, cpu_env,
9226                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
9227            register_name = "VPEScheFBack";
9228            break;
9229        case CP0_REG01__VPEOPT:
9230            CP0_CHECK(ctx->insn_flags & ASE_MT);
9231            gen_helper_mtc0_vpeopt(cpu_env, arg);
9232            register_name = "VPEOpt";
9233            break;
9234        default:
9235            goto cp0_unimplemented;
9236        }
9237        break;
9238    case CP0_REGISTER_02:
9239        switch (sel) {
9240        case CP0_REG02__ENTRYLO0:
9241            gen_helper_dmtc0_entrylo0(cpu_env, arg);
9242            register_name = "EntryLo0";
9243            break;
9244        case CP0_REG02__TCSTATUS:
9245            CP0_CHECK(ctx->insn_flags & ASE_MT);
9246            gen_helper_mtc0_tcstatus(cpu_env, arg);
9247            register_name = "TCStatus";
9248            break;
9249        case CP0_REG02__TCBIND:
9250            CP0_CHECK(ctx->insn_flags & ASE_MT);
9251            gen_helper_mtc0_tcbind(cpu_env, arg);
9252            register_name = "TCBind";
9253            break;
9254        case CP0_REG02__TCRESTART:
9255            CP0_CHECK(ctx->insn_flags & ASE_MT);
9256            gen_helper_mtc0_tcrestart(cpu_env, arg);
9257            register_name = "TCRestart";
9258            break;
9259        case CP0_REG02__TCHALT:
9260            CP0_CHECK(ctx->insn_flags & ASE_MT);
9261            gen_helper_mtc0_tchalt(cpu_env, arg);
9262            register_name = "TCHalt";
9263            break;
9264        case CP0_REG02__TCCONTEXT:
9265            CP0_CHECK(ctx->insn_flags & ASE_MT);
9266            gen_helper_mtc0_tccontext(cpu_env, arg);
9267            register_name = "TCContext";
9268            break;
9269        case CP0_REG02__TCSCHEDULE:
9270            CP0_CHECK(ctx->insn_flags & ASE_MT);
9271            gen_helper_mtc0_tcschedule(cpu_env, arg);
9272            register_name = "TCSchedule";
9273            break;
9274        case CP0_REG02__TCSCHEFBACK:
9275            CP0_CHECK(ctx->insn_flags & ASE_MT);
9276            gen_helper_mtc0_tcschefback(cpu_env, arg);
9277            register_name = "TCScheFBack";
9278            break;
9279        default:
9280            goto cp0_unimplemented;
9281        }
9282        break;
9283    case CP0_REGISTER_03:
9284        switch (sel) {
9285        case CP0_REG03__ENTRYLO1:
9286            gen_helper_dmtc0_entrylo1(cpu_env, arg);
9287            register_name = "EntryLo1";
9288            break;
9289        case CP0_REG03__GLOBALNUM:
9290            CP0_CHECK(ctx->vp);
9291            /* ignored */
9292            register_name = "GlobalNumber";
9293            break;
9294        default:
9295            goto cp0_unimplemented;
9296        }
9297        break;
9298    case CP0_REGISTER_04:
9299        switch (sel) {
9300        case CP0_REG04__CONTEXT:
9301            gen_helper_mtc0_context(cpu_env, arg);
9302            register_name = "Context";
9303            break;
9304        case CP0_REG04__CONTEXTCONFIG:
9305            /* SmartMIPS ASE */
9306            /* gen_helper_dmtc0_contextconfig(arg); */
9307            register_name = "ContextConfig";
9308            goto cp0_unimplemented;
9309        case CP0_REG04__USERLOCAL:
9310            CP0_CHECK(ctx->ulri);
9311            tcg_gen_st_tl(arg, cpu_env,
9312                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9313            register_name = "UserLocal";
9314            break;
9315        default:
9316            goto cp0_unimplemented;
9317        }
9318        break;
9319    case CP0_REGISTER_05:
9320        switch (sel) {
9321        case CP0_REG05__PAGEMASK:
9322            gen_helper_mtc0_pagemask(cpu_env, arg);
9323            register_name = "PageMask";
9324            break;
9325        case CP0_REG05__PAGEGRAIN:
9326            check_insn(ctx, ISA_MIPS32R2);
9327            gen_helper_mtc0_pagegrain(cpu_env, arg);
9328            register_name = "PageGrain";
9329            break;
9330        case CP0_REG05__SEGCTL0:
9331            CP0_CHECK(ctx->sc);
9332            gen_helper_mtc0_segctl0(cpu_env, arg);
9333            register_name = "SegCtl0";
9334            break;
9335        case CP0_REG05__SEGCTL1:
9336            CP0_CHECK(ctx->sc);
9337            gen_helper_mtc0_segctl1(cpu_env, arg);
9338            register_name = "SegCtl1";
9339            break;
9340        case CP0_REG05__SEGCTL2:
9341            CP0_CHECK(ctx->sc);
9342            gen_helper_mtc0_segctl2(cpu_env, arg);
9343            register_name = "SegCtl2";
9344            break;
9345        case CP0_REG05__PWBASE:
9346            check_pw(ctx);
9347            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9348            register_name = "PWBase";
9349            break;
9350        case CP0_REG05__PWFIELD:
9351            check_pw(ctx);
9352            gen_helper_mtc0_pwfield(cpu_env, arg);
9353            register_name = "PWField";
9354            break;
9355        case CP0_REG05__PWSIZE:
9356            check_pw(ctx);
9357            gen_helper_mtc0_pwsize(cpu_env, arg);
9358            register_name = "PWSize";
9359            break;
9360        default:
9361            goto cp0_unimplemented;
9362        }
9363        break;
9364    case CP0_REGISTER_06:
9365        switch (sel) {
9366        case CP0_REG06__WIRED:
9367            gen_helper_mtc0_wired(cpu_env, arg);
9368            register_name = "Wired";
9369            break;
9370        case CP0_REG06__SRSCONF0:
9371            check_insn(ctx, ISA_MIPS32R2);
9372            gen_helper_mtc0_srsconf0(cpu_env, arg);
9373            register_name = "SRSConf0";
9374            break;
9375        case CP0_REG06__SRSCONF1:
9376            check_insn(ctx, ISA_MIPS32R2);
9377            gen_helper_mtc0_srsconf1(cpu_env, arg);
9378            register_name = "SRSConf1";
9379            break;
9380        case CP0_REG06__SRSCONF2:
9381            check_insn(ctx, ISA_MIPS32R2);
9382            gen_helper_mtc0_srsconf2(cpu_env, arg);
9383            register_name = "SRSConf2";
9384            break;
9385        case CP0_REG06__SRSCONF3:
9386            check_insn(ctx, ISA_MIPS32R2);
9387            gen_helper_mtc0_srsconf3(cpu_env, arg);
9388            register_name = "SRSConf3";
9389            break;
9390        case CP0_REG06__SRSCONF4:
9391            check_insn(ctx, ISA_MIPS32R2);
9392            gen_helper_mtc0_srsconf4(cpu_env, arg);
9393            register_name = "SRSConf4";
9394            break;
9395        case CP0_REG06__PWCTL:
9396            check_pw(ctx);
9397            gen_helper_mtc0_pwctl(cpu_env, arg);
9398            register_name = "PWCtl";
9399            break;
9400        default:
9401            goto cp0_unimplemented;
9402        }
9403        break;
9404    case CP0_REGISTER_07:
9405        switch (sel) {
9406        case CP0_REG07__HWRENA:
9407            check_insn(ctx, ISA_MIPS32R2);
9408            gen_helper_mtc0_hwrena(cpu_env, arg);
9409            ctx->base.is_jmp = DISAS_STOP;
9410            register_name = "HWREna";
9411            break;
9412        default:
9413            goto cp0_unimplemented;
9414        }
9415        break;
9416    case CP0_REGISTER_08:
9417        switch (sel) {
9418        case CP0_REG08__BADVADDR:
9419            /* ignored */
9420            register_name = "BadVAddr";
9421            break;
9422        case CP0_REG08__BADINSTR:
9423            /* ignored */
9424            register_name = "BadInstr";
9425            break;
9426        case CP0_REG08__BADINSTRP:
9427            /* ignored */
9428            register_name = "BadInstrP";
9429            break;
9430        case CP0_REG08__BADINSTRX:
9431            /* ignored */
9432            register_name = "BadInstrX";
9433            break;
9434        default:
9435            goto cp0_unimplemented;
9436        }
9437        break;
9438    case CP0_REGISTER_09:
9439        switch (sel) {
9440        case CP0_REG09__COUNT:
9441            gen_helper_mtc0_count(cpu_env, arg);
9442            register_name = "Count";
9443            break;
9444        case CP0_REG09__SAARI:
9445            CP0_CHECK(ctx->saar);
9446            gen_helper_mtc0_saari(cpu_env, arg);
9447            register_name = "SAARI";
9448            break;
9449        case CP0_REG09__SAAR:
9450            CP0_CHECK(ctx->saar);
9451            gen_helper_mtc0_saar(cpu_env, arg);
9452            register_name = "SAAR";
9453            break;
9454        default:
9455            goto cp0_unimplemented;
9456        }
9457        /* Stop translation as we may have switched the execution mode */
9458        ctx->base.is_jmp = DISAS_STOP;
9459        break;
9460    case CP0_REGISTER_10:
9461        switch (sel) {
9462        case CP0_REG10__ENTRYHI:
9463            gen_helper_mtc0_entryhi(cpu_env, arg);
9464            register_name = "EntryHi";
9465            break;
9466        default:
9467            goto cp0_unimplemented;
9468        }
9469        break;
9470    case CP0_REGISTER_11:
9471        switch (sel) {
9472        case CP0_REG11__COMPARE:
9473            gen_helper_mtc0_compare(cpu_env, arg);
9474            register_name = "Compare";
9475            break;
9476        /* 6,7 are implementation dependent */
9477        default:
9478            goto cp0_unimplemented;
9479        }
9480        /* Stop translation as we may have switched the execution mode */
9481        ctx->base.is_jmp = DISAS_STOP;
9482        break;
9483    case CP0_REGISTER_12:
9484        switch (sel) {
9485        case CP0_REG12__STATUS:
9486            save_cpu_state(ctx, 1);
9487            gen_helper_mtc0_status(cpu_env, arg);
9488            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9489            gen_save_pc(ctx->base.pc_next + 4);
9490            ctx->base.is_jmp = DISAS_EXIT;
9491            register_name = "Status";
9492            break;
9493        case CP0_REG12__INTCTL:
9494            check_insn(ctx, ISA_MIPS32R2);
9495            gen_helper_mtc0_intctl(cpu_env, arg);
9496            /* Stop translation as we may have switched the execution mode */
9497            ctx->base.is_jmp = DISAS_STOP;
9498            register_name = "IntCtl";
9499            break;
9500        case CP0_REG12__SRSCTL:
9501            check_insn(ctx, ISA_MIPS32R2);
9502            gen_helper_mtc0_srsctl(cpu_env, arg);
9503            /* Stop translation as we may have switched the execution mode */
9504            ctx->base.is_jmp = DISAS_STOP;
9505            register_name = "SRSCtl";
9506            break;
9507        case CP0_REG12__SRSMAP:
9508            check_insn(ctx, ISA_MIPS32R2);
9509            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9510            /* Stop translation as we may have switched the execution mode */
9511            ctx->base.is_jmp = DISAS_STOP;
9512            register_name = "SRSMap";
9513            break;
9514        default:
9515            goto cp0_unimplemented;
9516        }
9517        break;
9518    case CP0_REGISTER_13:
9519        switch (sel) {
9520        case CP0_REG13__CAUSE:
9521            save_cpu_state(ctx, 1);
9522            gen_helper_mtc0_cause(cpu_env, arg);
9523            /*
9524             * Stop translation as we may have triggered an interrupt.
9525             * DISAS_STOP isn't sufficient, we need to ensure we break out of
9526             * translated code to check for pending interrupts.
9527             */
9528            gen_save_pc(ctx->base.pc_next + 4);
9529            ctx->base.is_jmp = DISAS_EXIT;
9530            register_name = "Cause";
9531            break;
9532        default:
9533            goto cp0_unimplemented;
9534        }
9535        break;
9536    case CP0_REGISTER_14:
9537        switch (sel) {
9538        case CP0_REG14__EPC:
9539            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9540            register_name = "EPC";
9541            break;
9542        default:
9543            goto cp0_unimplemented;
9544        }
9545        break;
9546    case CP0_REGISTER_15:
9547        switch (sel) {
9548        case CP0_REG15__PRID:
9549            /* ignored */
9550            register_name = "PRid";
9551            break;
9552        case CP0_REG15__EBASE:
9553            check_insn(ctx, ISA_MIPS32R2);
9554            gen_helper_mtc0_ebase(cpu_env, arg);
9555            register_name = "EBase";
9556            break;
9557        default:
9558            goto cp0_unimplemented;
9559        }
9560        break;
9561    case CP0_REGISTER_16:
9562        switch (sel) {
9563        case CP0_REG16__CONFIG:
9564            gen_helper_mtc0_config0(cpu_env, arg);
9565            register_name = "Config";
9566            /* Stop translation as we may have switched the execution mode */
9567            ctx->base.is_jmp = DISAS_STOP;
9568            break;
9569        case CP0_REG16__CONFIG1:
9570            /* ignored, read only */
9571            register_name = "Config1";
9572            break;
9573        case CP0_REG16__CONFIG2:
9574            gen_helper_mtc0_config2(cpu_env, arg);
9575            register_name = "Config2";
9576            /* Stop translation as we may have switched the execution mode */
9577            ctx->base.is_jmp = DISAS_STOP;
9578            break;
9579        case CP0_REG16__CONFIG3:
9580            gen_helper_mtc0_config3(cpu_env, arg);
9581            register_name = "Config3";
9582            /* Stop translation as we may have switched the execution mode */
9583            ctx->base.is_jmp = DISAS_STOP;
9584            break;
9585        case CP0_REG16__CONFIG4:
9586            /* currently ignored */
9587            register_name = "Config4";
9588            break;
9589        case CP0_REG16__CONFIG5:
9590            gen_helper_mtc0_config5(cpu_env, arg);
9591            register_name = "Config5";
9592            /* Stop translation as we may have switched the execution mode */
9593            ctx->base.is_jmp = DISAS_STOP;
9594            break;
9595        /* 6,7 are implementation dependent */
9596        default:
9597            register_name = "Invalid config selector";
9598            goto cp0_unimplemented;
9599        }
9600        break;
9601    case CP0_REGISTER_17:
9602        switch (sel) {
9603        case CP0_REG17__LLADDR:
9604            gen_helper_mtc0_lladdr(cpu_env, arg);
9605            register_name = "LLAddr";
9606            break;
9607        case CP0_REG17__MAAR:
9608            CP0_CHECK(ctx->mrp);
9609            gen_helper_mtc0_maar(cpu_env, arg);
9610            register_name = "MAAR";
9611            break;
9612        case CP0_REG17__MAARI:
9613            CP0_CHECK(ctx->mrp);
9614            gen_helper_mtc0_maari(cpu_env, arg);
9615            register_name = "MAARI";
9616            break;
9617        default:
9618            goto cp0_unimplemented;
9619        }
9620        break;
9621    case CP0_REGISTER_18:
9622        switch (sel) {
9623        case CP0_REG18__WATCHLO0:
9624        case CP0_REG18__WATCHLO1:
9625        case CP0_REG18__WATCHLO2:
9626        case CP0_REG18__WATCHLO3:
9627        case CP0_REG18__WATCHLO4:
9628        case CP0_REG18__WATCHLO5:
9629        case CP0_REG18__WATCHLO6:
9630        case CP0_REG18__WATCHLO7:
9631            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9632            gen_helper_0e1i(mtc0_watchlo, arg, sel);
9633            register_name = "WatchLo";
9634            break;
9635        default:
9636            goto cp0_unimplemented;
9637        }
9638        break;
9639    case CP0_REGISTER_19:
9640        switch (sel) {
9641        case CP0_REG19__WATCHHI0:
9642        case CP0_REG19__WATCHHI1:
9643        case CP0_REG19__WATCHHI2:
9644        case CP0_REG19__WATCHHI3:
9645        case CP0_REG19__WATCHHI4:
9646        case CP0_REG19__WATCHHI5:
9647        case CP0_REG19__WATCHHI6:
9648        case CP0_REG19__WATCHHI7:
9649            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9650            gen_helper_0e1i(mtc0_watchhi, arg, sel);
9651            register_name = "WatchHi";
9652            break;
9653        default:
9654            goto cp0_unimplemented;
9655        }
9656        break;
9657    case CP0_REGISTER_20:
9658        switch (sel) {
9659        case CP0_REG20__XCONTEXT:
9660            check_insn(ctx, ISA_MIPS3);
9661            gen_helper_mtc0_xcontext(cpu_env, arg);
9662            register_name = "XContext";
9663            break;
9664        default:
9665            goto cp0_unimplemented;
9666        }
9667        break;
9668    case CP0_REGISTER_21:
9669       /* Officially reserved, but sel 0 is used for R1x000 framemask */
9670        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9671        switch (sel) {
9672        case 0:
9673            gen_helper_mtc0_framemask(cpu_env, arg);
9674            register_name = "Framemask";
9675            break;
9676        default:
9677            goto cp0_unimplemented;
9678        }
9679        break;
9680    case CP0_REGISTER_22:
9681        /* ignored */
9682        register_name = "Diagnostic"; /* implementation dependent */
9683        break;
9684    case CP0_REGISTER_23:
9685        switch (sel) {
9686        case CP0_REG23__DEBUG:
9687            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9688            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9689            gen_save_pc(ctx->base.pc_next + 4);
9690            ctx->base.is_jmp = DISAS_EXIT;
9691            register_name = "Debug";
9692            break;
9693        case CP0_REG23__TRACECONTROL:
9694            /* PDtrace support */
9695            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
9696            /* Stop translation as we may have switched the execution mode */
9697            ctx->base.is_jmp = DISAS_STOP;
9698            register_name = "TraceControl";
9699            goto cp0_unimplemented;
9700        case CP0_REG23__TRACECONTROL2:
9701            /* PDtrace support */
9702            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9703            /* Stop translation as we may have switched the execution mode */
9704            ctx->base.is_jmp = DISAS_STOP;
9705            register_name = "TraceControl2";
9706            goto cp0_unimplemented;
9707        case CP0_REG23__USERTRACEDATA1:
9708            /* PDtrace support */
9709            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9710            /* Stop translation as we may have switched the execution mode */
9711            ctx->base.is_jmp = DISAS_STOP;
9712            register_name = "UserTraceData1";
9713            goto cp0_unimplemented;
9714        case CP0_REG23__TRACEIBPC:
9715            /* PDtrace support */
9716            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
9717            /* Stop translation as we may have switched the execution mode */
9718            ctx->base.is_jmp = DISAS_STOP;
9719            register_name = "TraceIBPC";
9720            goto cp0_unimplemented;
9721        case CP0_REG23__TRACEDBPC:
9722            /* PDtrace support */
9723            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
9724            /* Stop translation as we may have switched the execution mode */
9725            ctx->base.is_jmp = DISAS_STOP;
9726            register_name = "TraceDBPC";
9727            goto cp0_unimplemented;
9728        default:
9729            goto cp0_unimplemented;
9730        }
9731        break;
9732    case CP0_REGISTER_24:
9733        switch (sel) {
9734        case CP0_REG24__DEPC:
9735            /* EJTAG support */
9736            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9737            register_name = "DEPC";
9738            break;
9739        default:
9740            goto cp0_unimplemented;
9741        }
9742        break;
9743    case CP0_REGISTER_25:
9744        switch (sel) {
9745        case CP0_REG25__PERFCTL0:
9746            gen_helper_mtc0_performance0(cpu_env, arg);
9747            register_name = "Performance0";
9748            break;
9749        case CP0_REG25__PERFCNT0:
9750            /* gen_helper_mtc0_performance1(cpu_env, arg); */
9751            register_name = "Performance1";
9752            goto cp0_unimplemented;
9753        case CP0_REG25__PERFCTL1:
9754            /* gen_helper_mtc0_performance2(cpu_env, arg); */
9755            register_name = "Performance2";
9756            goto cp0_unimplemented;
9757        case CP0_REG25__PERFCNT1:
9758            /* gen_helper_mtc0_performance3(cpu_env, arg); */
9759            register_name = "Performance3";
9760            goto cp0_unimplemented;
9761        case CP0_REG25__PERFCTL2:
9762            /* gen_helper_mtc0_performance4(cpu_env, arg); */
9763            register_name = "Performance4";
9764            goto cp0_unimplemented;
9765        case CP0_REG25__PERFCNT2:
9766            /* gen_helper_mtc0_performance5(cpu_env, arg); */
9767            register_name = "Performance5";
9768            goto cp0_unimplemented;
9769        case CP0_REG25__PERFCTL3:
9770            /* gen_helper_mtc0_performance6(cpu_env, arg); */
9771            register_name = "Performance6";
9772            goto cp0_unimplemented;
9773        case CP0_REG25__PERFCNT3:
9774            /* gen_helper_mtc0_performance7(cpu_env, arg); */
9775            register_name = "Performance7";
9776            goto cp0_unimplemented;
9777        default:
9778            goto cp0_unimplemented;
9779        }
9780        break;
9781    case CP0_REGISTER_26:
9782        switch (sel) {
9783        case CP0_REG26__ERRCTL:
9784            gen_helper_mtc0_errctl(cpu_env, arg);
9785            ctx->base.is_jmp = DISAS_STOP;
9786            register_name = "ErrCtl";
9787            break;
9788        default:
9789            goto cp0_unimplemented;
9790        }
9791        break;
9792    case CP0_REGISTER_27:
9793        switch (sel) {
9794        case CP0_REG27__CACHERR:
9795            /* ignored */
9796            register_name = "CacheErr";
9797            break;
9798        default:
9799            goto cp0_unimplemented;
9800        }
9801        break;
9802    case CP0_REGISTER_28:
9803        switch (sel) {
9804        case CP0_REG28__TAGLO:
9805        case CP0_REG28__TAGLO1:
9806        case CP0_REG28__TAGLO2:
9807        case CP0_REG28__TAGLO3:
9808            gen_helper_mtc0_taglo(cpu_env, arg);
9809            register_name = "TagLo";
9810            break;
9811        case CP0_REG28__DATALO:
9812        case CP0_REG28__DATALO1:
9813        case CP0_REG28__DATALO2:
9814        case CP0_REG28__DATALO3:
9815            gen_helper_mtc0_datalo(cpu_env, arg);
9816            register_name = "DataLo";
9817            break;
9818        default:
9819            goto cp0_unimplemented;
9820        }
9821        break;
9822    case CP0_REGISTER_29:
9823        switch (sel) {
9824        case CP0_REG29__TAGHI:
9825        case CP0_REG29__TAGHI1:
9826        case CP0_REG29__TAGHI2:
9827        case CP0_REG29__TAGHI3:
9828            gen_helper_mtc0_taghi(cpu_env, arg);
9829            register_name = "TagHi";
9830            break;
9831        case CP0_REG29__DATAHI:
9832        case CP0_REG29__DATAHI1:
9833        case CP0_REG29__DATAHI2:
9834        case CP0_REG29__DATAHI3:
9835            gen_helper_mtc0_datahi(cpu_env, arg);
9836            register_name = "DataHi";
9837            break;
9838        default:
9839            register_name = "invalid sel";
9840            goto cp0_unimplemented;
9841        }
9842        break;
9843    case CP0_REGISTER_30:
9844        switch (sel) {
9845        case CP0_REG30__ERROREPC:
9846            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9847            register_name = "ErrorEPC";
9848            break;
9849        default:
9850            goto cp0_unimplemented;
9851        }
9852        break;
9853    case CP0_REGISTER_31:
9854        switch (sel) {
9855        case CP0_REG31__DESAVE:
9856            /* EJTAG support */
9857            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9858            register_name = "DESAVE";
9859            break;
9860        case CP0_REG31__KSCRATCH1:
9861        case CP0_REG31__KSCRATCH2:
9862        case CP0_REG31__KSCRATCH3:
9863        case CP0_REG31__KSCRATCH4:
9864        case CP0_REG31__KSCRATCH5:
9865        case CP0_REG31__KSCRATCH6:
9866            CP0_CHECK(ctx->kscrexist & (1 << sel));
9867            tcg_gen_st_tl(arg, cpu_env,
9868                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
9869            register_name = "KScratch";
9870            break;
9871        default:
9872            goto cp0_unimplemented;
9873        }
9874        break;
9875    default:
9876        goto cp0_unimplemented;
9877    }
9878    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9879
9880    /* For simplicity assume that all writes can cause interrupts.  */
9881    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9882        /*
9883         * DISAS_STOP isn't sufficient, we need to ensure we break out of
9884         * translated code to check for pending interrupts.
9885         */
9886        gen_save_pc(ctx->base.pc_next + 4);
9887        ctx->base.is_jmp = DISAS_EXIT;
9888    }
9889    return;
9890
9891cp0_unimplemented:
9892    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9893                  register_name, reg, sel);
9894}
9895#endif /* TARGET_MIPS64 */
9896
9897static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9898                     int u, int sel, int h)
9899{
9900    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9901    TCGv t0 = tcg_temp_local_new();
9902
9903    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9904        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9905         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9906        tcg_gen_movi_tl(t0, -1);
9907    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9908               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
9909        tcg_gen_movi_tl(t0, -1);
9910    } else if (u == 0) {
9911        switch (rt) {
9912        case 1:
9913            switch (sel) {
9914            case 1:
9915                gen_helper_mftc0_vpecontrol(t0, cpu_env);
9916                break;
9917            case 2:
9918                gen_helper_mftc0_vpeconf0(t0, cpu_env);
9919                break;
9920            default:
9921                goto die;
9922                break;
9923            }
9924            break;
9925        case 2:
9926            switch (sel) {
9927            case 1:
9928                gen_helper_mftc0_tcstatus(t0, cpu_env);
9929                break;
9930            case 2:
9931                gen_helper_mftc0_tcbind(t0, cpu_env);
9932                break;
9933            case 3:
9934                gen_helper_mftc0_tcrestart(t0, cpu_env);
9935                break;
9936            case 4:
9937                gen_helper_mftc0_tchalt(t0, cpu_env);
9938                break;
9939            case 5:
9940                gen_helper_mftc0_tccontext(t0, cpu_env);
9941                break;
9942            case 6:
9943                gen_helper_mftc0_tcschedule(t0, cpu_env);
9944                break;
9945            case 7:
9946                gen_helper_mftc0_tcschefback(t0, cpu_env);
9947                break;
9948            default:
9949                gen_mfc0(ctx, t0, rt, sel);
9950                break;
9951            }
9952            break;
9953        case 10:
9954            switch (sel) {
9955            case 0:
9956                gen_helper_mftc0_entryhi(t0, cpu_env);
9957                break;
9958            default:
9959                gen_mfc0(ctx, t0, rt, sel);
9960                break;
9961            }
9962            break;
9963        case 12:
9964            switch (sel) {
9965            case 0:
9966                gen_helper_mftc0_status(t0, cpu_env);
9967                break;
9968            default:
9969                gen_mfc0(ctx, t0, rt, sel);
9970                break;
9971            }
9972            break;
9973        case 13:
9974            switch (sel) {
9975            case 0:
9976                gen_helper_mftc0_cause(t0, cpu_env);
9977                break;
9978            default:
9979                goto die;
9980                break;
9981            }
9982            break;
9983        case 14:
9984            switch (sel) {
9985            case 0:
9986                gen_helper_mftc0_epc(t0, cpu_env);
9987                break;
9988            default:
9989                goto die;
9990                break;
9991            }
9992            break;
9993        case 15:
9994            switch (sel) {
9995            case 1:
9996                gen_helper_mftc0_ebase(t0, cpu_env);
9997                break;
9998            default:
9999                goto die;
10000                break;
10001            }
10002            break;
10003        case 16:
10004            switch (sel) {
10005            case 0:
10006            case 1:
10007            case 2:
10008            case 3:
10009            case 4:
10010            case 5:
10011            case 6:
10012            case 7:
10013                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
10014                break;
10015            default:
10016                goto die;
10017                break;
10018            }
10019            break;
10020        case 23:
10021            switch (sel) {
10022            case 0:
10023                gen_helper_mftc0_debug(t0, cpu_env);
10024                break;
10025            default:
10026                gen_mfc0(ctx, t0, rt, sel);
10027                break;
10028            }
10029            break;
10030        default:
10031            gen_mfc0(ctx, t0, rt, sel);
10032        }
10033    } else {
10034        switch (sel) {
10035        /* GPR registers. */
10036        case 0:
10037            gen_helper_1e0i(mftgpr, t0, rt);
10038            break;
10039        /* Auxiliary CPU registers */
10040        case 1:
10041            switch (rt) {
10042            case 0:
10043                gen_helper_1e0i(mftlo, t0, 0);
10044                break;
10045            case 1:
10046                gen_helper_1e0i(mfthi, t0, 0);
10047                break;
10048            case 2:
10049                gen_helper_1e0i(mftacx, t0, 0);
10050                break;
10051            case 4:
10052                gen_helper_1e0i(mftlo, t0, 1);
10053                break;
10054            case 5:
10055                gen_helper_1e0i(mfthi, t0, 1);
10056                break;
10057            case 6:
10058                gen_helper_1e0i(mftacx, t0, 1);
10059                break;
10060            case 8:
10061                gen_helper_1e0i(mftlo, t0, 2);
10062                break;
10063            case 9:
10064                gen_helper_1e0i(mfthi, t0, 2);
10065                break;
10066            case 10:
10067                gen_helper_1e0i(mftacx, t0, 2);
10068                break;
10069            case 12:
10070                gen_helper_1e0i(mftlo, t0, 3);
10071                break;
10072            case 13:
10073                gen_helper_1e0i(mfthi, t0, 3);
10074                break;
10075            case 14:
10076                gen_helper_1e0i(mftacx, t0, 3);
10077                break;
10078            case 16:
10079                gen_helper_mftdsp(t0, cpu_env);
10080                break;
10081            default:
10082                goto die;
10083            }
10084            break;
10085        /* Floating point (COP1). */
10086        case 2:
10087            /* XXX: For now we support only a single FPU context. */
10088            if (h == 0) {
10089                TCGv_i32 fp0 = tcg_temp_new_i32();
10090
10091                gen_load_fpr32(ctx, fp0, rt);
10092                tcg_gen_ext_i32_tl(t0, fp0);
10093                tcg_temp_free_i32(fp0);
10094            } else {
10095                TCGv_i32 fp0 = tcg_temp_new_i32();
10096
10097                gen_load_fpr32h(ctx, fp0, rt);
10098                tcg_gen_ext_i32_tl(t0, fp0);
10099                tcg_temp_free_i32(fp0);
10100            }
10101            break;
10102        case 3:
10103            /* XXX: For now we support only a single FPU context. */
10104            gen_helper_1e0i(cfc1, t0, rt);
10105            break;
10106        /* COP2: Not implemented. */
10107        case 4:
10108        case 5:
10109            /* fall through */
10110        default:
10111            goto die;
10112        }
10113    }
10114    trace_mips_translate_tr("mftr", rt, u, sel, h);
10115    gen_store_gpr(t0, rd);
10116    tcg_temp_free(t0);
10117    return;
10118
10119die:
10120    tcg_temp_free(t0);
10121    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
10122    generate_exception_end(ctx, EXCP_RI);
10123}
10124
10125static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
10126                     int u, int sel, int h)
10127{
10128    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
10129    TCGv t0 = tcg_temp_local_new();
10130
10131    gen_load_gpr(t0, rt);
10132    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
10133        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
10134         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
10135        /* NOP */
10136        ;
10137    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
10138             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
10139        /* NOP */
10140        ;
10141    } else if (u == 0) {
10142        switch (rd) {
10143        case 1:
10144            switch (sel) {
10145            case 1:
10146                gen_helper_mttc0_vpecontrol(cpu_env, t0);
10147                break;
10148            case 2:
10149                gen_helper_mttc0_vpeconf0(cpu_env, t0);
10150                break;
10151            default:
10152                goto die;
10153                break;
10154            }
10155            break;
10156        case 2:
10157            switch (sel) {
10158            case 1:
10159                gen_helper_mttc0_tcstatus(cpu_env, t0);
10160                break;
10161            case 2:
10162                gen_helper_mttc0_tcbind(cpu_env, t0);
10163                break;
10164            case 3:
10165                gen_helper_mttc0_tcrestart(cpu_env, t0);
10166                break;
10167            case 4:
10168                gen_helper_mttc0_tchalt(cpu_env, t0);
10169                break;
10170            case 5:
10171                gen_helper_mttc0_tccontext(cpu_env, t0);
10172                break;
10173            case 6:
10174                gen_helper_mttc0_tcschedule(cpu_env, t0);
10175                break;
10176            case 7:
10177                gen_helper_mttc0_tcschefback(cpu_env, t0);
10178                break;
10179            default:
10180                gen_mtc0(ctx, t0, rd, sel);
10181                break;
10182            }
10183            break;
10184        case 10:
10185            switch (sel) {
10186            case 0:
10187                gen_helper_mttc0_entryhi(cpu_env, t0);
10188                break;
10189            default:
10190                gen_mtc0(ctx, t0, rd, sel);
10191                break;
10192            }
10193            break;
10194        case 12:
10195            switch (sel) {
10196            case 0:
10197                gen_helper_mttc0_status(cpu_env, t0);
10198                break;
10199            default:
10200                gen_mtc0(ctx, t0, rd, sel);
10201                break;
10202            }
10203            break;
10204        case 13:
10205            switch (sel) {
10206            case 0:
10207                gen_helper_mttc0_cause(cpu_env, t0);
10208                break;
10209            default:
10210                goto die;
10211                break;
10212            }
10213            break;
10214        case 15:
10215            switch (sel) {
10216            case 1:
10217                gen_helper_mttc0_ebase(cpu_env, t0);
10218                break;
10219            default:
10220                goto die;
10221                break;
10222            }
10223            break;
10224        case 23:
10225            switch (sel) {
10226            case 0:
10227                gen_helper_mttc0_debug(cpu_env, t0);
10228                break;
10229            default:
10230                gen_mtc0(ctx, t0, rd, sel);
10231                break;
10232            }
10233            break;
10234        default:
10235            gen_mtc0(ctx, t0, rd, sel);
10236        }
10237    } else {
10238        switch (sel) {
10239        /* GPR registers. */
10240        case 0:
10241            gen_helper_0e1i(mttgpr, t0, rd);
10242            break;
10243        /* Auxiliary CPU registers */
10244        case 1:
10245            switch (rd) {
10246            case 0:
10247                gen_helper_0e1i(mttlo, t0, 0);
10248                break;
10249            case 1:
10250                gen_helper_0e1i(mtthi, t0, 0);
10251                break;
10252            case 2:
10253                gen_helper_0e1i(mttacx, t0, 0);
10254                break;
10255            case 4:
10256                gen_helper_0e1i(mttlo, t0, 1);
10257                break;
10258            case 5:
10259                gen_helper_0e1i(mtthi, t0, 1);
10260                break;
10261            case 6:
10262                gen_helper_0e1i(mttacx, t0, 1);
10263                break;
10264            case 8:
10265                gen_helper_0e1i(mttlo, t0, 2);
10266                break;
10267            case 9:
10268                gen_helper_0e1i(mtthi, t0, 2);
10269                break;
10270            case 10:
10271                gen_helper_0e1i(mttacx, t0, 2);
10272                break;
10273            case 12:
10274                gen_helper_0e1i(mttlo, t0, 3);
10275                break;
10276            case 13:
10277                gen_helper_0e1i(mtthi, t0, 3);
10278                break;
10279            case 14:
10280                gen_helper_0e1i(mttacx, t0, 3);
10281                break;
10282            case 16:
10283                gen_helper_mttdsp(cpu_env, t0);
10284                break;
10285            default:
10286                goto die;
10287            }
10288            break;
10289        /* Floating point (COP1). */
10290        case 2:
10291            /* XXX: For now we support only a single FPU context. */
10292            if (h == 0) {
10293                TCGv_i32 fp0 = tcg_temp_new_i32();
10294
10295                tcg_gen_trunc_tl_i32(fp0, t0);
10296                gen_store_fpr32(ctx, fp0, rd);
10297                tcg_temp_free_i32(fp0);
10298            } else {
10299                TCGv_i32 fp0 = tcg_temp_new_i32();
10300
10301                tcg_gen_trunc_tl_i32(fp0, t0);
10302                gen_store_fpr32h(ctx, fp0, rd);
10303                tcg_temp_free_i32(fp0);
10304            }
10305            break;
10306        case 3:
10307            /* XXX: For now we support only a single FPU context. */
10308            {
10309                TCGv_i32 fs_tmp = tcg_const_i32(rd);
10310
10311                gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10312                tcg_temp_free_i32(fs_tmp);
10313            }
10314            /* Stop translation as we may have changed hflags */
10315            ctx->base.is_jmp = DISAS_STOP;
10316            break;
10317        /* COP2: Not implemented. */
10318        case 4:
10319        case 5:
10320            /* fall through */
10321        default:
10322            goto die;
10323        }
10324    }
10325    trace_mips_translate_tr("mttr", rd, u, sel, h);
10326    tcg_temp_free(t0);
10327    return;
10328
10329die:
10330    tcg_temp_free(t0);
10331    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10332    generate_exception_end(ctx, EXCP_RI);
10333}
10334
10335static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
10336                    int rt, int rd)
10337{
10338    const char *opn = "ldst";
10339
10340    check_cp0_enabled(ctx);
10341    switch (opc) {
10342    case OPC_MFC0:
10343        if (rt == 0) {
10344            /* Treat as NOP. */
10345            return;
10346        }
10347        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10348        opn = "mfc0";
10349        break;
10350    case OPC_MTC0:
10351        {
10352            TCGv t0 = tcg_temp_new();
10353
10354            gen_load_gpr(t0, rt);
10355            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10356            tcg_temp_free(t0);
10357        }
10358        opn = "mtc0";
10359        break;
10360#if defined(TARGET_MIPS64)
10361    case OPC_DMFC0:
10362        check_insn(ctx, ISA_MIPS3);
10363        if (rt == 0) {
10364            /* Treat as NOP. */
10365            return;
10366        }
10367        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10368        opn = "dmfc0";
10369        break;
10370    case OPC_DMTC0:
10371        check_insn(ctx, ISA_MIPS3);
10372        {
10373            TCGv t0 = tcg_temp_new();
10374
10375            gen_load_gpr(t0, rt);
10376            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10377            tcg_temp_free(t0);
10378        }
10379        opn = "dmtc0";
10380        break;
10381#endif
10382    case OPC_MFHC0:
10383        check_mvh(ctx);
10384        if (rt == 0) {
10385            /* Treat as NOP. */
10386            return;
10387        }
10388        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10389        opn = "mfhc0";
10390        break;
10391    case OPC_MTHC0:
10392        check_mvh(ctx);
10393        {
10394            TCGv t0 = tcg_temp_new();
10395            gen_load_gpr(t0, rt);
10396            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10397            tcg_temp_free(t0);
10398        }
10399        opn = "mthc0";
10400        break;
10401    case OPC_MFTR:
10402        check_cp0_enabled(ctx);
10403        if (rd == 0) {
10404            /* Treat as NOP. */
10405            return;
10406        }
10407        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10408                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10409        opn = "mftr";
10410        break;
10411    case OPC_MTTR:
10412        check_cp0_enabled(ctx);
10413        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10414                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10415        opn = "mttr";
10416        break;
10417    case OPC_TLBWI:
10418        opn = "tlbwi";
10419        if (!env->tlb->helper_tlbwi) {
10420            goto die;
10421        }
10422        gen_helper_tlbwi(cpu_env);
10423        break;
10424    case OPC_TLBINV:
10425        opn = "tlbinv";
10426        if (ctx->ie >= 2) {
10427            if (!env->tlb->helper_tlbinv) {
10428                goto die;
10429            }
10430            gen_helper_tlbinv(cpu_env);
10431        } /* treat as nop if TLBINV not supported */
10432        break;
10433    case OPC_TLBINVF:
10434        opn = "tlbinvf";
10435        if (ctx->ie >= 2) {
10436            if (!env->tlb->helper_tlbinvf) {
10437                goto die;
10438            }
10439            gen_helper_tlbinvf(cpu_env);
10440        } /* treat as nop if TLBINV not supported */
10441        break;
10442    case OPC_TLBWR:
10443        opn = "tlbwr";
10444        if (!env->tlb->helper_tlbwr) {
10445            goto die;
10446        }
10447        gen_helper_tlbwr(cpu_env);
10448        break;
10449    case OPC_TLBP:
10450        opn = "tlbp";
10451        if (!env->tlb->helper_tlbp) {
10452            goto die;
10453        }
10454        gen_helper_tlbp(cpu_env);
10455        break;
10456    case OPC_TLBR:
10457        opn = "tlbr";
10458        if (!env->tlb->helper_tlbr) {
10459            goto die;
10460        }
10461        gen_helper_tlbr(cpu_env);
10462        break;
10463    case OPC_ERET: /* OPC_ERETNC */
10464        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10465            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10466            goto die;
10467        } else {
10468            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10469            if (ctx->opcode & (1 << bit_shift)) {
10470                /* OPC_ERETNC */
10471                opn = "eretnc";
10472                check_insn(ctx, ISA_MIPS32R5);
10473                gen_helper_eretnc(cpu_env);
10474            } else {
10475                /* OPC_ERET */
10476                opn = "eret";
10477                check_insn(ctx, ISA_MIPS2);
10478                gen_helper_eret(cpu_env);
10479            }
10480            ctx->base.is_jmp = DISAS_EXIT;
10481        }
10482        break;
10483    case OPC_DERET:
10484        opn = "deret";
10485        check_insn(ctx, ISA_MIPS32);
10486        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10487            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10488            goto die;
10489        }
10490        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10491            MIPS_INVAL(opn);
10492            generate_exception_end(ctx, EXCP_RI);
10493        } else {
10494            gen_helper_deret(cpu_env);
10495            ctx->base.is_jmp = DISAS_EXIT;
10496        }
10497        break;
10498    case OPC_WAIT:
10499        opn = "wait";
10500        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10501        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10502            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10503            goto die;
10504        }
10505        /* If we get an exception, we want to restart at next instruction */
10506        ctx->base.pc_next += 4;
10507        save_cpu_state(ctx, 1);
10508        ctx->base.pc_next -= 4;
10509        gen_helper_wait(cpu_env);
10510        ctx->base.is_jmp = DISAS_NORETURN;
10511        break;
10512    default:
10513 die:
10514        MIPS_INVAL(opn);
10515        generate_exception_end(ctx, EXCP_RI);
10516        return;
10517    }
10518    (void)opn; /* avoid a compiler warning */
10519}
10520#endif /* !CONFIG_USER_ONLY */
10521
10522/* CP1 Branches (before delay slot) */
10523static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10524                                int32_t cc, int32_t offset)
10525{
10526    target_ulong btarget;
10527    TCGv_i32 t0 = tcg_temp_new_i32();
10528
10529    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10530        generate_exception_end(ctx, EXCP_RI);
10531        goto out;
10532    }
10533
10534    if (cc != 0) {
10535        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10536    }
10537
10538    btarget = ctx->base.pc_next + 4 + offset;
10539
10540    switch (op) {
10541    case OPC_BC1F:
10542        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10543        tcg_gen_not_i32(t0, t0);
10544        tcg_gen_andi_i32(t0, t0, 1);
10545        tcg_gen_extu_i32_tl(bcond, t0);
10546        goto not_likely;
10547    case OPC_BC1FL:
10548        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10549        tcg_gen_not_i32(t0, t0);
10550        tcg_gen_andi_i32(t0, t0, 1);
10551        tcg_gen_extu_i32_tl(bcond, t0);
10552        goto likely;
10553    case OPC_BC1T:
10554        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10555        tcg_gen_andi_i32(t0, t0, 1);
10556        tcg_gen_extu_i32_tl(bcond, t0);
10557        goto not_likely;
10558    case OPC_BC1TL:
10559        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10560        tcg_gen_andi_i32(t0, t0, 1);
10561        tcg_gen_extu_i32_tl(bcond, t0);
10562    likely:
10563        ctx->hflags |= MIPS_HFLAG_BL;
10564        break;
10565    case OPC_BC1FANY2:
10566        {
10567            TCGv_i32 t1 = tcg_temp_new_i32();
10568            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10569            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10570            tcg_gen_nand_i32(t0, t0, t1);
10571            tcg_temp_free_i32(t1);
10572            tcg_gen_andi_i32(t0, t0, 1);
10573            tcg_gen_extu_i32_tl(bcond, t0);
10574        }
10575        goto not_likely;
10576    case OPC_BC1TANY2:
10577        {
10578            TCGv_i32 t1 = tcg_temp_new_i32();
10579            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10580            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10581            tcg_gen_or_i32(t0, t0, t1);
10582            tcg_temp_free_i32(t1);
10583            tcg_gen_andi_i32(t0, t0, 1);
10584            tcg_gen_extu_i32_tl(bcond, t0);
10585        }
10586        goto not_likely;
10587    case OPC_BC1FANY4:
10588        {
10589            TCGv_i32 t1 = tcg_temp_new_i32();
10590            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10591            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10592            tcg_gen_and_i32(t0, t0, t1);
10593            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
10594            tcg_gen_and_i32(t0, t0, t1);
10595            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
10596            tcg_gen_nand_i32(t0, t0, t1);
10597            tcg_temp_free_i32(t1);
10598            tcg_gen_andi_i32(t0, t0, 1);
10599            tcg_gen_extu_i32_tl(bcond, t0);
10600        }
10601        goto not_likely;
10602    case OPC_BC1TANY4:
10603        {
10604            TCGv_i32 t1 = tcg_temp_new_i32();
10605            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10606            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
10607            tcg_gen_or_i32(t0, t0, t1);
10608            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
10609            tcg_gen_or_i32(t0, t0, t1);
10610            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
10611            tcg_gen_or_i32(t0, t0, t1);
10612            tcg_temp_free_i32(t1);
10613            tcg_gen_andi_i32(t0, t0, 1);
10614            tcg_gen_extu_i32_tl(bcond, t0);
10615        }
10616    not_likely:
10617        ctx->hflags |= MIPS_HFLAG_BC;
10618        break;
10619    default:
10620        MIPS_INVAL("cp1 cond branch");
10621        generate_exception_end(ctx, EXCP_RI);
10622        goto out;
10623    }
10624    ctx->btarget = btarget;
10625    ctx->hflags |= MIPS_HFLAG_BDS32;
10626 out:
10627    tcg_temp_free_i32(t0);
10628}
10629
10630/* R6 CP1 Branches */
10631static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10632                                   int32_t ft, int32_t offset,
10633                                   int delayslot_size)
10634{
10635    target_ulong btarget;
10636    TCGv_i64 t0 = tcg_temp_new_i64();
10637
10638    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10639#ifdef MIPS_DEBUG_DISAS
10640        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10641                  "\n", ctx->base.pc_next);
10642#endif
10643        generate_exception_end(ctx, EXCP_RI);
10644        goto out;
10645    }
10646
10647    gen_load_fpr64(ctx, t0, ft);
10648    tcg_gen_andi_i64(t0, t0, 1);
10649
10650    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10651
10652    switch (op) {
10653    case OPC_BC1EQZ:
10654        tcg_gen_xori_i64(t0, t0, 1);
10655        ctx->hflags |= MIPS_HFLAG_BC;
10656        break;
10657    case OPC_BC1NEZ:
10658        /* t0 already set */
10659        ctx->hflags |= MIPS_HFLAG_BC;
10660        break;
10661    default:
10662        MIPS_INVAL("cp1 cond branch");
10663        generate_exception_end(ctx, EXCP_RI);
10664        goto out;
10665    }
10666
10667    tcg_gen_trunc_i64_tl(bcond, t0);
10668
10669    ctx->btarget = btarget;
10670
10671    switch (delayslot_size) {
10672    case 2:
10673        ctx->hflags |= MIPS_HFLAG_BDS16;
10674        break;
10675    case 4:
10676        ctx->hflags |= MIPS_HFLAG_BDS32;
10677        break;
10678    }
10679
10680out:
10681    tcg_temp_free_i64(t0);
10682}
10683
10684/* Coprocessor 1 (FPU) */
10685
10686#define FOP(func, fmt) (((fmt) << 21) | (func))
10687
10688enum fopcode {
10689    OPC_ADD_S = FOP(0, FMT_S),
10690    OPC_SUB_S = FOP(1, FMT_S),
10691    OPC_MUL_S = FOP(2, FMT_S),
10692    OPC_DIV_S = FOP(3, FMT_S),
10693    OPC_SQRT_S = FOP(4, FMT_S),
10694    OPC_ABS_S = FOP(5, FMT_S),
10695    OPC_MOV_S = FOP(6, FMT_S),
10696    OPC_NEG_S = FOP(7, FMT_S),
10697    OPC_ROUND_L_S = FOP(8, FMT_S),
10698    OPC_TRUNC_L_S = FOP(9, FMT_S),
10699    OPC_CEIL_L_S = FOP(10, FMT_S),
10700    OPC_FLOOR_L_S = FOP(11, FMT_S),
10701    OPC_ROUND_W_S = FOP(12, FMT_S),
10702    OPC_TRUNC_W_S = FOP(13, FMT_S),
10703    OPC_CEIL_W_S = FOP(14, FMT_S),
10704    OPC_FLOOR_W_S = FOP(15, FMT_S),
10705    OPC_SEL_S = FOP(16, FMT_S),
10706    OPC_MOVCF_S = FOP(17, FMT_S),
10707    OPC_MOVZ_S = FOP(18, FMT_S),
10708    OPC_MOVN_S = FOP(19, FMT_S),
10709    OPC_SELEQZ_S = FOP(20, FMT_S),
10710    OPC_RECIP_S = FOP(21, FMT_S),
10711    OPC_RSQRT_S = FOP(22, FMT_S),
10712    OPC_SELNEZ_S = FOP(23, FMT_S),
10713    OPC_MADDF_S = FOP(24, FMT_S),
10714    OPC_MSUBF_S = FOP(25, FMT_S),
10715    OPC_RINT_S = FOP(26, FMT_S),
10716    OPC_CLASS_S = FOP(27, FMT_S),
10717    OPC_MIN_S = FOP(28, FMT_S),
10718    OPC_RECIP2_S = FOP(28, FMT_S),
10719    OPC_MINA_S = FOP(29, FMT_S),
10720    OPC_RECIP1_S = FOP(29, FMT_S),
10721    OPC_MAX_S = FOP(30, FMT_S),
10722    OPC_RSQRT1_S = FOP(30, FMT_S),
10723    OPC_MAXA_S = FOP(31, FMT_S),
10724    OPC_RSQRT2_S = FOP(31, FMT_S),
10725    OPC_CVT_D_S = FOP(33, FMT_S),
10726    OPC_CVT_W_S = FOP(36, FMT_S),
10727    OPC_CVT_L_S = FOP(37, FMT_S),
10728    OPC_CVT_PS_S = FOP(38, FMT_S),
10729    OPC_CMP_F_S = FOP(48, FMT_S),
10730    OPC_CMP_UN_S = FOP(49, FMT_S),
10731    OPC_CMP_EQ_S = FOP(50, FMT_S),
10732    OPC_CMP_UEQ_S = FOP(51, FMT_S),
10733    OPC_CMP_OLT_S = FOP(52, FMT_S),
10734    OPC_CMP_ULT_S = FOP(53, FMT_S),
10735    OPC_CMP_OLE_S = FOP(54, FMT_S),
10736    OPC_CMP_ULE_S = FOP(55, FMT_S),
10737    OPC_CMP_SF_S = FOP(56, FMT_S),
10738    OPC_CMP_NGLE_S = FOP(57, FMT_S),
10739    OPC_CMP_SEQ_S = FOP(58, FMT_S),
10740    OPC_CMP_NGL_S = FOP(59, FMT_S),
10741    OPC_CMP_LT_S = FOP(60, FMT_S),
10742    OPC_CMP_NGE_S = FOP(61, FMT_S),
10743    OPC_CMP_LE_S = FOP(62, FMT_S),
10744    OPC_CMP_NGT_S = FOP(63, FMT_S),
10745
10746    OPC_ADD_D = FOP(0, FMT_D),
10747    OPC_SUB_D = FOP(1, FMT_D),
10748    OPC_MUL_D = FOP(2, FMT_D),
10749    OPC_DIV_D = FOP(3, FMT_D),
10750    OPC_SQRT_D = FOP(4, FMT_D),
10751    OPC_ABS_D = FOP(5, FMT_D),
10752    OPC_MOV_D = FOP(6, FMT_D),
10753    OPC_NEG_D = FOP(7, FMT_D),
10754    OPC_ROUND_L_D = FOP(8, FMT_D),
10755    OPC_TRUNC_L_D = FOP(9, FMT_D),
10756    OPC_CEIL_L_D = FOP(10, FMT_D),
10757    OPC_FLOOR_L_D = FOP(11, FMT_D),
10758    OPC_ROUND_W_D = FOP(12, FMT_D),
10759    OPC_TRUNC_W_D = FOP(13, FMT_D),
10760    OPC_CEIL_W_D = FOP(14, FMT_D),
10761    OPC_FLOOR_W_D = FOP(15, FMT_D),
10762    OPC_SEL_D = FOP(16, FMT_D),
10763    OPC_MOVCF_D = FOP(17, FMT_D),
10764    OPC_MOVZ_D = FOP(18, FMT_D),
10765    OPC_MOVN_D = FOP(19, FMT_D),
10766    OPC_SELEQZ_D = FOP(20, FMT_D),
10767    OPC_RECIP_D = FOP(21, FMT_D),
10768    OPC_RSQRT_D = FOP(22, FMT_D),
10769    OPC_SELNEZ_D = FOP(23, FMT_D),
10770    OPC_MADDF_D = FOP(24, FMT_D),
10771    OPC_MSUBF_D = FOP(25, FMT_D),
10772    OPC_RINT_D = FOP(26, FMT_D),
10773    OPC_CLASS_D = FOP(27, FMT_D),
10774    OPC_MIN_D = FOP(28, FMT_D),
10775    OPC_RECIP2_D = FOP(28, FMT_D),
10776    OPC_MINA_D = FOP(29, FMT_D),
10777    OPC_RECIP1_D = FOP(29, FMT_D),
10778    OPC_MAX_D = FOP(30, FMT_D),
10779    OPC_RSQRT1_D = FOP(30, FMT_D),
10780    OPC_MAXA_D = FOP(31, FMT_D),
10781    OPC_RSQRT2_D = FOP(31, FMT_D),
10782    OPC_CVT_S_D = FOP(32, FMT_D),
10783    OPC_CVT_W_D = FOP(36, FMT_D),
10784    OPC_CVT_L_D = FOP(37, FMT_D),
10785    OPC_CMP_F_D = FOP(48, FMT_D),
10786    OPC_CMP_UN_D = FOP(49, FMT_D),
10787    OPC_CMP_EQ_D = FOP(50, FMT_D),
10788    OPC_CMP_UEQ_D = FOP(51, FMT_D),
10789    OPC_CMP_OLT_D = FOP(52, FMT_D),
10790    OPC_CMP_ULT_D = FOP(53, FMT_D),
10791    OPC_CMP_OLE_D = FOP(54, FMT_D),
10792    OPC_CMP_ULE_D = FOP(55, FMT_D),
10793    OPC_CMP_SF_D = FOP(56, FMT_D),
10794    OPC_CMP_NGLE_D = FOP(57, FMT_D),
10795    OPC_CMP_SEQ_D = FOP(58, FMT_D),
10796    OPC_CMP_NGL_D = FOP(59, FMT_D),
10797    OPC_CMP_LT_D = FOP(60, FMT_D),
10798    OPC_CMP_NGE_D = FOP(61, FMT_D),
10799    OPC_CMP_LE_D = FOP(62, FMT_D),
10800    OPC_CMP_NGT_D = FOP(63, FMT_D),
10801
10802    OPC_CVT_S_W = FOP(32, FMT_W),
10803    OPC_CVT_D_W = FOP(33, FMT_W),
10804    OPC_CVT_S_L = FOP(32, FMT_L),
10805    OPC_CVT_D_L = FOP(33, FMT_L),
10806    OPC_CVT_PS_PW = FOP(38, FMT_W),
10807
10808    OPC_ADD_PS = FOP(0, FMT_PS),
10809    OPC_SUB_PS = FOP(1, FMT_PS),
10810    OPC_MUL_PS = FOP(2, FMT_PS),
10811    OPC_DIV_PS = FOP(3, FMT_PS),
10812    OPC_ABS_PS = FOP(5, FMT_PS),
10813    OPC_MOV_PS = FOP(6, FMT_PS),
10814    OPC_NEG_PS = FOP(7, FMT_PS),
10815    OPC_MOVCF_PS = FOP(17, FMT_PS),
10816    OPC_MOVZ_PS = FOP(18, FMT_PS),
10817    OPC_MOVN_PS = FOP(19, FMT_PS),
10818    OPC_ADDR_PS = FOP(24, FMT_PS),
10819    OPC_MULR_PS = FOP(26, FMT_PS),
10820    OPC_RECIP2_PS = FOP(28, FMT_PS),
10821    OPC_RECIP1_PS = FOP(29, FMT_PS),
10822    OPC_RSQRT1_PS = FOP(30, FMT_PS),
10823    OPC_RSQRT2_PS = FOP(31, FMT_PS),
10824
10825    OPC_CVT_S_PU = FOP(32, FMT_PS),
10826    OPC_CVT_PW_PS = FOP(36, FMT_PS),
10827    OPC_CVT_S_PL = FOP(40, FMT_PS),
10828    OPC_PLL_PS = FOP(44, FMT_PS),
10829    OPC_PLU_PS = FOP(45, FMT_PS),
10830    OPC_PUL_PS = FOP(46, FMT_PS),
10831    OPC_PUU_PS = FOP(47, FMT_PS),
10832    OPC_CMP_F_PS = FOP(48, FMT_PS),
10833    OPC_CMP_UN_PS = FOP(49, FMT_PS),
10834    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
10835    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
10836    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
10837    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
10838    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
10839    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
10840    OPC_CMP_SF_PS = FOP(56, FMT_PS),
10841    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
10842    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
10843    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
10844    OPC_CMP_LT_PS = FOP(60, FMT_PS),
10845    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
10846    OPC_CMP_LE_PS = FOP(62, FMT_PS),
10847    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
10848};
10849
10850enum r6_f_cmp_op {
10851    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10852    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10853    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10854    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10855    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10856    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10857    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10858    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10859    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10860    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10861    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10862    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10863    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10864    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10865    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10866    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10867    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10868    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10869    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10870    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10871    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10872    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10873
10874    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10875    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10876    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10877    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10878    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10879    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10880    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10881    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10882    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10883    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10884    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10885    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10886    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10887    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10888    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10889    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10890    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10891    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10892    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10893    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10894    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10895    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10896};
10897
10898static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
10899{
10900    TCGv t0 = tcg_temp_new();
10901
10902    switch (opc) {
10903    case OPC_MFC1:
10904        {
10905            TCGv_i32 fp0 = tcg_temp_new_i32();
10906
10907            gen_load_fpr32(ctx, fp0, fs);
10908            tcg_gen_ext_i32_tl(t0, fp0);
10909            tcg_temp_free_i32(fp0);
10910        }
10911        gen_store_gpr(t0, rt);
10912        break;
10913    case OPC_MTC1:
10914        gen_load_gpr(t0, rt);
10915        {
10916            TCGv_i32 fp0 = tcg_temp_new_i32();
10917
10918            tcg_gen_trunc_tl_i32(fp0, t0);
10919            gen_store_fpr32(ctx, fp0, fs);
10920            tcg_temp_free_i32(fp0);
10921        }
10922        break;
10923    case OPC_CFC1:
10924        gen_helper_1e0i(cfc1, t0, fs);
10925        gen_store_gpr(t0, rt);
10926        break;
10927    case OPC_CTC1:
10928        gen_load_gpr(t0, rt);
10929        save_cpu_state(ctx, 0);
10930        {
10931            TCGv_i32 fs_tmp = tcg_const_i32(fs);
10932
10933            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10934            tcg_temp_free_i32(fs_tmp);
10935        }
10936        /* Stop translation as we may have changed hflags */
10937        ctx->base.is_jmp = DISAS_STOP;
10938        break;
10939#if defined(TARGET_MIPS64)
10940    case OPC_DMFC1:
10941        gen_load_fpr64(ctx, t0, fs);
10942        gen_store_gpr(t0, rt);
10943        break;
10944    case OPC_DMTC1:
10945        gen_load_gpr(t0, rt);
10946        gen_store_fpr64(ctx, t0, fs);
10947        break;
10948#endif
10949    case OPC_MFHC1:
10950        {
10951            TCGv_i32 fp0 = tcg_temp_new_i32();
10952
10953            gen_load_fpr32h(ctx, fp0, fs);
10954            tcg_gen_ext_i32_tl(t0, fp0);
10955            tcg_temp_free_i32(fp0);
10956        }
10957        gen_store_gpr(t0, rt);
10958        break;
10959    case OPC_MTHC1:
10960        gen_load_gpr(t0, rt);
10961        {
10962            TCGv_i32 fp0 = tcg_temp_new_i32();
10963
10964            tcg_gen_trunc_tl_i32(fp0, t0);
10965            gen_store_fpr32h(ctx, fp0, fs);
10966            tcg_temp_free_i32(fp0);
10967        }
10968        break;
10969    default:
10970        MIPS_INVAL("cp1 move");
10971        generate_exception_end(ctx, EXCP_RI);
10972        goto out;
10973    }
10974
10975 out:
10976    tcg_temp_free(t0);
10977}
10978
10979static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
10980{
10981    TCGLabel *l1;
10982    TCGCond cond;
10983    TCGv_i32 t0;
10984
10985    if (rd == 0) {
10986        /* Treat as NOP. */
10987        return;
10988    }
10989
10990    if (tf) {
10991        cond = TCG_COND_EQ;
10992    } else {
10993        cond = TCG_COND_NE;
10994    }
10995
10996    l1 = gen_new_label();
10997    t0 = tcg_temp_new_i32();
10998    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10999    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11000    tcg_temp_free_i32(t0);
11001    if (rs == 0) {
11002        tcg_gen_movi_tl(cpu_gpr[rd], 0);
11003    } else {
11004        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
11005    }
11006    gen_set_label(l1);
11007}
11008
11009static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
11010                               int tf)
11011{
11012    int cond;
11013    TCGv_i32 t0 = tcg_temp_new_i32();
11014    TCGLabel *l1 = gen_new_label();
11015
11016    if (tf) {
11017        cond = TCG_COND_EQ;
11018    } else {
11019        cond = TCG_COND_NE;
11020    }
11021
11022    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11023    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11024    gen_load_fpr32(ctx, t0, fs);
11025    gen_store_fpr32(ctx, t0, fd);
11026    gen_set_label(l1);
11027    tcg_temp_free_i32(t0);
11028}
11029
11030static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
11031                               int tf)
11032{
11033    int cond;
11034    TCGv_i32 t0 = tcg_temp_new_i32();
11035    TCGv_i64 fp0;
11036    TCGLabel *l1 = gen_new_label();
11037
11038    if (tf) {
11039        cond = TCG_COND_EQ;
11040    } else {
11041        cond = TCG_COND_NE;
11042    }
11043
11044    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11045    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11046    tcg_temp_free_i32(t0);
11047    fp0 = tcg_temp_new_i64();
11048    gen_load_fpr64(ctx, fp0, fs);
11049    gen_store_fpr64(ctx, fp0, fd);
11050    tcg_temp_free_i64(fp0);
11051    gen_set_label(l1);
11052}
11053
11054static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
11055                                int cc, int tf)
11056{
11057    int cond;
11058    TCGv_i32 t0 = tcg_temp_new_i32();
11059    TCGLabel *l1 = gen_new_label();
11060    TCGLabel *l2 = gen_new_label();
11061
11062    if (tf) {
11063        cond = TCG_COND_EQ;
11064    } else {
11065        cond = TCG_COND_NE;
11066    }
11067
11068    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
11069    tcg_gen_brcondi_i32(cond, t0, 0, l1);
11070    gen_load_fpr32(ctx, t0, fs);
11071    gen_store_fpr32(ctx, t0, fd);
11072    gen_set_label(l1);
11073
11074    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
11075    tcg_gen_brcondi_i32(cond, t0, 0, l2);
11076    gen_load_fpr32h(ctx, t0, fs);
11077    gen_store_fpr32h(ctx, t0, fd);
11078    tcg_temp_free_i32(t0);
11079    gen_set_label(l2);
11080}
11081
11082static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11083                      int fs)
11084{
11085    TCGv_i32 t1 = tcg_const_i32(0);
11086    TCGv_i32 fp0 = tcg_temp_new_i32();
11087    TCGv_i32 fp1 = tcg_temp_new_i32();
11088    TCGv_i32 fp2 = tcg_temp_new_i32();
11089    gen_load_fpr32(ctx, fp0, fd);
11090    gen_load_fpr32(ctx, fp1, ft);
11091    gen_load_fpr32(ctx, fp2, fs);
11092
11093    switch (op1) {
11094    case OPC_SEL_S:
11095        tcg_gen_andi_i32(fp0, fp0, 1);
11096        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11097        break;
11098    case OPC_SELEQZ_S:
11099        tcg_gen_andi_i32(fp1, fp1, 1);
11100        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11101        break;
11102    case OPC_SELNEZ_S:
11103        tcg_gen_andi_i32(fp1, fp1, 1);
11104        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11105        break;
11106    default:
11107        MIPS_INVAL("gen_sel_s");
11108        generate_exception_end(ctx, EXCP_RI);
11109        break;
11110    }
11111
11112    gen_store_fpr32(ctx, fp0, fd);
11113    tcg_temp_free_i32(fp2);
11114    tcg_temp_free_i32(fp1);
11115    tcg_temp_free_i32(fp0);
11116    tcg_temp_free_i32(t1);
11117}
11118
11119static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
11120                      int fs)
11121{
11122    TCGv_i64 t1 = tcg_const_i64(0);
11123    TCGv_i64 fp0 = tcg_temp_new_i64();
11124    TCGv_i64 fp1 = tcg_temp_new_i64();
11125    TCGv_i64 fp2 = tcg_temp_new_i64();
11126    gen_load_fpr64(ctx, fp0, fd);
11127    gen_load_fpr64(ctx, fp1, ft);
11128    gen_load_fpr64(ctx, fp2, fs);
11129
11130    switch (op1) {
11131    case OPC_SEL_D:
11132        tcg_gen_andi_i64(fp0, fp0, 1);
11133        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
11134        break;
11135    case OPC_SELEQZ_D:
11136        tcg_gen_andi_i64(fp1, fp1, 1);
11137        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
11138        break;
11139    case OPC_SELNEZ_D:
11140        tcg_gen_andi_i64(fp1, fp1, 1);
11141        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
11142        break;
11143    default:
11144        MIPS_INVAL("gen_sel_d");
11145        generate_exception_end(ctx, EXCP_RI);
11146        break;
11147    }
11148
11149    gen_store_fpr64(ctx, fp0, fd);
11150    tcg_temp_free_i64(fp2);
11151    tcg_temp_free_i64(fp1);
11152    tcg_temp_free_i64(fp0);
11153    tcg_temp_free_i64(t1);
11154}
11155
11156static void gen_farith(DisasContext *ctx, enum fopcode op1,
11157                       int ft, int fs, int fd, int cc)
11158{
11159    uint32_t func = ctx->opcode & 0x3f;
11160    switch (op1) {
11161    case OPC_ADD_S:
11162        {
11163            TCGv_i32 fp0 = tcg_temp_new_i32();
11164            TCGv_i32 fp1 = tcg_temp_new_i32();
11165
11166            gen_load_fpr32(ctx, fp0, fs);
11167            gen_load_fpr32(ctx, fp1, ft);
11168            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
11169            tcg_temp_free_i32(fp1);
11170            gen_store_fpr32(ctx, fp0, fd);
11171            tcg_temp_free_i32(fp0);
11172        }
11173        break;
11174    case OPC_SUB_S:
11175        {
11176            TCGv_i32 fp0 = tcg_temp_new_i32();
11177            TCGv_i32 fp1 = tcg_temp_new_i32();
11178
11179            gen_load_fpr32(ctx, fp0, fs);
11180            gen_load_fpr32(ctx, fp1, ft);
11181            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
11182            tcg_temp_free_i32(fp1);
11183            gen_store_fpr32(ctx, fp0, fd);
11184            tcg_temp_free_i32(fp0);
11185        }
11186        break;
11187    case OPC_MUL_S:
11188        {
11189            TCGv_i32 fp0 = tcg_temp_new_i32();
11190            TCGv_i32 fp1 = tcg_temp_new_i32();
11191
11192            gen_load_fpr32(ctx, fp0, fs);
11193            gen_load_fpr32(ctx, fp1, ft);
11194            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
11195            tcg_temp_free_i32(fp1);
11196            gen_store_fpr32(ctx, fp0, fd);
11197            tcg_temp_free_i32(fp0);
11198        }
11199        break;
11200    case OPC_DIV_S:
11201        {
11202            TCGv_i32 fp0 = tcg_temp_new_i32();
11203            TCGv_i32 fp1 = tcg_temp_new_i32();
11204
11205            gen_load_fpr32(ctx, fp0, fs);
11206            gen_load_fpr32(ctx, fp1, ft);
11207            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
11208            tcg_temp_free_i32(fp1);
11209            gen_store_fpr32(ctx, fp0, fd);
11210            tcg_temp_free_i32(fp0);
11211        }
11212        break;
11213    case OPC_SQRT_S:
11214        {
11215            TCGv_i32 fp0 = tcg_temp_new_i32();
11216
11217            gen_load_fpr32(ctx, fp0, fs);
11218            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
11219            gen_store_fpr32(ctx, fp0, fd);
11220            tcg_temp_free_i32(fp0);
11221        }
11222        break;
11223    case OPC_ABS_S:
11224        {
11225            TCGv_i32 fp0 = tcg_temp_new_i32();
11226
11227            gen_load_fpr32(ctx, fp0, fs);
11228            if (ctx->abs2008) {
11229                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11230            } else {
11231                gen_helper_float_abs_s(fp0, fp0);
11232            }
11233            gen_store_fpr32(ctx, fp0, fd);
11234            tcg_temp_free_i32(fp0);
11235        }
11236        break;
11237    case OPC_MOV_S:
11238        {
11239            TCGv_i32 fp0 = tcg_temp_new_i32();
11240
11241            gen_load_fpr32(ctx, fp0, fs);
11242            gen_store_fpr32(ctx, fp0, fd);
11243            tcg_temp_free_i32(fp0);
11244        }
11245        break;
11246    case OPC_NEG_S:
11247        {
11248            TCGv_i32 fp0 = tcg_temp_new_i32();
11249
11250            gen_load_fpr32(ctx, fp0, fs);
11251            if (ctx->abs2008) {
11252                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11253            } else {
11254                gen_helper_float_chs_s(fp0, fp0);
11255            }
11256            gen_store_fpr32(ctx, fp0, fd);
11257            tcg_temp_free_i32(fp0);
11258        }
11259        break;
11260    case OPC_ROUND_L_S:
11261        check_cp1_64bitmode(ctx);
11262        {
11263            TCGv_i32 fp32 = tcg_temp_new_i32();
11264            TCGv_i64 fp64 = tcg_temp_new_i64();
11265
11266            gen_load_fpr32(ctx, fp32, fs);
11267            if (ctx->nan2008) {
11268                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11269            } else {
11270                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11271            }
11272            tcg_temp_free_i32(fp32);
11273            gen_store_fpr64(ctx, fp64, fd);
11274            tcg_temp_free_i64(fp64);
11275        }
11276        break;
11277    case OPC_TRUNC_L_S:
11278        check_cp1_64bitmode(ctx);
11279        {
11280            TCGv_i32 fp32 = tcg_temp_new_i32();
11281            TCGv_i64 fp64 = tcg_temp_new_i64();
11282
11283            gen_load_fpr32(ctx, fp32, fs);
11284            if (ctx->nan2008) {
11285                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11286            } else {
11287                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11288            }
11289            tcg_temp_free_i32(fp32);
11290            gen_store_fpr64(ctx, fp64, fd);
11291            tcg_temp_free_i64(fp64);
11292        }
11293        break;
11294    case OPC_CEIL_L_S:
11295        check_cp1_64bitmode(ctx);
11296        {
11297            TCGv_i32 fp32 = tcg_temp_new_i32();
11298            TCGv_i64 fp64 = tcg_temp_new_i64();
11299
11300            gen_load_fpr32(ctx, fp32, fs);
11301            if (ctx->nan2008) {
11302                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11303            } else {
11304                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11305            }
11306            tcg_temp_free_i32(fp32);
11307            gen_store_fpr64(ctx, fp64, fd);
11308            tcg_temp_free_i64(fp64);
11309        }
11310        break;
11311    case OPC_FLOOR_L_S:
11312        check_cp1_64bitmode(ctx);
11313        {
11314            TCGv_i32 fp32 = tcg_temp_new_i32();
11315            TCGv_i64 fp64 = tcg_temp_new_i64();
11316
11317            gen_load_fpr32(ctx, fp32, fs);
11318            if (ctx->nan2008) {
11319                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11320            } else {
11321                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11322            }
11323            tcg_temp_free_i32(fp32);
11324            gen_store_fpr64(ctx, fp64, fd);
11325            tcg_temp_free_i64(fp64);
11326        }
11327        break;
11328    case OPC_ROUND_W_S:
11329        {
11330            TCGv_i32 fp0 = tcg_temp_new_i32();
11331
11332            gen_load_fpr32(ctx, fp0, fs);
11333            if (ctx->nan2008) {
11334                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11335            } else {
11336                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11337            }
11338            gen_store_fpr32(ctx, fp0, fd);
11339            tcg_temp_free_i32(fp0);
11340        }
11341        break;
11342    case OPC_TRUNC_W_S:
11343        {
11344            TCGv_i32 fp0 = tcg_temp_new_i32();
11345
11346            gen_load_fpr32(ctx, fp0, fs);
11347            if (ctx->nan2008) {
11348                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11349            } else {
11350                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11351            }
11352            gen_store_fpr32(ctx, fp0, fd);
11353            tcg_temp_free_i32(fp0);
11354        }
11355        break;
11356    case OPC_CEIL_W_S:
11357        {
11358            TCGv_i32 fp0 = tcg_temp_new_i32();
11359
11360            gen_load_fpr32(ctx, fp0, fs);
11361            if (ctx->nan2008) {
11362                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11363            } else {
11364                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11365            }
11366            gen_store_fpr32(ctx, fp0, fd);
11367            tcg_temp_free_i32(fp0);
11368        }
11369        break;
11370    case OPC_FLOOR_W_S:
11371        {
11372            TCGv_i32 fp0 = tcg_temp_new_i32();
11373
11374            gen_load_fpr32(ctx, fp0, fs);
11375            if (ctx->nan2008) {
11376                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11377            } else {
11378                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11379            }
11380            gen_store_fpr32(ctx, fp0, fd);
11381            tcg_temp_free_i32(fp0);
11382        }
11383        break;
11384    case OPC_SEL_S:
11385        check_insn(ctx, ISA_MIPS32R6);
11386        gen_sel_s(ctx, op1, fd, ft, fs);
11387        break;
11388    case OPC_SELEQZ_S:
11389        check_insn(ctx, ISA_MIPS32R6);
11390        gen_sel_s(ctx, op1, fd, ft, fs);
11391        break;
11392    case OPC_SELNEZ_S:
11393        check_insn(ctx, ISA_MIPS32R6);
11394        gen_sel_s(ctx, op1, fd, ft, fs);
11395        break;
11396    case OPC_MOVCF_S:
11397        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11398        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11399        break;
11400    case OPC_MOVZ_S:
11401        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11402        {
11403            TCGLabel *l1 = gen_new_label();
11404            TCGv_i32 fp0;
11405
11406            if (ft != 0) {
11407                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11408            }
11409            fp0 = tcg_temp_new_i32();
11410            gen_load_fpr32(ctx, fp0, fs);
11411            gen_store_fpr32(ctx, fp0, fd);
11412            tcg_temp_free_i32(fp0);
11413            gen_set_label(l1);
11414        }
11415        break;
11416    case OPC_MOVN_S:
11417        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11418        {
11419            TCGLabel *l1 = gen_new_label();
11420            TCGv_i32 fp0;
11421
11422            if (ft != 0) {
11423                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11424                fp0 = tcg_temp_new_i32();
11425                gen_load_fpr32(ctx, fp0, fs);
11426                gen_store_fpr32(ctx, fp0, fd);
11427                tcg_temp_free_i32(fp0);
11428                gen_set_label(l1);
11429            }
11430        }
11431        break;
11432    case OPC_RECIP_S:
11433        {
11434            TCGv_i32 fp0 = tcg_temp_new_i32();
11435
11436            gen_load_fpr32(ctx, fp0, fs);
11437            gen_helper_float_recip_s(fp0, cpu_env, fp0);
11438            gen_store_fpr32(ctx, fp0, fd);
11439            tcg_temp_free_i32(fp0);
11440        }
11441        break;
11442    case OPC_RSQRT_S:
11443        {
11444            TCGv_i32 fp0 = tcg_temp_new_i32();
11445
11446            gen_load_fpr32(ctx, fp0, fs);
11447            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11448            gen_store_fpr32(ctx, fp0, fd);
11449            tcg_temp_free_i32(fp0);
11450        }
11451        break;
11452    case OPC_MADDF_S:
11453        check_insn(ctx, ISA_MIPS32R6);
11454        {
11455            TCGv_i32 fp0 = tcg_temp_new_i32();
11456            TCGv_i32 fp1 = tcg_temp_new_i32();
11457            TCGv_i32 fp2 = tcg_temp_new_i32();
11458            gen_load_fpr32(ctx, fp0, fs);
11459            gen_load_fpr32(ctx, fp1, ft);
11460            gen_load_fpr32(ctx, fp2, fd);
11461            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11462            gen_store_fpr32(ctx, fp2, fd);
11463            tcg_temp_free_i32(fp2);
11464            tcg_temp_free_i32(fp1);
11465            tcg_temp_free_i32(fp0);
11466        }
11467        break;
11468    case OPC_MSUBF_S:
11469        check_insn(ctx, ISA_MIPS32R6);
11470        {
11471            TCGv_i32 fp0 = tcg_temp_new_i32();
11472            TCGv_i32 fp1 = tcg_temp_new_i32();
11473            TCGv_i32 fp2 = tcg_temp_new_i32();
11474            gen_load_fpr32(ctx, fp0, fs);
11475            gen_load_fpr32(ctx, fp1, ft);
11476            gen_load_fpr32(ctx, fp2, fd);
11477            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11478            gen_store_fpr32(ctx, fp2, fd);
11479            tcg_temp_free_i32(fp2);
11480            tcg_temp_free_i32(fp1);
11481            tcg_temp_free_i32(fp0);
11482        }
11483        break;
11484    case OPC_RINT_S:
11485        check_insn(ctx, ISA_MIPS32R6);
11486        {
11487            TCGv_i32 fp0 = tcg_temp_new_i32();
11488            gen_load_fpr32(ctx, fp0, fs);
11489            gen_helper_float_rint_s(fp0, cpu_env, fp0);
11490            gen_store_fpr32(ctx, fp0, fd);
11491            tcg_temp_free_i32(fp0);
11492        }
11493        break;
11494    case OPC_CLASS_S:
11495        check_insn(ctx, ISA_MIPS32R6);
11496        {
11497            TCGv_i32 fp0 = tcg_temp_new_i32();
11498            gen_load_fpr32(ctx, fp0, fs);
11499            gen_helper_float_class_s(fp0, cpu_env, fp0);
11500            gen_store_fpr32(ctx, fp0, fd);
11501            tcg_temp_free_i32(fp0);
11502        }
11503        break;
11504    case OPC_MIN_S: /* OPC_RECIP2_S */
11505        if (ctx->insn_flags & ISA_MIPS32R6) {
11506            /* OPC_MIN_S */
11507            TCGv_i32 fp0 = tcg_temp_new_i32();
11508            TCGv_i32 fp1 = tcg_temp_new_i32();
11509            TCGv_i32 fp2 = tcg_temp_new_i32();
11510            gen_load_fpr32(ctx, fp0, fs);
11511            gen_load_fpr32(ctx, fp1, ft);
11512            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11513            gen_store_fpr32(ctx, fp2, fd);
11514            tcg_temp_free_i32(fp2);
11515            tcg_temp_free_i32(fp1);
11516            tcg_temp_free_i32(fp0);
11517        } else {
11518            /* OPC_RECIP2_S */
11519            check_cp1_64bitmode(ctx);
11520            {
11521                TCGv_i32 fp0 = tcg_temp_new_i32();
11522                TCGv_i32 fp1 = tcg_temp_new_i32();
11523
11524                gen_load_fpr32(ctx, fp0, fs);
11525                gen_load_fpr32(ctx, fp1, ft);
11526                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11527                tcg_temp_free_i32(fp1);
11528                gen_store_fpr32(ctx, fp0, fd);
11529                tcg_temp_free_i32(fp0);
11530            }
11531        }
11532        break;
11533    case OPC_MINA_S: /* OPC_RECIP1_S */
11534        if (ctx->insn_flags & ISA_MIPS32R6) {
11535            /* OPC_MINA_S */
11536            TCGv_i32 fp0 = tcg_temp_new_i32();
11537            TCGv_i32 fp1 = tcg_temp_new_i32();
11538            TCGv_i32 fp2 = tcg_temp_new_i32();
11539            gen_load_fpr32(ctx, fp0, fs);
11540            gen_load_fpr32(ctx, fp1, ft);
11541            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11542            gen_store_fpr32(ctx, fp2, fd);
11543            tcg_temp_free_i32(fp2);
11544            tcg_temp_free_i32(fp1);
11545            tcg_temp_free_i32(fp0);
11546        } else {
11547            /* OPC_RECIP1_S */
11548            check_cp1_64bitmode(ctx);
11549            {
11550                TCGv_i32 fp0 = tcg_temp_new_i32();
11551
11552                gen_load_fpr32(ctx, fp0, fs);
11553                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11554                gen_store_fpr32(ctx, fp0, fd);
11555                tcg_temp_free_i32(fp0);
11556            }
11557        }
11558        break;
11559    case OPC_MAX_S: /* OPC_RSQRT1_S */
11560        if (ctx->insn_flags & ISA_MIPS32R6) {
11561            /* OPC_MAX_S */
11562            TCGv_i32 fp0 = tcg_temp_new_i32();
11563            TCGv_i32 fp1 = tcg_temp_new_i32();
11564            gen_load_fpr32(ctx, fp0, fs);
11565            gen_load_fpr32(ctx, fp1, ft);
11566            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11567            gen_store_fpr32(ctx, fp1, fd);
11568            tcg_temp_free_i32(fp1);
11569            tcg_temp_free_i32(fp0);
11570        } else {
11571            /* OPC_RSQRT1_S */
11572            check_cp1_64bitmode(ctx);
11573            {
11574                TCGv_i32 fp0 = tcg_temp_new_i32();
11575
11576                gen_load_fpr32(ctx, fp0, fs);
11577                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11578                gen_store_fpr32(ctx, fp0, fd);
11579                tcg_temp_free_i32(fp0);
11580            }
11581        }
11582        break;
11583    case OPC_MAXA_S: /* OPC_RSQRT2_S */
11584        if (ctx->insn_flags & ISA_MIPS32R6) {
11585            /* OPC_MAXA_S */
11586            TCGv_i32 fp0 = tcg_temp_new_i32();
11587            TCGv_i32 fp1 = tcg_temp_new_i32();
11588            gen_load_fpr32(ctx, fp0, fs);
11589            gen_load_fpr32(ctx, fp1, ft);
11590            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11591            gen_store_fpr32(ctx, fp1, fd);
11592            tcg_temp_free_i32(fp1);
11593            tcg_temp_free_i32(fp0);
11594        } else {
11595            /* OPC_RSQRT2_S */
11596            check_cp1_64bitmode(ctx);
11597            {
11598                TCGv_i32 fp0 = tcg_temp_new_i32();
11599                TCGv_i32 fp1 = tcg_temp_new_i32();
11600
11601                gen_load_fpr32(ctx, fp0, fs);
11602                gen_load_fpr32(ctx, fp1, ft);
11603                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11604                tcg_temp_free_i32(fp1);
11605                gen_store_fpr32(ctx, fp0, fd);
11606                tcg_temp_free_i32(fp0);
11607            }
11608        }
11609        break;
11610    case OPC_CVT_D_S:
11611        check_cp1_registers(ctx, fd);
11612        {
11613            TCGv_i32 fp32 = tcg_temp_new_i32();
11614            TCGv_i64 fp64 = tcg_temp_new_i64();
11615
11616            gen_load_fpr32(ctx, fp32, fs);
11617            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11618            tcg_temp_free_i32(fp32);
11619            gen_store_fpr64(ctx, fp64, fd);
11620            tcg_temp_free_i64(fp64);
11621        }
11622        break;
11623    case OPC_CVT_W_S:
11624        {
11625            TCGv_i32 fp0 = tcg_temp_new_i32();
11626
11627            gen_load_fpr32(ctx, fp0, fs);
11628            if (ctx->nan2008) {
11629                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11630            } else {
11631                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11632            }
11633            gen_store_fpr32(ctx, fp0, fd);
11634            tcg_temp_free_i32(fp0);
11635        }
11636        break;
11637    case OPC_CVT_L_S:
11638        check_cp1_64bitmode(ctx);
11639        {
11640            TCGv_i32 fp32 = tcg_temp_new_i32();
11641            TCGv_i64 fp64 = tcg_temp_new_i64();
11642
11643            gen_load_fpr32(ctx, fp32, fs);
11644            if (ctx->nan2008) {
11645                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11646            } else {
11647                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11648            }
11649            tcg_temp_free_i32(fp32);
11650            gen_store_fpr64(ctx, fp64, fd);
11651            tcg_temp_free_i64(fp64);
11652        }
11653        break;
11654    case OPC_CVT_PS_S:
11655        check_ps(ctx);
11656        {
11657            TCGv_i64 fp64 = tcg_temp_new_i64();
11658            TCGv_i32 fp32_0 = tcg_temp_new_i32();
11659            TCGv_i32 fp32_1 = tcg_temp_new_i32();
11660
11661            gen_load_fpr32(ctx, fp32_0, fs);
11662            gen_load_fpr32(ctx, fp32_1, ft);
11663            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11664            tcg_temp_free_i32(fp32_1);
11665            tcg_temp_free_i32(fp32_0);
11666            gen_store_fpr64(ctx, fp64, fd);
11667            tcg_temp_free_i64(fp64);
11668        }
11669        break;
11670    case OPC_CMP_F_S:
11671    case OPC_CMP_UN_S:
11672    case OPC_CMP_EQ_S:
11673    case OPC_CMP_UEQ_S:
11674    case OPC_CMP_OLT_S:
11675    case OPC_CMP_ULT_S:
11676    case OPC_CMP_OLE_S:
11677    case OPC_CMP_ULE_S:
11678    case OPC_CMP_SF_S:
11679    case OPC_CMP_NGLE_S:
11680    case OPC_CMP_SEQ_S:
11681    case OPC_CMP_NGL_S:
11682    case OPC_CMP_LT_S:
11683    case OPC_CMP_NGE_S:
11684    case OPC_CMP_LE_S:
11685    case OPC_CMP_NGT_S:
11686        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11687        if (ctx->opcode & (1 << 6)) {
11688            gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
11689        } else {
11690            gen_cmp_s(ctx, func - 48, ft, fs, cc);
11691        }
11692        break;
11693    case OPC_ADD_D:
11694        check_cp1_registers(ctx, fs | ft | fd);
11695        {
11696            TCGv_i64 fp0 = tcg_temp_new_i64();
11697            TCGv_i64 fp1 = tcg_temp_new_i64();
11698
11699            gen_load_fpr64(ctx, fp0, fs);
11700            gen_load_fpr64(ctx, fp1, ft);
11701            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11702            tcg_temp_free_i64(fp1);
11703            gen_store_fpr64(ctx, fp0, fd);
11704            tcg_temp_free_i64(fp0);
11705        }
11706        break;
11707    case OPC_SUB_D:
11708        check_cp1_registers(ctx, fs | ft | fd);
11709        {
11710            TCGv_i64 fp0 = tcg_temp_new_i64();
11711            TCGv_i64 fp1 = tcg_temp_new_i64();
11712
11713            gen_load_fpr64(ctx, fp0, fs);
11714            gen_load_fpr64(ctx, fp1, ft);
11715            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11716            tcg_temp_free_i64(fp1);
11717            gen_store_fpr64(ctx, fp0, fd);
11718            tcg_temp_free_i64(fp0);
11719        }
11720        break;
11721    case OPC_MUL_D:
11722        check_cp1_registers(ctx, fs | ft | fd);
11723        {
11724            TCGv_i64 fp0 = tcg_temp_new_i64();
11725            TCGv_i64 fp1 = tcg_temp_new_i64();
11726
11727            gen_load_fpr64(ctx, fp0, fs);
11728            gen_load_fpr64(ctx, fp1, ft);
11729            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11730            tcg_temp_free_i64(fp1);
11731            gen_store_fpr64(ctx, fp0, fd);
11732            tcg_temp_free_i64(fp0);
11733        }
11734        break;
11735    case OPC_DIV_D:
11736        check_cp1_registers(ctx, fs | ft | fd);
11737        {
11738            TCGv_i64 fp0 = tcg_temp_new_i64();
11739            TCGv_i64 fp1 = tcg_temp_new_i64();
11740
11741            gen_load_fpr64(ctx, fp0, fs);
11742            gen_load_fpr64(ctx, fp1, ft);
11743            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11744            tcg_temp_free_i64(fp1);
11745            gen_store_fpr64(ctx, fp0, fd);
11746            tcg_temp_free_i64(fp0);
11747        }
11748        break;
11749    case OPC_SQRT_D:
11750        check_cp1_registers(ctx, fs | fd);
11751        {
11752            TCGv_i64 fp0 = tcg_temp_new_i64();
11753
11754            gen_load_fpr64(ctx, fp0, fs);
11755            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11756            gen_store_fpr64(ctx, fp0, fd);
11757            tcg_temp_free_i64(fp0);
11758        }
11759        break;
11760    case OPC_ABS_D:
11761        check_cp1_registers(ctx, fs | fd);
11762        {
11763            TCGv_i64 fp0 = tcg_temp_new_i64();
11764
11765            gen_load_fpr64(ctx, fp0, fs);
11766            if (ctx->abs2008) {
11767                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11768            } else {
11769                gen_helper_float_abs_d(fp0, fp0);
11770            }
11771            gen_store_fpr64(ctx, fp0, fd);
11772            tcg_temp_free_i64(fp0);
11773        }
11774        break;
11775    case OPC_MOV_D:
11776        check_cp1_registers(ctx, fs | fd);
11777        {
11778            TCGv_i64 fp0 = tcg_temp_new_i64();
11779
11780            gen_load_fpr64(ctx, fp0, fs);
11781            gen_store_fpr64(ctx, fp0, fd);
11782            tcg_temp_free_i64(fp0);
11783        }
11784        break;
11785    case OPC_NEG_D:
11786        check_cp1_registers(ctx, fs | fd);
11787        {
11788            TCGv_i64 fp0 = tcg_temp_new_i64();
11789
11790            gen_load_fpr64(ctx, fp0, fs);
11791            if (ctx->abs2008) {
11792                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11793            } else {
11794                gen_helper_float_chs_d(fp0, fp0);
11795            }
11796            gen_store_fpr64(ctx, fp0, fd);
11797            tcg_temp_free_i64(fp0);
11798        }
11799        break;
11800    case OPC_ROUND_L_D:
11801        check_cp1_64bitmode(ctx);
11802        {
11803            TCGv_i64 fp0 = tcg_temp_new_i64();
11804
11805            gen_load_fpr64(ctx, fp0, fs);
11806            if (ctx->nan2008) {
11807                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11808            } else {
11809                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11810            }
11811            gen_store_fpr64(ctx, fp0, fd);
11812            tcg_temp_free_i64(fp0);
11813        }
11814        break;
11815    case OPC_TRUNC_L_D:
11816        check_cp1_64bitmode(ctx);
11817        {
11818            TCGv_i64 fp0 = tcg_temp_new_i64();
11819
11820            gen_load_fpr64(ctx, fp0, fs);
11821            if (ctx->nan2008) {
11822                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11823            } else {
11824                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11825            }
11826            gen_store_fpr64(ctx, fp0, fd);
11827            tcg_temp_free_i64(fp0);
11828        }
11829        break;
11830    case OPC_CEIL_L_D:
11831        check_cp1_64bitmode(ctx);
11832        {
11833            TCGv_i64 fp0 = tcg_temp_new_i64();
11834
11835            gen_load_fpr64(ctx, fp0, fs);
11836            if (ctx->nan2008) {
11837                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11838            } else {
11839                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11840            }
11841            gen_store_fpr64(ctx, fp0, fd);
11842            tcg_temp_free_i64(fp0);
11843        }
11844        break;
11845    case OPC_FLOOR_L_D:
11846        check_cp1_64bitmode(ctx);
11847        {
11848            TCGv_i64 fp0 = tcg_temp_new_i64();
11849
11850            gen_load_fpr64(ctx, fp0, fs);
11851            if (ctx->nan2008) {
11852                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11853            } else {
11854                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11855            }
11856            gen_store_fpr64(ctx, fp0, fd);
11857            tcg_temp_free_i64(fp0);
11858        }
11859        break;
11860    case OPC_ROUND_W_D:
11861        check_cp1_registers(ctx, fs);
11862        {
11863            TCGv_i32 fp32 = tcg_temp_new_i32();
11864            TCGv_i64 fp64 = tcg_temp_new_i64();
11865
11866            gen_load_fpr64(ctx, fp64, fs);
11867            if (ctx->nan2008) {
11868                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11869            } else {
11870                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11871            }
11872            tcg_temp_free_i64(fp64);
11873            gen_store_fpr32(ctx, fp32, fd);
11874            tcg_temp_free_i32(fp32);
11875        }
11876        break;
11877    case OPC_TRUNC_W_D:
11878        check_cp1_registers(ctx, fs);
11879        {
11880            TCGv_i32 fp32 = tcg_temp_new_i32();
11881            TCGv_i64 fp64 = tcg_temp_new_i64();
11882
11883            gen_load_fpr64(ctx, fp64, fs);
11884            if (ctx->nan2008) {
11885                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11886            } else {
11887                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11888            }
11889            tcg_temp_free_i64(fp64);
11890            gen_store_fpr32(ctx, fp32, fd);
11891            tcg_temp_free_i32(fp32);
11892        }
11893        break;
11894    case OPC_CEIL_W_D:
11895        check_cp1_registers(ctx, fs);
11896        {
11897            TCGv_i32 fp32 = tcg_temp_new_i32();
11898            TCGv_i64 fp64 = tcg_temp_new_i64();
11899
11900            gen_load_fpr64(ctx, fp64, fs);
11901            if (ctx->nan2008) {
11902                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11903            } else {
11904                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11905            }
11906            tcg_temp_free_i64(fp64);
11907            gen_store_fpr32(ctx, fp32, fd);
11908            tcg_temp_free_i32(fp32);
11909        }
11910        break;
11911    case OPC_FLOOR_W_D:
11912        check_cp1_registers(ctx, fs);
11913        {
11914            TCGv_i32 fp32 = tcg_temp_new_i32();
11915            TCGv_i64 fp64 = tcg_temp_new_i64();
11916
11917            gen_load_fpr64(ctx, fp64, fs);
11918            if (ctx->nan2008) {
11919                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11920            } else {
11921                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11922            }
11923            tcg_temp_free_i64(fp64);
11924            gen_store_fpr32(ctx, fp32, fd);
11925            tcg_temp_free_i32(fp32);
11926        }
11927        break;
11928    case OPC_SEL_D:
11929        check_insn(ctx, ISA_MIPS32R6);
11930        gen_sel_d(ctx, op1, fd, ft, fs);
11931        break;
11932    case OPC_SELEQZ_D:
11933        check_insn(ctx, ISA_MIPS32R6);
11934        gen_sel_d(ctx, op1, fd, ft, fs);
11935        break;
11936    case OPC_SELNEZ_D:
11937        check_insn(ctx, ISA_MIPS32R6);
11938        gen_sel_d(ctx, op1, fd, ft, fs);
11939        break;
11940    case OPC_MOVCF_D:
11941        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11942        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11943        break;
11944    case OPC_MOVZ_D:
11945        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11946        {
11947            TCGLabel *l1 = gen_new_label();
11948            TCGv_i64 fp0;
11949
11950            if (ft != 0) {
11951                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11952            }
11953            fp0 = tcg_temp_new_i64();
11954            gen_load_fpr64(ctx, fp0, fs);
11955            gen_store_fpr64(ctx, fp0, fd);
11956            tcg_temp_free_i64(fp0);
11957            gen_set_label(l1);
11958        }
11959        break;
11960    case OPC_MOVN_D:
11961        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11962        {
11963            TCGLabel *l1 = gen_new_label();
11964            TCGv_i64 fp0;
11965
11966            if (ft != 0) {
11967                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11968                fp0 = tcg_temp_new_i64();
11969                gen_load_fpr64(ctx, fp0, fs);
11970                gen_store_fpr64(ctx, fp0, fd);
11971                tcg_temp_free_i64(fp0);
11972                gen_set_label(l1);
11973            }
11974        }
11975        break;
11976    case OPC_RECIP_D:
11977        check_cp1_registers(ctx, fs | fd);
11978        {
11979            TCGv_i64 fp0 = tcg_temp_new_i64();
11980
11981            gen_load_fpr64(ctx, fp0, fs);
11982            gen_helper_float_recip_d(fp0, cpu_env, fp0);
11983            gen_store_fpr64(ctx, fp0, fd);
11984            tcg_temp_free_i64(fp0);
11985        }
11986        break;
11987    case OPC_RSQRT_D:
11988        check_cp1_registers(ctx, fs | fd);
11989        {
11990            TCGv_i64 fp0 = tcg_temp_new_i64();
11991
11992            gen_load_fpr64(ctx, fp0, fs);
11993            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11994            gen_store_fpr64(ctx, fp0, fd);
11995            tcg_temp_free_i64(fp0);
11996        }
11997        break;
11998    case OPC_MADDF_D:
11999        check_insn(ctx, ISA_MIPS32R6);
12000        {
12001            TCGv_i64 fp0 = tcg_temp_new_i64();
12002            TCGv_i64 fp1 = tcg_temp_new_i64();
12003            TCGv_i64 fp2 = tcg_temp_new_i64();
12004            gen_load_fpr64(ctx, fp0, fs);
12005            gen_load_fpr64(ctx, fp1, ft);
12006            gen_load_fpr64(ctx, fp2, fd);
12007            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
12008            gen_store_fpr64(ctx, fp2, fd);
12009            tcg_temp_free_i64(fp2);
12010            tcg_temp_free_i64(fp1);
12011            tcg_temp_free_i64(fp0);
12012        }
12013        break;
12014    case OPC_MSUBF_D:
12015        check_insn(ctx, ISA_MIPS32R6);
12016        {
12017            TCGv_i64 fp0 = tcg_temp_new_i64();
12018            TCGv_i64 fp1 = tcg_temp_new_i64();
12019            TCGv_i64 fp2 = tcg_temp_new_i64();
12020            gen_load_fpr64(ctx, fp0, fs);
12021            gen_load_fpr64(ctx, fp1, ft);
12022            gen_load_fpr64(ctx, fp2, fd);
12023            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
12024            gen_store_fpr64(ctx, fp2, fd);
12025            tcg_temp_free_i64(fp2);
12026            tcg_temp_free_i64(fp1);
12027            tcg_temp_free_i64(fp0);
12028        }
12029        break;
12030    case OPC_RINT_D:
12031        check_insn(ctx, ISA_MIPS32R6);
12032        {
12033            TCGv_i64 fp0 = tcg_temp_new_i64();
12034            gen_load_fpr64(ctx, fp0, fs);
12035            gen_helper_float_rint_d(fp0, cpu_env, fp0);
12036            gen_store_fpr64(ctx, fp0, fd);
12037            tcg_temp_free_i64(fp0);
12038        }
12039        break;
12040    case OPC_CLASS_D:
12041        check_insn(ctx, ISA_MIPS32R6);
12042        {
12043            TCGv_i64 fp0 = tcg_temp_new_i64();
12044            gen_load_fpr64(ctx, fp0, fs);
12045            gen_helper_float_class_d(fp0, cpu_env, fp0);
12046            gen_store_fpr64(ctx, fp0, fd);
12047            tcg_temp_free_i64(fp0);
12048        }
12049        break;
12050    case OPC_MIN_D: /* OPC_RECIP2_D */
12051        if (ctx->insn_flags & ISA_MIPS32R6) {
12052            /* OPC_MIN_D */
12053            TCGv_i64 fp0 = tcg_temp_new_i64();
12054            TCGv_i64 fp1 = tcg_temp_new_i64();
12055            gen_load_fpr64(ctx, fp0, fs);
12056            gen_load_fpr64(ctx, fp1, ft);
12057            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
12058            gen_store_fpr64(ctx, fp1, fd);
12059            tcg_temp_free_i64(fp1);
12060            tcg_temp_free_i64(fp0);
12061        } else {
12062            /* OPC_RECIP2_D */
12063            check_cp1_64bitmode(ctx);
12064            {
12065                TCGv_i64 fp0 = tcg_temp_new_i64();
12066                TCGv_i64 fp1 = tcg_temp_new_i64();
12067
12068                gen_load_fpr64(ctx, fp0, fs);
12069                gen_load_fpr64(ctx, fp1, ft);
12070                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
12071                tcg_temp_free_i64(fp1);
12072                gen_store_fpr64(ctx, fp0, fd);
12073                tcg_temp_free_i64(fp0);
12074            }
12075        }
12076        break;
12077    case OPC_MINA_D: /* OPC_RECIP1_D */
12078        if (ctx->insn_flags & ISA_MIPS32R6) {
12079            /* OPC_MINA_D */
12080            TCGv_i64 fp0 = tcg_temp_new_i64();
12081            TCGv_i64 fp1 = tcg_temp_new_i64();
12082            gen_load_fpr64(ctx, fp0, fs);
12083            gen_load_fpr64(ctx, fp1, ft);
12084            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
12085            gen_store_fpr64(ctx, fp1, fd);
12086            tcg_temp_free_i64(fp1);
12087            tcg_temp_free_i64(fp0);
12088        } else {
12089            /* OPC_RECIP1_D */
12090            check_cp1_64bitmode(ctx);
12091            {
12092                TCGv_i64 fp0 = tcg_temp_new_i64();
12093
12094                gen_load_fpr64(ctx, fp0, fs);
12095                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
12096                gen_store_fpr64(ctx, fp0, fd);
12097                tcg_temp_free_i64(fp0);
12098            }
12099        }
12100        break;
12101    case OPC_MAX_D: /*  OPC_RSQRT1_D */
12102        if (ctx->insn_flags & ISA_MIPS32R6) {
12103            /* OPC_MAX_D */
12104            TCGv_i64 fp0 = tcg_temp_new_i64();
12105            TCGv_i64 fp1 = tcg_temp_new_i64();
12106            gen_load_fpr64(ctx, fp0, fs);
12107            gen_load_fpr64(ctx, fp1, ft);
12108            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
12109            gen_store_fpr64(ctx, fp1, fd);
12110            tcg_temp_free_i64(fp1);
12111            tcg_temp_free_i64(fp0);
12112        } else {
12113            /* OPC_RSQRT1_D */
12114            check_cp1_64bitmode(ctx);
12115            {
12116                TCGv_i64 fp0 = tcg_temp_new_i64();
12117
12118                gen_load_fpr64(ctx, fp0, fs);
12119                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
12120                gen_store_fpr64(ctx, fp0, fd);
12121                tcg_temp_free_i64(fp0);
12122            }
12123        }
12124        break;
12125    case OPC_MAXA_D: /* OPC_RSQRT2_D */
12126        if (ctx->insn_flags & ISA_MIPS32R6) {
12127            /* OPC_MAXA_D */
12128            TCGv_i64 fp0 = tcg_temp_new_i64();
12129            TCGv_i64 fp1 = tcg_temp_new_i64();
12130            gen_load_fpr64(ctx, fp0, fs);
12131            gen_load_fpr64(ctx, fp1, ft);
12132            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
12133            gen_store_fpr64(ctx, fp1, fd);
12134            tcg_temp_free_i64(fp1);
12135            tcg_temp_free_i64(fp0);
12136        } else {
12137            /* OPC_RSQRT2_D */
12138            check_cp1_64bitmode(ctx);
12139            {
12140                TCGv_i64 fp0 = tcg_temp_new_i64();
12141                TCGv_i64 fp1 = tcg_temp_new_i64();
12142
12143                gen_load_fpr64(ctx, fp0, fs);
12144                gen_load_fpr64(ctx, fp1, ft);
12145                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
12146                tcg_temp_free_i64(fp1);
12147                gen_store_fpr64(ctx, fp0, fd);
12148                tcg_temp_free_i64(fp0);
12149            }
12150        }
12151        break;
12152    case OPC_CMP_F_D:
12153    case OPC_CMP_UN_D:
12154    case OPC_CMP_EQ_D:
12155    case OPC_CMP_UEQ_D:
12156    case OPC_CMP_OLT_D:
12157    case OPC_CMP_ULT_D:
12158    case OPC_CMP_OLE_D:
12159    case OPC_CMP_ULE_D:
12160    case OPC_CMP_SF_D:
12161    case OPC_CMP_NGLE_D:
12162    case OPC_CMP_SEQ_D:
12163    case OPC_CMP_NGL_D:
12164    case OPC_CMP_LT_D:
12165    case OPC_CMP_NGE_D:
12166    case OPC_CMP_LE_D:
12167    case OPC_CMP_NGT_D:
12168        check_insn_opc_removed(ctx, ISA_MIPS32R6);
12169        if (ctx->opcode & (1 << 6)) {
12170            gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
12171        } else {
12172            gen_cmp_d(ctx, func - 48, ft, fs, cc);
12173        }
12174        break;
12175    case OPC_CVT_S_D:
12176        check_cp1_registers(ctx, fs);
12177        {
12178            TCGv_i32 fp32 = tcg_temp_new_i32();
12179            TCGv_i64 fp64 = tcg_temp_new_i64();
12180
12181            gen_load_fpr64(ctx, fp64, fs);
12182            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
12183            tcg_temp_free_i64(fp64);
12184            gen_store_fpr32(ctx, fp32, fd);
12185            tcg_temp_free_i32(fp32);
12186        }
12187        break;
12188    case OPC_CVT_W_D:
12189        check_cp1_registers(ctx, fs);
12190        {
12191            TCGv_i32 fp32 = tcg_temp_new_i32();
12192            TCGv_i64 fp64 = tcg_temp_new_i64();
12193
12194            gen_load_fpr64(ctx, fp64, fs);
12195            if (ctx->nan2008) {
12196                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
12197            } else {
12198                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
12199            }
12200            tcg_temp_free_i64(fp64);
12201            gen_store_fpr32(ctx, fp32, fd);
12202            tcg_temp_free_i32(fp32);
12203        }
12204        break;
12205    case OPC_CVT_L_D:
12206        check_cp1_64bitmode(ctx);
12207        {
12208            TCGv_i64 fp0 = tcg_temp_new_i64();
12209
12210            gen_load_fpr64(ctx, fp0, fs);
12211            if (ctx->nan2008) {
12212                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
12213            } else {
12214                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
12215            }
12216            gen_store_fpr64(ctx, fp0, fd);
12217            tcg_temp_free_i64(fp0);
12218        }
12219        break;
12220    case OPC_CVT_S_W:
12221        {
12222            TCGv_i32 fp0 = tcg_temp_new_i32();
12223
12224            gen_load_fpr32(ctx, fp0, fs);
12225            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
12226            gen_store_fpr32(ctx, fp0, fd);
12227            tcg_temp_free_i32(fp0);
12228        }
12229        break;
12230    case OPC_CVT_D_W:
12231        check_cp1_registers(ctx, fd);
12232        {
12233            TCGv_i32 fp32 = tcg_temp_new_i32();
12234            TCGv_i64 fp64 = tcg_temp_new_i64();
12235
12236            gen_load_fpr32(ctx, fp32, fs);
12237            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12238            tcg_temp_free_i32(fp32);
12239            gen_store_fpr64(ctx, fp64, fd);
12240            tcg_temp_free_i64(fp64);
12241        }
12242        break;
12243    case OPC_CVT_S_L:
12244        check_cp1_64bitmode(ctx);
12245        {
12246            TCGv_i32 fp32 = tcg_temp_new_i32();
12247            TCGv_i64 fp64 = tcg_temp_new_i64();
12248
12249            gen_load_fpr64(ctx, fp64, fs);
12250            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12251            tcg_temp_free_i64(fp64);
12252            gen_store_fpr32(ctx, fp32, fd);
12253            tcg_temp_free_i32(fp32);
12254        }
12255        break;
12256    case OPC_CVT_D_L:
12257        check_cp1_64bitmode(ctx);
12258        {
12259            TCGv_i64 fp0 = tcg_temp_new_i64();
12260
12261            gen_load_fpr64(ctx, fp0, fs);
12262            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12263            gen_store_fpr64(ctx, fp0, fd);
12264            tcg_temp_free_i64(fp0);
12265        }
12266        break;
12267    case OPC_CVT_PS_PW:
12268        check_ps(ctx);
12269        {
12270            TCGv_i64 fp0 = tcg_temp_new_i64();
12271
12272            gen_load_fpr64(ctx, fp0, fs);
12273            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12274            gen_store_fpr64(ctx, fp0, fd);
12275            tcg_temp_free_i64(fp0);
12276        }
12277        break;
12278    case OPC_ADD_PS:
12279        check_ps(ctx);
12280        {
12281            TCGv_i64 fp0 = tcg_temp_new_i64();
12282            TCGv_i64 fp1 = tcg_temp_new_i64();
12283
12284            gen_load_fpr64(ctx, fp0, fs);
12285            gen_load_fpr64(ctx, fp1, ft);
12286            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12287            tcg_temp_free_i64(fp1);
12288            gen_store_fpr64(ctx, fp0, fd);
12289            tcg_temp_free_i64(fp0);
12290        }
12291        break;
12292    case OPC_SUB_PS:
12293        check_ps(ctx);
12294        {
12295            TCGv_i64 fp0 = tcg_temp_new_i64();
12296            TCGv_i64 fp1 = tcg_temp_new_i64();
12297
12298            gen_load_fpr64(ctx, fp0, fs);
12299            gen_load_fpr64(ctx, fp1, ft);
12300            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12301            tcg_temp_free_i64(fp1);
12302            gen_store_fpr64(ctx, fp0, fd);
12303            tcg_temp_free_i64(fp0);
12304        }
12305        break;
12306    case OPC_MUL_PS:
12307        check_ps(ctx);
12308        {
12309            TCGv_i64 fp0 = tcg_temp_new_i64();
12310            TCGv_i64 fp1 = tcg_temp_new_i64();
12311
12312            gen_load_fpr64(ctx, fp0, fs);
12313            gen_load_fpr64(ctx, fp1, ft);
12314            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12315            tcg_temp_free_i64(fp1);
12316            gen_store_fpr64(ctx, fp0, fd);
12317            tcg_temp_free_i64(fp0);
12318        }
12319        break;
12320    case OPC_ABS_PS:
12321        check_ps(ctx);
12322        {
12323            TCGv_i64 fp0 = tcg_temp_new_i64();
12324
12325            gen_load_fpr64(ctx, fp0, fs);
12326            gen_helper_float_abs_ps(fp0, fp0);
12327            gen_store_fpr64(ctx, fp0, fd);
12328            tcg_temp_free_i64(fp0);
12329        }
12330        break;
12331    case OPC_MOV_PS:
12332        check_ps(ctx);
12333        {
12334            TCGv_i64 fp0 = tcg_temp_new_i64();
12335
12336            gen_load_fpr64(ctx, fp0, fs);
12337            gen_store_fpr64(ctx, fp0, fd);
12338            tcg_temp_free_i64(fp0);
12339        }
12340        break;
12341    case OPC_NEG_PS:
12342        check_ps(ctx);
12343        {
12344            TCGv_i64 fp0 = tcg_temp_new_i64();
12345
12346            gen_load_fpr64(ctx, fp0, fs);
12347            gen_helper_float_chs_ps(fp0, fp0);
12348            gen_store_fpr64(ctx, fp0, fd);
12349            tcg_temp_free_i64(fp0);
12350        }
12351        break;
12352    case OPC_MOVCF_PS:
12353        check_ps(ctx);
12354        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12355        break;
12356    case OPC_MOVZ_PS:
12357        check_ps(ctx);
12358        {
12359            TCGLabel *l1 = gen_new_label();
12360            TCGv_i64 fp0;
12361
12362            if (ft != 0) {
12363                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12364            }
12365            fp0 = tcg_temp_new_i64();
12366            gen_load_fpr64(ctx, fp0, fs);
12367            gen_store_fpr64(ctx, fp0, fd);
12368            tcg_temp_free_i64(fp0);
12369            gen_set_label(l1);
12370        }
12371        break;
12372    case OPC_MOVN_PS:
12373        check_ps(ctx);
12374        {
12375            TCGLabel *l1 = gen_new_label();
12376            TCGv_i64 fp0;
12377
12378            if (ft != 0) {
12379                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12380                fp0 = tcg_temp_new_i64();
12381                gen_load_fpr64(ctx, fp0, fs);
12382                gen_store_fpr64(ctx, fp0, fd);
12383                tcg_temp_free_i64(fp0);
12384                gen_set_label(l1);
12385            }
12386        }
12387        break;
12388    case OPC_ADDR_PS:
12389        check_ps(ctx);
12390        {
12391            TCGv_i64 fp0 = tcg_temp_new_i64();
12392            TCGv_i64 fp1 = tcg_temp_new_i64();
12393
12394            gen_load_fpr64(ctx, fp0, ft);
12395            gen_load_fpr64(ctx, fp1, fs);
12396            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12397            tcg_temp_free_i64(fp1);
12398            gen_store_fpr64(ctx, fp0, fd);
12399            tcg_temp_free_i64(fp0);
12400        }
12401        break;
12402    case OPC_MULR_PS:
12403        check_ps(ctx);
12404        {
12405            TCGv_i64 fp0 = tcg_temp_new_i64();
12406            TCGv_i64 fp1 = tcg_temp_new_i64();
12407
12408            gen_load_fpr64(ctx, fp0, ft);
12409            gen_load_fpr64(ctx, fp1, fs);
12410            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12411            tcg_temp_free_i64(fp1);
12412            gen_store_fpr64(ctx, fp0, fd);
12413            tcg_temp_free_i64(fp0);
12414        }
12415        break;
12416    case OPC_RECIP2_PS:
12417        check_ps(ctx);
12418        {
12419            TCGv_i64 fp0 = tcg_temp_new_i64();
12420            TCGv_i64 fp1 = tcg_temp_new_i64();
12421
12422            gen_load_fpr64(ctx, fp0, fs);
12423            gen_load_fpr64(ctx, fp1, ft);
12424            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12425            tcg_temp_free_i64(fp1);
12426            gen_store_fpr64(ctx, fp0, fd);
12427            tcg_temp_free_i64(fp0);
12428        }
12429        break;
12430    case OPC_RECIP1_PS:
12431        check_ps(ctx);
12432        {
12433            TCGv_i64 fp0 = tcg_temp_new_i64();
12434
12435            gen_load_fpr64(ctx, fp0, fs);
12436            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12437            gen_store_fpr64(ctx, fp0, fd);
12438            tcg_temp_free_i64(fp0);
12439        }
12440        break;
12441    case OPC_RSQRT1_PS:
12442        check_ps(ctx);
12443        {
12444            TCGv_i64 fp0 = tcg_temp_new_i64();
12445
12446            gen_load_fpr64(ctx, fp0, fs);
12447            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12448            gen_store_fpr64(ctx, fp0, fd);
12449            tcg_temp_free_i64(fp0);
12450        }
12451        break;
12452    case OPC_RSQRT2_PS:
12453        check_ps(ctx);
12454        {
12455            TCGv_i64 fp0 = tcg_temp_new_i64();
12456            TCGv_i64 fp1 = tcg_temp_new_i64();
12457
12458            gen_load_fpr64(ctx, fp0, fs);
12459            gen_load_fpr64(ctx, fp1, ft);
12460            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12461            tcg_temp_free_i64(fp1);
12462            gen_store_fpr64(ctx, fp0, fd);
12463            tcg_temp_free_i64(fp0);
12464        }
12465        break;
12466    case OPC_CVT_S_PU:
12467        check_cp1_64bitmode(ctx);
12468        {
12469            TCGv_i32 fp0 = tcg_temp_new_i32();
12470
12471            gen_load_fpr32h(ctx, fp0, fs);
12472            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12473            gen_store_fpr32(ctx, fp0, fd);
12474            tcg_temp_free_i32(fp0);
12475        }
12476        break;
12477    case OPC_CVT_PW_PS:
12478        check_ps(ctx);
12479        {
12480            TCGv_i64 fp0 = tcg_temp_new_i64();
12481
12482            gen_load_fpr64(ctx, fp0, fs);
12483            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12484            gen_store_fpr64(ctx, fp0, fd);
12485            tcg_temp_free_i64(fp0);
12486        }
12487        break;
12488    case OPC_CVT_S_PL:
12489        check_cp1_64bitmode(ctx);
12490        {
12491            TCGv_i32 fp0 = tcg_temp_new_i32();
12492
12493            gen_load_fpr32(ctx, fp0, fs);
12494            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12495            gen_store_fpr32(ctx, fp0, fd);
12496            tcg_temp_free_i32(fp0);
12497        }
12498        break;
12499    case OPC_PLL_PS:
12500        check_ps(ctx);
12501        {
12502            TCGv_i32 fp0 = tcg_temp_new_i32();
12503            TCGv_i32 fp1 = tcg_temp_new_i32();
12504
12505            gen_load_fpr32(ctx, fp0, fs);
12506            gen_load_fpr32(ctx, fp1, ft);
12507            gen_store_fpr32h(ctx, fp0, fd);
12508            gen_store_fpr32(ctx, fp1, fd);
12509            tcg_temp_free_i32(fp0);
12510            tcg_temp_free_i32(fp1);
12511        }
12512        break;
12513    case OPC_PLU_PS:
12514        check_ps(ctx);
12515        {
12516            TCGv_i32 fp0 = tcg_temp_new_i32();
12517            TCGv_i32 fp1 = tcg_temp_new_i32();
12518
12519            gen_load_fpr32(ctx, fp0, fs);
12520            gen_load_fpr32h(ctx, fp1, ft);
12521            gen_store_fpr32(ctx, fp1, fd);
12522            gen_store_fpr32h(ctx, fp0, fd);
12523            tcg_temp_free_i32(fp0);
12524            tcg_temp_free_i32(fp1);
12525        }
12526        break;
12527    case OPC_PUL_PS:
12528        check_ps(ctx);
12529        {
12530            TCGv_i32 fp0 = tcg_temp_new_i32();
12531            TCGv_i32 fp1 = tcg_temp_new_i32();
12532
12533            gen_load_fpr32h(ctx, fp0, fs);
12534            gen_load_fpr32(ctx, fp1, ft);
12535            gen_store_fpr32(ctx, fp1, fd);
12536            gen_store_fpr32h(ctx, fp0, fd);
12537            tcg_temp_free_i32(fp0);
12538            tcg_temp_free_i32(fp1);
12539        }
12540        break;
12541    case OPC_PUU_PS:
12542        check_ps(ctx);
12543        {
12544            TCGv_i32 fp0 = tcg_temp_new_i32();
12545            TCGv_i32 fp1 = tcg_temp_new_i32();
12546
12547            gen_load_fpr32h(ctx, fp0, fs);
12548            gen_load_fpr32h(ctx, fp1, ft);
12549            gen_store_fpr32(ctx, fp1, fd);
12550            gen_store_fpr32h(ctx, fp0, fd);
12551            tcg_temp_free_i32(fp0);
12552            tcg_temp_free_i32(fp1);
12553        }
12554        break;
12555    case OPC_CMP_F_PS:
12556    case OPC_CMP_UN_PS:
12557    case OPC_CMP_EQ_PS:
12558    case OPC_CMP_UEQ_PS:
12559    case OPC_CMP_OLT_PS:
12560    case OPC_CMP_ULT_PS:
12561    case OPC_CMP_OLE_PS:
12562    case OPC_CMP_ULE_PS:
12563    case OPC_CMP_SF_PS:
12564    case OPC_CMP_NGLE_PS:
12565    case OPC_CMP_SEQ_PS:
12566    case OPC_CMP_NGL_PS:
12567    case OPC_CMP_LT_PS:
12568    case OPC_CMP_NGE_PS:
12569    case OPC_CMP_LE_PS:
12570    case OPC_CMP_NGT_PS:
12571        if (ctx->opcode & (1 << 6)) {
12572            gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
12573        } else {
12574            gen_cmp_ps(ctx, func - 48, ft, fs, cc);
12575        }
12576        break;
12577    default:
12578        MIPS_INVAL("farith");
12579        generate_exception_end(ctx, EXCP_RI);
12580        return;
12581    }
12582}
12583
12584/* Coprocessor 3 (FPU) */
12585static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
12586                          int fd, int fs, int base, int index)
12587{
12588    TCGv t0 = tcg_temp_new();
12589
12590    if (base == 0) {
12591        gen_load_gpr(t0, index);
12592    } else if (index == 0) {
12593        gen_load_gpr(t0, base);
12594    } else {
12595        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12596    }
12597    /*
12598     * Don't do NOP if destination is zero: we must perform the actual
12599     * memory access.
12600     */
12601    switch (opc) {
12602    case OPC_LWXC1:
12603        check_cop1x(ctx);
12604        {
12605            TCGv_i32 fp0 = tcg_temp_new_i32();
12606
12607            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12608            tcg_gen_trunc_tl_i32(fp0, t0);
12609            gen_store_fpr32(ctx, fp0, fd);
12610            tcg_temp_free_i32(fp0);
12611        }
12612        break;
12613    case OPC_LDXC1:
12614        check_cop1x(ctx);
12615        check_cp1_registers(ctx, fd);
12616        {
12617            TCGv_i64 fp0 = tcg_temp_new_i64();
12618            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12619            gen_store_fpr64(ctx, fp0, fd);
12620            tcg_temp_free_i64(fp0);
12621        }
12622        break;
12623    case OPC_LUXC1:
12624        check_cp1_64bitmode(ctx);
12625        tcg_gen_andi_tl(t0, t0, ~0x7);
12626        {
12627            TCGv_i64 fp0 = tcg_temp_new_i64();
12628
12629            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12630            gen_store_fpr64(ctx, fp0, fd);
12631            tcg_temp_free_i64(fp0);
12632        }
12633        break;
12634    case OPC_SWXC1:
12635        check_cop1x(ctx);
12636        {
12637            TCGv_i32 fp0 = tcg_temp_new_i32();
12638            gen_load_fpr32(ctx, fp0, fs);
12639            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12640            tcg_temp_free_i32(fp0);
12641        }
12642        break;
12643    case OPC_SDXC1:
12644        check_cop1x(ctx);
12645        check_cp1_registers(ctx, fs);
12646        {
12647            TCGv_i64 fp0 = tcg_temp_new_i64();
12648            gen_load_fpr64(ctx, fp0, fs);
12649            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12650            tcg_temp_free_i64(fp0);
12651        }
12652        break;
12653    case OPC_SUXC1:
12654        check_cp1_64bitmode(ctx);
12655        tcg_gen_andi_tl(t0, t0, ~0x7);
12656        {
12657            TCGv_i64 fp0 = tcg_temp_new_i64();
12658            gen_load_fpr64(ctx, fp0, fs);
12659            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12660            tcg_temp_free_i64(fp0);
12661        }
12662        break;
12663    }
12664    tcg_temp_free(t0);
12665}
12666
12667static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
12668                           int fd, int fr, int fs, int ft)
12669{
12670    switch (opc) {
12671    case OPC_ALNV_PS:
12672        check_ps(ctx);
12673        {
12674            TCGv t0 = tcg_temp_local_new();
12675            TCGv_i32 fp = tcg_temp_new_i32();
12676            TCGv_i32 fph = tcg_temp_new_i32();
12677            TCGLabel *l1 = gen_new_label();
12678            TCGLabel *l2 = gen_new_label();
12679
12680            gen_load_gpr(t0, fr);
12681            tcg_gen_andi_tl(t0, t0, 0x7);
12682
12683            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12684            gen_load_fpr32(ctx, fp, fs);
12685            gen_load_fpr32h(ctx, fph, fs);
12686            gen_store_fpr32(ctx, fp, fd);
12687            gen_store_fpr32h(ctx, fph, fd);
12688            tcg_gen_br(l2);
12689            gen_set_label(l1);
12690            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12691            tcg_temp_free(t0);
12692#ifdef TARGET_WORDS_BIGENDIAN
12693            gen_load_fpr32(ctx, fp, fs);
12694            gen_load_fpr32h(ctx, fph, ft);
12695            gen_store_fpr32h(ctx, fp, fd);
12696            gen_store_fpr32(ctx, fph, fd);
12697#else
12698            gen_load_fpr32h(ctx, fph, fs);
12699            gen_load_fpr32(ctx, fp, ft);
12700            gen_store_fpr32(ctx, fph, fd);
12701            gen_store_fpr32h(ctx, fp, fd);
12702#endif
12703            gen_set_label(l2);
12704            tcg_temp_free_i32(fp);
12705            tcg_temp_free_i32(fph);
12706        }
12707        break;
12708    case OPC_MADD_S:
12709        check_cop1x(ctx);
12710        {
12711            TCGv_i32 fp0 = tcg_temp_new_i32();
12712            TCGv_i32 fp1 = tcg_temp_new_i32();
12713            TCGv_i32 fp2 = tcg_temp_new_i32();
12714
12715            gen_load_fpr32(ctx, fp0, fs);
12716            gen_load_fpr32(ctx, fp1, ft);
12717            gen_load_fpr32(ctx, fp2, fr);
12718            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12719            tcg_temp_free_i32(fp0);
12720            tcg_temp_free_i32(fp1);
12721            gen_store_fpr32(ctx, fp2, fd);
12722            tcg_temp_free_i32(fp2);
12723        }
12724        break;
12725    case OPC_MADD_D:
12726        check_cop1x(ctx);
12727        check_cp1_registers(ctx, fd | fs | ft | fr);
12728        {
12729            TCGv_i64 fp0 = tcg_temp_new_i64();
12730            TCGv_i64 fp1 = tcg_temp_new_i64();
12731            TCGv_i64 fp2 = tcg_temp_new_i64();
12732
12733            gen_load_fpr64(ctx, fp0, fs);
12734            gen_load_fpr64(ctx, fp1, ft);
12735            gen_load_fpr64(ctx, fp2, fr);
12736            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12737            tcg_temp_free_i64(fp0);
12738            tcg_temp_free_i64(fp1);
12739            gen_store_fpr64(ctx, fp2, fd);
12740            tcg_temp_free_i64(fp2);
12741        }
12742        break;
12743    case OPC_MADD_PS:
12744        check_ps(ctx);
12745        {
12746            TCGv_i64 fp0 = tcg_temp_new_i64();
12747            TCGv_i64 fp1 = tcg_temp_new_i64();
12748            TCGv_i64 fp2 = tcg_temp_new_i64();
12749
12750            gen_load_fpr64(ctx, fp0, fs);
12751            gen_load_fpr64(ctx, fp1, ft);
12752            gen_load_fpr64(ctx, fp2, fr);
12753            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12754            tcg_temp_free_i64(fp0);
12755            tcg_temp_free_i64(fp1);
12756            gen_store_fpr64(ctx, fp2, fd);
12757            tcg_temp_free_i64(fp2);
12758        }
12759        break;
12760    case OPC_MSUB_S:
12761        check_cop1x(ctx);
12762        {
12763            TCGv_i32 fp0 = tcg_temp_new_i32();
12764            TCGv_i32 fp1 = tcg_temp_new_i32();
12765            TCGv_i32 fp2 = tcg_temp_new_i32();
12766
12767            gen_load_fpr32(ctx, fp0, fs);
12768            gen_load_fpr32(ctx, fp1, ft);
12769            gen_load_fpr32(ctx, fp2, fr);
12770            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12771            tcg_temp_free_i32(fp0);
12772            tcg_temp_free_i32(fp1);
12773            gen_store_fpr32(ctx, fp2, fd);
12774            tcg_temp_free_i32(fp2);
12775        }
12776        break;
12777    case OPC_MSUB_D:
12778        check_cop1x(ctx);
12779        check_cp1_registers(ctx, fd | fs | ft | fr);
12780        {
12781            TCGv_i64 fp0 = tcg_temp_new_i64();
12782            TCGv_i64 fp1 = tcg_temp_new_i64();
12783            TCGv_i64 fp2 = tcg_temp_new_i64();
12784
12785            gen_load_fpr64(ctx, fp0, fs);
12786            gen_load_fpr64(ctx, fp1, ft);
12787            gen_load_fpr64(ctx, fp2, fr);
12788            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12789            tcg_temp_free_i64(fp0);
12790            tcg_temp_free_i64(fp1);
12791            gen_store_fpr64(ctx, fp2, fd);
12792            tcg_temp_free_i64(fp2);
12793        }
12794        break;
12795    case OPC_MSUB_PS:
12796        check_ps(ctx);
12797        {
12798            TCGv_i64 fp0 = tcg_temp_new_i64();
12799            TCGv_i64 fp1 = tcg_temp_new_i64();
12800            TCGv_i64 fp2 = tcg_temp_new_i64();
12801
12802            gen_load_fpr64(ctx, fp0, fs);
12803            gen_load_fpr64(ctx, fp1, ft);
12804            gen_load_fpr64(ctx, fp2, fr);
12805            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12806            tcg_temp_free_i64(fp0);
12807            tcg_temp_free_i64(fp1);
12808            gen_store_fpr64(ctx, fp2, fd);
12809            tcg_temp_free_i64(fp2);
12810        }
12811        break;
12812    case OPC_NMADD_S:
12813        check_cop1x(ctx);
12814        {
12815            TCGv_i32 fp0 = tcg_temp_new_i32();
12816            TCGv_i32 fp1 = tcg_temp_new_i32();
12817            TCGv_i32 fp2 = tcg_temp_new_i32();
12818
12819            gen_load_fpr32(ctx, fp0, fs);
12820            gen_load_fpr32(ctx, fp1, ft);
12821            gen_load_fpr32(ctx, fp2, fr);
12822            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12823            tcg_temp_free_i32(fp0);
12824            tcg_temp_free_i32(fp1);
12825            gen_store_fpr32(ctx, fp2, fd);
12826            tcg_temp_free_i32(fp2);
12827        }
12828        break;
12829    case OPC_NMADD_D:
12830        check_cop1x(ctx);
12831        check_cp1_registers(ctx, fd | fs | ft | fr);
12832        {
12833            TCGv_i64 fp0 = tcg_temp_new_i64();
12834            TCGv_i64 fp1 = tcg_temp_new_i64();
12835            TCGv_i64 fp2 = tcg_temp_new_i64();
12836
12837            gen_load_fpr64(ctx, fp0, fs);
12838            gen_load_fpr64(ctx, fp1, ft);
12839            gen_load_fpr64(ctx, fp2, fr);
12840            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12841            tcg_temp_free_i64(fp0);
12842            tcg_temp_free_i64(fp1);
12843            gen_store_fpr64(ctx, fp2, fd);
12844            tcg_temp_free_i64(fp2);
12845        }
12846        break;
12847    case OPC_NMADD_PS:
12848        check_ps(ctx);
12849        {
12850            TCGv_i64 fp0 = tcg_temp_new_i64();
12851            TCGv_i64 fp1 = tcg_temp_new_i64();
12852            TCGv_i64 fp2 = tcg_temp_new_i64();
12853
12854            gen_load_fpr64(ctx, fp0, fs);
12855            gen_load_fpr64(ctx, fp1, ft);
12856            gen_load_fpr64(ctx, fp2, fr);
12857            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12858            tcg_temp_free_i64(fp0);
12859            tcg_temp_free_i64(fp1);
12860            gen_store_fpr64(ctx, fp2, fd);
12861            tcg_temp_free_i64(fp2);
12862        }
12863        break;
12864    case OPC_NMSUB_S:
12865        check_cop1x(ctx);
12866        {
12867            TCGv_i32 fp0 = tcg_temp_new_i32();
12868            TCGv_i32 fp1 = tcg_temp_new_i32();
12869            TCGv_i32 fp2 = tcg_temp_new_i32();
12870
12871            gen_load_fpr32(ctx, fp0, fs);
12872            gen_load_fpr32(ctx, fp1, ft);
12873            gen_load_fpr32(ctx, fp2, fr);
12874            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12875            tcg_temp_free_i32(fp0);
12876            tcg_temp_free_i32(fp1);
12877            gen_store_fpr32(ctx, fp2, fd);
12878            tcg_temp_free_i32(fp2);
12879        }
12880        break;
12881    case OPC_NMSUB_D:
12882        check_cop1x(ctx);
12883        check_cp1_registers(ctx, fd | fs | ft | fr);
12884        {
12885            TCGv_i64 fp0 = tcg_temp_new_i64();
12886            TCGv_i64 fp1 = tcg_temp_new_i64();
12887            TCGv_i64 fp2 = tcg_temp_new_i64();
12888
12889            gen_load_fpr64(ctx, fp0, fs);
12890            gen_load_fpr64(ctx, fp1, ft);
12891            gen_load_fpr64(ctx, fp2, fr);
12892            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12893            tcg_temp_free_i64(fp0);
12894            tcg_temp_free_i64(fp1);
12895            gen_store_fpr64(ctx, fp2, fd);
12896            tcg_temp_free_i64(fp2);
12897        }
12898        break;
12899    case OPC_NMSUB_PS:
12900        check_ps(ctx);
12901        {
12902            TCGv_i64 fp0 = tcg_temp_new_i64();
12903            TCGv_i64 fp1 = tcg_temp_new_i64();
12904            TCGv_i64 fp2 = tcg_temp_new_i64();
12905
12906            gen_load_fpr64(ctx, fp0, fs);
12907            gen_load_fpr64(ctx, fp1, ft);
12908            gen_load_fpr64(ctx, fp2, fr);
12909            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12910            tcg_temp_free_i64(fp0);
12911            tcg_temp_free_i64(fp1);
12912            gen_store_fpr64(ctx, fp2, fd);
12913            tcg_temp_free_i64(fp2);
12914        }
12915        break;
12916    default:
12917        MIPS_INVAL("flt3_arith");
12918        generate_exception_end(ctx, EXCP_RI);
12919        return;
12920    }
12921}
12922
12923static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12924{
12925    TCGv t0;
12926
12927#if !defined(CONFIG_USER_ONLY)
12928    /*
12929     * The Linux kernel will emulate rdhwr if it's not supported natively.
12930     * Therefore only check the ISA in system mode.
12931     */
12932    check_insn(ctx, ISA_MIPS32R2);
12933#endif
12934    t0 = tcg_temp_new();
12935
12936    switch (rd) {
12937    case 0:
12938        gen_helper_rdhwr_cpunum(t0, cpu_env);
12939        gen_store_gpr(t0, rt);
12940        break;
12941    case 1:
12942        gen_helper_rdhwr_synci_step(t0, cpu_env);
12943        gen_store_gpr(t0, rt);
12944        break;
12945    case 2:
12946        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12947            gen_io_start();
12948        }
12949        gen_helper_rdhwr_cc(t0, cpu_env);
12950        gen_store_gpr(t0, rt);
12951        /*
12952         * Break the TB to be able to take timer interrupts immediately
12953         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12954         * we break completely out of translated code.
12955         */
12956        gen_save_pc(ctx->base.pc_next + 4);
12957        ctx->base.is_jmp = DISAS_EXIT;
12958        break;
12959    case 3:
12960        gen_helper_rdhwr_ccres(t0, cpu_env);
12961        gen_store_gpr(t0, rt);
12962        break;
12963    case 4:
12964        check_insn(ctx, ISA_MIPS32R6);
12965        if (sel != 0) {
12966            /*
12967             * Performance counter registers are not implemented other than
12968             * control register 0.
12969             */
12970            generate_exception(ctx, EXCP_RI);
12971        }
12972        gen_helper_rdhwr_performance(t0, cpu_env);
12973        gen_store_gpr(t0, rt);
12974        break;
12975    case 5:
12976        check_insn(ctx, ISA_MIPS32R6);
12977        gen_helper_rdhwr_xnp(t0, cpu_env);
12978        gen_store_gpr(t0, rt);
12979        break;
12980    case 29:
12981#if defined(CONFIG_USER_ONLY)
12982        tcg_gen_ld_tl(t0, cpu_env,
12983                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12984        gen_store_gpr(t0, rt);
12985        break;
12986#else
12987        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12988            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12989            tcg_gen_ld_tl(t0, cpu_env,
12990                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12991            gen_store_gpr(t0, rt);
12992        } else {
12993            generate_exception_end(ctx, EXCP_RI);
12994        }
12995        break;
12996#endif
12997    default:            /* Invalid */
12998        MIPS_INVAL("rdhwr");
12999        generate_exception_end(ctx, EXCP_RI);
13000        break;
13001    }
13002    tcg_temp_free(t0);
13003}
13004
13005static inline void clear_branch_hflags(DisasContext *ctx)
13006{
13007    ctx->hflags &= ~MIPS_HFLAG_BMASK;
13008    if (ctx->base.is_jmp == DISAS_NEXT) {
13009        save_cpu_state(ctx, 0);
13010    } else {
13011        /*
13012         * It is not safe to save ctx->hflags as hflags may be changed
13013         * in execution time by the instruction in delay / forbidden slot.
13014         */
13015        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
13016    }
13017}
13018
13019static void gen_branch(DisasContext *ctx, int insn_bytes)
13020{
13021    if (ctx->hflags & MIPS_HFLAG_BMASK) {
13022        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
13023        /* Branches completion */
13024        clear_branch_hflags(ctx);
13025        ctx->base.is_jmp = DISAS_NORETURN;
13026        /* FIXME: Need to clear can_do_io.  */
13027        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
13028        case MIPS_HFLAG_FBNSLOT:
13029            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
13030            break;
13031        case MIPS_HFLAG_B:
13032            /* unconditional branch */
13033            if (proc_hflags & MIPS_HFLAG_BX) {
13034                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
13035            }
13036            gen_goto_tb(ctx, 0, ctx->btarget);
13037            break;
13038        case MIPS_HFLAG_BL:
13039            /* blikely taken case */
13040            gen_goto_tb(ctx, 0, ctx->btarget);
13041            break;
13042        case MIPS_HFLAG_BC:
13043            /* Conditional branch */
13044            {
13045                TCGLabel *l1 = gen_new_label();
13046
13047                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
13048                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
13049                gen_set_label(l1);
13050                gen_goto_tb(ctx, 0, ctx->btarget);
13051            }
13052            break;
13053        case MIPS_HFLAG_BR:
13054            /* unconditional branch to register */
13055            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
13056                TCGv t0 = tcg_temp_new();
13057                TCGv_i32 t1 = tcg_temp_new_i32();
13058
13059                tcg_gen_andi_tl(t0, btarget, 0x1);
13060                tcg_gen_trunc_tl_i32(t1, t0);
13061                tcg_temp_free(t0);
13062                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
13063                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
13064                tcg_gen_or_i32(hflags, hflags, t1);
13065                tcg_temp_free_i32(t1);
13066
13067                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
13068            } else {
13069                tcg_gen_mov_tl(cpu_PC, btarget);
13070            }
13071            if (ctx->base.singlestep_enabled) {
13072                save_cpu_state(ctx, 0);
13073                gen_helper_raise_exception_debug(cpu_env);
13074            }
13075            tcg_gen_lookup_and_goto_ptr();
13076            break;
13077        default:
13078            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
13079            abort();
13080        }
13081    }
13082}
13083
13084/* Compact Branches */
13085static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
13086                                       int rs, int rt, int32_t offset)
13087{
13088    int bcond_compute = 0;
13089    TCGv t0 = tcg_temp_new();
13090    TCGv t1 = tcg_temp_new();
13091    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
13092
13093    if (ctx->hflags & MIPS_HFLAG_BMASK) {
13094#ifdef MIPS_DEBUG_DISAS
13095        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13096                  "\n", ctx->base.pc_next);
13097#endif
13098        generate_exception_end(ctx, EXCP_RI);
13099        goto out;
13100    }
13101
13102    /* Load needed operands and calculate btarget */
13103    switch (opc) {
13104    /* compact branch */
13105    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13106    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13107        gen_load_gpr(t0, rs);
13108        gen_load_gpr(t1, rt);
13109        bcond_compute = 1;
13110        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13111        if (rs <= rt && rs == 0) {
13112            /* OPC_BEQZALC, OPC_BNEZALC */
13113            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13114        }
13115        break;
13116    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13117    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13118        gen_load_gpr(t0, rs);
13119        gen_load_gpr(t1, rt);
13120        bcond_compute = 1;
13121        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13122        break;
13123    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13124    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13125        if (rs == 0 || rs == rt) {
13126            /* OPC_BLEZALC, OPC_BGEZALC */
13127            /* OPC_BGTZALC, OPC_BLTZALC */
13128            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13129        }
13130        gen_load_gpr(t0, rs);
13131        gen_load_gpr(t1, rt);
13132        bcond_compute = 1;
13133        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13134        break;
13135    case OPC_BC:
13136    case OPC_BALC:
13137        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13138        break;
13139    case OPC_BEQZC:
13140    case OPC_BNEZC:
13141        if (rs != 0) {
13142            /* OPC_BEQZC, OPC_BNEZC */
13143            gen_load_gpr(t0, rs);
13144            bcond_compute = 1;
13145            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
13146        } else {
13147            /* OPC_JIC, OPC_JIALC */
13148            TCGv tbase = tcg_temp_new();
13149            TCGv toffset = tcg_temp_new();
13150
13151            gen_load_gpr(tbase, rt);
13152            tcg_gen_movi_tl(toffset, offset);
13153            gen_op_addr_add(ctx, btarget, tbase, toffset);
13154            tcg_temp_free(tbase);
13155            tcg_temp_free(toffset);
13156        }
13157        break;
13158    default:
13159        MIPS_INVAL("Compact branch/jump");
13160        generate_exception_end(ctx, EXCP_RI);
13161        goto out;
13162    }
13163
13164    if (bcond_compute == 0) {
13165        /* Uncoditional compact branch */
13166        switch (opc) {
13167        case OPC_JIALC:
13168            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13169            /* Fallthrough */
13170        case OPC_JIC:
13171            ctx->hflags |= MIPS_HFLAG_BR;
13172            break;
13173        case OPC_BALC:
13174            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
13175            /* Fallthrough */
13176        case OPC_BC:
13177            ctx->hflags |= MIPS_HFLAG_B;
13178            break;
13179        default:
13180            MIPS_INVAL("Compact branch/jump");
13181            generate_exception_end(ctx, EXCP_RI);
13182            goto out;
13183        }
13184
13185        /* Generating branch here as compact branches don't have delay slot */
13186        gen_branch(ctx, 4);
13187    } else {
13188        /* Conditional compact branch */
13189        TCGLabel *fs = gen_new_label();
13190        save_cpu_state(ctx, 0);
13191
13192        switch (opc) {
13193        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
13194            if (rs == 0 && rt != 0) {
13195                /* OPC_BLEZALC */
13196                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13197            } else if (rs != 0 && rt != 0 && rs == rt) {
13198                /* OPC_BGEZALC */
13199                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13200            } else {
13201                /* OPC_BGEUC */
13202                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
13203            }
13204            break;
13205        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
13206            if (rs == 0 && rt != 0) {
13207                /* OPC_BGTZALC */
13208                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13209            } else if (rs != 0 && rt != 0 && rs == rt) {
13210                /* OPC_BLTZALC */
13211                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13212            } else {
13213                /* OPC_BLTUC */
13214                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
13215            }
13216            break;
13217        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
13218            if (rs == 0 && rt != 0) {
13219                /* OPC_BLEZC */
13220                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
13221            } else if (rs != 0 && rt != 0 && rs == rt) {
13222                /* OPC_BGEZC */
13223                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
13224            } else {
13225                /* OPC_BGEC */
13226                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
13227            }
13228            break;
13229        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
13230            if (rs == 0 && rt != 0) {
13231                /* OPC_BGTZC */
13232                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
13233            } else if (rs != 0 && rt != 0 && rs == rt) {
13234                /* OPC_BLTZC */
13235                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13236            } else {
13237                /* OPC_BLTC */
13238                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13239            }
13240            break;
13241        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13242        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13243            if (rs >= rt) {
13244                /* OPC_BOVC, OPC_BNVC */
13245                TCGv t2 = tcg_temp_new();
13246                TCGv t3 = tcg_temp_new();
13247                TCGv t4 = tcg_temp_new();
13248                TCGv input_overflow = tcg_temp_new();
13249
13250                gen_load_gpr(t0, rs);
13251                gen_load_gpr(t1, rt);
13252                tcg_gen_ext32s_tl(t2, t0);
13253                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13254                tcg_gen_ext32s_tl(t3, t1);
13255                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13256                tcg_gen_or_tl(input_overflow, input_overflow, t4);
13257
13258                tcg_gen_add_tl(t4, t2, t3);
13259                tcg_gen_ext32s_tl(t4, t4);
13260                tcg_gen_xor_tl(t2, t2, t3);
13261                tcg_gen_xor_tl(t3, t4, t3);
13262                tcg_gen_andc_tl(t2, t3, t2);
13263                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13264                tcg_gen_or_tl(t4, t4, input_overflow);
13265                if (opc == OPC_BOVC) {
13266                    /* OPC_BOVC */
13267                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13268                } else {
13269                    /* OPC_BNVC */
13270                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13271                }
13272                tcg_temp_free(input_overflow);
13273                tcg_temp_free(t4);
13274                tcg_temp_free(t3);
13275                tcg_temp_free(t2);
13276            } else if (rs < rt && rs == 0) {
13277                /* OPC_BEQZALC, OPC_BNEZALC */
13278                if (opc == OPC_BEQZALC) {
13279                    /* OPC_BEQZALC */
13280                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13281                } else {
13282                    /* OPC_BNEZALC */
13283                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13284                }
13285            } else {
13286                /* OPC_BEQC, OPC_BNEC */
13287                if (opc == OPC_BEQC) {
13288                    /* OPC_BEQC */
13289                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13290                } else {
13291                    /* OPC_BNEC */
13292                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13293                }
13294            }
13295            break;
13296        case OPC_BEQZC:
13297            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13298            break;
13299        case OPC_BNEZC:
13300            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13301            break;
13302        default:
13303            MIPS_INVAL("Compact conditional branch/jump");
13304            generate_exception_end(ctx, EXCP_RI);
13305            goto out;
13306        }
13307
13308        /* Generating branch here as compact branches don't have delay slot */
13309        gen_goto_tb(ctx, 1, ctx->btarget);
13310        gen_set_label(fs);
13311
13312        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13313    }
13314
13315out:
13316    tcg_temp_free(t0);
13317    tcg_temp_free(t1);
13318}
13319
13320/* ISA extensions (ASEs) */
13321/* MIPS16 extension to MIPS32 */
13322
13323/* MIPS16 major opcodes */
13324enum {
13325  M16_OPC_ADDIUSP = 0x00,
13326  M16_OPC_ADDIUPC = 0x01,
13327  M16_OPC_B = 0x02,
13328  M16_OPC_JAL = 0x03,
13329  M16_OPC_BEQZ = 0x04,
13330  M16_OPC_BNEQZ = 0x05,
13331  M16_OPC_SHIFT = 0x06,
13332  M16_OPC_LD = 0x07,
13333  M16_OPC_RRIA = 0x08,
13334  M16_OPC_ADDIU8 = 0x09,
13335  M16_OPC_SLTI = 0x0a,
13336  M16_OPC_SLTIU = 0x0b,
13337  M16_OPC_I8 = 0x0c,
13338  M16_OPC_LI = 0x0d,
13339  M16_OPC_CMPI = 0x0e,
13340  M16_OPC_SD = 0x0f,
13341  M16_OPC_LB = 0x10,
13342  M16_OPC_LH = 0x11,
13343  M16_OPC_LWSP = 0x12,
13344  M16_OPC_LW = 0x13,
13345  M16_OPC_LBU = 0x14,
13346  M16_OPC_LHU = 0x15,
13347  M16_OPC_LWPC = 0x16,
13348  M16_OPC_LWU = 0x17,
13349  M16_OPC_SB = 0x18,
13350  M16_OPC_SH = 0x19,
13351  M16_OPC_SWSP = 0x1a,
13352  M16_OPC_SW = 0x1b,
13353  M16_OPC_RRR = 0x1c,
13354  M16_OPC_RR = 0x1d,
13355  M16_OPC_EXTEND = 0x1e,
13356  M16_OPC_I64 = 0x1f
13357};
13358
13359/* I8 funct field */
13360enum {
13361  I8_BTEQZ = 0x0,
13362  I8_BTNEZ = 0x1,
13363  I8_SWRASP = 0x2,
13364  I8_ADJSP = 0x3,
13365  I8_SVRS = 0x4,
13366  I8_MOV32R = 0x5,
13367  I8_MOVR32 = 0x7
13368};
13369
13370/* RRR f field */
13371enum {
13372  RRR_DADDU = 0x0,
13373  RRR_ADDU = 0x1,
13374  RRR_DSUBU = 0x2,
13375  RRR_SUBU = 0x3
13376};
13377
13378/* RR funct field */
13379enum {
13380  RR_JR = 0x00,
13381  RR_SDBBP = 0x01,
13382  RR_SLT = 0x02,
13383  RR_SLTU = 0x03,
13384  RR_SLLV = 0x04,
13385  RR_BREAK = 0x05,
13386  RR_SRLV = 0x06,
13387  RR_SRAV = 0x07,
13388  RR_DSRL = 0x08,
13389  RR_CMP = 0x0a,
13390  RR_NEG = 0x0b,
13391  RR_AND = 0x0c,
13392  RR_OR = 0x0d,
13393  RR_XOR = 0x0e,
13394  RR_NOT = 0x0f,
13395  RR_MFHI = 0x10,
13396  RR_CNVT = 0x11,
13397  RR_MFLO = 0x12,
13398  RR_DSRA = 0x13,
13399  RR_DSLLV = 0x14,
13400  RR_DSRLV = 0x16,
13401  RR_DSRAV = 0x17,
13402  RR_MULT = 0x18,
13403  RR_MULTU = 0x19,
13404  RR_DIV = 0x1a,
13405  RR_DIVU = 0x1b,
13406  RR_DMULT = 0x1c,
13407  RR_DMULTU = 0x1d,
13408  RR_DDIV = 0x1e,
13409  RR_DDIVU = 0x1f
13410};
13411
13412/* I64 funct field */
13413enum {
13414  I64_LDSP = 0x0,
13415  I64_SDSP = 0x1,
13416  I64_SDRASP = 0x2,
13417  I64_DADJSP = 0x3,
13418  I64_LDPC = 0x4,
13419  I64_DADDIU5 = 0x5,
13420  I64_DADDIUPC = 0x6,
13421  I64_DADDIUSP = 0x7
13422};
13423
13424/* RR ry field for CNVT */
13425enum {
13426  RR_RY_CNVT_ZEB = 0x0,
13427  RR_RY_CNVT_ZEH = 0x1,
13428  RR_RY_CNVT_ZEW = 0x2,
13429  RR_RY_CNVT_SEB = 0x4,
13430  RR_RY_CNVT_SEH = 0x5,
13431  RR_RY_CNVT_SEW = 0x6,
13432};
13433
13434static int xlat(int r)
13435{
13436  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13437
13438  return map[r];
13439}
13440
13441static void gen_mips16_save(DisasContext *ctx,
13442                            int xsregs, int aregs,
13443                            int do_ra, int do_s0, int do_s1,
13444                            int framesize)
13445{
13446    TCGv t0 = tcg_temp_new();
13447    TCGv t1 = tcg_temp_new();
13448    TCGv t2 = tcg_temp_new();
13449    int args, astatic;
13450
13451    switch (aregs) {
13452    case 0:
13453    case 1:
13454    case 2:
13455    case 3:
13456    case 11:
13457        args = 0;
13458        break;
13459    case 4:
13460    case 5:
13461    case 6:
13462    case 7:
13463        args = 1;
13464        break;
13465    case 8:
13466    case 9:
13467    case 10:
13468        args = 2;
13469        break;
13470    case 12:
13471    case 13:
13472        args = 3;
13473        break;
13474    case 14:
13475        args = 4;
13476        break;
13477    default:
13478        generate_exception_end(ctx, EXCP_RI);
13479        return;
13480    }
13481
13482    switch (args) {
13483    case 4:
13484        gen_base_offset_addr(ctx, t0, 29, 12);
13485        gen_load_gpr(t1, 7);
13486        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13487        /* Fall through */
13488    case 3:
13489        gen_base_offset_addr(ctx, t0, 29, 8);
13490        gen_load_gpr(t1, 6);
13491        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13492        /* Fall through */
13493    case 2:
13494        gen_base_offset_addr(ctx, t0, 29, 4);
13495        gen_load_gpr(t1, 5);
13496        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13497        /* Fall through */
13498    case 1:
13499        gen_base_offset_addr(ctx, t0, 29, 0);
13500        gen_load_gpr(t1, 4);
13501        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13502    }
13503
13504    gen_load_gpr(t0, 29);
13505
13506#define DECR_AND_STORE(reg) do {                                 \
13507        tcg_gen_movi_tl(t2, -4);                                 \
13508        gen_op_addr_add(ctx, t0, t0, t2);                        \
13509        gen_load_gpr(t1, reg);                                   \
13510        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13511    } while (0)
13512
13513    if (do_ra) {
13514        DECR_AND_STORE(31);
13515    }
13516
13517    switch (xsregs) {
13518    case 7:
13519        DECR_AND_STORE(30);
13520        /* Fall through */
13521    case 6:
13522        DECR_AND_STORE(23);
13523        /* Fall through */
13524    case 5:
13525        DECR_AND_STORE(22);
13526        /* Fall through */
13527    case 4:
13528        DECR_AND_STORE(21);
13529        /* Fall through */
13530    case 3:
13531        DECR_AND_STORE(20);
13532        /* Fall through */
13533    case 2:
13534        DECR_AND_STORE(19);
13535        /* Fall through */
13536    case 1:
13537        DECR_AND_STORE(18);
13538    }
13539
13540    if (do_s1) {
13541        DECR_AND_STORE(17);
13542    }
13543    if (do_s0) {
13544        DECR_AND_STORE(16);
13545    }
13546
13547    switch (aregs) {
13548    case 0:
13549    case 4:
13550    case 8:
13551    case 12:
13552    case 14:
13553        astatic = 0;
13554        break;
13555    case 1:
13556    case 5:
13557    case 9:
13558    case 13:
13559        astatic = 1;
13560        break;
13561    case 2:
13562    case 6:
13563    case 10:
13564        astatic = 2;
13565        break;
13566    case 3:
13567    case 7:
13568        astatic = 3;
13569        break;
13570    case 11:
13571        astatic = 4;
13572        break;
13573    default:
13574        generate_exception_end(ctx, EXCP_RI);
13575        return;
13576    }
13577
13578    if (astatic > 0) {
13579        DECR_AND_STORE(7);
13580        if (astatic > 1) {
13581            DECR_AND_STORE(6);
13582            if (astatic > 2) {
13583                DECR_AND_STORE(5);
13584                if (astatic > 3) {
13585                    DECR_AND_STORE(4);
13586                }
13587            }
13588        }
13589    }
13590#undef DECR_AND_STORE
13591
13592    tcg_gen_movi_tl(t2, -framesize);
13593    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13594    tcg_temp_free(t0);
13595    tcg_temp_free(t1);
13596    tcg_temp_free(t2);
13597}
13598
13599static void gen_mips16_restore(DisasContext *ctx,
13600                               int xsregs, int aregs,
13601                               int do_ra, int do_s0, int do_s1,
13602                               int framesize)
13603{
13604    int astatic;
13605    TCGv t0 = tcg_temp_new();
13606    TCGv t1 = tcg_temp_new();
13607    TCGv t2 = tcg_temp_new();
13608
13609    tcg_gen_movi_tl(t2, framesize);
13610    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13611
13612#define DECR_AND_LOAD(reg) do {                            \
13613        tcg_gen_movi_tl(t2, -4);                           \
13614        gen_op_addr_add(ctx, t0, t0, t2);                  \
13615        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13616        gen_store_gpr(t1, reg);                            \
13617    } while (0)
13618
13619    if (do_ra) {
13620        DECR_AND_LOAD(31);
13621    }
13622
13623    switch (xsregs) {
13624    case 7:
13625        DECR_AND_LOAD(30);
13626        /* Fall through */
13627    case 6:
13628        DECR_AND_LOAD(23);
13629        /* Fall through */
13630    case 5:
13631        DECR_AND_LOAD(22);
13632        /* Fall through */
13633    case 4:
13634        DECR_AND_LOAD(21);
13635        /* Fall through */
13636    case 3:
13637        DECR_AND_LOAD(20);
13638        /* Fall through */
13639    case 2:
13640        DECR_AND_LOAD(19);
13641        /* Fall through */
13642    case 1:
13643        DECR_AND_LOAD(18);
13644    }
13645
13646    if (do_s1) {
13647        DECR_AND_LOAD(17);
13648    }
13649    if (do_s0) {
13650        DECR_AND_LOAD(16);
13651    }
13652
13653    switch (aregs) {
13654    case 0:
13655    case 4:
13656    case 8:
13657    case 12:
13658    case 14:
13659        astatic = 0;
13660        break;
13661    case 1:
13662    case 5:
13663    case 9:
13664    case 13:
13665        astatic = 1;
13666        break;
13667    case 2:
13668    case 6:
13669    case 10:
13670        astatic = 2;
13671        break;
13672    case 3:
13673    case 7:
13674        astatic = 3;
13675        break;
13676    case 11:
13677        astatic = 4;
13678        break;
13679    default:
13680        generate_exception_end(ctx, EXCP_RI);
13681        return;
13682    }
13683
13684    if (astatic > 0) {
13685        DECR_AND_LOAD(7);
13686        if (astatic > 1) {
13687            DECR_AND_LOAD(6);
13688            if (astatic > 2) {
13689                DECR_AND_LOAD(5);
13690                if (astatic > 3) {
13691                    DECR_AND_LOAD(4);
13692                }
13693            }
13694        }
13695    }
13696#undef DECR_AND_LOAD
13697
13698    tcg_gen_movi_tl(t2, framesize);
13699    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13700    tcg_temp_free(t0);
13701    tcg_temp_free(t1);
13702    tcg_temp_free(t2);
13703}
13704
13705static void gen_addiupc(DisasContext *ctx, int rx, int imm,
13706                        int is_64_bit, int extended)
13707{
13708    TCGv t0;
13709
13710    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13711        generate_exception_end(ctx, EXCP_RI);
13712        return;
13713    }
13714
13715    t0 = tcg_temp_new();
13716
13717    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13718    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13719    if (!is_64_bit) {
13720        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13721    }
13722
13723    tcg_temp_free(t0);
13724}
13725
13726static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13727                                int16_t offset)
13728{
13729    TCGv_i32 t0 = tcg_const_i32(op);
13730    TCGv t1 = tcg_temp_new();
13731    gen_base_offset_addr(ctx, t1, base, offset);
13732    gen_helper_cache(cpu_env, t1, t0);
13733}
13734
13735#if defined(TARGET_MIPS64)
13736static void decode_i64_mips16(DisasContext *ctx,
13737                              int ry, int funct, int16_t offset,
13738                              int extended)
13739{
13740    switch (funct) {
13741    case I64_LDSP:
13742        check_insn(ctx, ISA_MIPS3);
13743        check_mips_64(ctx);
13744        offset = extended ? offset : offset << 3;
13745        gen_ld(ctx, OPC_LD, ry, 29, offset);
13746        break;
13747    case I64_SDSP:
13748        check_insn(ctx, ISA_MIPS3);
13749        check_mips_64(ctx);
13750        offset = extended ? offset : offset << 3;
13751        gen_st(ctx, OPC_SD, ry, 29, offset);
13752        break;
13753    case I64_SDRASP:
13754        check_insn(ctx, ISA_MIPS3);
13755        check_mips_64(ctx);
13756        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13757        gen_st(ctx, OPC_SD, 31, 29, offset);
13758        break;
13759    case I64_DADJSP:
13760        check_insn(ctx, ISA_MIPS3);
13761        check_mips_64(ctx);
13762        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13763        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13764        break;
13765    case I64_LDPC:
13766        check_insn(ctx, ISA_MIPS3);
13767        check_mips_64(ctx);
13768        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13769            generate_exception_end(ctx, EXCP_RI);
13770        } else {
13771            offset = extended ? offset : offset << 3;
13772            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13773        }
13774        break;
13775    case I64_DADDIU5:
13776        check_insn(ctx, ISA_MIPS3);
13777        check_mips_64(ctx);
13778        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13779        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13780        break;
13781    case I64_DADDIUPC:
13782        check_insn(ctx, ISA_MIPS3);
13783        check_mips_64(ctx);
13784        offset = extended ? offset : offset << 2;
13785        gen_addiupc(ctx, ry, offset, 1, extended);
13786        break;
13787    case I64_DADDIUSP:
13788        check_insn(ctx, ISA_MIPS3);
13789        check_mips_64(ctx);
13790        offset = extended ? offset : offset << 2;
13791        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13792        break;
13793    }
13794}
13795#endif
13796
13797static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13798{
13799    int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13800    int op, rx, ry, funct, sa;
13801    int16_t imm, offset;
13802
13803    ctx->opcode = (ctx->opcode << 16) | extend;
13804    op = (ctx->opcode >> 11) & 0x1f;
13805    sa = (ctx->opcode >> 22) & 0x1f;
13806    funct = (ctx->opcode >> 8) & 0x7;
13807    rx = xlat((ctx->opcode >> 8) & 0x7);
13808    ry = xlat((ctx->opcode >> 5) & 0x7);
13809    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13810                              | ((ctx->opcode >> 21) & 0x3f) << 5
13811                              | (ctx->opcode & 0x1f));
13812
13813    /*
13814     * The extended opcodes cleverly reuse the opcodes from their 16-bit
13815     * counterparts.
13816     */
13817    switch (op) {
13818    case M16_OPC_ADDIUSP:
13819        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13820        break;
13821    case M16_OPC_ADDIUPC:
13822        gen_addiupc(ctx, rx, imm, 0, 1);
13823        break;
13824    case M16_OPC_B:
13825        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13826        /* No delay slot, so just process as a normal instruction */
13827        break;
13828    case M16_OPC_BEQZ:
13829        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13830        /* No delay slot, so just process as a normal instruction */
13831        break;
13832    case M16_OPC_BNEQZ:
13833        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13834        /* No delay slot, so just process as a normal instruction */
13835        break;
13836    case M16_OPC_SHIFT:
13837        switch (ctx->opcode & 0x3) {
13838        case 0x0:
13839            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13840            break;
13841        case 0x1:
13842#if defined(TARGET_MIPS64)
13843            check_mips_64(ctx);
13844            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13845#else
13846            generate_exception_end(ctx, EXCP_RI);
13847#endif
13848            break;
13849        case 0x2:
13850            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13851            break;
13852        case 0x3:
13853            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13854            break;
13855        }
13856        break;
13857#if defined(TARGET_MIPS64)
13858    case M16_OPC_LD:
13859        check_insn(ctx, ISA_MIPS3);
13860        check_mips_64(ctx);
13861        gen_ld(ctx, OPC_LD, ry, rx, offset);
13862        break;
13863#endif
13864    case M16_OPC_RRIA:
13865        imm = ctx->opcode & 0xf;
13866        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13867        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13868        imm = (int16_t) (imm << 1) >> 1;
13869        if ((ctx->opcode >> 4) & 0x1) {
13870#if defined(TARGET_MIPS64)
13871            check_mips_64(ctx);
13872            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13873#else
13874            generate_exception_end(ctx, EXCP_RI);
13875#endif
13876        } else {
13877            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13878        }
13879        break;
13880    case M16_OPC_ADDIU8:
13881        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13882        break;
13883    case M16_OPC_SLTI:
13884        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13885        break;
13886    case M16_OPC_SLTIU:
13887        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13888        break;
13889    case M16_OPC_I8:
13890        switch (funct) {
13891        case I8_BTEQZ:
13892            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13893            break;
13894        case I8_BTNEZ:
13895            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13896            break;
13897        case I8_SWRASP:
13898            gen_st(ctx, OPC_SW, 31, 29, imm);
13899            break;
13900        case I8_ADJSP:
13901            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13902            break;
13903        case I8_SVRS:
13904            check_insn(ctx, ISA_MIPS32);
13905            {
13906                int xsregs = (ctx->opcode >> 24) & 0x7;
13907                int aregs = (ctx->opcode >> 16) & 0xf;
13908                int do_ra = (ctx->opcode >> 6) & 0x1;
13909                int do_s0 = (ctx->opcode >> 5) & 0x1;
13910                int do_s1 = (ctx->opcode >> 4) & 0x1;
13911                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13912                                 | (ctx->opcode & 0xf)) << 3;
13913
13914                if (ctx->opcode & (1 << 7)) {
13915                    gen_mips16_save(ctx, xsregs, aregs,
13916                                    do_ra, do_s0, do_s1,
13917                                    framesize);
13918                } else {
13919                    gen_mips16_restore(ctx, xsregs, aregs,
13920                                       do_ra, do_s0, do_s1,
13921                                       framesize);
13922                }
13923            }
13924            break;
13925        default:
13926            generate_exception_end(ctx, EXCP_RI);
13927            break;
13928        }
13929        break;
13930    case M16_OPC_LI:
13931        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13932        break;
13933    case M16_OPC_CMPI:
13934        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13935        break;
13936#if defined(TARGET_MIPS64)
13937    case M16_OPC_SD:
13938        check_insn(ctx, ISA_MIPS3);
13939        check_mips_64(ctx);
13940        gen_st(ctx, OPC_SD, ry, rx, offset);
13941        break;
13942#endif
13943    case M16_OPC_LB:
13944        gen_ld(ctx, OPC_LB, ry, rx, offset);
13945        break;
13946    case M16_OPC_LH:
13947        gen_ld(ctx, OPC_LH, ry, rx, offset);
13948        break;
13949    case M16_OPC_LWSP:
13950        gen_ld(ctx, OPC_LW, rx, 29, offset);
13951        break;
13952    case M16_OPC_LW:
13953        gen_ld(ctx, OPC_LW, ry, rx, offset);
13954        break;
13955    case M16_OPC_LBU:
13956        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13957        break;
13958    case M16_OPC_LHU:
13959        gen_ld(ctx, OPC_LHU, ry, rx, offset);
13960        break;
13961    case M16_OPC_LWPC:
13962        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13963        break;
13964#if defined(TARGET_MIPS64)
13965    case M16_OPC_LWU:
13966        check_insn(ctx, ISA_MIPS3);
13967        check_mips_64(ctx);
13968        gen_ld(ctx, OPC_LWU, ry, rx, offset);
13969        break;
13970#endif
13971    case M16_OPC_SB:
13972        gen_st(ctx, OPC_SB, ry, rx, offset);
13973        break;
13974    case M16_OPC_SH:
13975        gen_st(ctx, OPC_SH, ry, rx, offset);
13976        break;
13977    case M16_OPC_SWSP:
13978        gen_st(ctx, OPC_SW, rx, 29, offset);
13979        break;
13980    case M16_OPC_SW:
13981        gen_st(ctx, OPC_SW, ry, rx, offset);
13982        break;
13983#if defined(TARGET_MIPS64)
13984    case M16_OPC_I64:
13985        decode_i64_mips16(ctx, ry, funct, offset, 1);
13986        break;
13987#endif
13988    default:
13989        generate_exception_end(ctx, EXCP_RI);
13990        break;
13991    }
13992
13993    return 4;
13994}
13995
13996static inline bool is_uhi(int sdbbp_code)
13997{
13998#ifdef CONFIG_USER_ONLY
13999    return false;
14000#else
14001    return semihosting_enabled() && sdbbp_code == 1;
14002#endif
14003}
14004
14005#ifdef CONFIG_USER_ONLY
14006/* The above should dead-code away any calls to this..*/
14007static inline void gen_helper_do_semihosting(void *env)
14008{
14009    g_assert_not_reached();
14010}
14011#endif
14012
14013static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
14014{
14015    int rx, ry;
14016    int sa;
14017    int op, cnvt_op, op1, offset;
14018    int funct;
14019    int n_bytes;
14020
14021    op = (ctx->opcode >> 11) & 0x1f;
14022    sa = (ctx->opcode >> 2) & 0x7;
14023    sa = sa == 0 ? 8 : sa;
14024    rx = xlat((ctx->opcode >> 8) & 0x7);
14025    cnvt_op = (ctx->opcode >> 5) & 0x7;
14026    ry = xlat((ctx->opcode >> 5) & 0x7);
14027    op1 = offset = ctx->opcode & 0x1f;
14028
14029    n_bytes = 2;
14030
14031    switch (op) {
14032    case M16_OPC_ADDIUSP:
14033        {
14034            int16_t imm = ((uint8_t) ctx->opcode) << 2;
14035
14036            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
14037        }
14038        break;
14039    case M16_OPC_ADDIUPC:
14040        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
14041        break;
14042    case M16_OPC_B:
14043        offset = (ctx->opcode & 0x7ff) << 1;
14044        offset = (int16_t)(offset << 4) >> 4;
14045        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
14046        /* No delay slot, so just process as a normal instruction */
14047        break;
14048    case M16_OPC_JAL:
14049        offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
14050        offset = (((ctx->opcode & 0x1f) << 21)
14051                  | ((ctx->opcode >> 5) & 0x1f) << 16
14052                  | offset) << 2;
14053        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
14054        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
14055        n_bytes = 4;
14056        break;
14057    case M16_OPC_BEQZ:
14058        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
14059                           ((int8_t)ctx->opcode) << 1, 0);
14060        /* No delay slot, so just process as a normal instruction */
14061        break;
14062    case M16_OPC_BNEQZ:
14063        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
14064                           ((int8_t)ctx->opcode) << 1, 0);
14065        /* No delay slot, so just process as a normal instruction */
14066        break;
14067    case M16_OPC_SHIFT:
14068        switch (ctx->opcode & 0x3) {
14069        case 0x0:
14070            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
14071            break;
14072        case 0x1:
14073#if defined(TARGET_MIPS64)
14074            check_insn(ctx, ISA_MIPS3);
14075            check_mips_64(ctx);
14076            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
14077#else
14078            generate_exception_end(ctx, EXCP_RI);
14079#endif
14080            break;
14081        case 0x2:
14082            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
14083            break;
14084        case 0x3:
14085            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
14086            break;
14087        }
14088        break;
14089#if defined(TARGET_MIPS64)
14090    case M16_OPC_LD:
14091        check_insn(ctx, ISA_MIPS3);
14092        check_mips_64(ctx);
14093        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
14094        break;
14095#endif
14096    case M16_OPC_RRIA:
14097        {
14098            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
14099
14100            if ((ctx->opcode >> 4) & 1) {
14101#if defined(TARGET_MIPS64)
14102                check_insn(ctx, ISA_MIPS3);
14103                check_mips_64(ctx);
14104                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
14105#else
14106                generate_exception_end(ctx, EXCP_RI);
14107#endif
14108            } else {
14109                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
14110            }
14111        }
14112        break;
14113    case M16_OPC_ADDIU8:
14114        {
14115            int16_t imm = (int8_t) ctx->opcode;
14116
14117            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
14118        }
14119        break;
14120    case M16_OPC_SLTI:
14121        {
14122            int16_t imm = (uint8_t) ctx->opcode;
14123            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
14124        }
14125        break;
14126    case M16_OPC_SLTIU:
14127        {
14128            int16_t imm = (uint8_t) ctx->opcode;
14129            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
14130        }
14131        break;
14132    case M16_OPC_I8:
14133        {
14134            int reg32;
14135
14136            funct = (ctx->opcode >> 8) & 0x7;
14137            switch (funct) {
14138            case I8_BTEQZ:
14139                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
14140                                   ((int8_t)ctx->opcode) << 1, 0);
14141                break;
14142            case I8_BTNEZ:
14143                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
14144                                   ((int8_t)ctx->opcode) << 1, 0);
14145                break;
14146            case I8_SWRASP:
14147                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
14148                break;
14149            case I8_ADJSP:
14150                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
14151                              ((int8_t)ctx->opcode) << 3);
14152                break;
14153            case I8_SVRS:
14154                check_insn(ctx, ISA_MIPS32);
14155                {
14156                    int do_ra = ctx->opcode & (1 << 6);
14157                    int do_s0 = ctx->opcode & (1 << 5);
14158                    int do_s1 = ctx->opcode & (1 << 4);
14159                    int framesize = ctx->opcode & 0xf;
14160
14161                    if (framesize == 0) {
14162                        framesize = 128;
14163                    } else {
14164                        framesize = framesize << 3;
14165                    }
14166
14167                    if (ctx->opcode & (1 << 7)) {
14168                        gen_mips16_save(ctx, 0, 0,
14169                                        do_ra, do_s0, do_s1, framesize);
14170                    } else {
14171                        gen_mips16_restore(ctx, 0, 0,
14172                                           do_ra, do_s0, do_s1, framesize);
14173                    }
14174                }
14175                break;
14176            case I8_MOV32R:
14177                {
14178                    int rz = xlat(ctx->opcode & 0x7);
14179
14180                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
14181                        ((ctx->opcode >> 5) & 0x7);
14182                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
14183                }
14184                break;
14185            case I8_MOVR32:
14186                reg32 = ctx->opcode & 0x1f;
14187                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
14188                break;
14189            default:
14190                generate_exception_end(ctx, EXCP_RI);
14191                break;
14192            }
14193        }
14194        break;
14195    case M16_OPC_LI:
14196        {
14197            int16_t imm = (uint8_t) ctx->opcode;
14198
14199            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
14200        }
14201        break;
14202    case M16_OPC_CMPI:
14203        {
14204            int16_t imm = (uint8_t) ctx->opcode;
14205            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
14206        }
14207        break;
14208#if defined(TARGET_MIPS64)
14209    case M16_OPC_SD:
14210        check_insn(ctx, ISA_MIPS3);
14211        check_mips_64(ctx);
14212        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
14213        break;
14214#endif
14215    case M16_OPC_LB:
14216        gen_ld(ctx, OPC_LB, ry, rx, offset);
14217        break;
14218    case M16_OPC_LH:
14219        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
14220        break;
14221    case M16_OPC_LWSP:
14222        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14223        break;
14224    case M16_OPC_LW:
14225        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
14226        break;
14227    case M16_OPC_LBU:
14228        gen_ld(ctx, OPC_LBU, ry, rx, offset);
14229        break;
14230    case M16_OPC_LHU:
14231        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
14232        break;
14233    case M16_OPC_LWPC:
14234        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
14235        break;
14236#if defined(TARGET_MIPS64)
14237    case M16_OPC_LWU:
14238        check_insn(ctx, ISA_MIPS3);
14239        check_mips_64(ctx);
14240        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
14241        break;
14242#endif
14243    case M16_OPC_SB:
14244        gen_st(ctx, OPC_SB, ry, rx, offset);
14245        break;
14246    case M16_OPC_SH:
14247        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
14248        break;
14249    case M16_OPC_SWSP:
14250        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14251        break;
14252    case M16_OPC_SW:
14253        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14254        break;
14255    case M16_OPC_RRR:
14256        {
14257            int rz = xlat((ctx->opcode >> 2) & 0x7);
14258            int mips32_op;
14259
14260            switch (ctx->opcode & 0x3) {
14261            case RRR_ADDU:
14262                mips32_op = OPC_ADDU;
14263                break;
14264            case RRR_SUBU:
14265                mips32_op = OPC_SUBU;
14266                break;
14267#if defined(TARGET_MIPS64)
14268            case RRR_DADDU:
14269                mips32_op = OPC_DADDU;
14270                check_insn(ctx, ISA_MIPS3);
14271                check_mips_64(ctx);
14272                break;
14273            case RRR_DSUBU:
14274                mips32_op = OPC_DSUBU;
14275                check_insn(ctx, ISA_MIPS3);
14276                check_mips_64(ctx);
14277                break;
14278#endif
14279            default:
14280                generate_exception_end(ctx, EXCP_RI);
14281                goto done;
14282            }
14283
14284            gen_arith(ctx, mips32_op, rz, rx, ry);
14285        done:
14286            ;
14287        }
14288        break;
14289    case M16_OPC_RR:
14290        switch (op1) {
14291        case RR_JR:
14292            {
14293                int nd = (ctx->opcode >> 7) & 0x1;
14294                int link = (ctx->opcode >> 6) & 0x1;
14295                int ra = (ctx->opcode >> 5) & 0x1;
14296
14297                if (nd) {
14298                    check_insn(ctx, ISA_MIPS32);
14299                }
14300
14301                if (link) {
14302                    op = OPC_JALR;
14303                } else {
14304                    op = OPC_JR;
14305                }
14306
14307                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14308                                   (nd ? 0 : 2));
14309            }
14310            break;
14311        case RR_SDBBP:
14312            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14313                gen_helper_do_semihosting(cpu_env);
14314            } else {
14315                /*
14316                 * XXX: not clear which exception should be raised
14317                 *      when in debug mode...
14318                 */
14319                check_insn(ctx, ISA_MIPS32);
14320                generate_exception_end(ctx, EXCP_DBp);
14321            }
14322            break;
14323        case RR_SLT:
14324            gen_slt(ctx, OPC_SLT, 24, rx, ry);
14325            break;
14326        case RR_SLTU:
14327            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14328            break;
14329        case RR_BREAK:
14330            generate_exception_end(ctx, EXCP_BREAK);
14331            break;
14332        case RR_SLLV:
14333            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14334            break;
14335        case RR_SRLV:
14336            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14337            break;
14338        case RR_SRAV:
14339            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14340            break;
14341#if defined(TARGET_MIPS64)
14342        case RR_DSRL:
14343            check_insn(ctx, ISA_MIPS3);
14344            check_mips_64(ctx);
14345            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14346            break;
14347#endif
14348        case RR_CMP:
14349            gen_logic(ctx, OPC_XOR, 24, rx, ry);
14350            break;
14351        case RR_NEG:
14352            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14353            break;
14354        case RR_AND:
14355            gen_logic(ctx, OPC_AND, rx, rx, ry);
14356            break;
14357        case RR_OR:
14358            gen_logic(ctx, OPC_OR, rx, rx, ry);
14359            break;
14360        case RR_XOR:
14361            gen_logic(ctx, OPC_XOR, rx, rx, ry);
14362            break;
14363        case RR_NOT:
14364            gen_logic(ctx, OPC_NOR, rx, ry, 0);
14365            break;
14366        case RR_MFHI:
14367            gen_HILO(ctx, OPC_MFHI, 0, rx);
14368            break;
14369        case RR_CNVT:
14370            check_insn(ctx, ISA_MIPS32);
14371            switch (cnvt_op) {
14372            case RR_RY_CNVT_ZEB:
14373                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14374                break;
14375            case RR_RY_CNVT_ZEH:
14376                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14377                break;
14378            case RR_RY_CNVT_SEB:
14379                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14380                break;
14381            case RR_RY_CNVT_SEH:
14382                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14383                break;
14384#if defined(TARGET_MIPS64)
14385            case RR_RY_CNVT_ZEW:
14386                check_insn(ctx, ISA_MIPS64);
14387                check_mips_64(ctx);
14388                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14389                break;
14390            case RR_RY_CNVT_SEW:
14391                check_insn(ctx, ISA_MIPS64);
14392                check_mips_64(ctx);
14393                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14394                break;
14395#endif
14396            default:
14397                generate_exception_end(ctx, EXCP_RI);
14398                break;
14399            }
14400            break;
14401        case RR_MFLO:
14402            gen_HILO(ctx, OPC_MFLO, 0, rx);
14403            break;
14404#if defined(TARGET_MIPS64)
14405        case RR_DSRA:
14406            check_insn(ctx, ISA_MIPS3);
14407            check_mips_64(ctx);
14408            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14409            break;
14410        case RR_DSLLV:
14411            check_insn(ctx, ISA_MIPS3);
14412            check_mips_64(ctx);
14413            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14414            break;
14415        case RR_DSRLV:
14416            check_insn(ctx, ISA_MIPS3);
14417            check_mips_64(ctx);
14418            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14419            break;
14420        case RR_DSRAV:
14421            check_insn(ctx, ISA_MIPS3);
14422            check_mips_64(ctx);
14423            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14424            break;
14425#endif
14426        case RR_MULT:
14427            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14428            break;
14429        case RR_MULTU:
14430            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14431            break;
14432        case RR_DIV:
14433            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14434            break;
14435        case RR_DIVU:
14436            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14437            break;
14438#if defined(TARGET_MIPS64)
14439        case RR_DMULT:
14440            check_insn(ctx, ISA_MIPS3);
14441            check_mips_64(ctx);
14442            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14443            break;
14444        case RR_DMULTU:
14445            check_insn(ctx, ISA_MIPS3);
14446            check_mips_64(ctx);
14447            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14448            break;
14449        case RR_DDIV:
14450            check_insn(ctx, ISA_MIPS3);
14451            check_mips_64(ctx);
14452            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14453            break;
14454        case RR_DDIVU:
14455            check_insn(ctx, ISA_MIPS3);
14456            check_mips_64(ctx);
14457            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14458            break;
14459#endif
14460        default:
14461            generate_exception_end(ctx, EXCP_RI);
14462            break;
14463        }
14464        break;
14465    case M16_OPC_EXTEND:
14466        decode_extended_mips16_opc(env, ctx);
14467        n_bytes = 4;
14468        break;
14469#if defined(TARGET_MIPS64)
14470    case M16_OPC_I64:
14471        funct = (ctx->opcode >> 8) & 0x7;
14472        decode_i64_mips16(ctx, ry, funct, offset, 0);
14473        break;
14474#endif
14475    default:
14476        generate_exception_end(ctx, EXCP_RI);
14477        break;
14478    }
14479
14480    return n_bytes;
14481}
14482
14483/* microMIPS extension to MIPS32/MIPS64 */
14484
14485/*
14486 * microMIPS32/microMIPS64 major opcodes
14487 *
14488 * 1. MIPS Architecture for Programmers Volume II-B:
14489 *      The microMIPS32 Instruction Set (Revision 3.05)
14490 *
14491 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14492 *
14493 * 2. MIPS Architecture For Programmers Volume II-A:
14494 *      The MIPS64 Instruction Set (Revision 3.51)
14495 */
14496
14497enum {
14498    POOL32A = 0x00,
14499    POOL16A = 0x01,
14500    LBU16 = 0x02,
14501    MOVE16 = 0x03,
14502    ADDI32 = 0x04,
14503    R6_LUI = 0x04,
14504    AUI = 0x04,
14505    LBU32 = 0x05,
14506    SB32 = 0x06,
14507    LB32 = 0x07,
14508
14509    POOL32B = 0x08,
14510    POOL16B = 0x09,
14511    LHU16 = 0x0a,
14512    ANDI16 = 0x0b,
14513    ADDIU32 = 0x0c,
14514    LHU32 = 0x0d,
14515    SH32 = 0x0e,
14516    LH32 = 0x0f,
14517
14518    POOL32I = 0x10,
14519    POOL16C = 0x11,
14520    LWSP16 = 0x12,
14521    POOL16D = 0x13,
14522    ORI32 = 0x14,
14523    POOL32F = 0x15,
14524    POOL32S = 0x16,  /* MIPS64 */
14525    DADDIU32 = 0x17, /* MIPS64 */
14526
14527    POOL32C = 0x18,
14528    LWGP16 = 0x19,
14529    LW16 = 0x1a,
14530    POOL16E = 0x1b,
14531    XORI32 = 0x1c,
14532    JALS32 = 0x1d,
14533    BOVC = 0x1d,
14534    BEQC = 0x1d,
14535    BEQZALC = 0x1d,
14536    ADDIUPC = 0x1e,
14537    PCREL = 0x1e,
14538    BNVC = 0x1f,
14539    BNEC = 0x1f,
14540    BNEZALC = 0x1f,
14541
14542    R6_BEQZC = 0x20,
14543    JIC = 0x20,
14544    POOL16F = 0x21,
14545    SB16 = 0x22,
14546    BEQZ16 = 0x23,
14547    BEQZC16 = 0x23,
14548    SLTI32 = 0x24,
14549    BEQ32 = 0x25,
14550    BC = 0x25,
14551    SWC132 = 0x26,
14552    LWC132 = 0x27,
14553
14554    /* 0x29 is reserved */
14555    RES_29 = 0x29,
14556    R6_BNEZC = 0x28,
14557    JIALC = 0x28,
14558    SH16 = 0x2a,
14559    BNEZ16 = 0x2b,
14560    BNEZC16 = 0x2b,
14561    SLTIU32 = 0x2c,
14562    BNE32 = 0x2d,
14563    BALC = 0x2d,
14564    SDC132 = 0x2e,
14565    LDC132 = 0x2f,
14566
14567    /* 0x31 is reserved */
14568    RES_31 = 0x31,
14569    BLEZALC = 0x30,
14570    BGEZALC = 0x30,
14571    BGEUC = 0x30,
14572    SWSP16 = 0x32,
14573    B16 = 0x33,
14574    BC16 = 0x33,
14575    ANDI32 = 0x34,
14576    J32 = 0x35,
14577    BGTZC = 0x35,
14578    BLTZC = 0x35,
14579    BLTC = 0x35,
14580    SD32 = 0x36, /* MIPS64 */
14581    LD32 = 0x37, /* MIPS64 */
14582
14583    /* 0x39 is reserved */
14584    RES_39 = 0x39,
14585    BGTZALC = 0x38,
14586    BLTZALC = 0x38,
14587    BLTUC = 0x38,
14588    SW16 = 0x3a,
14589    LI16 = 0x3b,
14590    JALX32 = 0x3c,
14591    JAL32 = 0x3d,
14592    BLEZC = 0x3d,
14593    BGEZC = 0x3d,
14594    BGEC = 0x3d,
14595    SW32 = 0x3e,
14596    LW32 = 0x3f
14597};
14598
14599/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14600enum {
14601    ADDIUPC_00 = 0x00,
14602    ADDIUPC_01 = 0x01,
14603    ADDIUPC_02 = 0x02,
14604    ADDIUPC_03 = 0x03,
14605    ADDIUPC_04 = 0x04,
14606    ADDIUPC_05 = 0x05,
14607    ADDIUPC_06 = 0x06,
14608    ADDIUPC_07 = 0x07,
14609    AUIPC = 0x1e,
14610    ALUIPC = 0x1f,
14611    LWPC_08 = 0x08,
14612    LWPC_09 = 0x09,
14613    LWPC_0A = 0x0A,
14614    LWPC_0B = 0x0B,
14615    LWPC_0C = 0x0C,
14616    LWPC_0D = 0x0D,
14617    LWPC_0E = 0x0E,
14618    LWPC_0F = 0x0F,
14619};
14620
14621/* POOL32A encoding of minor opcode field */
14622
14623enum {
14624    /*
14625     * These opcodes are distinguished only by bits 9..6; those bits are
14626     * what are recorded below.
14627     */
14628    SLL32 = 0x0,
14629    SRL32 = 0x1,
14630    SRA = 0x2,
14631    ROTR = 0x3,
14632    SELEQZ = 0x5,
14633    SELNEZ = 0x6,
14634    R6_RDHWR = 0x7,
14635
14636    SLLV = 0x0,
14637    SRLV = 0x1,
14638    SRAV = 0x2,
14639    ROTRV = 0x3,
14640    ADD = 0x4,
14641    ADDU32 = 0x5,
14642    SUB = 0x6,
14643    SUBU32 = 0x7,
14644    MUL = 0x8,
14645    AND = 0x9,
14646    OR32 = 0xa,
14647    NOR = 0xb,
14648    XOR32 = 0xc,
14649    SLT = 0xd,
14650    SLTU = 0xe,
14651
14652    MOVN = 0x0,
14653    R6_MUL  = 0x0,
14654    MOVZ = 0x1,
14655    MUH  = 0x1,
14656    MULU = 0x2,
14657    MUHU = 0x3,
14658    LWXS = 0x4,
14659    R6_DIV  = 0x4,
14660    MOD  = 0x5,
14661    R6_DIVU = 0x6,
14662    MODU = 0x7,
14663
14664    /* The following can be distinguished by their lower 6 bits. */
14665    BREAK32 = 0x07,
14666    INS = 0x0c,
14667    LSA = 0x0f,
14668    ALIGN = 0x1f,
14669    EXT = 0x2c,
14670    POOL32AXF = 0x3c,
14671    SIGRIE = 0x3f
14672};
14673
14674/* POOL32AXF encoding of minor opcode field extension */
14675
14676/*
14677 * 1. MIPS Architecture for Programmers Volume II-B:
14678 *      The microMIPS32 Instruction Set (Revision 3.05)
14679 *
14680 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14681 *
14682 * 2. MIPS Architecture for Programmers VolumeIV-e:
14683 *      The MIPS DSP Application-Specific Extension
14684 *        to the microMIPS32 Architecture (Revision 2.34)
14685 *
14686 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14687 */
14688
14689enum {
14690    /* bits 11..6 */
14691    TEQ = 0x00,
14692    TGE = 0x08,
14693    TGEU = 0x10,
14694    TLT = 0x20,
14695    TLTU = 0x28,
14696    TNE = 0x30,
14697
14698    MFC0 = 0x03,
14699    MTC0 = 0x0b,
14700
14701    /* begin of microMIPS32 DSP */
14702
14703    /* bits 13..12 for 0x01 */
14704    MFHI_ACC = 0x0,
14705    MFLO_ACC = 0x1,
14706    MTHI_ACC = 0x2,
14707    MTLO_ACC = 0x3,
14708
14709    /* bits 13..12 for 0x2a */
14710    MADD_ACC = 0x0,
14711    MADDU_ACC = 0x1,
14712    MSUB_ACC = 0x2,
14713    MSUBU_ACC = 0x3,
14714
14715    /* bits 13..12 for 0x32 */
14716    MULT_ACC = 0x0,
14717    MULTU_ACC = 0x1,
14718
14719    /* end of microMIPS32 DSP */
14720
14721    /* bits 15..12 for 0x2c */
14722    BITSWAP = 0x0,
14723    SEB = 0x2,
14724    SEH = 0x3,
14725    CLO = 0x4,
14726    CLZ = 0x5,
14727    RDHWR = 0x6,
14728    WSBH = 0x7,
14729    MULT = 0x8,
14730    MULTU = 0x9,
14731    DIV = 0xa,
14732    DIVU = 0xb,
14733    MADD = 0xc,
14734    MADDU = 0xd,
14735    MSUB = 0xe,
14736    MSUBU = 0xf,
14737
14738    /* bits 15..12 for 0x34 */
14739    MFC2 = 0x4,
14740    MTC2 = 0x5,
14741    MFHC2 = 0x8,
14742    MTHC2 = 0x9,
14743    CFC2 = 0xc,
14744    CTC2 = 0xd,
14745
14746    /* bits 15..12 for 0x3c */
14747    JALR = 0x0,
14748    JR = 0x0,                   /* alias */
14749    JALRC = 0x0,
14750    JRC = 0x0,
14751    JALR_HB = 0x1,
14752    JALRC_HB = 0x1,
14753    JALRS = 0x4,
14754    JALRS_HB = 0x5,
14755
14756    /* bits 15..12 for 0x05 */
14757    RDPGPR = 0xe,
14758    WRPGPR = 0xf,
14759
14760    /* bits 15..12 for 0x0d */
14761    TLBP = 0x0,
14762    TLBR = 0x1,
14763    TLBWI = 0x2,
14764    TLBWR = 0x3,
14765    TLBINV = 0x4,
14766    TLBINVF = 0x5,
14767    WAIT = 0x9,
14768    IRET = 0xd,
14769    DERET = 0xe,
14770    ERET = 0xf,
14771
14772    /* bits 15..12 for 0x15 */
14773    DMT = 0x0,
14774    DVPE = 0x1,
14775    EMT = 0x2,
14776    EVPE = 0x3,
14777
14778    /* bits 15..12 for 0x1d */
14779    DI = 0x4,
14780    EI = 0x5,
14781
14782    /* bits 15..12 for 0x2d */
14783    SYNC = 0x6,
14784    SYSCALL = 0x8,
14785    SDBBP = 0xd,
14786
14787    /* bits 15..12 for 0x35 */
14788    MFHI32 = 0x0,
14789    MFLO32 = 0x1,
14790    MTHI32 = 0x2,
14791    MTLO32 = 0x3,
14792};
14793
14794/* POOL32B encoding of minor opcode field (bits 15..12) */
14795
14796enum {
14797    LWC2 = 0x0,
14798    LWP = 0x1,
14799    LDP = 0x4,
14800    LWM32 = 0x5,
14801    CACHE = 0x6,
14802    LDM = 0x7,
14803    SWC2 = 0x8,
14804    SWP = 0x9,
14805    SDP = 0xc,
14806    SWM32 = 0xd,
14807    SDM = 0xf
14808};
14809
14810/* POOL32C encoding of minor opcode field (bits 15..12) */
14811
14812enum {
14813    LWL = 0x0,
14814    SWL = 0x8,
14815    LWR = 0x1,
14816    SWR = 0x9,
14817    PREF = 0x2,
14818    ST_EVA = 0xa,
14819    LL = 0x3,
14820    SC = 0xb,
14821    LDL = 0x4,
14822    SDL = 0xc,
14823    LDR = 0x5,
14824    SDR = 0xd,
14825    LD_EVA = 0x6,
14826    LWU = 0xe,
14827    LLD = 0x7,
14828    SCD = 0xf
14829};
14830
14831/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14832
14833enum {
14834    LBUE = 0x0,
14835    LHUE = 0x1,
14836    LWLE = 0x2,
14837    LWRE = 0x3,
14838    LBE = 0x4,
14839    LHE = 0x5,
14840    LLE = 0x6,
14841    LWE = 0x7,
14842};
14843
14844/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14845
14846enum {
14847    SWLE = 0x0,
14848    SWRE = 0x1,
14849    PREFE = 0x2,
14850    CACHEE = 0x3,
14851    SBE = 0x4,
14852    SHE = 0x5,
14853    SCE = 0x6,
14854    SWE = 0x7,
14855};
14856
14857/* POOL32F encoding of minor opcode field (bits 5..0) */
14858
14859enum {
14860    /* These are the bit 7..6 values */
14861    ADD_FMT = 0x0,
14862
14863    SUB_FMT = 0x1,
14864
14865    MUL_FMT = 0x2,
14866
14867    DIV_FMT = 0x3,
14868
14869    /* These are the bit 8..6 values */
14870    MOVN_FMT = 0x0,
14871    RSQRT2_FMT = 0x0,
14872    MOVF_FMT = 0x0,
14873    RINT_FMT = 0x0,
14874    SELNEZ_FMT = 0x0,
14875
14876    MOVZ_FMT = 0x1,
14877    LWXC1 = 0x1,
14878    MOVT_FMT = 0x1,
14879    CLASS_FMT = 0x1,
14880    SELEQZ_FMT = 0x1,
14881
14882    PLL_PS = 0x2,
14883    SWXC1 = 0x2,
14884    SEL_FMT = 0x2,
14885
14886    PLU_PS = 0x3,
14887    LDXC1 = 0x3,
14888
14889    MOVN_FMT_04 = 0x4,
14890    PUL_PS = 0x4,
14891    SDXC1 = 0x4,
14892    RECIP2_FMT = 0x4,
14893
14894    MOVZ_FMT_05 = 0x05,
14895    PUU_PS = 0x5,
14896    LUXC1 = 0x5,
14897
14898    CVT_PS_S = 0x6,
14899    SUXC1 = 0x6,
14900    ADDR_PS = 0x6,
14901    PREFX = 0x6,
14902    MADDF_FMT = 0x6,
14903
14904    MULR_PS = 0x7,
14905    MSUBF_FMT = 0x7,
14906
14907    MADD_S = 0x01,
14908    MADD_D = 0x09,
14909    MADD_PS = 0x11,
14910    ALNV_PS = 0x19,
14911    MSUB_S = 0x21,
14912    MSUB_D = 0x29,
14913    MSUB_PS = 0x31,
14914
14915    NMADD_S = 0x02,
14916    NMADD_D = 0x0a,
14917    NMADD_PS = 0x12,
14918    NMSUB_S = 0x22,
14919    NMSUB_D = 0x2a,
14920    NMSUB_PS = 0x32,
14921
14922    MIN_FMT = 0x3,
14923    MAX_FMT = 0xb,
14924    MINA_FMT = 0x23,
14925    MAXA_FMT = 0x2b,
14926    POOL32FXF = 0x3b,
14927
14928    CABS_COND_FMT = 0x1c,              /* MIPS3D */
14929    C_COND_FMT = 0x3c,
14930
14931    CMP_CONDN_S = 0x5,
14932    CMP_CONDN_D = 0x15
14933};
14934
14935/* POOL32Fxf encoding of minor opcode extension field */
14936
14937enum {
14938    CVT_L = 0x04,
14939    RSQRT_FMT = 0x08,
14940    FLOOR_L = 0x0c,
14941    CVT_PW_PS = 0x1c,
14942    CVT_W = 0x24,
14943    SQRT_FMT = 0x28,
14944    FLOOR_W = 0x2c,
14945    CVT_PS_PW = 0x3c,
14946    CFC1 = 0x40,
14947    RECIP_FMT = 0x48,
14948    CEIL_L = 0x4c,
14949    CTC1 = 0x60,
14950    CEIL_W = 0x6c,
14951    MFC1 = 0x80,
14952    CVT_S_PL = 0x84,
14953    TRUNC_L = 0x8c,
14954    MTC1 = 0xa0,
14955    CVT_S_PU = 0xa4,
14956    TRUNC_W = 0xac,
14957    MFHC1 = 0xc0,
14958    ROUND_L = 0xcc,
14959    MTHC1 = 0xe0,
14960    ROUND_W = 0xec,
14961
14962    MOV_FMT = 0x01,
14963    MOVF = 0x05,
14964    ABS_FMT = 0x0d,
14965    RSQRT1_FMT = 0x1d,
14966    MOVT = 0x25,
14967    NEG_FMT = 0x2d,
14968    CVT_D = 0x4d,
14969    RECIP1_FMT = 0x5d,
14970    CVT_S = 0x6d
14971};
14972
14973/* POOL32I encoding of minor opcode field (bits 25..21) */
14974
14975enum {
14976    BLTZ = 0x00,
14977    BLTZAL = 0x01,
14978    BGEZ = 0x02,
14979    BGEZAL = 0x03,
14980    BLEZ = 0x04,
14981    BNEZC = 0x05,
14982    BGTZ = 0x06,
14983    BEQZC = 0x07,
14984    TLTI = 0x08,
14985    BC1EQZC = 0x08,
14986    TGEI = 0x09,
14987    BC1NEZC = 0x09,
14988    TLTIU = 0x0a,
14989    BC2EQZC = 0x0a,
14990    TGEIU = 0x0b,
14991    BC2NEZC = 0x0a,
14992    TNEI = 0x0c,
14993    R6_SYNCI = 0x0c,
14994    LUI = 0x0d,
14995    TEQI = 0x0e,
14996    SYNCI = 0x10,
14997    BLTZALS = 0x11,
14998    BGEZALS = 0x13,
14999    BC2F = 0x14,
15000    BC2T = 0x15,
15001    BPOSGE64 = 0x1a,
15002    BPOSGE32 = 0x1b,
15003    /* These overlap and are distinguished by bit16 of the instruction */
15004    BC1F = 0x1c,
15005    BC1T = 0x1d,
15006    BC1ANY2F = 0x1c,
15007    BC1ANY2T = 0x1d,
15008    BC1ANY4F = 0x1e,
15009    BC1ANY4T = 0x1f
15010};
15011
15012/* POOL16A encoding of minor opcode field */
15013
15014enum {
15015    ADDU16 = 0x0,
15016    SUBU16 = 0x1
15017};
15018
15019/* POOL16B encoding of minor opcode field */
15020
15021enum {
15022    SLL16 = 0x0,
15023    SRL16 = 0x1
15024};
15025
15026/* POOL16C encoding of minor opcode field */
15027
15028enum {
15029    NOT16 = 0x00,
15030    XOR16 = 0x04,
15031    AND16 = 0x08,
15032    OR16 = 0x0c,
15033    LWM16 = 0x10,
15034    SWM16 = 0x14,
15035    JR16 = 0x18,
15036    JRC16 = 0x1a,
15037    JALR16 = 0x1c,
15038    JALR16S = 0x1e,
15039    MFHI16 = 0x20,
15040    MFLO16 = 0x24,
15041    BREAK16 = 0x28,
15042    SDBBP16 = 0x2c,
15043    JRADDIUSP = 0x30
15044};
15045
15046/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15047
15048enum {
15049    R6_NOT16    = 0x00,
15050    R6_AND16    = 0x01,
15051    R6_LWM16    = 0x02,
15052    R6_JRC16    = 0x03,
15053    MOVEP       = 0x04,
15054    MOVEP_05    = 0x05,
15055    MOVEP_06    = 0x06,
15056    MOVEP_07    = 0x07,
15057    R6_XOR16    = 0x08,
15058    R6_OR16     = 0x09,
15059    R6_SWM16    = 0x0a,
15060    JALRC16     = 0x0b,
15061    MOVEP_0C    = 0x0c,
15062    MOVEP_0D    = 0x0d,
15063    MOVEP_0E    = 0x0e,
15064    MOVEP_0F    = 0x0f,
15065    JRCADDIUSP  = 0x13,
15066    R6_BREAK16  = 0x1b,
15067    R6_SDBBP16  = 0x3b
15068};
15069
15070/* POOL16D encoding of minor opcode field */
15071
15072enum {
15073    ADDIUS5 = 0x0,
15074    ADDIUSP = 0x1
15075};
15076
15077/* POOL16E encoding of minor opcode field */
15078
15079enum {
15080    ADDIUR2 = 0x0,
15081    ADDIUR1SP = 0x1
15082};
15083
15084static int mmreg(int r)
15085{
15086    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15087
15088    return map[r];
15089}
15090
15091/* Used for 16-bit store instructions.  */
15092static int mmreg2(int r)
15093{
15094    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15095
15096    return map[r];
15097}
15098
15099#define uMIPS_RD(op) ((op >> 7) & 0x7)
15100#define uMIPS_RS(op) ((op >> 4) & 0x7)
15101#define uMIPS_RS2(op) uMIPS_RS(op)
15102#define uMIPS_RS1(op) ((op >> 1) & 0x7)
15103#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15104#define uMIPS_RS5(op) (op & 0x1f)
15105
15106/* Signed immediate */
15107#define SIMM(op, start, width)                                          \
15108    ((int32_t)(((op >> start) & ((~0U) >> (32 - width)))                \
15109               << (32 - width))                                         \
15110     >> (32 - width))
15111/* Zero-extended immediate */
15112#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15113
15114static void gen_addiur1sp(DisasContext *ctx)
15115{
15116    int rd = mmreg(uMIPS_RD(ctx->opcode));
15117
15118    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
15119}
15120
15121static void gen_addiur2(DisasContext *ctx)
15122{
15123    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15124    int rd = mmreg(uMIPS_RD(ctx->opcode));
15125    int rs = mmreg(uMIPS_RS(ctx->opcode));
15126
15127    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
15128}
15129
15130static void gen_addiusp(DisasContext *ctx)
15131{
15132    int encoded = ZIMM(ctx->opcode, 1, 9);
15133    int decoded;
15134
15135    if (encoded <= 1) {
15136        decoded = 256 + encoded;
15137    } else if (encoded <= 255) {
15138        decoded = encoded;
15139    } else if (encoded <= 509) {
15140        decoded = encoded - 512;
15141    } else {
15142        decoded = encoded - 768;
15143    }
15144
15145    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
15146}
15147
15148static void gen_addius5(DisasContext *ctx)
15149{
15150    int imm = SIMM(ctx->opcode, 1, 4);
15151    int rd = (ctx->opcode >> 5) & 0x1f;
15152
15153    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
15154}
15155
15156static void gen_andi16(DisasContext *ctx)
15157{
15158    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15159                                 31, 32, 63, 64, 255, 32768, 65535 };
15160    int rd = mmreg(uMIPS_RD(ctx->opcode));
15161    int rs = mmreg(uMIPS_RS(ctx->opcode));
15162    int encoded = ZIMM(ctx->opcode, 0, 4);
15163
15164    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
15165}
15166
15167static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
15168                              int base, int16_t offset)
15169{
15170    TCGv t0, t1;
15171    TCGv_i32 t2;
15172
15173    if (ctx->hflags & MIPS_HFLAG_BMASK) {
15174        generate_exception_end(ctx, EXCP_RI);
15175        return;
15176    }
15177
15178    t0 = tcg_temp_new();
15179
15180    gen_base_offset_addr(ctx, t0, base, offset);
15181
15182    t1 = tcg_const_tl(reglist);
15183    t2 = tcg_const_i32(ctx->mem_idx);
15184
15185    save_cpu_state(ctx, 1);
15186    switch (opc) {
15187    case LWM32:
15188        gen_helper_lwm(cpu_env, t0, t1, t2);
15189        break;
15190    case SWM32:
15191        gen_helper_swm(cpu_env, t0, t1, t2);
15192        break;
15193#ifdef TARGET_MIPS64
15194    case LDM:
15195        gen_helper_ldm(cpu_env, t0, t1, t2);
15196        break;
15197    case SDM:
15198        gen_helper_sdm(cpu_env, t0, t1, t2);
15199        break;
15200#endif
15201    }
15202    tcg_temp_free(t0);
15203    tcg_temp_free(t1);
15204    tcg_temp_free_i32(t2);
15205}
15206
15207
15208static void gen_pool16c_insn(DisasContext *ctx)
15209{
15210    int rd = mmreg((ctx->opcode >> 3) & 0x7);
15211    int rs = mmreg(ctx->opcode & 0x7);
15212
15213    switch (((ctx->opcode) >> 4) & 0x3f) {
15214    case NOT16 + 0:
15215    case NOT16 + 1:
15216    case NOT16 + 2:
15217    case NOT16 + 3:
15218        gen_logic(ctx, OPC_NOR, rd, rs, 0);
15219        break;
15220    case XOR16 + 0:
15221    case XOR16 + 1:
15222    case XOR16 + 2:
15223    case XOR16 + 3:
15224        gen_logic(ctx, OPC_XOR, rd, rd, rs);
15225        break;
15226    case AND16 + 0:
15227    case AND16 + 1:
15228    case AND16 + 2:
15229    case AND16 + 3:
15230        gen_logic(ctx, OPC_AND, rd, rd, rs);
15231        break;
15232    case OR16 + 0:
15233    case OR16 + 1:
15234    case OR16 + 2:
15235    case OR16 + 3:
15236        gen_logic(ctx, OPC_OR, rd, rd, rs);
15237        break;
15238    case LWM16 + 0:
15239    case LWM16 + 1:
15240    case LWM16 + 2:
15241    case LWM16 + 3:
15242        {
15243            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15244            int offset = ZIMM(ctx->opcode, 0, 4);
15245
15246            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15247                              29, offset << 2);
15248        }
15249        break;
15250    case SWM16 + 0:
15251    case SWM16 + 1:
15252    case SWM16 + 2:
15253    case SWM16 + 3:
15254        {
15255            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15256            int offset = ZIMM(ctx->opcode, 0, 4);
15257
15258            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15259                              29, offset << 2);
15260        }
15261        break;
15262    case JR16 + 0:
15263    case JR16 + 1:
15264        {
15265            int reg = ctx->opcode & 0x1f;
15266
15267            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15268        }
15269        break;
15270    case JRC16 + 0:
15271    case JRC16 + 1:
15272        {
15273            int reg = ctx->opcode & 0x1f;
15274            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15275            /*
15276             * Let normal delay slot handling in our caller take us
15277             * to the branch target.
15278             */
15279        }
15280        break;
15281    case JALR16 + 0:
15282    case JALR16 + 1:
15283        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15284        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15285        break;
15286    case JALR16S + 0:
15287    case JALR16S + 1:
15288        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15289        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15290        break;
15291    case MFHI16 + 0:
15292    case MFHI16 + 1:
15293        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15294        break;
15295    case MFLO16 + 0:
15296    case MFLO16 + 1:
15297        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15298        break;
15299    case BREAK16:
15300        generate_exception_end(ctx, EXCP_BREAK);
15301        break;
15302    case SDBBP16:
15303        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15304            gen_helper_do_semihosting(cpu_env);
15305        } else {
15306            /*
15307             * XXX: not clear which exception should be raised
15308             *      when in debug mode...
15309             */
15310            check_insn(ctx, ISA_MIPS32);
15311            generate_exception_end(ctx, EXCP_DBp);
15312        }
15313        break;
15314    case JRADDIUSP + 0:
15315    case JRADDIUSP + 1:
15316        {
15317            int imm = ZIMM(ctx->opcode, 0, 5);
15318            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15319            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15320            /*
15321             * Let normal delay slot handling in our caller take us
15322             * to the branch target.
15323             */
15324        }
15325        break;
15326    default:
15327        generate_exception_end(ctx, EXCP_RI);
15328        break;
15329    }
15330}
15331
15332static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15333                             int enc_rs)
15334{
15335    int rd, rs, re, rt;
15336    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15337    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15338    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15339    rd = rd_enc[enc_dest];
15340    re = re_enc[enc_dest];
15341    rs = rs_rt_enc[enc_rs];
15342    rt = rs_rt_enc[enc_rt];
15343    if (rs) {
15344        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15345    } else {
15346        tcg_gen_movi_tl(cpu_gpr[rd], 0);
15347    }
15348    if (rt) {
15349        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15350    } else {
15351        tcg_gen_movi_tl(cpu_gpr[re], 0);
15352    }
15353}
15354
15355static void gen_pool16c_r6_insn(DisasContext *ctx)
15356{
15357    int rt = mmreg((ctx->opcode >> 7) & 0x7);
15358    int rs = mmreg((ctx->opcode >> 4) & 0x7);
15359
15360    switch (ctx->opcode & 0xf) {
15361    case R6_NOT16:
15362        gen_logic(ctx, OPC_NOR, rt, rs, 0);
15363        break;
15364    case R6_AND16:
15365        gen_logic(ctx, OPC_AND, rt, rt, rs);
15366        break;
15367    case R6_LWM16:
15368        {
15369            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15370            int offset = extract32(ctx->opcode, 4, 4);
15371            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15372        }
15373        break;
15374    case R6_JRC16: /* JRCADDIUSP */
15375        if ((ctx->opcode >> 4) & 1) {
15376            /* JRCADDIUSP */
15377            int imm = extract32(ctx->opcode, 5, 5);
15378            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15379            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15380        } else {
15381            /* JRC16 */
15382            rs = extract32(ctx->opcode, 5, 5);
15383            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15384        }
15385        break;
15386    case MOVEP:
15387    case MOVEP_05:
15388    case MOVEP_06:
15389    case MOVEP_07:
15390    case MOVEP_0C:
15391    case MOVEP_0D:
15392    case MOVEP_0E:
15393    case MOVEP_0F:
15394        {
15395            int enc_dest = uMIPS_RD(ctx->opcode);
15396            int enc_rt = uMIPS_RS2(ctx->opcode);
15397            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15398            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15399        }
15400        break;
15401    case R6_XOR16:
15402        gen_logic(ctx, OPC_XOR, rt, rt, rs);
15403        break;
15404    case R6_OR16:
15405        gen_logic(ctx, OPC_OR, rt, rt, rs);
15406        break;
15407    case R6_SWM16:
15408        {
15409            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15410            int offset = extract32(ctx->opcode, 4, 4);
15411            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15412        }
15413        break;
15414    case JALRC16: /* BREAK16, SDBBP16 */
15415        switch (ctx->opcode & 0x3f) {
15416        case JALRC16:
15417        case JALRC16 + 0x20:
15418            /* JALRC16 */
15419            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15420                               31, 0, 0);
15421            break;
15422        case R6_BREAK16:
15423            /* BREAK16 */
15424            generate_exception(ctx, EXCP_BREAK);
15425            break;
15426        case R6_SDBBP16:
15427            /* SDBBP16 */
15428            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15429                gen_helper_do_semihosting(cpu_env);
15430            } else {
15431                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15432                    generate_exception(ctx, EXCP_RI);
15433                } else {
15434                    generate_exception(ctx, EXCP_DBp);
15435                }
15436            }
15437            break;
15438        }
15439        break;
15440    default:
15441        generate_exception(ctx, EXCP_RI);
15442        break;
15443    }
15444}
15445
15446static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
15447{
15448    TCGv t0 = tcg_temp_new();
15449    TCGv t1 = tcg_temp_new();
15450
15451    gen_load_gpr(t0, base);
15452
15453    if (index != 0) {
15454        gen_load_gpr(t1, index);
15455        tcg_gen_shli_tl(t1, t1, 2);
15456        gen_op_addr_add(ctx, t0, t1, t0);
15457    }
15458
15459    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15460    gen_store_gpr(t1, rd);
15461
15462    tcg_temp_free(t0);
15463    tcg_temp_free(t1);
15464}
15465
15466static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
15467                          int base, int16_t offset)
15468{
15469    TCGv t0, t1;
15470
15471    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15472        generate_exception_end(ctx, EXCP_RI);
15473        return;
15474    }
15475
15476    t0 = tcg_temp_new();
15477    t1 = tcg_temp_new();
15478
15479    gen_base_offset_addr(ctx, t0, base, offset);
15480
15481    switch (opc) {
15482    case LWP:
15483        if (rd == base) {
15484            generate_exception_end(ctx, EXCP_RI);
15485            return;
15486        }
15487        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15488        gen_store_gpr(t1, rd);
15489        tcg_gen_movi_tl(t1, 4);
15490        gen_op_addr_add(ctx, t0, t0, t1);
15491        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15492        gen_store_gpr(t1, rd + 1);
15493        break;
15494    case SWP:
15495        gen_load_gpr(t1, rd);
15496        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15497        tcg_gen_movi_tl(t1, 4);
15498        gen_op_addr_add(ctx, t0, t0, t1);
15499        gen_load_gpr(t1, rd + 1);
15500        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15501        break;
15502#ifdef TARGET_MIPS64
15503    case LDP:
15504        if (rd == base) {
15505            generate_exception_end(ctx, EXCP_RI);
15506            return;
15507        }
15508        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15509        gen_store_gpr(t1, rd);
15510        tcg_gen_movi_tl(t1, 8);
15511        gen_op_addr_add(ctx, t0, t0, t1);
15512        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15513        gen_store_gpr(t1, rd + 1);
15514        break;
15515    case SDP:
15516        gen_load_gpr(t1, rd);
15517        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15518        tcg_gen_movi_tl(t1, 8);
15519        gen_op_addr_add(ctx, t0, t0, t1);
15520        gen_load_gpr(t1, rd + 1);
15521        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15522        break;
15523#endif
15524    }
15525    tcg_temp_free(t0);
15526    tcg_temp_free(t1);
15527}
15528
15529static void gen_sync(int stype)
15530{
15531    TCGBar tcg_mo = TCG_BAR_SC;
15532
15533    switch (stype) {
15534    case 0x4: /* SYNC_WMB */
15535        tcg_mo |= TCG_MO_ST_ST;
15536        break;
15537    case 0x10: /* SYNC_MB */
15538        tcg_mo |= TCG_MO_ALL;
15539        break;
15540    case 0x11: /* SYNC_ACQUIRE */
15541        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15542        break;
15543    case 0x12: /* SYNC_RELEASE */
15544        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15545        break;
15546    case 0x13: /* SYNC_RMB */
15547        tcg_mo |= TCG_MO_LD_LD;
15548        break;
15549    default:
15550        tcg_mo |= TCG_MO_ALL;
15551        break;
15552    }
15553
15554    tcg_gen_mb(tcg_mo);
15555}
15556
15557static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15558{
15559    int extension = (ctx->opcode >> 6) & 0x3f;
15560    int minor = (ctx->opcode >> 12) & 0xf;
15561    uint32_t mips32_op;
15562
15563    switch (extension) {
15564    case TEQ:
15565        mips32_op = OPC_TEQ;
15566        goto do_trap;
15567    case TGE:
15568        mips32_op = OPC_TGE;
15569        goto do_trap;
15570    case TGEU:
15571        mips32_op = OPC_TGEU;
15572        goto do_trap;
15573    case TLT:
15574        mips32_op = OPC_TLT;
15575        goto do_trap;
15576    case TLTU:
15577        mips32_op = OPC_TLTU;
15578        goto do_trap;
15579    case TNE:
15580        mips32_op = OPC_TNE;
15581    do_trap:
15582        gen_trap(ctx, mips32_op, rs, rt, -1);
15583        break;
15584#ifndef CONFIG_USER_ONLY
15585    case MFC0:
15586    case MFC0 + 32:
15587        check_cp0_enabled(ctx);
15588        if (rt == 0) {
15589            /* Treat as NOP. */
15590            break;
15591        }
15592        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15593        break;
15594    case MTC0:
15595    case MTC0 + 32:
15596        check_cp0_enabled(ctx);
15597        {
15598            TCGv t0 = tcg_temp_new();
15599
15600            gen_load_gpr(t0, rt);
15601            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15602            tcg_temp_free(t0);
15603        }
15604        break;
15605#endif
15606    case 0x2a:
15607        switch (minor & 3) {
15608        case MADD_ACC:
15609            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15610            break;
15611        case MADDU_ACC:
15612            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15613            break;
15614        case MSUB_ACC:
15615            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15616            break;
15617        case MSUBU_ACC:
15618            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15619            break;
15620        default:
15621            goto pool32axf_invalid;
15622        }
15623        break;
15624    case 0x32:
15625        switch (minor & 3) {
15626        case MULT_ACC:
15627            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15628            break;
15629        case MULTU_ACC:
15630            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15631            break;
15632        default:
15633            goto pool32axf_invalid;
15634        }
15635        break;
15636    case 0x2c:
15637        switch (minor) {
15638        case BITSWAP:
15639            check_insn(ctx, ISA_MIPS32R6);
15640            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15641            break;
15642        case SEB:
15643            gen_bshfl(ctx, OPC_SEB, rs, rt);
15644            break;
15645        case SEH:
15646            gen_bshfl(ctx, OPC_SEH, rs, rt);
15647            break;
15648        case CLO:
15649            mips32_op = OPC_CLO;
15650            goto do_cl;
15651        case CLZ:
15652            mips32_op = OPC_CLZ;
15653        do_cl:
15654            check_insn(ctx, ISA_MIPS32);
15655            gen_cl(ctx, mips32_op, rt, rs);
15656            break;
15657        case RDHWR:
15658            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15659            gen_rdhwr(ctx, rt, rs, 0);
15660            break;
15661        case WSBH:
15662            gen_bshfl(ctx, OPC_WSBH, rs, rt);
15663            break;
15664        case MULT:
15665            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15666            mips32_op = OPC_MULT;
15667            goto do_mul;
15668        case MULTU:
15669            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15670            mips32_op = OPC_MULTU;
15671            goto do_mul;
15672        case DIV:
15673            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15674            mips32_op = OPC_DIV;
15675            goto do_div;
15676        case DIVU:
15677            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15678            mips32_op = OPC_DIVU;
15679            goto do_div;
15680        do_div:
15681            check_insn(ctx, ISA_MIPS32);
15682            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15683            break;
15684        case MADD:
15685            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15686            mips32_op = OPC_MADD;
15687            goto do_mul;
15688        case MADDU:
15689            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15690            mips32_op = OPC_MADDU;
15691            goto do_mul;
15692        case MSUB:
15693            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15694            mips32_op = OPC_MSUB;
15695            goto do_mul;
15696        case MSUBU:
15697            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15698            mips32_op = OPC_MSUBU;
15699        do_mul:
15700            check_insn(ctx, ISA_MIPS32);
15701            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15702            break;
15703        default:
15704            goto pool32axf_invalid;
15705        }
15706        break;
15707    case 0x34:
15708        switch (minor) {
15709        case MFC2:
15710        case MTC2:
15711        case MFHC2:
15712        case MTHC2:
15713        case CFC2:
15714        case CTC2:
15715            generate_exception_err(ctx, EXCP_CpU, 2);
15716            break;
15717        default:
15718            goto pool32axf_invalid;
15719        }
15720        break;
15721    case 0x3c:
15722        switch (minor) {
15723        case JALR:    /* JALRC */
15724        case JALR_HB: /* JALRC_HB */
15725            if (ctx->insn_flags & ISA_MIPS32R6) {
15726                /* JALRC, JALRC_HB */
15727                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15728            } else {
15729                /* JALR, JALR_HB */
15730                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15731                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15732            }
15733            break;
15734        case JALRS:
15735        case JALRS_HB:
15736            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15737            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15738            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15739            break;
15740        default:
15741            goto pool32axf_invalid;
15742        }
15743        break;
15744    case 0x05:
15745        switch (minor) {
15746        case RDPGPR:
15747            check_cp0_enabled(ctx);
15748            check_insn(ctx, ISA_MIPS32R2);
15749            gen_load_srsgpr(rs, rt);
15750            break;
15751        case WRPGPR:
15752            check_cp0_enabled(ctx);
15753            check_insn(ctx, ISA_MIPS32R2);
15754            gen_store_srsgpr(rs, rt);
15755            break;
15756        default:
15757            goto pool32axf_invalid;
15758        }
15759        break;
15760#ifndef CONFIG_USER_ONLY
15761    case 0x0d:
15762        switch (minor) {
15763        case TLBP:
15764            mips32_op = OPC_TLBP;
15765            goto do_cp0;
15766        case TLBR:
15767            mips32_op = OPC_TLBR;
15768            goto do_cp0;
15769        case TLBWI:
15770            mips32_op = OPC_TLBWI;
15771            goto do_cp0;
15772        case TLBWR:
15773            mips32_op = OPC_TLBWR;
15774            goto do_cp0;
15775        case TLBINV:
15776            mips32_op = OPC_TLBINV;
15777            goto do_cp0;
15778        case TLBINVF:
15779            mips32_op = OPC_TLBINVF;
15780            goto do_cp0;
15781        case WAIT:
15782            mips32_op = OPC_WAIT;
15783            goto do_cp0;
15784        case DERET:
15785            mips32_op = OPC_DERET;
15786            goto do_cp0;
15787        case ERET:
15788            mips32_op = OPC_ERET;
15789        do_cp0:
15790            gen_cp0(env, ctx, mips32_op, rt, rs);
15791            break;
15792        default:
15793            goto pool32axf_invalid;
15794        }
15795        break;
15796    case 0x1d:
15797        switch (minor) {
15798        case DI:
15799            check_cp0_enabled(ctx);
15800            {
15801                TCGv t0 = tcg_temp_new();
15802
15803                save_cpu_state(ctx, 1);
15804                gen_helper_di(t0, cpu_env);
15805                gen_store_gpr(t0, rs);
15806                /*
15807                 * Stop translation as we may have switched the execution
15808                 * mode.
15809                 */
15810                ctx->base.is_jmp = DISAS_STOP;
15811                tcg_temp_free(t0);
15812            }
15813            break;
15814        case EI:
15815            check_cp0_enabled(ctx);
15816            {
15817                TCGv t0 = tcg_temp_new();
15818
15819                save_cpu_state(ctx, 1);
15820                gen_helper_ei(t0, cpu_env);
15821                gen_store_gpr(t0, rs);
15822                /*
15823                 * DISAS_STOP isn't sufficient, we need to ensure we break out
15824                 * of translated code to check for pending interrupts.
15825                 */
15826                gen_save_pc(ctx->base.pc_next + 4);
15827                ctx->base.is_jmp = DISAS_EXIT;
15828                tcg_temp_free(t0);
15829            }
15830            break;
15831        default:
15832            goto pool32axf_invalid;
15833        }
15834        break;
15835#endif
15836    case 0x2d:
15837        switch (minor) {
15838        case SYNC:
15839            gen_sync(extract32(ctx->opcode, 16, 5));
15840            break;
15841        case SYSCALL:
15842            generate_exception_end(ctx, EXCP_SYSCALL);
15843            break;
15844        case SDBBP:
15845            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15846                gen_helper_do_semihosting(cpu_env);
15847            } else {
15848                check_insn(ctx, ISA_MIPS32);
15849                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15850                    generate_exception_end(ctx, EXCP_RI);
15851                } else {
15852                    generate_exception_end(ctx, EXCP_DBp);
15853                }
15854            }
15855            break;
15856        default:
15857            goto pool32axf_invalid;
15858        }
15859        break;
15860    case 0x01:
15861        switch (minor & 3) {
15862        case MFHI_ACC:
15863            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15864            break;
15865        case MFLO_ACC:
15866            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15867            break;
15868        case MTHI_ACC:
15869            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15870            break;
15871        case MTLO_ACC:
15872            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15873            break;
15874        default:
15875            goto pool32axf_invalid;
15876        }
15877        break;
15878    case 0x35:
15879        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15880        switch (minor) {
15881        case MFHI32:
15882            gen_HILO(ctx, OPC_MFHI, 0, rs);
15883            break;
15884        case MFLO32:
15885            gen_HILO(ctx, OPC_MFLO, 0, rs);
15886            break;
15887        case MTHI32:
15888            gen_HILO(ctx, OPC_MTHI, 0, rs);
15889            break;
15890        case MTLO32:
15891            gen_HILO(ctx, OPC_MTLO, 0, rs);
15892            break;
15893        default:
15894            goto pool32axf_invalid;
15895        }
15896        break;
15897    default:
15898    pool32axf_invalid:
15899        MIPS_INVAL("pool32axf");
15900        generate_exception_end(ctx, EXCP_RI);
15901        break;
15902    }
15903}
15904
15905/*
15906 * Values for microMIPS fmt field.  Variable-width, depending on which
15907 * formats the instruction supports.
15908 */
15909enum {
15910    FMT_SD_S = 0,
15911    FMT_SD_D = 1,
15912
15913    FMT_SDPS_S = 0,
15914    FMT_SDPS_D = 1,
15915    FMT_SDPS_PS = 2,
15916
15917    FMT_SWL_S = 0,
15918    FMT_SWL_W = 1,
15919    FMT_SWL_L = 2,
15920
15921    FMT_DWL_D = 0,
15922    FMT_DWL_W = 1,
15923    FMT_DWL_L = 2
15924};
15925
15926static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15927{
15928    int extension = (ctx->opcode >> 6) & 0x3ff;
15929    uint32_t mips32_op;
15930
15931#define FLOAT_1BIT_FMT(opc, fmt)    ((fmt << 8) | opc)
15932#define FLOAT_2BIT_FMT(opc, fmt)    ((fmt << 7) | opc)
15933#define COND_FLOAT_MOV(opc, cond)   ((cond << 7) | opc)
15934
15935    switch (extension) {
15936    case FLOAT_1BIT_FMT(CFC1, 0):
15937        mips32_op = OPC_CFC1;
15938        goto do_cp1;
15939    case FLOAT_1BIT_FMT(CTC1, 0):
15940        mips32_op = OPC_CTC1;
15941        goto do_cp1;
15942    case FLOAT_1BIT_FMT(MFC1, 0):
15943        mips32_op = OPC_MFC1;
15944        goto do_cp1;
15945    case FLOAT_1BIT_FMT(MTC1, 0):
15946        mips32_op = OPC_MTC1;
15947        goto do_cp1;
15948    case FLOAT_1BIT_FMT(MFHC1, 0):
15949        mips32_op = OPC_MFHC1;
15950        goto do_cp1;
15951    case FLOAT_1BIT_FMT(MTHC1, 0):
15952        mips32_op = OPC_MTHC1;
15953    do_cp1:
15954        gen_cp1(ctx, mips32_op, rt, rs);
15955        break;
15956
15957        /* Reciprocal square root */
15958    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15959        mips32_op = OPC_RSQRT_S;
15960        goto do_unaryfp;
15961    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15962        mips32_op = OPC_RSQRT_D;
15963        goto do_unaryfp;
15964
15965        /* Square root */
15966    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15967        mips32_op = OPC_SQRT_S;
15968        goto do_unaryfp;
15969    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15970        mips32_op = OPC_SQRT_D;
15971        goto do_unaryfp;
15972
15973        /* Reciprocal */
15974    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15975        mips32_op = OPC_RECIP_S;
15976        goto do_unaryfp;
15977    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15978        mips32_op = OPC_RECIP_D;
15979        goto do_unaryfp;
15980
15981        /* Floor */
15982    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15983        mips32_op = OPC_FLOOR_L_S;
15984        goto do_unaryfp;
15985    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15986        mips32_op = OPC_FLOOR_L_D;
15987        goto do_unaryfp;
15988    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15989        mips32_op = OPC_FLOOR_W_S;
15990        goto do_unaryfp;
15991    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15992        mips32_op = OPC_FLOOR_W_D;
15993        goto do_unaryfp;
15994
15995        /* Ceiling */
15996    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15997        mips32_op = OPC_CEIL_L_S;
15998        goto do_unaryfp;
15999    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
16000        mips32_op = OPC_CEIL_L_D;
16001        goto do_unaryfp;
16002    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
16003        mips32_op = OPC_CEIL_W_S;
16004        goto do_unaryfp;
16005    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
16006        mips32_op = OPC_CEIL_W_D;
16007        goto do_unaryfp;
16008
16009        /* Truncation */
16010    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
16011        mips32_op = OPC_TRUNC_L_S;
16012        goto do_unaryfp;
16013    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
16014        mips32_op = OPC_TRUNC_L_D;
16015        goto do_unaryfp;
16016    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
16017        mips32_op = OPC_TRUNC_W_S;
16018        goto do_unaryfp;
16019    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
16020        mips32_op = OPC_TRUNC_W_D;
16021        goto do_unaryfp;
16022
16023        /* Round */
16024    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
16025        mips32_op = OPC_ROUND_L_S;
16026        goto do_unaryfp;
16027    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
16028        mips32_op = OPC_ROUND_L_D;
16029        goto do_unaryfp;
16030    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
16031        mips32_op = OPC_ROUND_W_S;
16032        goto do_unaryfp;
16033    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
16034        mips32_op = OPC_ROUND_W_D;
16035        goto do_unaryfp;
16036
16037        /* Integer to floating-point conversion */
16038    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
16039        mips32_op = OPC_CVT_L_S;
16040        goto do_unaryfp;
16041    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
16042        mips32_op = OPC_CVT_L_D;
16043        goto do_unaryfp;
16044    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
16045        mips32_op = OPC_CVT_W_S;
16046        goto do_unaryfp;
16047    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
16048        mips32_op = OPC_CVT_W_D;
16049        goto do_unaryfp;
16050
16051        /* Paired-foo conversions */
16052    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
16053        mips32_op = OPC_CVT_S_PL;
16054        goto do_unaryfp;
16055    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
16056        mips32_op = OPC_CVT_S_PU;
16057        goto do_unaryfp;
16058    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
16059        mips32_op = OPC_CVT_PW_PS;
16060        goto do_unaryfp;
16061    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
16062        mips32_op = OPC_CVT_PS_PW;
16063        goto do_unaryfp;
16064
16065        /* Floating-point moves */
16066    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
16067        mips32_op = OPC_MOV_S;
16068        goto do_unaryfp;
16069    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
16070        mips32_op = OPC_MOV_D;
16071        goto do_unaryfp;
16072    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
16073        mips32_op = OPC_MOV_PS;
16074        goto do_unaryfp;
16075
16076        /* Absolute value */
16077    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
16078        mips32_op = OPC_ABS_S;
16079        goto do_unaryfp;
16080    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
16081        mips32_op = OPC_ABS_D;
16082        goto do_unaryfp;
16083    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
16084        mips32_op = OPC_ABS_PS;
16085        goto do_unaryfp;
16086
16087        /* Negation */
16088    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
16089        mips32_op = OPC_NEG_S;
16090        goto do_unaryfp;
16091    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
16092        mips32_op = OPC_NEG_D;
16093        goto do_unaryfp;
16094    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
16095        mips32_op = OPC_NEG_PS;
16096        goto do_unaryfp;
16097
16098        /* Reciprocal square root step */
16099    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
16100        mips32_op = OPC_RSQRT1_S;
16101        goto do_unaryfp;
16102    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
16103        mips32_op = OPC_RSQRT1_D;
16104        goto do_unaryfp;
16105    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
16106        mips32_op = OPC_RSQRT1_PS;
16107        goto do_unaryfp;
16108
16109        /* Reciprocal step */
16110    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
16111        mips32_op = OPC_RECIP1_S;
16112        goto do_unaryfp;
16113    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
16114        mips32_op = OPC_RECIP1_S;
16115        goto do_unaryfp;
16116    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
16117        mips32_op = OPC_RECIP1_PS;
16118        goto do_unaryfp;
16119
16120        /* Conversions from double */
16121    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
16122        mips32_op = OPC_CVT_D_S;
16123        goto do_unaryfp;
16124    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
16125        mips32_op = OPC_CVT_D_W;
16126        goto do_unaryfp;
16127    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
16128        mips32_op = OPC_CVT_D_L;
16129        goto do_unaryfp;
16130
16131        /* Conversions from single */
16132    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
16133        mips32_op = OPC_CVT_S_D;
16134        goto do_unaryfp;
16135    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
16136        mips32_op = OPC_CVT_S_W;
16137        goto do_unaryfp;
16138    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
16139        mips32_op = OPC_CVT_S_L;
16140    do_unaryfp:
16141        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
16142        break;
16143
16144        /* Conditional moves on floating-point codes */
16145    case COND_FLOAT_MOV(MOVT, 0):
16146    case COND_FLOAT_MOV(MOVT, 1):
16147    case COND_FLOAT_MOV(MOVT, 2):
16148    case COND_FLOAT_MOV(MOVT, 3):
16149    case COND_FLOAT_MOV(MOVT, 4):
16150    case COND_FLOAT_MOV(MOVT, 5):
16151    case COND_FLOAT_MOV(MOVT, 6):
16152    case COND_FLOAT_MOV(MOVT, 7):
16153        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16154        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
16155        break;
16156    case COND_FLOAT_MOV(MOVF, 0):
16157    case COND_FLOAT_MOV(MOVF, 1):
16158    case COND_FLOAT_MOV(MOVF, 2):
16159    case COND_FLOAT_MOV(MOVF, 3):
16160    case COND_FLOAT_MOV(MOVF, 4):
16161    case COND_FLOAT_MOV(MOVF, 5):
16162    case COND_FLOAT_MOV(MOVF, 6):
16163    case COND_FLOAT_MOV(MOVF, 7):
16164        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16165        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
16166        break;
16167    default:
16168        MIPS_INVAL("pool32fxf");
16169        generate_exception_end(ctx, EXCP_RI);
16170        break;
16171    }
16172}
16173
16174static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
16175{
16176    int32_t offset;
16177    uint16_t insn;
16178    int rt, rs, rd, rr;
16179    int16_t imm;
16180    uint32_t op, minor, minor2, mips32_op;
16181    uint32_t cond, fmt, cc;
16182
16183    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
16184    ctx->opcode = (ctx->opcode << 16) | insn;
16185
16186    rt = (ctx->opcode >> 21) & 0x1f;
16187    rs = (ctx->opcode >> 16) & 0x1f;
16188    rd = (ctx->opcode >> 11) & 0x1f;
16189    rr = (ctx->opcode >> 6) & 0x1f;
16190    imm = (int16_t) ctx->opcode;
16191
16192    op = (ctx->opcode >> 26) & 0x3f;
16193    switch (op) {
16194    case POOL32A:
16195        minor = ctx->opcode & 0x3f;
16196        switch (minor) {
16197        case 0x00:
16198            minor = (ctx->opcode >> 6) & 0xf;
16199            switch (minor) {
16200            case SLL32:
16201                mips32_op = OPC_SLL;
16202                goto do_shifti;
16203            case SRA:
16204                mips32_op = OPC_SRA;
16205                goto do_shifti;
16206            case SRL32:
16207                mips32_op = OPC_SRL;
16208                goto do_shifti;
16209            case ROTR:
16210                mips32_op = OPC_ROTR;
16211            do_shifti:
16212                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
16213                break;
16214            case SELEQZ:
16215                check_insn(ctx, ISA_MIPS32R6);
16216                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
16217                break;
16218            case SELNEZ:
16219                check_insn(ctx, ISA_MIPS32R6);
16220                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
16221                break;
16222            case R6_RDHWR:
16223                check_insn(ctx, ISA_MIPS32R6);
16224                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
16225                break;
16226            default:
16227                goto pool32a_invalid;
16228            }
16229            break;
16230        case 0x10:
16231            minor = (ctx->opcode >> 6) & 0xf;
16232            switch (minor) {
16233                /* Arithmetic */
16234            case ADD:
16235                mips32_op = OPC_ADD;
16236                goto do_arith;
16237            case ADDU32:
16238                mips32_op = OPC_ADDU;
16239                goto do_arith;
16240            case SUB:
16241                mips32_op = OPC_SUB;
16242                goto do_arith;
16243            case SUBU32:
16244                mips32_op = OPC_SUBU;
16245                goto do_arith;
16246            case MUL:
16247                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16248                mips32_op = OPC_MUL;
16249            do_arith:
16250                gen_arith(ctx, mips32_op, rd, rs, rt);
16251                break;
16252                /* Shifts */
16253            case SLLV:
16254                mips32_op = OPC_SLLV;
16255                goto do_shift;
16256            case SRLV:
16257                mips32_op = OPC_SRLV;
16258                goto do_shift;
16259            case SRAV:
16260                mips32_op = OPC_SRAV;
16261                goto do_shift;
16262            case ROTRV:
16263                mips32_op = OPC_ROTRV;
16264            do_shift:
16265                gen_shift(ctx, mips32_op, rd, rs, rt);
16266                break;
16267                /* Logical operations */
16268            case AND:
16269                mips32_op = OPC_AND;
16270                goto do_logic;
16271            case OR32:
16272                mips32_op = OPC_OR;
16273                goto do_logic;
16274            case NOR:
16275                mips32_op = OPC_NOR;
16276                goto do_logic;
16277            case XOR32:
16278                mips32_op = OPC_XOR;
16279            do_logic:
16280                gen_logic(ctx, mips32_op, rd, rs, rt);
16281                break;
16282                /* Set less than */
16283            case SLT:
16284                mips32_op = OPC_SLT;
16285                goto do_slt;
16286            case SLTU:
16287                mips32_op = OPC_SLTU;
16288            do_slt:
16289                gen_slt(ctx, mips32_op, rd, rs, rt);
16290                break;
16291            default:
16292                goto pool32a_invalid;
16293            }
16294            break;
16295        case 0x18:
16296            minor = (ctx->opcode >> 6) & 0xf;
16297            switch (minor) {
16298                /* Conditional moves */
16299            case MOVN: /* MUL */
16300                if (ctx->insn_flags & ISA_MIPS32R6) {
16301                    /* MUL */
16302                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16303                } else {
16304                    /* MOVN */
16305                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16306                }
16307                break;
16308            case MOVZ: /* MUH */
16309                if (ctx->insn_flags & ISA_MIPS32R6) {
16310                    /* MUH */
16311                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16312                } else {
16313                    /* MOVZ */
16314                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16315                }
16316                break;
16317            case MULU:
16318                check_insn(ctx, ISA_MIPS32R6);
16319                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16320                break;
16321            case MUHU:
16322                check_insn(ctx, ISA_MIPS32R6);
16323                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16324                break;
16325            case LWXS: /* DIV */
16326                if (ctx->insn_flags & ISA_MIPS32R6) {
16327                    /* DIV */
16328                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16329                } else {
16330                    /* LWXS */
16331                    gen_ldxs(ctx, rs, rt, rd);
16332                }
16333                break;
16334            case MOD:
16335                check_insn(ctx, ISA_MIPS32R6);
16336                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16337                break;
16338            case R6_DIVU:
16339                check_insn(ctx, ISA_MIPS32R6);
16340                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16341                break;
16342            case MODU:
16343                check_insn(ctx, ISA_MIPS32R6);
16344                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16345                break;
16346            default:
16347                goto pool32a_invalid;
16348            }
16349            break;
16350        case INS:
16351            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16352            return;
16353        case LSA:
16354            check_insn(ctx, ISA_MIPS32R6);
16355            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16356                    extract32(ctx->opcode, 9, 2));
16357            break;
16358        case ALIGN:
16359            check_insn(ctx, ISA_MIPS32R6);
16360            gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16361            break;
16362        case EXT:
16363            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16364            return;
16365        case POOL32AXF:
16366            gen_pool32axf(env, ctx, rt, rs);
16367            break;
16368        case BREAK32:
16369            generate_exception_end(ctx, EXCP_BREAK);
16370            break;
16371        case SIGRIE:
16372            check_insn(ctx, ISA_MIPS32R6);
16373            generate_exception_end(ctx, EXCP_RI);
16374            break;
16375        default:
16376        pool32a_invalid:
16377                MIPS_INVAL("pool32a");
16378                generate_exception_end(ctx, EXCP_RI);
16379                break;
16380        }
16381        break;
16382    case POOL32B:
16383        minor = (ctx->opcode >> 12) & 0xf;
16384        switch (minor) {
16385        case CACHE:
16386            check_cp0_enabled(ctx);
16387            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16388                gen_cache_operation(ctx, rt, rs, imm);
16389            }
16390            break;
16391        case LWC2:
16392        case SWC2:
16393            /* COP2: Not implemented. */
16394            generate_exception_err(ctx, EXCP_CpU, 2);
16395            break;
16396#ifdef TARGET_MIPS64
16397        case LDP:
16398        case SDP:
16399            check_insn(ctx, ISA_MIPS3);
16400            check_mips_64(ctx);
16401#endif
16402            /* fall through */
16403        case LWP:
16404        case SWP:
16405            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16406            break;
16407#ifdef TARGET_MIPS64
16408        case LDM:
16409        case SDM:
16410            check_insn(ctx, ISA_MIPS3);
16411            check_mips_64(ctx);
16412#endif
16413            /* fall through */
16414        case LWM32:
16415        case SWM32:
16416            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16417            break;
16418        default:
16419            MIPS_INVAL("pool32b");
16420            generate_exception_end(ctx, EXCP_RI);
16421            break;
16422        }
16423        break;
16424    case POOL32F:
16425        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16426            minor = ctx->opcode & 0x3f;
16427            check_cp1_enabled(ctx);
16428            switch (minor) {
16429            case ALNV_PS:
16430                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16431                mips32_op = OPC_ALNV_PS;
16432                goto do_madd;
16433            case MADD_S:
16434                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16435                mips32_op = OPC_MADD_S;
16436                goto do_madd;
16437            case MADD_D:
16438                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16439                mips32_op = OPC_MADD_D;
16440                goto do_madd;
16441            case MADD_PS:
16442                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16443                mips32_op = OPC_MADD_PS;
16444                goto do_madd;
16445            case MSUB_S:
16446                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16447                mips32_op = OPC_MSUB_S;
16448                goto do_madd;
16449            case MSUB_D:
16450                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16451                mips32_op = OPC_MSUB_D;
16452                goto do_madd;
16453            case MSUB_PS:
16454                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16455                mips32_op = OPC_MSUB_PS;
16456                goto do_madd;
16457            case NMADD_S:
16458                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16459                mips32_op = OPC_NMADD_S;
16460                goto do_madd;
16461            case NMADD_D:
16462                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16463                mips32_op = OPC_NMADD_D;
16464                goto do_madd;
16465            case NMADD_PS:
16466                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16467                mips32_op = OPC_NMADD_PS;
16468                goto do_madd;
16469            case NMSUB_S:
16470                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16471                mips32_op = OPC_NMSUB_S;
16472                goto do_madd;
16473            case NMSUB_D:
16474                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16475                mips32_op = OPC_NMSUB_D;
16476                goto do_madd;
16477            case NMSUB_PS:
16478                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16479                mips32_op = OPC_NMSUB_PS;
16480            do_madd:
16481                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16482                break;
16483            case CABS_COND_FMT:
16484                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16485                cond = (ctx->opcode >> 6) & 0xf;
16486                cc = (ctx->opcode >> 13) & 0x7;
16487                fmt = (ctx->opcode >> 10) & 0x3;
16488                switch (fmt) {
16489                case 0x0:
16490                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
16491                    break;
16492                case 0x1:
16493                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
16494                    break;
16495                case 0x2:
16496                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16497                    break;
16498                default:
16499                    goto pool32f_invalid;
16500                }
16501                break;
16502            case C_COND_FMT:
16503                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16504                cond = (ctx->opcode >> 6) & 0xf;
16505                cc = (ctx->opcode >> 13) & 0x7;
16506                fmt = (ctx->opcode >> 10) & 0x3;
16507                switch (fmt) {
16508                case 0x0:
16509                    gen_cmp_s(ctx, cond, rt, rs, cc);
16510                    break;
16511                case 0x1:
16512                    gen_cmp_d(ctx, cond, rt, rs, cc);
16513                    break;
16514                case 0x2:
16515                    gen_cmp_ps(ctx, cond, rt, rs, cc);
16516                    break;
16517                default:
16518                    goto pool32f_invalid;
16519                }
16520                break;
16521            case CMP_CONDN_S:
16522                check_insn(ctx, ISA_MIPS32R6);
16523                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16524                break;
16525            case CMP_CONDN_D:
16526                check_insn(ctx, ISA_MIPS32R6);
16527                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16528                break;
16529            case POOL32FXF:
16530                gen_pool32fxf(ctx, rt, rs);
16531                break;
16532            case 0x00:
16533                /* PLL foo */
16534                switch ((ctx->opcode >> 6) & 0x7) {
16535                case PLL_PS:
16536                    mips32_op = OPC_PLL_PS;
16537                    goto do_ps;
16538                case PLU_PS:
16539                    mips32_op = OPC_PLU_PS;
16540                    goto do_ps;
16541                case PUL_PS:
16542                    mips32_op = OPC_PUL_PS;
16543                    goto do_ps;
16544                case PUU_PS:
16545                    mips32_op = OPC_PUU_PS;
16546                    goto do_ps;
16547                case CVT_PS_S:
16548                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16549                    mips32_op = OPC_CVT_PS_S;
16550                do_ps:
16551                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16552                    break;
16553                default:
16554                    goto pool32f_invalid;
16555                }
16556                break;
16557            case MIN_FMT:
16558                check_insn(ctx, ISA_MIPS32R6);
16559                switch ((ctx->opcode >> 9) & 0x3) {
16560                case FMT_SDPS_S:
16561                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16562                    break;
16563                case FMT_SDPS_D:
16564                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16565                    break;
16566                default:
16567                    goto pool32f_invalid;
16568                }
16569                break;
16570            case 0x08:
16571                /* [LS][WDU]XC1 */
16572                switch ((ctx->opcode >> 6) & 0x7) {
16573                case LWXC1:
16574                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16575                    mips32_op = OPC_LWXC1;
16576                    goto do_ldst_cp1;
16577                case SWXC1:
16578                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16579                    mips32_op = OPC_SWXC1;
16580                    goto do_ldst_cp1;
16581                case LDXC1:
16582                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16583                    mips32_op = OPC_LDXC1;
16584                    goto do_ldst_cp1;
16585                case SDXC1:
16586                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16587                    mips32_op = OPC_SDXC1;
16588                    goto do_ldst_cp1;
16589                case LUXC1:
16590                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16591                    mips32_op = OPC_LUXC1;
16592                    goto do_ldst_cp1;
16593                case SUXC1:
16594                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16595                    mips32_op = OPC_SUXC1;
16596                do_ldst_cp1:
16597                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16598                    break;
16599                default:
16600                    goto pool32f_invalid;
16601                }
16602                break;
16603            case MAX_FMT:
16604                check_insn(ctx, ISA_MIPS32R6);
16605                switch ((ctx->opcode >> 9) & 0x3) {
16606                case FMT_SDPS_S:
16607                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16608                    break;
16609                case FMT_SDPS_D:
16610                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16611                    break;
16612                default:
16613                    goto pool32f_invalid;
16614                }
16615                break;
16616            case 0x18:
16617                /* 3D insns */
16618                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16619                fmt = (ctx->opcode >> 9) & 0x3;
16620                switch ((ctx->opcode >> 6) & 0x7) {
16621                case RSQRT2_FMT:
16622                    switch (fmt) {
16623                    case FMT_SDPS_S:
16624                        mips32_op = OPC_RSQRT2_S;
16625                        goto do_3d;
16626                    case FMT_SDPS_D:
16627                        mips32_op = OPC_RSQRT2_D;
16628                        goto do_3d;
16629                    case FMT_SDPS_PS:
16630                        mips32_op = OPC_RSQRT2_PS;
16631                        goto do_3d;
16632                    default:
16633                        goto pool32f_invalid;
16634                    }
16635                    break;
16636                case RECIP2_FMT:
16637                    switch (fmt) {
16638                    case FMT_SDPS_S:
16639                        mips32_op = OPC_RECIP2_S;
16640                        goto do_3d;
16641                    case FMT_SDPS_D:
16642                        mips32_op = OPC_RECIP2_D;
16643                        goto do_3d;
16644                    case FMT_SDPS_PS:
16645                        mips32_op = OPC_RECIP2_PS;
16646                        goto do_3d;
16647                    default:
16648                        goto pool32f_invalid;
16649                    }
16650                    break;
16651                case ADDR_PS:
16652                    mips32_op = OPC_ADDR_PS;
16653                    goto do_3d;
16654                case MULR_PS:
16655                    mips32_op = OPC_MULR_PS;
16656                do_3d:
16657                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16658                    break;
16659                default:
16660                    goto pool32f_invalid;
16661                }
16662                break;
16663            case 0x20:
16664                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16665                cc = (ctx->opcode >> 13) & 0x7;
16666                fmt = (ctx->opcode >> 9) & 0x3;
16667                switch ((ctx->opcode >> 6) & 0x7) {
16668                case MOVF_FMT: /* RINT_FMT */
16669                    if (ctx->insn_flags & ISA_MIPS32R6) {
16670                        /* RINT_FMT */
16671                        switch (fmt) {
16672                        case FMT_SDPS_S:
16673                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16674                            break;
16675                        case FMT_SDPS_D:
16676                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16677                            break;
16678                        default:
16679                            goto pool32f_invalid;
16680                        }
16681                    } else {
16682                        /* MOVF_FMT */
16683                        switch (fmt) {
16684                        case FMT_SDPS_S:
16685                            gen_movcf_s(ctx, rs, rt, cc, 0);
16686                            break;
16687                        case FMT_SDPS_D:
16688                            gen_movcf_d(ctx, rs, rt, cc, 0);
16689                            break;
16690                        case FMT_SDPS_PS:
16691                            check_ps(ctx);
16692                            gen_movcf_ps(ctx, rs, rt, cc, 0);
16693                            break;
16694                        default:
16695                            goto pool32f_invalid;
16696                        }
16697                    }
16698                    break;
16699                case MOVT_FMT: /* CLASS_FMT */
16700                    if (ctx->insn_flags & ISA_MIPS32R6) {
16701                        /* CLASS_FMT */
16702                        switch (fmt) {
16703                        case FMT_SDPS_S:
16704                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16705                            break;
16706                        case FMT_SDPS_D:
16707                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16708                            break;
16709                        default:
16710                            goto pool32f_invalid;
16711                        }
16712                    } else {
16713                        /* MOVT_FMT */
16714                        switch (fmt) {
16715                        case FMT_SDPS_S:
16716                            gen_movcf_s(ctx, rs, rt, cc, 1);
16717                            break;
16718                        case FMT_SDPS_D:
16719                            gen_movcf_d(ctx, rs, rt, cc, 1);
16720                            break;
16721                        case FMT_SDPS_PS:
16722                            check_ps(ctx);
16723                            gen_movcf_ps(ctx, rs, rt, cc, 1);
16724                            break;
16725                        default:
16726                            goto pool32f_invalid;
16727                        }
16728                    }
16729                    break;
16730                case PREFX:
16731                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16732                    break;
16733                default:
16734                    goto pool32f_invalid;
16735                }
16736                break;
16737#define FINSN_3ARG_SDPS(prfx)                           \
16738                switch ((ctx->opcode >> 8) & 0x3) {     \
16739                case FMT_SDPS_S:                        \
16740                    mips32_op = OPC_##prfx##_S;         \
16741                    goto do_fpop;                       \
16742                case FMT_SDPS_D:                        \
16743                    mips32_op = OPC_##prfx##_D;         \
16744                    goto do_fpop;                       \
16745                case FMT_SDPS_PS:                       \
16746                    check_ps(ctx);                      \
16747                    mips32_op = OPC_##prfx##_PS;        \
16748                    goto do_fpop;                       \
16749                default:                                \
16750                    goto pool32f_invalid;               \
16751                }
16752            case MINA_FMT:
16753                check_insn(ctx, ISA_MIPS32R6);
16754                switch ((ctx->opcode >> 9) & 0x3) {
16755                case FMT_SDPS_S:
16756                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16757                    break;
16758                case FMT_SDPS_D:
16759                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16760                    break;
16761                default:
16762                    goto pool32f_invalid;
16763                }
16764                break;
16765            case MAXA_FMT:
16766                check_insn(ctx, ISA_MIPS32R6);
16767                switch ((ctx->opcode >> 9) & 0x3) {
16768                case FMT_SDPS_S:
16769                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16770                    break;
16771                case FMT_SDPS_D:
16772                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16773                    break;
16774                default:
16775                    goto pool32f_invalid;
16776                }
16777                break;
16778            case 0x30:
16779                /* regular FP ops */
16780                switch ((ctx->opcode >> 6) & 0x3) {
16781                case ADD_FMT:
16782                    FINSN_3ARG_SDPS(ADD);
16783                    break;
16784                case SUB_FMT:
16785                    FINSN_3ARG_SDPS(SUB);
16786                    break;
16787                case MUL_FMT:
16788                    FINSN_3ARG_SDPS(MUL);
16789                    break;
16790                case DIV_FMT:
16791                    fmt = (ctx->opcode >> 8) & 0x3;
16792                    if (fmt == 1) {
16793                        mips32_op = OPC_DIV_D;
16794                    } else if (fmt == 0) {
16795                        mips32_op = OPC_DIV_S;
16796                    } else {
16797                        goto pool32f_invalid;
16798                    }
16799                    goto do_fpop;
16800                default:
16801                    goto pool32f_invalid;
16802                }
16803                break;
16804            case 0x38:
16805                /* cmovs */
16806                switch ((ctx->opcode >> 6) & 0x7) {
16807                case MOVN_FMT: /* SELEQZ_FMT */
16808                    if (ctx->insn_flags & ISA_MIPS32R6) {
16809                        /* SELEQZ_FMT */
16810                        switch ((ctx->opcode >> 9) & 0x3) {
16811                        case FMT_SDPS_S:
16812                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16813                            break;
16814                        case FMT_SDPS_D:
16815                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16816                            break;
16817                        default:
16818                            goto pool32f_invalid;
16819                        }
16820                    } else {
16821                        /* MOVN_FMT */
16822                        FINSN_3ARG_SDPS(MOVN);
16823                    }
16824                    break;
16825                case MOVN_FMT_04:
16826                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16827                    FINSN_3ARG_SDPS(MOVN);
16828                    break;
16829                case MOVZ_FMT: /* SELNEZ_FMT */
16830                    if (ctx->insn_flags & ISA_MIPS32R6) {
16831                        /* SELNEZ_FMT */
16832                        switch ((ctx->opcode >> 9) & 0x3) {
16833                        case FMT_SDPS_S:
16834                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16835                            break;
16836                        case FMT_SDPS_D:
16837                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16838                            break;
16839                        default:
16840                            goto pool32f_invalid;
16841                        }
16842                    } else {
16843                        /* MOVZ_FMT */
16844                        FINSN_3ARG_SDPS(MOVZ);
16845                    }
16846                    break;
16847                case MOVZ_FMT_05:
16848                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16849                    FINSN_3ARG_SDPS(MOVZ);
16850                    break;
16851                case SEL_FMT:
16852                    check_insn(ctx, ISA_MIPS32R6);
16853                    switch ((ctx->opcode >> 9) & 0x3) {
16854                    case FMT_SDPS_S:
16855                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16856                        break;
16857                    case FMT_SDPS_D:
16858                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16859                        break;
16860                    default:
16861                        goto pool32f_invalid;
16862                    }
16863                    break;
16864                case MADDF_FMT:
16865                    check_insn(ctx, ISA_MIPS32R6);
16866                    switch ((ctx->opcode >> 9) & 0x3) {
16867                    case FMT_SDPS_S:
16868                        mips32_op = OPC_MADDF_S;
16869                        goto do_fpop;
16870                    case FMT_SDPS_D:
16871                        mips32_op = OPC_MADDF_D;
16872                        goto do_fpop;
16873                    default:
16874                        goto pool32f_invalid;
16875                    }
16876                    break;
16877                case MSUBF_FMT:
16878                    check_insn(ctx, ISA_MIPS32R6);
16879                    switch ((ctx->opcode >> 9) & 0x3) {
16880                    case FMT_SDPS_S:
16881                        mips32_op = OPC_MSUBF_S;
16882                        goto do_fpop;
16883                    case FMT_SDPS_D:
16884                        mips32_op = OPC_MSUBF_D;
16885                        goto do_fpop;
16886                    default:
16887                        goto pool32f_invalid;
16888                    }
16889                    break;
16890                default:
16891                    goto pool32f_invalid;
16892                }
16893                break;
16894            do_fpop:
16895                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16896                break;
16897            default:
16898            pool32f_invalid:
16899                MIPS_INVAL("pool32f");
16900                generate_exception_end(ctx, EXCP_RI);
16901                break;
16902            }
16903        } else {
16904            generate_exception_err(ctx, EXCP_CpU, 1);
16905        }
16906        break;
16907    case POOL32I:
16908        minor = (ctx->opcode >> 21) & 0x1f;
16909        switch (minor) {
16910        case BLTZ:
16911            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16912            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16913            break;
16914        case BLTZAL:
16915            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16916            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16917            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16918            break;
16919        case BLTZALS:
16920            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16921            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16922            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16923            break;
16924        case BGEZ:
16925            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16926            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16927            break;
16928        case BGEZAL:
16929            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16930            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16931            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16932            break;
16933        case BGEZALS:
16934            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16935            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16936            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16937            break;
16938        case BLEZ:
16939            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16940            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16941            break;
16942        case BGTZ:
16943            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16944            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16945            break;
16946
16947            /* Traps */
16948        case TLTI: /* BC1EQZC */
16949            if (ctx->insn_flags & ISA_MIPS32R6) {
16950                /* BC1EQZC */
16951                check_cp1_enabled(ctx);
16952                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16953            } else {
16954                /* TLTI */
16955                mips32_op = OPC_TLTI;
16956                goto do_trapi;
16957            }
16958            break;
16959        case TGEI: /* BC1NEZC */
16960            if (ctx->insn_flags & ISA_MIPS32R6) {
16961                /* BC1NEZC */
16962                check_cp1_enabled(ctx);
16963                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16964            } else {
16965                /* TGEI */
16966                mips32_op = OPC_TGEI;
16967                goto do_trapi;
16968            }
16969            break;
16970        case TLTIU:
16971            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16972            mips32_op = OPC_TLTIU;
16973            goto do_trapi;
16974        case TGEIU:
16975            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16976            mips32_op = OPC_TGEIU;
16977            goto do_trapi;
16978        case TNEI: /* SYNCI */
16979            if (ctx->insn_flags & ISA_MIPS32R6) {
16980                /* SYNCI */
16981                /*
16982                 * Break the TB to be able to sync copied instructions
16983                 * immediately.
16984                 */
16985                ctx->base.is_jmp = DISAS_STOP;
16986            } else {
16987                /* TNEI */
16988                mips32_op = OPC_TNEI;
16989                goto do_trapi;
16990            }
16991            break;
16992        case TEQI:
16993            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16994            mips32_op = OPC_TEQI;
16995        do_trapi:
16996            gen_trap(ctx, mips32_op, rs, -1, imm);
16997            break;
16998
16999        case BNEZC:
17000        case BEQZC:
17001            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17002            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
17003                               4, rs, 0, imm << 1, 0);
17004            /*
17005             * Compact branches don't have a delay slot, so just let
17006             * the normal delay slot handling take us to the branch
17007             * target.
17008             */
17009            break;
17010        case LUI:
17011            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17012            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
17013            break;
17014        case SYNCI:
17015            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17016            /*
17017             * Break the TB to be able to sync copied instructions
17018             * immediately.
17019             */
17020            ctx->base.is_jmp = DISAS_STOP;
17021            break;
17022        case BC2F:
17023        case BC2T:
17024            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17025            /* COP2: Not implemented. */
17026            generate_exception_err(ctx, EXCP_CpU, 2);
17027            break;
17028        case BC1F:
17029            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17030            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
17031            goto do_cp1branch;
17032        case BC1T:
17033            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17034            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
17035            goto do_cp1branch;
17036        case BC1ANY4F:
17037            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17038            mips32_op = OPC_BC1FANY4;
17039            goto do_cp1mips3d;
17040        case BC1ANY4T:
17041            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17042            mips32_op = OPC_BC1TANY4;
17043        do_cp1mips3d:
17044            check_cop1x(ctx);
17045            check_insn(ctx, ASE_MIPS3D);
17046            /* Fall through */
17047        do_cp1branch:
17048            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17049                check_cp1_enabled(ctx);
17050                gen_compute_branch1(ctx, mips32_op,
17051                                    (ctx->opcode >> 18) & 0x7, imm << 1);
17052            } else {
17053                generate_exception_err(ctx, EXCP_CpU, 1);
17054            }
17055            break;
17056        case BPOSGE64:
17057        case BPOSGE32:
17058            /* MIPS DSP: not implemented */
17059            /* Fall through */
17060        default:
17061            MIPS_INVAL("pool32i");
17062            generate_exception_end(ctx, EXCP_RI);
17063            break;
17064        }
17065        break;
17066    case POOL32C:
17067        minor = (ctx->opcode >> 12) & 0xf;
17068        offset = sextract32(ctx->opcode, 0,
17069                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
17070        switch (minor) {
17071        case LWL:
17072            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17073            mips32_op = OPC_LWL;
17074            goto do_ld_lr;
17075        case SWL:
17076            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17077            mips32_op = OPC_SWL;
17078            goto do_st_lr;
17079        case LWR:
17080            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17081            mips32_op = OPC_LWR;
17082            goto do_ld_lr;
17083        case SWR:
17084            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17085            mips32_op = OPC_SWR;
17086            goto do_st_lr;
17087#if defined(TARGET_MIPS64)
17088        case LDL:
17089            check_insn(ctx, ISA_MIPS3);
17090            check_mips_64(ctx);
17091            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17092            mips32_op = OPC_LDL;
17093            goto do_ld_lr;
17094        case SDL:
17095            check_insn(ctx, ISA_MIPS3);
17096            check_mips_64(ctx);
17097            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17098            mips32_op = OPC_SDL;
17099            goto do_st_lr;
17100        case LDR:
17101            check_insn(ctx, ISA_MIPS3);
17102            check_mips_64(ctx);
17103            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17104            mips32_op = OPC_LDR;
17105            goto do_ld_lr;
17106        case SDR:
17107            check_insn(ctx, ISA_MIPS3);
17108            check_mips_64(ctx);
17109            check_insn_opc_removed(ctx, ISA_MIPS32R6);
17110            mips32_op = OPC_SDR;
17111            goto do_st_lr;
17112        case LWU:
17113            check_insn(ctx, ISA_MIPS3);
17114            check_mips_64(ctx);
17115            mips32_op = OPC_LWU;
17116            goto do_ld_lr;
17117        case LLD:
17118            check_insn(ctx, ISA_MIPS3);
17119            check_mips_64(ctx);
17120            mips32_op = OPC_LLD;
17121            goto do_ld_lr;
17122#endif
17123        case LL:
17124            mips32_op = OPC_LL;
17125            goto do_ld_lr;
17126        do_ld_lr:
17127            gen_ld(ctx, mips32_op, rt, rs, offset);
17128            break;
17129        do_st_lr:
17130            gen_st(ctx, mips32_op, rt, rs, offset);
17131            break;
17132        case SC:
17133            gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
17134            break;
17135#if defined(TARGET_MIPS64)
17136        case SCD:
17137            check_insn(ctx, ISA_MIPS3);
17138            check_mips_64(ctx);
17139            gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
17140            break;
17141#endif
17142        case LD_EVA:
17143            if (!ctx->eva) {
17144                MIPS_INVAL("pool32c ld-eva");
17145                generate_exception_end(ctx, EXCP_RI);
17146                break;
17147            }
17148            check_cp0_enabled(ctx);
17149
17150            minor2 = (ctx->opcode >> 9) & 0x7;
17151            offset = sextract32(ctx->opcode, 0, 9);
17152            switch (minor2) {
17153            case LBUE:
17154                mips32_op = OPC_LBUE;
17155                goto do_ld_lr;
17156            case LHUE:
17157                mips32_op = OPC_LHUE;
17158                goto do_ld_lr;
17159            case LWLE:
17160                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17161                mips32_op = OPC_LWLE;
17162                goto do_ld_lr;
17163            case LWRE:
17164                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17165                mips32_op = OPC_LWRE;
17166                goto do_ld_lr;
17167            case LBE:
17168                mips32_op = OPC_LBE;
17169                goto do_ld_lr;
17170            case LHE:
17171                mips32_op = OPC_LHE;
17172                goto do_ld_lr;
17173            case LLE:
17174                mips32_op = OPC_LLE;
17175                goto do_ld_lr;
17176            case LWE:
17177                mips32_op = OPC_LWE;
17178                goto do_ld_lr;
17179            };
17180            break;
17181        case ST_EVA:
17182            if (!ctx->eva) {
17183                MIPS_INVAL("pool32c st-eva");
17184                generate_exception_end(ctx, EXCP_RI);
17185                break;
17186            }
17187            check_cp0_enabled(ctx);
17188
17189            minor2 = (ctx->opcode >> 9) & 0x7;
17190            offset = sextract32(ctx->opcode, 0, 9);
17191            switch (minor2) {
17192            case SWLE:
17193                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17194                mips32_op = OPC_SWLE;
17195                goto do_st_lr;
17196            case SWRE:
17197                check_insn_opc_removed(ctx, ISA_MIPS32R6);
17198                mips32_op = OPC_SWRE;
17199                goto do_st_lr;
17200            case PREFE:
17201                /* Treat as no-op */
17202                if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17203                    /* hint codes 24-31 are reserved and signal RI */
17204                    generate_exception(ctx, EXCP_RI);
17205                }
17206                break;
17207            case CACHEE:
17208                /* Treat as no-op */
17209                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17210                    gen_cache_operation(ctx, rt, rs, offset);
17211                }
17212                break;
17213            case SBE:
17214                mips32_op = OPC_SBE;
17215                goto do_st_lr;
17216            case SHE:
17217                mips32_op = OPC_SHE;
17218                goto do_st_lr;
17219            case SCE:
17220                gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
17221                break;
17222            case SWE:
17223                mips32_op = OPC_SWE;
17224                goto do_st_lr;
17225            };
17226            break;
17227        case PREF:
17228            /* Treat as no-op */
17229            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
17230                /* hint codes 24-31 are reserved and signal RI */
17231                generate_exception(ctx, EXCP_RI);
17232            }
17233            break;
17234        default:
17235            MIPS_INVAL("pool32c");
17236            generate_exception_end(ctx, EXCP_RI);
17237            break;
17238        }
17239        break;
17240    case ADDI32: /* AUI, LUI */
17241        if (ctx->insn_flags & ISA_MIPS32R6) {
17242            /* AUI, LUI */
17243            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
17244        } else {
17245            /* ADDI32 */
17246            mips32_op = OPC_ADDI;
17247            goto do_addi;
17248        }
17249        break;
17250    case ADDIU32:
17251        mips32_op = OPC_ADDIU;
17252    do_addi:
17253        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
17254        break;
17255
17256        /* Logical operations */
17257    case ORI32:
17258        mips32_op = OPC_ORI;
17259        goto do_logici;
17260    case XORI32:
17261        mips32_op = OPC_XORI;
17262        goto do_logici;
17263    case ANDI32:
17264        mips32_op = OPC_ANDI;
17265    do_logici:
17266        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
17267        break;
17268
17269        /* Set less than immediate */
17270    case SLTI32:
17271        mips32_op = OPC_SLTI;
17272        goto do_slti;
17273    case SLTIU32:
17274        mips32_op = OPC_SLTIU;
17275    do_slti:
17276        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17277        break;
17278    case JALX32:
17279        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17280        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17281        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17282        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17283        break;
17284    case JALS32: /* BOVC, BEQC, BEQZALC */
17285        if (ctx->insn_flags & ISA_MIPS32R6) {
17286            if (rs >= rt) {
17287                /* BOVC */
17288                mips32_op = OPC_BOVC;
17289            } else if (rs < rt && rs == 0) {
17290                /* BEQZALC */
17291                mips32_op = OPC_BEQZALC;
17292            } else {
17293                /* BEQC */
17294                mips32_op = OPC_BEQC;
17295            }
17296            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17297        } else {
17298            /* JALS32 */
17299            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17300            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17301            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17302        }
17303        break;
17304    case BEQ32: /* BC */
17305        if (ctx->insn_flags & ISA_MIPS32R6) {
17306            /* BC */
17307            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17308                                       sextract32(ctx->opcode << 1, 0, 27));
17309        } else {
17310            /* BEQ32 */
17311            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17312        }
17313        break;
17314    case BNE32: /* BALC */
17315        if (ctx->insn_flags & ISA_MIPS32R6) {
17316            /* BALC */
17317            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17318                                       sextract32(ctx->opcode << 1, 0, 27));
17319        } else {
17320            /* BNE32 */
17321            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17322        }
17323        break;
17324    case J32: /* BGTZC, BLTZC, BLTC */
17325        if (ctx->insn_flags & ISA_MIPS32R6) {
17326            if (rs == 0 && rt != 0) {
17327                /* BGTZC */
17328                mips32_op = OPC_BGTZC;
17329            } else if (rs != 0 && rt != 0 && rs == rt) {
17330                /* BLTZC */
17331                mips32_op = OPC_BLTZC;
17332            } else {
17333                /* BLTC */
17334                mips32_op = OPC_BLTC;
17335            }
17336            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17337        } else {
17338            /* J32 */
17339            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17340                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17341        }
17342        break;
17343    case JAL32: /* BLEZC, BGEZC, BGEC */
17344        if (ctx->insn_flags & ISA_MIPS32R6) {
17345            if (rs == 0 && rt != 0) {
17346                /* BLEZC */
17347                mips32_op = OPC_BLEZC;
17348            } else if (rs != 0 && rt != 0 && rs == rt) {
17349                /* BGEZC */
17350                mips32_op = OPC_BGEZC;
17351            } else {
17352                /* BGEC */
17353                mips32_op = OPC_BGEC;
17354            }
17355            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17356        } else {
17357            /* JAL32 */
17358            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17359                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17360            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17361        }
17362        break;
17363        /* Floating point (COP1) */
17364    case LWC132:
17365        mips32_op = OPC_LWC1;
17366        goto do_cop1;
17367    case LDC132:
17368        mips32_op = OPC_LDC1;
17369        goto do_cop1;
17370    case SWC132:
17371        mips32_op = OPC_SWC1;
17372        goto do_cop1;
17373    case SDC132:
17374        mips32_op = OPC_SDC1;
17375    do_cop1:
17376        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17377        break;
17378    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17379        if (ctx->insn_flags & ISA_MIPS32R6) {
17380            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17381            switch ((ctx->opcode >> 16) & 0x1f) {
17382            case ADDIUPC_00:
17383            case ADDIUPC_01:
17384            case ADDIUPC_02:
17385            case ADDIUPC_03:
17386            case ADDIUPC_04:
17387            case ADDIUPC_05:
17388            case ADDIUPC_06:
17389            case ADDIUPC_07:
17390                gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17391                break;
17392            case AUIPC:
17393                gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17394                break;
17395            case ALUIPC:
17396                gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17397                break;
17398            case LWPC_08:
17399            case LWPC_09:
17400            case LWPC_0A:
17401            case LWPC_0B:
17402            case LWPC_0C:
17403            case LWPC_0D:
17404            case LWPC_0E:
17405            case LWPC_0F:
17406                gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17407                break;
17408            default:
17409                generate_exception(ctx, EXCP_RI);
17410                break;
17411            }
17412        } else {
17413            /* ADDIUPC */
17414            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17415            offset = SIMM(ctx->opcode, 0, 23) << 2;
17416
17417            gen_addiupc(ctx, reg, offset, 0, 0);
17418        }
17419        break;
17420    case BNVC: /* BNEC, BNEZALC */
17421        check_insn(ctx, ISA_MIPS32R6);
17422        if (rs >= rt) {
17423            /* BNVC */
17424            mips32_op = OPC_BNVC;
17425        } else if (rs < rt && rs == 0) {
17426            /* BNEZALC */
17427            mips32_op = OPC_BNEZALC;
17428        } else {
17429            /* BNEC */
17430            mips32_op = OPC_BNEC;
17431        }
17432        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17433        break;
17434    case R6_BNEZC: /* JIALC */
17435        check_insn(ctx, ISA_MIPS32R6);
17436        if (rt != 0) {
17437            /* BNEZC */
17438            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17439                                       sextract32(ctx->opcode << 1, 0, 22));
17440        } else {
17441            /* JIALC */
17442            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17443        }
17444        break;
17445    case R6_BEQZC: /* JIC */
17446        check_insn(ctx, ISA_MIPS32R6);
17447        if (rt != 0) {
17448            /* BEQZC */
17449            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17450                                       sextract32(ctx->opcode << 1, 0, 22));
17451        } else {
17452            /* JIC */
17453            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17454        }
17455        break;
17456    case BLEZALC: /* BGEZALC, BGEUC */
17457        check_insn(ctx, ISA_MIPS32R6);
17458        if (rs == 0 && rt != 0) {
17459            /* BLEZALC */
17460            mips32_op = OPC_BLEZALC;
17461        } else if (rs != 0 && rt != 0 && rs == rt) {
17462            /* BGEZALC */
17463            mips32_op = OPC_BGEZALC;
17464        } else {
17465            /* BGEUC */
17466            mips32_op = OPC_BGEUC;
17467        }
17468        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17469        break;
17470    case BGTZALC: /* BLTZALC, BLTUC */
17471        check_insn(ctx, ISA_MIPS32R6);
17472        if (rs == 0 && rt != 0) {
17473            /* BGTZALC */
17474            mips32_op = OPC_BGTZALC;
17475        } else if (rs != 0 && rt != 0 && rs == rt) {
17476            /* BLTZALC */
17477            mips32_op = OPC_BLTZALC;
17478        } else {
17479            /* BLTUC */
17480            mips32_op = OPC_BLTUC;
17481        }
17482        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17483        break;
17484        /* Loads and stores */
17485    case LB32:
17486        mips32_op = OPC_LB;
17487        goto do_ld;
17488    case LBU32:
17489        mips32_op = OPC_LBU;
17490        goto do_ld;
17491    case LH32:
17492        mips32_op = OPC_LH;
17493        goto do_ld;
17494    case LHU32:
17495        mips32_op = OPC_LHU;
17496        goto do_ld;
17497    case LW32:
17498        mips32_op = OPC_LW;
17499        goto do_ld;
17500#ifdef TARGET_MIPS64
17501    case LD32:
17502        check_insn(ctx, ISA_MIPS3);
17503        check_mips_64(ctx);
17504        mips32_op = OPC_LD;
17505        goto do_ld;
17506    case SD32:
17507        check_insn(ctx, ISA_MIPS3);
17508        check_mips_64(ctx);
17509        mips32_op = OPC_SD;
17510        goto do_st;
17511#endif
17512    case SB32:
17513        mips32_op = OPC_SB;
17514        goto do_st;
17515    case SH32:
17516        mips32_op = OPC_SH;
17517        goto do_st;
17518    case SW32:
17519        mips32_op = OPC_SW;
17520        goto do_st;
17521    do_ld:
17522        gen_ld(ctx, mips32_op, rt, rs, imm);
17523        break;
17524    do_st:
17525        gen_st(ctx, mips32_op, rt, rs, imm);
17526        break;
17527    default:
17528        generate_exception_end(ctx, EXCP_RI);
17529        break;
17530    }
17531}
17532
17533static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
17534{
17535    uint32_t op;
17536
17537    /* make sure instructions are on a halfword boundary */
17538    if (ctx->base.pc_next & 0x1) {
17539        env->CP0_BadVAddr = ctx->base.pc_next;
17540        generate_exception_end(ctx, EXCP_AdEL);
17541        return 2;
17542    }
17543
17544    op = (ctx->opcode >> 10) & 0x3f;
17545    /* Enforce properly-sized instructions in a delay slot */
17546    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17547        switch (op & 0x7) { /* MSB-3..MSB-5 */
17548        case 0:
17549        /* POOL32A, POOL32B, POOL32I, POOL32C */
17550        case 4:
17551        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17552        case 5:
17553        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17554        case 6:
17555        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17556        case 7:
17557        /* LB32, LH32, LWC132, LDC132, LW32 */
17558            if (ctx->hflags & MIPS_HFLAG_BDS16) {
17559                generate_exception_end(ctx, EXCP_RI);
17560                return 2;
17561            }
17562            break;
17563        case 1:
17564        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17565        case 2:
17566        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17567        case 3:
17568        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17569            if (ctx->hflags & MIPS_HFLAG_BDS32) {
17570                generate_exception_end(ctx, EXCP_RI);
17571                return 2;
17572            }
17573            break;
17574        }
17575    }
17576
17577    switch (op) {
17578    case POOL16A:
17579        {
17580            int rd = mmreg(uMIPS_RD(ctx->opcode));
17581            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17582            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17583            uint32_t opc = 0;
17584
17585            switch (ctx->opcode & 0x1) {
17586            case ADDU16:
17587                opc = OPC_ADDU;
17588                break;
17589            case SUBU16:
17590                opc = OPC_SUBU;
17591                break;
17592            }
17593            if (ctx->insn_flags & ISA_MIPS32R6) {
17594                /*
17595                 * In the Release 6, the register number location in
17596                 * the instruction encoding has changed.
17597                 */
17598                gen_arith(ctx, opc, rs1, rd, rs2);
17599            } else {
17600                gen_arith(ctx, opc, rd, rs1, rs2);
17601            }
17602        }
17603        break;
17604    case POOL16B:
17605        {
17606            int rd = mmreg(uMIPS_RD(ctx->opcode));
17607            int rs = mmreg(uMIPS_RS(ctx->opcode));
17608            int amount = (ctx->opcode >> 1) & 0x7;
17609            uint32_t opc = 0;
17610            amount = amount == 0 ? 8 : amount;
17611
17612            switch (ctx->opcode & 0x1) {
17613            case SLL16:
17614                opc = OPC_SLL;
17615                break;
17616            case SRL16:
17617                opc = OPC_SRL;
17618                break;
17619            }
17620
17621            gen_shift_imm(ctx, opc, rd, rs, amount);
17622        }
17623        break;
17624    case POOL16C:
17625        if (ctx->insn_flags & ISA_MIPS32R6) {
17626            gen_pool16c_r6_insn(ctx);
17627        } else {
17628            gen_pool16c_insn(ctx);
17629        }
17630        break;
17631    case LWGP16:
17632        {
17633            int rd = mmreg(uMIPS_RD(ctx->opcode));
17634            int rb = 28;            /* GP */
17635            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17636
17637            gen_ld(ctx, OPC_LW, rd, rb, offset);
17638        }
17639        break;
17640    case POOL16F:
17641        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17642        if (ctx->opcode & 1) {
17643            generate_exception_end(ctx, EXCP_RI);
17644        } else {
17645            /* MOVEP */
17646            int enc_dest = uMIPS_RD(ctx->opcode);
17647            int enc_rt = uMIPS_RS2(ctx->opcode);
17648            int enc_rs = uMIPS_RS1(ctx->opcode);
17649            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17650        }
17651        break;
17652    case LBU16:
17653        {
17654            int rd = mmreg(uMIPS_RD(ctx->opcode));
17655            int rb = mmreg(uMIPS_RS(ctx->opcode));
17656            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17657            offset = (offset == 0xf ? -1 : offset);
17658
17659            gen_ld(ctx, OPC_LBU, rd, rb, offset);
17660        }
17661        break;
17662    case LHU16:
17663        {
17664            int rd = mmreg(uMIPS_RD(ctx->opcode));
17665            int rb = mmreg(uMIPS_RS(ctx->opcode));
17666            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17667
17668            gen_ld(ctx, OPC_LHU, rd, rb, offset);
17669        }
17670        break;
17671    case LWSP16:
17672        {
17673            int rd = (ctx->opcode >> 5) & 0x1f;
17674            int rb = 29;            /* SP */
17675            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17676
17677            gen_ld(ctx, OPC_LW, rd, rb, offset);
17678        }
17679        break;
17680    case LW16:
17681        {
17682            int rd = mmreg(uMIPS_RD(ctx->opcode));
17683            int rb = mmreg(uMIPS_RS(ctx->opcode));
17684            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17685
17686            gen_ld(ctx, OPC_LW, rd, rb, offset);
17687        }
17688        break;
17689    case SB16:
17690        {
17691            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17692            int rb = mmreg(uMIPS_RS(ctx->opcode));
17693            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17694
17695            gen_st(ctx, OPC_SB, rd, rb, offset);
17696        }
17697        break;
17698    case SH16:
17699        {
17700            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17701            int rb = mmreg(uMIPS_RS(ctx->opcode));
17702            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17703
17704            gen_st(ctx, OPC_SH, rd, rb, offset);
17705        }
17706        break;
17707    case SWSP16:
17708        {
17709            int rd = (ctx->opcode >> 5) & 0x1f;
17710            int rb = 29;            /* SP */
17711            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17712
17713            gen_st(ctx, OPC_SW, rd, rb, offset);
17714        }
17715        break;
17716    case SW16:
17717        {
17718            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17719            int rb = mmreg(uMIPS_RS(ctx->opcode));
17720            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17721
17722            gen_st(ctx, OPC_SW, rd, rb, offset);
17723        }
17724        break;
17725    case MOVE16:
17726        {
17727            int rd = uMIPS_RD5(ctx->opcode);
17728            int rs = uMIPS_RS5(ctx->opcode);
17729
17730            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17731        }
17732        break;
17733    case ANDI16:
17734        gen_andi16(ctx);
17735        break;
17736    case POOL16D:
17737        switch (ctx->opcode & 0x1) {
17738        case ADDIUS5:
17739            gen_addius5(ctx);
17740            break;
17741        case ADDIUSP:
17742            gen_addiusp(ctx);
17743            break;
17744        }
17745        break;
17746    case POOL16E:
17747        switch (ctx->opcode & 0x1) {
17748        case ADDIUR2:
17749            gen_addiur2(ctx);
17750            break;
17751        case ADDIUR1SP:
17752            gen_addiur1sp(ctx);
17753            break;
17754        }
17755        break;
17756    case B16: /* BC16 */
17757        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17758                           sextract32(ctx->opcode, 0, 10) << 1,
17759                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17760        break;
17761    case BNEZ16: /* BNEZC16 */
17762    case BEQZ16: /* BEQZC16 */
17763        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17764                           mmreg(uMIPS_RD(ctx->opcode)),
17765                           0, sextract32(ctx->opcode, 0, 7) << 1,
17766                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17767
17768        break;
17769    case LI16:
17770        {
17771            int reg = mmreg(uMIPS_RD(ctx->opcode));
17772            int imm = ZIMM(ctx->opcode, 0, 7);
17773
17774            imm = (imm == 0x7f ? -1 : imm);
17775            tcg_gen_movi_tl(cpu_gpr[reg], imm);
17776        }
17777        break;
17778    case RES_29:
17779    case RES_31:
17780    case RES_39:
17781        generate_exception_end(ctx, EXCP_RI);
17782        break;
17783    default:
17784        decode_micromips32_opc(env, ctx);
17785        return 4;
17786    }
17787
17788    return 2;
17789}
17790
17791/*
17792 *
17793 * nanoMIPS opcodes
17794 *
17795 */
17796
17797/* MAJOR, P16, and P32 pools opcodes */
17798enum {
17799    NM_P_ADDIU      = 0x00,
17800    NM_ADDIUPC      = 0x01,
17801    NM_MOVE_BALC    = 0x02,
17802    NM_P16_MV       = 0x04,
17803    NM_LW16         = 0x05,
17804    NM_BC16         = 0x06,
17805    NM_P16_SR       = 0x07,
17806
17807    NM_POOL32A      = 0x08,
17808    NM_P_BAL        = 0x0a,
17809    NM_P16_SHIFT    = 0x0c,
17810    NM_LWSP16       = 0x0d,
17811    NM_BALC16       = 0x0e,
17812    NM_P16_4X4      = 0x0f,
17813
17814    NM_P_GP_W       = 0x10,
17815    NM_P_GP_BH      = 0x11,
17816    NM_P_J          = 0x12,
17817    NM_P16C         = 0x14,
17818    NM_LWGP16       = 0x15,
17819    NM_P16_LB       = 0x17,
17820
17821    NM_P48I         = 0x18,
17822    NM_P16_A1       = 0x1c,
17823    NM_LW4X4        = 0x1d,
17824    NM_P16_LH       = 0x1f,
17825
17826    NM_P_U12        = 0x20,
17827    NM_P_LS_U12     = 0x21,
17828    NM_P_BR1        = 0x22,
17829    NM_P16_A2       = 0x24,
17830    NM_SW16         = 0x25,
17831    NM_BEQZC16      = 0x26,
17832
17833    NM_POOL32F      = 0x28,
17834    NM_P_LS_S9      = 0x29,
17835    NM_P_BR2        = 0x2a,
17836
17837    NM_P16_ADDU     = 0x2c,
17838    NM_SWSP16       = 0x2d,
17839    NM_BNEZC16      = 0x2e,
17840    NM_MOVEP        = 0x2f,
17841
17842    NM_POOL32S      = 0x30,
17843    NM_P_BRI        = 0x32,
17844    NM_LI16         = 0x34,
17845    NM_SWGP16       = 0x35,
17846    NM_P16_BR       = 0x36,
17847
17848    NM_P_LUI        = 0x38,
17849    NM_ANDI16       = 0x3c,
17850    NM_SW4X4        = 0x3d,
17851    NM_MOVEPREV     = 0x3f,
17852};
17853
17854/* POOL32A instruction pool */
17855enum {
17856    NM_POOL32A0    = 0x00,
17857    NM_SPECIAL2    = 0x01,
17858    NM_COP2_1      = 0x02,
17859    NM_UDI         = 0x03,
17860    NM_POOL32A5    = 0x05,
17861    NM_POOL32A7    = 0x07,
17862};
17863
17864/* P.GP.W instruction pool */
17865enum {
17866    NM_ADDIUGP_W = 0x00,
17867    NM_LWGP      = 0x02,
17868    NM_SWGP      = 0x03,
17869};
17870
17871/* P48I instruction pool */
17872enum {
17873    NM_LI48        = 0x00,
17874    NM_ADDIU48     = 0x01,
17875    NM_ADDIUGP48   = 0x02,
17876    NM_ADDIUPC48   = 0x03,
17877    NM_LWPC48      = 0x0b,
17878    NM_SWPC48      = 0x0f,
17879};
17880
17881/* P.U12 instruction pool */
17882enum {
17883    NM_ORI      = 0x00,
17884    NM_XORI     = 0x01,
17885    NM_ANDI     = 0x02,
17886    NM_P_SR     = 0x03,
17887    NM_SLTI     = 0x04,
17888    NM_SLTIU    = 0x05,
17889    NM_SEQI     = 0x06,
17890    NM_ADDIUNEG = 0x08,
17891    NM_P_SHIFT  = 0x0c,
17892    NM_P_ROTX   = 0x0d,
17893    NM_P_INS    = 0x0e,
17894    NM_P_EXT    = 0x0f,
17895};
17896
17897/* POOL32F instruction pool */
17898enum {
17899    NM_POOL32F_0   = 0x00,
17900    NM_POOL32F_3   = 0x03,
17901    NM_POOL32F_5   = 0x05,
17902};
17903
17904/* POOL32S instruction pool */
17905enum {
17906    NM_POOL32S_0   = 0x00,
17907    NM_POOL32S_4   = 0x04,
17908};
17909
17910/* P.LUI instruction pool */
17911enum {
17912    NM_LUI      = 0x00,
17913    NM_ALUIPC   = 0x01,
17914};
17915
17916/* P.GP.BH instruction pool */
17917enum {
17918    NM_LBGP      = 0x00,
17919    NM_SBGP      = 0x01,
17920    NM_LBUGP     = 0x02,
17921    NM_ADDIUGP_B = 0x03,
17922    NM_P_GP_LH   = 0x04,
17923    NM_P_GP_SH   = 0x05,
17924    NM_P_GP_CP1  = 0x06,
17925};
17926
17927/* P.LS.U12 instruction pool */
17928enum {
17929    NM_LB        = 0x00,
17930    NM_SB        = 0x01,
17931    NM_LBU       = 0x02,
17932    NM_P_PREFU12 = 0x03,
17933    NM_LH        = 0x04,
17934    NM_SH        = 0x05,
17935    NM_LHU       = 0x06,
17936    NM_LWU       = 0x07,
17937    NM_LW        = 0x08,
17938    NM_SW        = 0x09,
17939    NM_LWC1      = 0x0a,
17940    NM_SWC1      = 0x0b,
17941    NM_LDC1      = 0x0e,
17942    NM_SDC1      = 0x0f,
17943};
17944
17945/* P.LS.S9 instruction pool */
17946enum {
17947    NM_P_LS_S0         = 0x00,
17948    NM_P_LS_S1         = 0x01,
17949    NM_P_LS_E0         = 0x02,
17950    NM_P_LS_WM         = 0x04,
17951    NM_P_LS_UAWM       = 0x05,
17952};
17953
17954/* P.BAL instruction pool */
17955enum {
17956    NM_BC       = 0x00,
17957    NM_BALC     = 0x01,
17958};
17959
17960/* P.J instruction pool */
17961enum {
17962    NM_JALRC    = 0x00,
17963    NM_JALRC_HB = 0x01,
17964    NM_P_BALRSC = 0x08,
17965};
17966
17967/* P.BR1 instruction pool */
17968enum {
17969    NM_BEQC     = 0x00,
17970    NM_P_BR3A   = 0x01,
17971    NM_BGEC     = 0x02,
17972    NM_BGEUC    = 0x03,
17973};
17974
17975/* P.BR2 instruction pool */
17976enum {
17977    NM_BNEC     = 0x00,
17978    NM_BLTC     = 0x02,
17979    NM_BLTUC    = 0x03,
17980};
17981
17982/* P.BRI instruction pool */
17983enum {
17984    NM_BEQIC    = 0x00,
17985    NM_BBEQZC   = 0x01,
17986    NM_BGEIC    = 0x02,
17987    NM_BGEIUC   = 0x03,
17988    NM_BNEIC    = 0x04,
17989    NM_BBNEZC   = 0x05,
17990    NM_BLTIC    = 0x06,
17991    NM_BLTIUC   = 0x07,
17992};
17993
17994/* P16.SHIFT instruction pool */
17995enum {
17996    NM_SLL16    = 0x00,
17997    NM_SRL16    = 0x01,
17998};
17999
18000/* POOL16C instruction pool */
18001enum {
18002    NM_POOL16C_0  = 0x00,
18003    NM_LWXS16     = 0x01,
18004};
18005
18006/* P16.A1 instruction pool */
18007enum {
18008    NM_ADDIUR1SP = 0x01,
18009};
18010
18011/* P16.A2 instruction pool */
18012enum {
18013    NM_ADDIUR2  = 0x00,
18014    NM_P_ADDIURS5  = 0x01,
18015};
18016
18017/* P16.ADDU instruction pool */
18018enum {
18019    NM_ADDU16     = 0x00,
18020    NM_SUBU16     = 0x01,
18021};
18022
18023/* P16.SR instruction pool */
18024enum {
18025    NM_SAVE16        = 0x00,
18026    NM_RESTORE_JRC16 = 0x01,
18027};
18028
18029/* P16.4X4 instruction pool */
18030enum {
18031    NM_ADDU4X4      = 0x00,
18032    NM_MUL4X4       = 0x01,
18033};
18034
18035/* P16.LB instruction pool */
18036enum {
18037    NM_LB16       = 0x00,
18038    NM_SB16       = 0x01,
18039    NM_LBU16      = 0x02,
18040};
18041
18042/* P16.LH  instruction pool */
18043enum {
18044    NM_LH16     = 0x00,
18045    NM_SH16     = 0x01,
18046    NM_LHU16    = 0x02,
18047};
18048
18049/* P.RI instruction pool */
18050enum {
18051    NM_SIGRIE       = 0x00,
18052    NM_P_SYSCALL    = 0x01,
18053    NM_BREAK        = 0x02,
18054    NM_SDBBP        = 0x03,
18055};
18056
18057/* POOL32A0 instruction pool */
18058enum {
18059    NM_P_TRAP   = 0x00,
18060    NM_SEB      = 0x01,
18061    NM_SLLV     = 0x02,
18062    NM_MUL      = 0x03,
18063    NM_MFC0     = 0x06,
18064    NM_MFHC0    = 0x07,
18065    NM_SEH      = 0x09,
18066    NM_SRLV     = 0x0a,
18067    NM_MUH      = 0x0b,
18068    NM_MTC0     = 0x0e,
18069    NM_MTHC0    = 0x0f,
18070    NM_SRAV     = 0x12,
18071    NM_MULU     = 0x13,
18072    NM_ROTRV    = 0x1a,
18073    NM_MUHU     = 0x1b,
18074    NM_ADD      = 0x22,
18075    NM_DIV      = 0x23,
18076    NM_ADDU     = 0x2a,
18077    NM_MOD      = 0x2b,
18078    NM_SUB      = 0x32,
18079    NM_DIVU     = 0x33,
18080    NM_RDHWR    = 0x38,
18081    NM_SUBU     = 0x3a,
18082    NM_MODU     = 0x3b,
18083    NM_P_CMOVE  = 0x42,
18084    NM_FORK     = 0x45,
18085    NM_MFTR     = 0x46,
18086    NM_MFHTR    = 0x47,
18087    NM_AND      = 0x4a,
18088    NM_YIELD    = 0x4d,
18089    NM_MTTR     = 0x4e,
18090    NM_MTHTR    = 0x4f,
18091    NM_OR       = 0x52,
18092    NM_D_E_MT_VPE = 0x56,
18093    NM_NOR      = 0x5a,
18094    NM_XOR      = 0x62,
18095    NM_SLT      = 0x6a,
18096    NM_P_SLTU   = 0x72,
18097    NM_SOV      = 0x7a,
18098};
18099
18100/* CRC32 instruction pool */
18101enum {
18102    NM_CRC32B   = 0x00,
18103    NM_CRC32H   = 0x01,
18104    NM_CRC32W   = 0x02,
18105    NM_CRC32CB  = 0x04,
18106    NM_CRC32CH  = 0x05,
18107    NM_CRC32CW  = 0x06,
18108};
18109
18110/* POOL32A5 instruction pool */
18111enum {
18112    NM_CMP_EQ_PH        = 0x00,
18113    NM_CMP_LT_PH        = 0x08,
18114    NM_CMP_LE_PH        = 0x10,
18115    NM_CMPGU_EQ_QB      = 0x18,
18116    NM_CMPGU_LT_QB      = 0x20,
18117    NM_CMPGU_LE_QB      = 0x28,
18118    NM_CMPGDU_EQ_QB     = 0x30,
18119    NM_CMPGDU_LT_QB     = 0x38,
18120    NM_CMPGDU_LE_QB     = 0x40,
18121    NM_CMPU_EQ_QB       = 0x48,
18122    NM_CMPU_LT_QB       = 0x50,
18123    NM_CMPU_LE_QB       = 0x58,
18124    NM_ADDQ_S_W         = 0x60,
18125    NM_SUBQ_S_W         = 0x68,
18126    NM_ADDSC            = 0x70,
18127    NM_ADDWC            = 0x78,
18128
18129    NM_ADDQ_S_PH   = 0x01,
18130    NM_ADDQH_R_PH  = 0x09,
18131    NM_ADDQH_R_W   = 0x11,
18132    NM_ADDU_S_QB   = 0x19,
18133    NM_ADDU_S_PH   = 0x21,
18134    NM_ADDUH_R_QB  = 0x29,
18135    NM_SHRAV_R_PH  = 0x31,
18136    NM_SHRAV_R_QB  = 0x39,
18137    NM_SUBQ_S_PH   = 0x41,
18138    NM_SUBQH_R_PH  = 0x49,
18139    NM_SUBQH_R_W   = 0x51,
18140    NM_SUBU_S_QB   = 0x59,
18141    NM_SUBU_S_PH   = 0x61,
18142    NM_SUBUH_R_QB  = 0x69,
18143    NM_SHLLV_S_PH  = 0x71,
18144    NM_PRECR_SRA_R_PH_W = 0x79,
18145
18146    NM_MULEU_S_PH_QBL   = 0x12,
18147    NM_MULEU_S_PH_QBR   = 0x1a,
18148    NM_MULQ_RS_PH       = 0x22,
18149    NM_MULQ_S_PH        = 0x2a,
18150    NM_MULQ_RS_W        = 0x32,
18151    NM_MULQ_S_W         = 0x3a,
18152    NM_APPEND           = 0x42,
18153    NM_MODSUB           = 0x52,
18154    NM_SHRAV_R_W        = 0x5a,
18155    NM_SHRLV_PH         = 0x62,
18156    NM_SHRLV_QB         = 0x6a,
18157    NM_SHLLV_QB         = 0x72,
18158    NM_SHLLV_S_W        = 0x7a,
18159
18160    NM_SHILO            = 0x03,
18161
18162    NM_MULEQ_S_W_PHL    = 0x04,
18163    NM_MULEQ_S_W_PHR    = 0x0c,
18164
18165    NM_MUL_S_PH         = 0x05,
18166    NM_PRECR_QB_PH      = 0x0d,
18167    NM_PRECRQ_QB_PH     = 0x15,
18168    NM_PRECRQ_PH_W      = 0x1d,
18169    NM_PRECRQ_RS_PH_W   = 0x25,
18170    NM_PRECRQU_S_QB_PH  = 0x2d,
18171    NM_PACKRL_PH        = 0x35,
18172    NM_PICK_QB          = 0x3d,
18173    NM_PICK_PH          = 0x45,
18174
18175    NM_SHRA_R_W         = 0x5e,
18176    NM_SHRA_R_PH        = 0x66,
18177    NM_SHLL_S_PH        = 0x76,
18178    NM_SHLL_S_W         = 0x7e,
18179
18180    NM_REPL_PH          = 0x07
18181};
18182
18183/* POOL32A7 instruction pool */
18184enum {
18185    NM_P_LSX        = 0x00,
18186    NM_LSA          = 0x01,
18187    NM_EXTW         = 0x03,
18188    NM_POOL32AXF    = 0x07,
18189};
18190
18191/* P.SR instruction pool */
18192enum {
18193    NM_PP_SR           = 0x00,
18194    NM_P_SR_F          = 0x01,
18195};
18196
18197/* P.SHIFT instruction pool */
18198enum {
18199    NM_P_SLL        = 0x00,
18200    NM_SRL          = 0x02,
18201    NM_SRA          = 0x04,
18202    NM_ROTR         = 0x06,
18203};
18204
18205/* P.ROTX instruction pool */
18206enum {
18207    NM_ROTX         = 0x00,
18208};
18209
18210/* P.INS instruction pool */
18211enum {
18212    NM_INS          = 0x00,
18213};
18214
18215/* P.EXT instruction pool */
18216enum {
18217    NM_EXT          = 0x00,
18218};
18219
18220/* POOL32F_0 (fmt) instruction pool */
18221enum {
18222    NM_RINT_S              = 0x04,
18223    NM_RINT_D              = 0x44,
18224    NM_ADD_S               = 0x06,
18225    NM_SELEQZ_S            = 0x07,
18226    NM_SELEQZ_D            = 0x47,
18227    NM_CLASS_S             = 0x0c,
18228    NM_CLASS_D             = 0x4c,
18229    NM_SUB_S               = 0x0e,
18230    NM_SELNEZ_S            = 0x0f,
18231    NM_SELNEZ_D            = 0x4f,
18232    NM_MUL_S               = 0x16,
18233    NM_SEL_S               = 0x17,
18234    NM_SEL_D               = 0x57,
18235    NM_DIV_S               = 0x1e,
18236    NM_ADD_D               = 0x26,
18237    NM_SUB_D               = 0x2e,
18238    NM_MUL_D               = 0x36,
18239    NM_MADDF_S             = 0x37,
18240    NM_MADDF_D             = 0x77,
18241    NM_DIV_D               = 0x3e,
18242    NM_MSUBF_S             = 0x3f,
18243    NM_MSUBF_D             = 0x7f,
18244};
18245
18246/* POOL32F_3  instruction pool */
18247enum {
18248    NM_MIN_FMT         = 0x00,
18249    NM_MAX_FMT         = 0x01,
18250    NM_MINA_FMT        = 0x04,
18251    NM_MAXA_FMT        = 0x05,
18252    NM_POOL32FXF       = 0x07,
18253};
18254
18255/* POOL32F_5  instruction pool */
18256enum {
18257    NM_CMP_CONDN_S     = 0x00,
18258    NM_CMP_CONDN_D     = 0x02,
18259};
18260
18261/* P.GP.LH instruction pool */
18262enum {
18263    NM_LHGP    = 0x00,
18264    NM_LHUGP   = 0x01,
18265};
18266
18267/* P.GP.SH instruction pool */
18268enum {
18269    NM_SHGP    = 0x00,
18270};
18271
18272/* P.GP.CP1 instruction pool */
18273enum {
18274    NM_LWC1GP       = 0x00,
18275    NM_SWC1GP       = 0x01,
18276    NM_LDC1GP       = 0x02,
18277    NM_SDC1GP       = 0x03,
18278};
18279
18280/* P.LS.S0 instruction pool */
18281enum {
18282    NM_LBS9     = 0x00,
18283    NM_LHS9     = 0x04,
18284    NM_LWS9     = 0x08,
18285    NM_LDS9     = 0x0c,
18286
18287    NM_SBS9     = 0x01,
18288    NM_SHS9     = 0x05,
18289    NM_SWS9     = 0x09,
18290    NM_SDS9     = 0x0d,
18291
18292    NM_LBUS9    = 0x02,
18293    NM_LHUS9    = 0x06,
18294    NM_LWC1S9   = 0x0a,
18295    NM_LDC1S9   = 0x0e,
18296
18297    NM_P_PREFS9 = 0x03,
18298    NM_LWUS9    = 0x07,
18299    NM_SWC1S9   = 0x0b,
18300    NM_SDC1S9   = 0x0f,
18301};
18302
18303/* P.LS.S1 instruction pool */
18304enum {
18305    NM_ASET_ACLR = 0x02,
18306    NM_UALH      = 0x04,
18307    NM_UASH      = 0x05,
18308    NM_CACHE     = 0x07,
18309    NM_P_LL      = 0x0a,
18310    NM_P_SC      = 0x0b,
18311};
18312
18313/* P.LS.E0 instruction pool */
18314enum {
18315    NM_LBE      = 0x00,
18316    NM_SBE      = 0x01,
18317    NM_LBUE     = 0x02,
18318    NM_P_PREFE  = 0x03,
18319    NM_LHE      = 0x04,
18320    NM_SHE      = 0x05,
18321    NM_LHUE     = 0x06,
18322    NM_CACHEE   = 0x07,
18323    NM_LWE      = 0x08,
18324    NM_SWE      = 0x09,
18325    NM_P_LLE    = 0x0a,
18326    NM_P_SCE    = 0x0b,
18327};
18328
18329/* P.PREFE instruction pool */
18330enum {
18331    NM_SYNCIE   = 0x00,
18332    NM_PREFE    = 0x01,
18333};
18334
18335/* P.LLE instruction pool */
18336enum {
18337    NM_LLE      = 0x00,
18338    NM_LLWPE    = 0x01,
18339};
18340
18341/* P.SCE instruction pool */
18342enum {
18343    NM_SCE      = 0x00,
18344    NM_SCWPE    = 0x01,
18345};
18346
18347/* P.LS.WM instruction pool */
18348enum {
18349    NM_LWM       = 0x00,
18350    NM_SWM       = 0x01,
18351};
18352
18353/* P.LS.UAWM instruction pool */
18354enum {
18355    NM_UALWM       = 0x00,
18356    NM_UASWM       = 0x01,
18357};
18358
18359/* P.BR3A instruction pool */
18360enum {
18361    NM_BC1EQZC          = 0x00,
18362    NM_BC1NEZC          = 0x01,
18363    NM_BC2EQZC          = 0x02,
18364    NM_BC2NEZC          = 0x03,
18365    NM_BPOSGE32C        = 0x04,
18366};
18367
18368/* P16.RI instruction pool */
18369enum {
18370    NM_P16_SYSCALL  = 0x01,
18371    NM_BREAK16      = 0x02,
18372    NM_SDBBP16      = 0x03,
18373};
18374
18375/* POOL16C_0 instruction pool */
18376enum {
18377    NM_POOL16C_00      = 0x00,
18378};
18379
18380/* P16.JRC instruction pool */
18381enum {
18382    NM_JRC          = 0x00,
18383    NM_JALRC16      = 0x01,
18384};
18385
18386/* P.SYSCALL instruction pool */
18387enum {
18388    NM_SYSCALL      = 0x00,
18389    NM_HYPCALL      = 0x01,
18390};
18391
18392/* P.TRAP instruction pool */
18393enum {
18394    NM_TEQ          = 0x00,
18395    NM_TNE          = 0x01,
18396};
18397
18398/* P.CMOVE instruction pool */
18399enum {
18400    NM_MOVZ            = 0x00,
18401    NM_MOVN            = 0x01,
18402};
18403
18404/* POOL32Axf instruction pool */
18405enum {
18406    NM_POOL32AXF_1 = 0x01,
18407    NM_POOL32AXF_2 = 0x02,
18408    NM_POOL32AXF_4 = 0x04,
18409    NM_POOL32AXF_5 = 0x05,
18410    NM_POOL32AXF_7 = 0x07,
18411};
18412
18413/* POOL32Axf_1 instruction pool */
18414enum {
18415    NM_POOL32AXF_1_0 = 0x00,
18416    NM_POOL32AXF_1_1 = 0x01,
18417    NM_POOL32AXF_1_3 = 0x03,
18418    NM_POOL32AXF_1_4 = 0x04,
18419    NM_POOL32AXF_1_5 = 0x05,
18420    NM_POOL32AXF_1_7 = 0x07,
18421};
18422
18423/* POOL32Axf_2 instruction pool */
18424enum {
18425    NM_POOL32AXF_2_0_7     = 0x00,
18426    NM_POOL32AXF_2_8_15    = 0x01,
18427    NM_POOL32AXF_2_16_23   = 0x02,
18428    NM_POOL32AXF_2_24_31   = 0x03,
18429};
18430
18431/* POOL32Axf_7 instruction pool */
18432enum {
18433    NM_SHRA_R_QB    = 0x0,
18434    NM_SHRL_PH      = 0x1,
18435    NM_REPL_QB      = 0x2,
18436};
18437
18438/* POOL32Axf_1_0 instruction pool */
18439enum {
18440    NM_MFHI = 0x0,
18441    NM_MFLO = 0x1,
18442    NM_MTHI = 0x2,
18443    NM_MTLO = 0x3,
18444};
18445
18446/* POOL32Axf_1_1 instruction pool */
18447enum {
18448    NM_MTHLIP = 0x0,
18449    NM_SHILOV = 0x1,
18450};
18451
18452/* POOL32Axf_1_3 instruction pool */
18453enum {
18454    NM_RDDSP    = 0x0,
18455    NM_WRDSP    = 0x1,
18456    NM_EXTP     = 0x2,
18457    NM_EXTPDP   = 0x3,
18458};
18459
18460/* POOL32Axf_1_4 instruction pool */
18461enum {
18462    NM_SHLL_QB  = 0x0,
18463    NM_SHRL_QB  = 0x1,
18464};
18465
18466/* POOL32Axf_1_5 instruction pool */
18467enum {
18468    NM_MAQ_S_W_PHR   = 0x0,
18469    NM_MAQ_S_W_PHL   = 0x1,
18470    NM_MAQ_SA_W_PHR  = 0x2,
18471    NM_MAQ_SA_W_PHL  = 0x3,
18472};
18473
18474/* POOL32Axf_1_7 instruction pool */
18475enum {
18476    NM_EXTR_W       = 0x0,
18477    NM_EXTR_R_W     = 0x1,
18478    NM_EXTR_RS_W    = 0x2,
18479    NM_EXTR_S_H     = 0x3,
18480};
18481
18482/* POOL32Axf_2_0_7 instruction pool */
18483enum {
18484    NM_DPA_W_PH     = 0x0,
18485    NM_DPAQ_S_W_PH  = 0x1,
18486    NM_DPS_W_PH     = 0x2,
18487    NM_DPSQ_S_W_PH  = 0x3,
18488    NM_BALIGN       = 0x4,
18489    NM_MADD         = 0x5,
18490    NM_MULT         = 0x6,
18491    NM_EXTRV_W      = 0x7,
18492};
18493
18494/* POOL32Axf_2_8_15 instruction pool */
18495enum {
18496    NM_DPAX_W_PH    = 0x0,
18497    NM_DPAQ_SA_L_W  = 0x1,
18498    NM_DPSX_W_PH    = 0x2,
18499    NM_DPSQ_SA_L_W  = 0x3,
18500    NM_MADDU        = 0x5,
18501    NM_MULTU        = 0x6,
18502    NM_EXTRV_R_W    = 0x7,
18503};
18504
18505/* POOL32Axf_2_16_23 instruction pool */
18506enum {
18507    NM_DPAU_H_QBL       = 0x0,
18508    NM_DPAQX_S_W_PH     = 0x1,
18509    NM_DPSU_H_QBL       = 0x2,
18510    NM_DPSQX_S_W_PH     = 0x3,
18511    NM_EXTPV            = 0x4,
18512    NM_MSUB             = 0x5,
18513    NM_MULSA_W_PH       = 0x6,
18514    NM_EXTRV_RS_W       = 0x7,
18515};
18516
18517/* POOL32Axf_2_24_31 instruction pool */
18518enum {
18519    NM_DPAU_H_QBR       = 0x0,
18520    NM_DPAQX_SA_W_PH    = 0x1,
18521    NM_DPSU_H_QBR       = 0x2,
18522    NM_DPSQX_SA_W_PH    = 0x3,
18523    NM_EXTPDPV          = 0x4,
18524    NM_MSUBU            = 0x5,
18525    NM_MULSAQ_S_W_PH    = 0x6,
18526    NM_EXTRV_S_H        = 0x7,
18527};
18528
18529/* POOL32Axf_{4, 5} instruction pool */
18530enum {
18531    NM_CLO      = 0x25,
18532    NM_CLZ      = 0x2d,
18533
18534    NM_TLBP     = 0x01,
18535    NM_TLBR     = 0x09,
18536    NM_TLBWI    = 0x11,
18537    NM_TLBWR    = 0x19,
18538    NM_TLBINV   = 0x03,
18539    NM_TLBINVF  = 0x0b,
18540    NM_DI       = 0x23,
18541    NM_EI       = 0x2b,
18542    NM_RDPGPR   = 0x70,
18543    NM_WRPGPR   = 0x78,
18544    NM_WAIT     = 0x61,
18545    NM_DERET    = 0x71,
18546    NM_ERETX    = 0x79,
18547
18548    /* nanoMIPS DSP instructions */
18549    NM_ABSQ_S_QB        = 0x00,
18550    NM_ABSQ_S_PH        = 0x08,
18551    NM_ABSQ_S_W         = 0x10,
18552    NM_PRECEQ_W_PHL     = 0x28,
18553    NM_PRECEQ_W_PHR     = 0x30,
18554    NM_PRECEQU_PH_QBL   = 0x38,
18555    NM_PRECEQU_PH_QBR   = 0x48,
18556    NM_PRECEU_PH_QBL    = 0x58,
18557    NM_PRECEU_PH_QBR    = 0x68,
18558    NM_PRECEQU_PH_QBLA  = 0x39,
18559    NM_PRECEQU_PH_QBRA  = 0x49,
18560    NM_PRECEU_PH_QBLA   = 0x59,
18561    NM_PRECEU_PH_QBRA   = 0x69,
18562    NM_REPLV_PH         = 0x01,
18563    NM_REPLV_QB         = 0x09,
18564    NM_BITREV           = 0x18,
18565    NM_INSV             = 0x20,
18566    NM_RADDU_W_QB       = 0x78,
18567
18568    NM_BITSWAP          = 0x05,
18569    NM_WSBH             = 0x3d,
18570};
18571
18572/* PP.SR instruction pool */
18573enum {
18574    NM_SAVE         = 0x00,
18575    NM_RESTORE      = 0x02,
18576    NM_RESTORE_JRC  = 0x03,
18577};
18578
18579/* P.SR.F instruction pool */
18580enum {
18581    NM_SAVEF        = 0x00,
18582    NM_RESTOREF     = 0x01,
18583};
18584
18585/* P16.SYSCALL  instruction pool */
18586enum {
18587    NM_SYSCALL16     = 0x00,
18588    NM_HYPCALL16     = 0x01,
18589};
18590
18591/* POOL16C_00 instruction pool */
18592enum {
18593    NM_NOT16           = 0x00,
18594    NM_XOR16           = 0x01,
18595    NM_AND16           = 0x02,
18596    NM_OR16            = 0x03,
18597};
18598
18599/* PP.LSX and PP.LSXS instruction pool */
18600enum {
18601    NM_LBX      = 0x00,
18602    NM_LHX      = 0x04,
18603    NM_LWX      = 0x08,
18604    NM_LDX      = 0x0c,
18605
18606    NM_SBX      = 0x01,
18607    NM_SHX      = 0x05,
18608    NM_SWX      = 0x09,
18609    NM_SDX      = 0x0d,
18610
18611    NM_LBUX     = 0x02,
18612    NM_LHUX     = 0x06,
18613    NM_LWC1X    = 0x0a,
18614    NM_LDC1X    = 0x0e,
18615
18616    NM_LWUX     = 0x07,
18617    NM_SWC1X    = 0x0b,
18618    NM_SDC1X    = 0x0f,
18619
18620    NM_LHXS     = 0x04,
18621    NM_LWXS     = 0x08,
18622    NM_LDXS     = 0x0c,
18623
18624    NM_SHXS     = 0x05,
18625    NM_SWXS     = 0x09,
18626    NM_SDXS     = 0x0d,
18627
18628    NM_LHUXS    = 0x06,
18629    NM_LWC1XS   = 0x0a,
18630    NM_LDC1XS   = 0x0e,
18631
18632    NM_LWUXS    = 0x07,
18633    NM_SWC1XS   = 0x0b,
18634    NM_SDC1XS   = 0x0f,
18635};
18636
18637/* ERETx instruction pool */
18638enum {
18639    NM_ERET     = 0x00,
18640    NM_ERETNC   = 0x01,
18641};
18642
18643/* POOL32FxF_{0, 1} insturction pool */
18644enum {
18645    NM_CFC1     = 0x40,
18646    NM_CTC1     = 0x60,
18647    NM_MFC1     = 0x80,
18648    NM_MTC1     = 0xa0,
18649    NM_MFHC1    = 0xc0,
18650    NM_MTHC1    = 0xe0,
18651
18652    NM_CVT_S_PL = 0x84,
18653    NM_CVT_S_PU = 0xa4,
18654
18655    NM_CVT_L_S     = 0x004,
18656    NM_CVT_L_D     = 0x104,
18657    NM_CVT_W_S     = 0x024,
18658    NM_CVT_W_D     = 0x124,
18659
18660    NM_RSQRT_S     = 0x008,
18661    NM_RSQRT_D     = 0x108,
18662
18663    NM_SQRT_S      = 0x028,
18664    NM_SQRT_D      = 0x128,
18665
18666    NM_RECIP_S     = 0x048,
18667    NM_RECIP_D     = 0x148,
18668
18669    NM_FLOOR_L_S   = 0x00c,
18670    NM_FLOOR_L_D   = 0x10c,
18671
18672    NM_FLOOR_W_S   = 0x02c,
18673    NM_FLOOR_W_D   = 0x12c,
18674
18675    NM_CEIL_L_S    = 0x04c,
18676    NM_CEIL_L_D    = 0x14c,
18677    NM_CEIL_W_S    = 0x06c,
18678    NM_CEIL_W_D    = 0x16c,
18679    NM_TRUNC_L_S   = 0x08c,
18680    NM_TRUNC_L_D   = 0x18c,
18681    NM_TRUNC_W_S   = 0x0ac,
18682    NM_TRUNC_W_D   = 0x1ac,
18683    NM_ROUND_L_S   = 0x0cc,
18684    NM_ROUND_L_D   = 0x1cc,
18685    NM_ROUND_W_S   = 0x0ec,
18686    NM_ROUND_W_D   = 0x1ec,
18687
18688    NM_MOV_S       = 0x01,
18689    NM_MOV_D       = 0x81,
18690    NM_ABS_S       = 0x0d,
18691    NM_ABS_D       = 0x8d,
18692    NM_NEG_S       = 0x2d,
18693    NM_NEG_D       = 0xad,
18694    NM_CVT_D_S     = 0x04d,
18695    NM_CVT_D_W     = 0x0cd,
18696    NM_CVT_D_L     = 0x14d,
18697    NM_CVT_S_D     = 0x06d,
18698    NM_CVT_S_W     = 0x0ed,
18699    NM_CVT_S_L     = 0x16d,
18700};
18701
18702/* P.LL instruction pool */
18703enum {
18704    NM_LL       = 0x00,
18705    NM_LLWP     = 0x01,
18706};
18707
18708/* P.SC instruction pool */
18709enum {
18710    NM_SC       = 0x00,
18711    NM_SCWP     = 0x01,
18712};
18713
18714/* P.DVP instruction pool */
18715enum {
18716    NM_DVP      = 0x00,
18717    NM_EVP      = 0x01,
18718};
18719
18720
18721/*
18722 *
18723 * nanoMIPS decoding engine
18724 *
18725 */
18726
18727
18728/* extraction utilities */
18729
18730#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18731#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18732#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18733#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18734#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18735
18736/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18737static inline int decode_gpr_gpr3(int r)
18738{
18739    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18740
18741    return map[r & 0x7];
18742}
18743
18744/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18745static inline int decode_gpr_gpr3_src_store(int r)
18746{
18747    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18748
18749    return map[r & 0x7];
18750}
18751
18752/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18753static inline int decode_gpr_gpr4(int r)
18754{
18755    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18756                               16, 17, 18, 19, 20, 21, 22, 23 };
18757
18758    return map[r & 0xf];
18759}
18760
18761/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18762static inline int decode_gpr_gpr4_zero(int r)
18763{
18764    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18765                               16, 17, 18, 19, 20, 21, 22, 23 };
18766
18767    return map[r & 0xf];
18768}
18769
18770
18771static void gen_adjust_sp(DisasContext *ctx, int u)
18772{
18773    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18774}
18775
18776static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18777                     uint8_t gp, uint16_t u)
18778{
18779    int counter = 0;
18780    TCGv va = tcg_temp_new();
18781    TCGv t0 = tcg_temp_new();
18782
18783    while (counter != count) {
18784        bool use_gp = gp && (counter == count - 1);
18785        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18786        int this_offset = -((counter + 1) << 2);
18787        gen_base_offset_addr(ctx, va, 29, this_offset);
18788        gen_load_gpr(t0, this_rt);
18789        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18790                           (MO_TEUL | ctx->default_tcg_memop_mask));
18791        counter++;
18792    }
18793
18794    /* adjust stack pointer */
18795    gen_adjust_sp(ctx, -u);
18796
18797    tcg_temp_free(t0);
18798    tcg_temp_free(va);
18799}
18800
18801static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18802                        uint8_t gp, uint16_t u)
18803{
18804    int counter = 0;
18805    TCGv va = tcg_temp_new();
18806    TCGv t0 = tcg_temp_new();
18807
18808    while (counter != count) {
18809        bool use_gp = gp && (counter == count - 1);
18810        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18811        int this_offset = u - ((counter + 1) << 2);
18812        gen_base_offset_addr(ctx, va, 29, this_offset);
18813        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18814                        ctx->default_tcg_memop_mask);
18815        tcg_gen_ext32s_tl(t0, t0);
18816        gen_store_gpr(t0, this_rt);
18817        counter++;
18818    }
18819
18820    /* adjust stack pointer */
18821    gen_adjust_sp(ctx, u);
18822
18823    tcg_temp_free(t0);
18824    tcg_temp_free(va);
18825}
18826
18827static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18828{
18829    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18830    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18831
18832    switch (extract32(ctx->opcode, 2, 2)) {
18833    case NM_NOT16:
18834        gen_logic(ctx, OPC_NOR, rt, rs, 0);
18835        break;
18836    case NM_AND16:
18837        gen_logic(ctx, OPC_AND, rt, rt, rs);
18838        break;
18839    case NM_XOR16:
18840        gen_logic(ctx, OPC_XOR, rt, rt, rs);
18841        break;
18842    case NM_OR16:
18843        gen_logic(ctx, OPC_OR, rt, rt, rs);
18844        break;
18845    }
18846}
18847
18848static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18849{
18850    int rt = extract32(ctx->opcode, 21, 5);
18851    int rs = extract32(ctx->opcode, 16, 5);
18852    int rd = extract32(ctx->opcode, 11, 5);
18853
18854    switch (extract32(ctx->opcode, 3, 7)) {
18855    case NM_P_TRAP:
18856        switch (extract32(ctx->opcode, 10, 1)) {
18857        case NM_TEQ:
18858            check_nms(ctx);
18859            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18860            break;
18861        case NM_TNE:
18862            check_nms(ctx);
18863            gen_trap(ctx, OPC_TNE, rs, rt, -1);
18864            break;
18865        }
18866        break;
18867    case NM_RDHWR:
18868        check_nms(ctx);
18869        gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18870        break;
18871    case NM_SEB:
18872        check_nms(ctx);
18873        gen_bshfl(ctx, OPC_SEB, rs, rt);
18874        break;
18875    case NM_SEH:
18876        gen_bshfl(ctx, OPC_SEH, rs, rt);
18877        break;
18878    case NM_SLLV:
18879        gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18880        break;
18881    case NM_SRLV:
18882        gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18883        break;
18884    case NM_SRAV:
18885        gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18886        break;
18887    case NM_ROTRV:
18888        gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18889        break;
18890    case NM_ADD:
18891        gen_arith(ctx, OPC_ADD, rd, rs, rt);
18892        break;
18893    case NM_ADDU:
18894        gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18895        break;
18896    case NM_SUB:
18897        check_nms(ctx);
18898        gen_arith(ctx, OPC_SUB, rd, rs, rt);
18899        break;
18900    case NM_SUBU:
18901        gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18902        break;
18903    case NM_P_CMOVE:
18904        switch (extract32(ctx->opcode, 10, 1)) {
18905        case NM_MOVZ:
18906            gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18907            break;
18908        case NM_MOVN:
18909            gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18910            break;
18911        }
18912        break;
18913    case NM_AND:
18914        gen_logic(ctx, OPC_AND, rd, rs, rt);
18915        break;
18916    case NM_OR:
18917        gen_logic(ctx, OPC_OR, rd, rs, rt);
18918        break;
18919    case NM_NOR:
18920        gen_logic(ctx, OPC_NOR, rd, rs, rt);
18921        break;
18922    case NM_XOR:
18923        gen_logic(ctx, OPC_XOR, rd, rs, rt);
18924        break;
18925    case NM_SLT:
18926        gen_slt(ctx, OPC_SLT, rd, rs, rt);
18927        break;
18928    case NM_P_SLTU:
18929        if (rd == 0) {
18930            /* P_DVP */
18931#ifndef CONFIG_USER_ONLY
18932            TCGv t0 = tcg_temp_new();
18933            switch (extract32(ctx->opcode, 10, 1)) {
18934            case NM_DVP:
18935                if (ctx->vp) {
18936                    check_cp0_enabled(ctx);
18937                    gen_helper_dvp(t0, cpu_env);
18938                    gen_store_gpr(t0, rt);
18939                }
18940                break;
18941            case NM_EVP:
18942                if (ctx->vp) {
18943                    check_cp0_enabled(ctx);
18944                    gen_helper_evp(t0, cpu_env);
18945                    gen_store_gpr(t0, rt);
18946                }
18947                break;
18948            }
18949            tcg_temp_free(t0);
18950#endif
18951        } else {
18952            gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18953        }
18954        break;
18955    case NM_SOV:
18956        {
18957            TCGv t0 = tcg_temp_new();
18958            TCGv t1 = tcg_temp_new();
18959            TCGv t2 = tcg_temp_new();
18960
18961            gen_load_gpr(t1, rs);
18962            gen_load_gpr(t2, rt);
18963            tcg_gen_add_tl(t0, t1, t2);
18964            tcg_gen_ext32s_tl(t0, t0);
18965            tcg_gen_xor_tl(t1, t1, t2);
18966            tcg_gen_xor_tl(t2, t0, t2);
18967            tcg_gen_andc_tl(t1, t2, t1);
18968
18969            /* operands of same sign, result different sign */
18970            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18971            gen_store_gpr(t0, rd);
18972
18973            tcg_temp_free(t0);
18974            tcg_temp_free(t1);
18975            tcg_temp_free(t2);
18976        }
18977        break;
18978    case NM_MUL:
18979        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18980        break;
18981    case NM_MUH:
18982        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18983        break;
18984    case NM_MULU:
18985        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18986        break;
18987    case NM_MUHU:
18988        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18989        break;
18990    case NM_DIV:
18991        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18992        break;
18993    case NM_MOD:
18994        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18995        break;
18996    case NM_DIVU:
18997        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18998        break;
18999    case NM_MODU:
19000        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
19001        break;
19002#ifndef CONFIG_USER_ONLY
19003    case NM_MFC0:
19004        check_cp0_enabled(ctx);
19005        if (rt == 0) {
19006            /* Treat as NOP. */
19007            break;
19008        }
19009        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
19010        break;
19011    case NM_MTC0:
19012        check_cp0_enabled(ctx);
19013        {
19014            TCGv t0 = tcg_temp_new();
19015
19016            gen_load_gpr(t0, rt);
19017            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
19018            tcg_temp_free(t0);
19019        }
19020        break;
19021    case NM_D_E_MT_VPE:
19022        {
19023            uint8_t sc = extract32(ctx->opcode, 10, 1);
19024            TCGv t0 = tcg_temp_new();
19025
19026            switch (sc) {
19027            case 0:
19028                if (rs == 1) {
19029                    /* DMT */
19030                    check_cp0_mt(ctx);
19031                    gen_helper_dmt(t0);
19032                    gen_store_gpr(t0, rt);
19033                } else if (rs == 0) {
19034                    /* DVPE */
19035                    check_cp0_mt(ctx);
19036                    gen_helper_dvpe(t0, cpu_env);
19037                    gen_store_gpr(t0, rt);
19038                } else {
19039                    generate_exception_end(ctx, EXCP_RI);
19040                }
19041                break;
19042            case 1:
19043                if (rs == 1) {
19044                    /* EMT */
19045                    check_cp0_mt(ctx);
19046                    gen_helper_emt(t0);
19047                    gen_store_gpr(t0, rt);
19048                } else if (rs == 0) {
19049                    /* EVPE */
19050                    check_cp0_mt(ctx);
19051                    gen_helper_evpe(t0, cpu_env);
19052                    gen_store_gpr(t0, rt);
19053                } else {
19054                    generate_exception_end(ctx, EXCP_RI);
19055                }
19056                break;
19057            }
19058
19059            tcg_temp_free(t0);
19060        }
19061        break;
19062    case NM_FORK:
19063        check_mt(ctx);
19064        {
19065            TCGv t0 = tcg_temp_new();
19066            TCGv t1 = tcg_temp_new();
19067
19068            gen_load_gpr(t0, rt);
19069            gen_load_gpr(t1, rs);
19070            gen_helper_fork(t0, t1);
19071            tcg_temp_free(t0);
19072            tcg_temp_free(t1);
19073        }
19074        break;
19075    case NM_MFTR:
19076    case NM_MFHTR:
19077        check_cp0_enabled(ctx);
19078        if (rd == 0) {
19079            /* Treat as NOP. */
19080            return;
19081        }
19082        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19083                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19084        break;
19085    case NM_MTTR:
19086    case NM_MTHTR:
19087        check_cp0_enabled(ctx);
19088        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
19089                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
19090        break;
19091    case NM_YIELD:
19092        check_mt(ctx);
19093        {
19094            TCGv t0 = tcg_temp_new();
19095
19096            gen_load_gpr(t0, rs);
19097            gen_helper_yield(t0, cpu_env, t0);
19098            gen_store_gpr(t0, rt);
19099            tcg_temp_free(t0);
19100        }
19101        break;
19102#endif
19103    default:
19104        generate_exception_end(ctx, EXCP_RI);
19105        break;
19106    }
19107}
19108
19109/* dsp */
19110static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
19111                                            int ret, int v1, int v2)
19112{
19113    TCGv_i32 t0;
19114    TCGv v0_t;
19115    TCGv v1_t;
19116
19117    t0 = tcg_temp_new_i32();
19118
19119    v0_t = tcg_temp_new();
19120    v1_t = tcg_temp_new();
19121
19122    tcg_gen_movi_i32(t0, v2 >> 3);
19123
19124    gen_load_gpr(v0_t, ret);
19125    gen_load_gpr(v1_t, v1);
19126
19127    switch (opc) {
19128    case NM_MAQ_S_W_PHR:
19129        check_dsp(ctx);
19130        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
19131        break;
19132    case NM_MAQ_S_W_PHL:
19133        check_dsp(ctx);
19134        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
19135        break;
19136    case NM_MAQ_SA_W_PHR:
19137        check_dsp(ctx);
19138        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
19139        break;
19140    case NM_MAQ_SA_W_PHL:
19141        check_dsp(ctx);
19142        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
19143        break;
19144    default:
19145        generate_exception_end(ctx, EXCP_RI);
19146        break;
19147    }
19148
19149    tcg_temp_free_i32(t0);
19150
19151    tcg_temp_free(v0_t);
19152    tcg_temp_free(v1_t);
19153}
19154
19155
19156static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
19157                                    int ret, int v1, int v2)
19158{
19159    int16_t imm;
19160    TCGv t0 = tcg_temp_new();
19161    TCGv t1 = tcg_temp_new();
19162    TCGv v0_t = tcg_temp_new();
19163
19164    gen_load_gpr(v0_t, v1);
19165
19166    switch (opc) {
19167    case NM_POOL32AXF_1_0:
19168        check_dsp(ctx);
19169        switch (extract32(ctx->opcode, 12, 2)) {
19170        case NM_MFHI:
19171            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
19172            break;
19173        case NM_MFLO:
19174            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
19175            break;
19176        case NM_MTHI:
19177            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
19178            break;
19179        case NM_MTLO:
19180            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
19181            break;
19182        }
19183        break;
19184    case NM_POOL32AXF_1_1:
19185        check_dsp(ctx);
19186        switch (extract32(ctx->opcode, 12, 2)) {
19187        case NM_MTHLIP:
19188            tcg_gen_movi_tl(t0, v2);
19189            gen_helper_mthlip(t0, v0_t, cpu_env);
19190            break;
19191        case NM_SHILOV:
19192            tcg_gen_movi_tl(t0, v2 >> 3);
19193            gen_helper_shilo(t0, v0_t, cpu_env);
19194            break;
19195        default:
19196            generate_exception_end(ctx, EXCP_RI);
19197            break;
19198        }
19199        break;
19200    case NM_POOL32AXF_1_3:
19201        check_dsp(ctx);
19202        imm = extract32(ctx->opcode, 14, 7);
19203        switch (extract32(ctx->opcode, 12, 2)) {
19204        case NM_RDDSP:
19205            tcg_gen_movi_tl(t0, imm);
19206            gen_helper_rddsp(t0, t0, cpu_env);
19207            gen_store_gpr(t0, ret);
19208            break;
19209        case NM_WRDSP:
19210            gen_load_gpr(t0, ret);
19211            tcg_gen_movi_tl(t1, imm);
19212            gen_helper_wrdsp(t0, t1, cpu_env);
19213            break;
19214        case NM_EXTP:
19215            tcg_gen_movi_tl(t0, v2 >> 3);
19216            tcg_gen_movi_tl(t1, v1);
19217            gen_helper_extp(t0, t0, t1, cpu_env);
19218            gen_store_gpr(t0, ret);
19219            break;
19220        case NM_EXTPDP:
19221            tcg_gen_movi_tl(t0, v2 >> 3);
19222            tcg_gen_movi_tl(t1, v1);
19223            gen_helper_extpdp(t0, t0, t1, cpu_env);
19224            gen_store_gpr(t0, ret);
19225            break;
19226        }
19227        break;
19228    case NM_POOL32AXF_1_4:
19229        check_dsp(ctx);
19230        tcg_gen_movi_tl(t0, v2 >> 2);
19231        switch (extract32(ctx->opcode, 12, 1)) {
19232        case NM_SHLL_QB:
19233            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
19234            gen_store_gpr(t0, ret);
19235            break;
19236        case NM_SHRL_QB:
19237            gen_helper_shrl_qb(t0, t0, v0_t);
19238            gen_store_gpr(t0, ret);
19239            break;
19240        }
19241        break;
19242    case NM_POOL32AXF_1_5:
19243        opc = extract32(ctx->opcode, 12, 2);
19244        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
19245        break;
19246    case NM_POOL32AXF_1_7:
19247        check_dsp(ctx);
19248        tcg_gen_movi_tl(t0, v2 >> 3);
19249        tcg_gen_movi_tl(t1, v1);
19250        switch (extract32(ctx->opcode, 12, 2)) {
19251        case NM_EXTR_W:
19252            gen_helper_extr_w(t0, t0, t1, cpu_env);
19253            gen_store_gpr(t0, ret);
19254            break;
19255        case NM_EXTR_R_W:
19256            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19257            gen_store_gpr(t0, ret);
19258            break;
19259        case NM_EXTR_RS_W:
19260            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19261            gen_store_gpr(t0, ret);
19262            break;
19263        case NM_EXTR_S_H:
19264            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19265            gen_store_gpr(t0, ret);
19266            break;
19267        }
19268        break;
19269    default:
19270        generate_exception_end(ctx, EXCP_RI);
19271        break;
19272    }
19273
19274    tcg_temp_free(t0);
19275    tcg_temp_free(t1);
19276    tcg_temp_free(v0_t);
19277}
19278
19279static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19280                                    TCGv v0, TCGv v1, int rd)
19281{
19282    TCGv_i32 t0;
19283
19284    t0 = tcg_temp_new_i32();
19285
19286    tcg_gen_movi_i32(t0, rd >> 3);
19287
19288    switch (opc) {
19289    case NM_POOL32AXF_2_0_7:
19290        switch (extract32(ctx->opcode, 9, 3)) {
19291        case NM_DPA_W_PH:
19292            check_dsp_r2(ctx);
19293            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19294            break;
19295        case NM_DPAQ_S_W_PH:
19296            check_dsp(ctx);
19297            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19298            break;
19299        case NM_DPS_W_PH:
19300            check_dsp_r2(ctx);
19301            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19302            break;
19303        case NM_DPSQ_S_W_PH:
19304            check_dsp(ctx);
19305            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19306            break;
19307        default:
19308            generate_exception_end(ctx, EXCP_RI);
19309            break;
19310        }
19311        break;
19312    case NM_POOL32AXF_2_8_15:
19313        switch (extract32(ctx->opcode, 9, 3)) {
19314        case NM_DPAX_W_PH:
19315            check_dsp_r2(ctx);
19316            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19317            break;
19318        case NM_DPAQ_SA_L_W:
19319            check_dsp(ctx);
19320            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19321            break;
19322        case NM_DPSX_W_PH:
19323            check_dsp_r2(ctx);
19324            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19325            break;
19326        case NM_DPSQ_SA_L_W:
19327            check_dsp(ctx);
19328            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19329            break;
19330        default:
19331            generate_exception_end(ctx, EXCP_RI);
19332            break;
19333        }
19334        break;
19335    case NM_POOL32AXF_2_16_23:
19336        switch (extract32(ctx->opcode, 9, 3)) {
19337        case NM_DPAU_H_QBL:
19338            check_dsp(ctx);
19339            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19340            break;
19341        case NM_DPAQX_S_W_PH:
19342            check_dsp_r2(ctx);
19343            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19344            break;
19345        case NM_DPSU_H_QBL:
19346            check_dsp(ctx);
19347            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19348            break;
19349        case NM_DPSQX_S_W_PH:
19350            check_dsp_r2(ctx);
19351            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19352            break;
19353        case NM_MULSA_W_PH:
19354            check_dsp_r2(ctx);
19355            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19356            break;
19357        default:
19358            generate_exception_end(ctx, EXCP_RI);
19359            break;
19360        }
19361        break;
19362    case NM_POOL32AXF_2_24_31:
19363        switch (extract32(ctx->opcode, 9, 3)) {
19364        case NM_DPAU_H_QBR:
19365            check_dsp(ctx);
19366            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19367            break;
19368        case NM_DPAQX_SA_W_PH:
19369            check_dsp_r2(ctx);
19370            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19371            break;
19372        case NM_DPSU_H_QBR:
19373            check_dsp(ctx);
19374            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19375            break;
19376        case NM_DPSQX_SA_W_PH:
19377            check_dsp_r2(ctx);
19378            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19379            break;
19380        case NM_MULSAQ_S_W_PH:
19381            check_dsp(ctx);
19382            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19383            break;
19384        default:
19385            generate_exception_end(ctx, EXCP_RI);
19386            break;
19387        }
19388        break;
19389    default:
19390        generate_exception_end(ctx, EXCP_RI);
19391        break;
19392    }
19393
19394    tcg_temp_free_i32(t0);
19395}
19396
19397static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19398                                          int rt, int rs, int rd)
19399{
19400    int ret = rt;
19401    TCGv t0 = tcg_temp_new();
19402    TCGv t1 = tcg_temp_new();
19403    TCGv v0_t = tcg_temp_new();
19404    TCGv v1_t = tcg_temp_new();
19405
19406    gen_load_gpr(v0_t, rt);
19407    gen_load_gpr(v1_t, rs);
19408
19409    switch (opc) {
19410    case NM_POOL32AXF_2_0_7:
19411        switch (extract32(ctx->opcode, 9, 3)) {
19412        case NM_DPA_W_PH:
19413        case NM_DPAQ_S_W_PH:
19414        case NM_DPS_W_PH:
19415        case NM_DPSQ_S_W_PH:
19416            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19417            break;
19418        case NM_BALIGN:
19419            check_dsp_r2(ctx);
19420            if (rt != 0) {
19421                gen_load_gpr(t0, rs);
19422                rd &= 3;
19423                if (rd != 0 && rd != 2) {
19424                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19425                    tcg_gen_ext32u_tl(t0, t0);
19426                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19427                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19428                }
19429                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19430            }
19431            break;
19432        case NM_MADD:
19433            check_dsp(ctx);
19434            {
19435                int acc = extract32(ctx->opcode, 14, 2);
19436                TCGv_i64 t2 = tcg_temp_new_i64();
19437                TCGv_i64 t3 = tcg_temp_new_i64();
19438
19439                gen_load_gpr(t0, rt);
19440                gen_load_gpr(t1, rs);
19441                tcg_gen_ext_tl_i64(t2, t0);
19442                tcg_gen_ext_tl_i64(t3, t1);
19443                tcg_gen_mul_i64(t2, t2, t3);
19444                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19445                tcg_gen_add_i64(t2, t2, t3);
19446                tcg_temp_free_i64(t3);
19447                gen_move_low32(cpu_LO[acc], t2);
19448                gen_move_high32(cpu_HI[acc], t2);
19449                tcg_temp_free_i64(t2);
19450            }
19451            break;
19452        case NM_MULT:
19453            check_dsp(ctx);
19454            {
19455                int acc = extract32(ctx->opcode, 14, 2);
19456                TCGv_i32 t2 = tcg_temp_new_i32();
19457                TCGv_i32 t3 = tcg_temp_new_i32();
19458
19459                gen_load_gpr(t0, rs);
19460                gen_load_gpr(t1, rt);
19461                tcg_gen_trunc_tl_i32(t2, t0);
19462                tcg_gen_trunc_tl_i32(t3, t1);
19463                tcg_gen_muls2_i32(t2, t3, t2, t3);
19464                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19465                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19466                tcg_temp_free_i32(t2);
19467                tcg_temp_free_i32(t3);
19468            }
19469            break;
19470        case NM_EXTRV_W:
19471            check_dsp(ctx);
19472            gen_load_gpr(v1_t, rs);
19473            tcg_gen_movi_tl(t0, rd >> 3);
19474            gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19475            gen_store_gpr(t0, ret);
19476            break;
19477        }
19478        break;
19479    case NM_POOL32AXF_2_8_15:
19480        switch (extract32(ctx->opcode, 9, 3)) {
19481        case NM_DPAX_W_PH:
19482        case NM_DPAQ_SA_L_W:
19483        case NM_DPSX_W_PH:
19484        case NM_DPSQ_SA_L_W:
19485            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19486            break;
19487        case NM_MADDU:
19488            check_dsp(ctx);
19489            {
19490                int acc = extract32(ctx->opcode, 14, 2);
19491                TCGv_i64 t2 = tcg_temp_new_i64();
19492                TCGv_i64 t3 = tcg_temp_new_i64();
19493
19494                gen_load_gpr(t0, rs);
19495                gen_load_gpr(t1, rt);
19496                tcg_gen_ext32u_tl(t0, t0);
19497                tcg_gen_ext32u_tl(t1, t1);
19498                tcg_gen_extu_tl_i64(t2, t0);
19499                tcg_gen_extu_tl_i64(t3, t1);
19500                tcg_gen_mul_i64(t2, t2, t3);
19501                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19502                tcg_gen_add_i64(t2, t2, t3);
19503                tcg_temp_free_i64(t3);
19504                gen_move_low32(cpu_LO[acc], t2);
19505                gen_move_high32(cpu_HI[acc], t2);
19506                tcg_temp_free_i64(t2);
19507            }
19508            break;
19509        case NM_MULTU:
19510            check_dsp(ctx);
19511            {
19512                int acc = extract32(ctx->opcode, 14, 2);
19513                TCGv_i32 t2 = tcg_temp_new_i32();
19514                TCGv_i32 t3 = tcg_temp_new_i32();
19515
19516                gen_load_gpr(t0, rs);
19517                gen_load_gpr(t1, rt);
19518                tcg_gen_trunc_tl_i32(t2, t0);
19519                tcg_gen_trunc_tl_i32(t3, t1);
19520                tcg_gen_mulu2_i32(t2, t3, t2, t3);
19521                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19522                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19523                tcg_temp_free_i32(t2);
19524                tcg_temp_free_i32(t3);
19525            }
19526            break;
19527        case NM_EXTRV_R_W:
19528            check_dsp(ctx);
19529            tcg_gen_movi_tl(t0, rd >> 3);
19530            gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19531            gen_store_gpr(t0, ret);
19532            break;
19533        default:
19534            generate_exception_end(ctx, EXCP_RI);
19535            break;
19536        }
19537        break;
19538    case NM_POOL32AXF_2_16_23:
19539        switch (extract32(ctx->opcode, 9, 3)) {
19540        case NM_DPAU_H_QBL:
19541        case NM_DPAQX_S_W_PH:
19542        case NM_DPSU_H_QBL:
19543        case NM_DPSQX_S_W_PH:
19544        case NM_MULSA_W_PH:
19545            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19546            break;
19547        case NM_EXTPV:
19548            check_dsp(ctx);
19549            tcg_gen_movi_tl(t0, rd >> 3);
19550            gen_helper_extp(t0, t0, v1_t, cpu_env);
19551            gen_store_gpr(t0, ret);
19552            break;
19553        case NM_MSUB:
19554            check_dsp(ctx);
19555            {
19556                int acc = extract32(ctx->opcode, 14, 2);
19557                TCGv_i64 t2 = tcg_temp_new_i64();
19558                TCGv_i64 t3 = tcg_temp_new_i64();
19559
19560                gen_load_gpr(t0, rs);
19561                gen_load_gpr(t1, rt);
19562                tcg_gen_ext_tl_i64(t2, t0);
19563                tcg_gen_ext_tl_i64(t3, t1);
19564                tcg_gen_mul_i64(t2, t2, t3);
19565                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19566                tcg_gen_sub_i64(t2, t3, t2);
19567                tcg_temp_free_i64(t3);
19568                gen_move_low32(cpu_LO[acc], t2);
19569                gen_move_high32(cpu_HI[acc], t2);
19570                tcg_temp_free_i64(t2);
19571            }
19572            break;
19573        case NM_EXTRV_RS_W:
19574            check_dsp(ctx);
19575            tcg_gen_movi_tl(t0, rd >> 3);
19576            gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19577            gen_store_gpr(t0, ret);
19578            break;
19579        }
19580        break;
19581    case NM_POOL32AXF_2_24_31:
19582        switch (extract32(ctx->opcode, 9, 3)) {
19583        case NM_DPAU_H_QBR:
19584        case NM_DPAQX_SA_W_PH:
19585        case NM_DPSU_H_QBR:
19586        case NM_DPSQX_SA_W_PH:
19587        case NM_MULSAQ_S_W_PH:
19588            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19589            break;
19590        case NM_EXTPDPV:
19591            check_dsp(ctx);
19592            tcg_gen_movi_tl(t0, rd >> 3);
19593            gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19594            gen_store_gpr(t0, ret);
19595            break;
19596        case NM_MSUBU:
19597            check_dsp(ctx);
19598            {
19599                int acc = extract32(ctx->opcode, 14, 2);
19600                TCGv_i64 t2 = tcg_temp_new_i64();
19601                TCGv_i64 t3 = tcg_temp_new_i64();
19602
19603                gen_load_gpr(t0, rs);
19604                gen_load_gpr(t1, rt);
19605                tcg_gen_ext32u_tl(t0, t0);
19606                tcg_gen_ext32u_tl(t1, t1);
19607                tcg_gen_extu_tl_i64(t2, t0);
19608                tcg_gen_extu_tl_i64(t3, t1);
19609                tcg_gen_mul_i64(t2, t2, t3);
19610                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19611                tcg_gen_sub_i64(t2, t3, t2);
19612                tcg_temp_free_i64(t3);
19613                gen_move_low32(cpu_LO[acc], t2);
19614                gen_move_high32(cpu_HI[acc], t2);
19615                tcg_temp_free_i64(t2);
19616            }
19617            break;
19618        case NM_EXTRV_S_H:
19619            check_dsp(ctx);
19620            tcg_gen_movi_tl(t0, rd >> 3);
19621            gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19622            gen_store_gpr(t0, ret);
19623            break;
19624        }
19625        break;
19626    default:
19627        generate_exception_end(ctx, EXCP_RI);
19628        break;
19629    }
19630
19631    tcg_temp_free(t0);
19632    tcg_temp_free(t1);
19633
19634    tcg_temp_free(v0_t);
19635    tcg_temp_free(v1_t);
19636}
19637
19638static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19639                                          int rt, int rs)
19640{
19641    int ret = rt;
19642    TCGv t0 = tcg_temp_new();
19643    TCGv v0_t = tcg_temp_new();
19644
19645    gen_load_gpr(v0_t, rs);
19646
19647    switch (opc) {
19648    case NM_ABSQ_S_QB:
19649        check_dsp_r2(ctx);
19650        gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19651        gen_store_gpr(v0_t, ret);
19652        break;
19653    case NM_ABSQ_S_PH:
19654        check_dsp(ctx);
19655        gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19656        gen_store_gpr(v0_t, ret);
19657        break;
19658    case NM_ABSQ_S_W:
19659        check_dsp(ctx);
19660        gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19661        gen_store_gpr(v0_t, ret);
19662        break;
19663    case NM_PRECEQ_W_PHL:
19664        check_dsp(ctx);
19665        tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19666        tcg_gen_ext32s_tl(v0_t, v0_t);
19667        gen_store_gpr(v0_t, ret);
19668        break;
19669    case NM_PRECEQ_W_PHR:
19670        check_dsp(ctx);
19671        tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19672        tcg_gen_shli_tl(v0_t, v0_t, 16);
19673        tcg_gen_ext32s_tl(v0_t, v0_t);
19674        gen_store_gpr(v0_t, ret);
19675        break;
19676    case NM_PRECEQU_PH_QBL:
19677        check_dsp(ctx);
19678        gen_helper_precequ_ph_qbl(v0_t, v0_t);
19679        gen_store_gpr(v0_t, ret);
19680        break;
19681    case NM_PRECEQU_PH_QBR:
19682        check_dsp(ctx);
19683        gen_helper_precequ_ph_qbr(v0_t, v0_t);
19684        gen_store_gpr(v0_t, ret);
19685        break;
19686    case NM_PRECEQU_PH_QBLA:
19687        check_dsp(ctx);
19688        gen_helper_precequ_ph_qbla(v0_t, v0_t);
19689        gen_store_gpr(v0_t, ret);
19690        break;
19691    case NM_PRECEQU_PH_QBRA:
19692        check_dsp(ctx);
19693        gen_helper_precequ_ph_qbra(v0_t, v0_t);
19694        gen_store_gpr(v0_t, ret);
19695        break;
19696    case NM_PRECEU_PH_QBL:
19697        check_dsp(ctx);
19698        gen_helper_preceu_ph_qbl(v0_t, v0_t);
19699        gen_store_gpr(v0_t, ret);
19700        break;
19701    case NM_PRECEU_PH_QBR:
19702        check_dsp(ctx);
19703        gen_helper_preceu_ph_qbr(v0_t, v0_t);
19704        gen_store_gpr(v0_t, ret);
19705        break;
19706    case NM_PRECEU_PH_QBLA:
19707        check_dsp(ctx);
19708        gen_helper_preceu_ph_qbla(v0_t, v0_t);
19709        gen_store_gpr(v0_t, ret);
19710        break;
19711    case NM_PRECEU_PH_QBRA:
19712        check_dsp(ctx);
19713        gen_helper_preceu_ph_qbra(v0_t, v0_t);
19714        gen_store_gpr(v0_t, ret);
19715        break;
19716    case NM_REPLV_PH:
19717        check_dsp(ctx);
19718        tcg_gen_ext16u_tl(v0_t, v0_t);
19719        tcg_gen_shli_tl(t0, v0_t, 16);
19720        tcg_gen_or_tl(v0_t, v0_t, t0);
19721        tcg_gen_ext32s_tl(v0_t, v0_t);
19722        gen_store_gpr(v0_t, ret);
19723        break;
19724    case NM_REPLV_QB:
19725        check_dsp(ctx);
19726        tcg_gen_ext8u_tl(v0_t, v0_t);
19727        tcg_gen_shli_tl(t0, v0_t, 8);
19728        tcg_gen_or_tl(v0_t, v0_t, t0);
19729        tcg_gen_shli_tl(t0, v0_t, 16);
19730        tcg_gen_or_tl(v0_t, v0_t, t0);
19731        tcg_gen_ext32s_tl(v0_t, v0_t);
19732        gen_store_gpr(v0_t, ret);
19733        break;
19734    case NM_BITREV:
19735        check_dsp(ctx);
19736        gen_helper_bitrev(v0_t, v0_t);
19737        gen_store_gpr(v0_t, ret);
19738        break;
19739    case NM_INSV:
19740        check_dsp(ctx);
19741        {
19742            TCGv tv0 = tcg_temp_new();
19743
19744            gen_load_gpr(tv0, rt);
19745            gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19746            gen_store_gpr(v0_t, ret);
19747            tcg_temp_free(tv0);
19748        }
19749        break;
19750    case NM_RADDU_W_QB:
19751        check_dsp(ctx);
19752        gen_helper_raddu_w_qb(v0_t, v0_t);
19753        gen_store_gpr(v0_t, ret);
19754        break;
19755    case NM_BITSWAP:
19756        gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19757        break;
19758    case NM_CLO:
19759        check_nms(ctx);
19760        gen_cl(ctx, OPC_CLO, ret, rs);
19761        break;
19762    case NM_CLZ:
19763        check_nms(ctx);
19764        gen_cl(ctx, OPC_CLZ, ret, rs);
19765        break;
19766    case NM_WSBH:
19767        gen_bshfl(ctx, OPC_WSBH, ret, rs);
19768        break;
19769    default:
19770        generate_exception_end(ctx, EXCP_RI);
19771        break;
19772    }
19773
19774    tcg_temp_free(v0_t);
19775    tcg_temp_free(t0);
19776}
19777
19778static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19779                                          int rt, int rs, int rd)
19780{
19781    TCGv t0 = tcg_temp_new();
19782    TCGv rs_t = tcg_temp_new();
19783
19784    gen_load_gpr(rs_t, rs);
19785
19786    switch (opc) {
19787    case NM_SHRA_R_QB:
19788        check_dsp_r2(ctx);
19789        tcg_gen_movi_tl(t0, rd >> 2);
19790        switch (extract32(ctx->opcode, 12, 1)) {
19791        case 0:
19792            /* NM_SHRA_QB */
19793            gen_helper_shra_qb(t0, t0, rs_t);
19794            gen_store_gpr(t0, rt);
19795            break;
19796        case 1:
19797            /* NM_SHRA_R_QB */
19798            gen_helper_shra_r_qb(t0, t0, rs_t);
19799            gen_store_gpr(t0, rt);
19800            break;
19801        }
19802        break;
19803    case NM_SHRL_PH:
19804        check_dsp_r2(ctx);
19805        tcg_gen_movi_tl(t0, rd >> 1);
19806        gen_helper_shrl_ph(t0, t0, rs_t);
19807        gen_store_gpr(t0, rt);
19808        break;
19809    case NM_REPL_QB:
19810        check_dsp(ctx);
19811        {
19812            int16_t imm;
19813            target_long result;
19814            imm = extract32(ctx->opcode, 13, 8);
19815            result = (uint32_t)imm << 24 |
19816                     (uint32_t)imm << 16 |
19817                     (uint32_t)imm << 8  |
19818                     (uint32_t)imm;
19819            result = (int32_t)result;
19820            tcg_gen_movi_tl(t0, result);
19821            gen_store_gpr(t0, rt);
19822        }
19823        break;
19824    default:
19825        generate_exception_end(ctx, EXCP_RI);
19826        break;
19827    }
19828    tcg_temp_free(t0);
19829    tcg_temp_free(rs_t);
19830}
19831
19832
19833static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19834{
19835    int rt = extract32(ctx->opcode, 21, 5);
19836    int rs = extract32(ctx->opcode, 16, 5);
19837    int rd = extract32(ctx->opcode, 11, 5);
19838
19839    switch (extract32(ctx->opcode, 6, 3)) {
19840    case NM_POOL32AXF_1:
19841        {
19842            int32_t op1 = extract32(ctx->opcode, 9, 3);
19843            gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19844        }
19845        break;
19846    case NM_POOL32AXF_2:
19847        {
19848            int32_t op1 = extract32(ctx->opcode, 12, 2);
19849            gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19850        }
19851        break;
19852    case NM_POOL32AXF_4:
19853        {
19854            int32_t op1 = extract32(ctx->opcode, 9, 7);
19855            gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19856        }
19857        break;
19858    case NM_POOL32AXF_5:
19859        switch (extract32(ctx->opcode, 9, 7)) {
19860#ifndef CONFIG_USER_ONLY
19861        case NM_TLBP:
19862            gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19863            break;
19864        case NM_TLBR:
19865            gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19866            break;
19867        case NM_TLBWI:
19868            gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19869            break;
19870        case NM_TLBWR:
19871            gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19872            break;
19873        case NM_TLBINV:
19874            gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19875            break;
19876        case NM_TLBINVF:
19877            gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19878            break;
19879        case NM_DI:
19880            check_cp0_enabled(ctx);
19881            {
19882                TCGv t0 = tcg_temp_new();
19883
19884                save_cpu_state(ctx, 1);
19885                gen_helper_di(t0, cpu_env);
19886                gen_store_gpr(t0, rt);
19887            /* Stop translation as we may have switched the execution mode */
19888                ctx->base.is_jmp = DISAS_STOP;
19889                tcg_temp_free(t0);
19890            }
19891            break;
19892        case NM_EI:
19893            check_cp0_enabled(ctx);
19894            {
19895                TCGv t0 = tcg_temp_new();
19896
19897                save_cpu_state(ctx, 1);
19898                gen_helper_ei(t0, cpu_env);
19899                gen_store_gpr(t0, rt);
19900            /* Stop translation as we may have switched the execution mode */
19901                ctx->base.is_jmp = DISAS_STOP;
19902                tcg_temp_free(t0);
19903            }
19904            break;
19905        case NM_RDPGPR:
19906            gen_load_srsgpr(rs, rt);
19907            break;
19908        case NM_WRPGPR:
19909            gen_store_srsgpr(rs, rt);
19910            break;
19911        case NM_WAIT:
19912            gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19913            break;
19914        case NM_DERET:
19915            gen_cp0(env, ctx, OPC_DERET, 0, 0);
19916            break;
19917        case NM_ERETX:
19918            gen_cp0(env, ctx, OPC_ERET, 0, 0);
19919            break;
19920#endif
19921        default:
19922            generate_exception_end(ctx, EXCP_RI);
19923            break;
19924        }
19925        break;
19926    case NM_POOL32AXF_7:
19927        {
19928            int32_t op1 = extract32(ctx->opcode, 9, 3);
19929            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19930        }
19931        break;
19932    default:
19933        generate_exception_end(ctx, EXCP_RI);
19934        break;
19935    }
19936}
19937
19938/* Immediate Value Compact Branches */
19939static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19940                                   int rt, int32_t imm, int32_t offset)
19941{
19942    TCGCond cond;
19943    int bcond_compute = 0;
19944    TCGv t0 = tcg_temp_new();
19945    TCGv t1 = tcg_temp_new();
19946
19947    gen_load_gpr(t0, rt);
19948    tcg_gen_movi_tl(t1, imm);
19949    ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19950
19951    /* Load needed operands and calculate btarget */
19952    switch (opc) {
19953    case NM_BEQIC:
19954        if (rt == 0 && imm == 0) {
19955            /* Unconditional branch */
19956        } else if (rt == 0 && imm != 0) {
19957            /* Treat as NOP */
19958            goto out;
19959        } else {
19960            bcond_compute = 1;
19961            cond = TCG_COND_EQ;
19962        }
19963        break;
19964    case NM_BBEQZC:
19965    case NM_BBNEZC:
19966        check_nms(ctx);
19967        if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19968            generate_exception_end(ctx, EXCP_RI);
19969            goto out;
19970        } else if (rt == 0 && opc == NM_BBEQZC) {
19971            /* Unconditional branch */
19972        } else if (rt == 0 && opc == NM_BBNEZC) {
19973            /* Treat as NOP */
19974            goto out;
19975        } else {
19976            tcg_gen_shri_tl(t0, t0, imm);
19977            tcg_gen_andi_tl(t0, t0, 1);
19978            tcg_gen_movi_tl(t1, 0);
19979            bcond_compute = 1;
19980            if (opc == NM_BBEQZC) {
19981                cond = TCG_COND_EQ;
19982            } else {
19983                cond = TCG_COND_NE;
19984            }
19985        }
19986        break;
19987    case NM_BNEIC:
19988        if (rt == 0 && imm == 0) {
19989            /* Treat as NOP */
19990            goto out;
19991        } else if (rt == 0 && imm != 0) {
19992            /* Unconditional branch */
19993        } else {
19994            bcond_compute = 1;
19995            cond = TCG_COND_NE;
19996        }
19997        break;
19998    case NM_BGEIC:
19999        if (rt == 0 && imm == 0) {
20000            /* Unconditional branch */
20001        } else  {
20002            bcond_compute = 1;
20003            cond = TCG_COND_GE;
20004        }
20005        break;
20006    case NM_BLTIC:
20007        bcond_compute = 1;
20008        cond = TCG_COND_LT;
20009        break;
20010    case NM_BGEIUC:
20011        if (rt == 0 && imm == 0) {
20012            /* Unconditional branch */
20013        } else  {
20014            bcond_compute = 1;
20015            cond = TCG_COND_GEU;
20016        }
20017        break;
20018    case NM_BLTIUC:
20019        bcond_compute = 1;
20020        cond = TCG_COND_LTU;
20021        break;
20022    default:
20023        MIPS_INVAL("Immediate Value Compact branch");
20024        generate_exception_end(ctx, EXCP_RI);
20025        goto out;
20026    }
20027
20028    /* branch completion */
20029    clear_branch_hflags(ctx);
20030    ctx->base.is_jmp = DISAS_NORETURN;
20031
20032    if (bcond_compute == 0) {
20033        /* Uncoditional compact branch */
20034        gen_goto_tb(ctx, 0, ctx->btarget);
20035    } else {
20036        /* Conditional compact branch */
20037        TCGLabel *fs = gen_new_label();
20038
20039        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
20040
20041        gen_goto_tb(ctx, 1, ctx->btarget);
20042        gen_set_label(fs);
20043
20044        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20045    }
20046
20047out:
20048    tcg_temp_free(t0);
20049    tcg_temp_free(t1);
20050}
20051
20052/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20053static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
20054                                                int rt)
20055{
20056    TCGv t0 = tcg_temp_new();
20057    TCGv t1 = tcg_temp_new();
20058
20059    /* load rs */
20060    gen_load_gpr(t0, rs);
20061
20062    /* link */
20063    if (rt != 0) {
20064        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
20065    }
20066
20067    /* calculate btarget */
20068    tcg_gen_shli_tl(t0, t0, 1);
20069    tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
20070    gen_op_addr_add(ctx, btarget, t1, t0);
20071
20072    /* branch completion */
20073    clear_branch_hflags(ctx);
20074    ctx->base.is_jmp = DISAS_NORETURN;
20075
20076    /* unconditional branch to register */
20077    tcg_gen_mov_tl(cpu_PC, btarget);
20078    tcg_gen_lookup_and_goto_ptr();
20079
20080    tcg_temp_free(t0);
20081    tcg_temp_free(t1);
20082}
20083
20084/* nanoMIPS Branches */
20085static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
20086                                       int rs, int rt, int32_t offset)
20087{
20088    int bcond_compute = 0;
20089    TCGv t0 = tcg_temp_new();
20090    TCGv t1 = tcg_temp_new();
20091
20092    /* Load needed operands and calculate btarget */
20093    switch (opc) {
20094    /* compact branch */
20095    case OPC_BGEC:
20096    case OPC_BLTC:
20097        gen_load_gpr(t0, rs);
20098        gen_load_gpr(t1, rt);
20099        bcond_compute = 1;
20100        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20101        break;
20102    case OPC_BGEUC:
20103    case OPC_BLTUC:
20104        if (rs == 0 || rs == rt) {
20105            /* OPC_BLEZALC, OPC_BGEZALC */
20106            /* OPC_BGTZALC, OPC_BLTZALC */
20107            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
20108        }
20109        gen_load_gpr(t0, rs);
20110        gen_load_gpr(t1, rt);
20111        bcond_compute = 1;
20112        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20113        break;
20114    case OPC_BC:
20115        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20116        break;
20117    case OPC_BEQZC:
20118        if (rs != 0) {
20119            /* OPC_BEQZC, OPC_BNEZC */
20120            gen_load_gpr(t0, rs);
20121            bcond_compute = 1;
20122            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20123        } else {
20124            /* OPC_JIC, OPC_JIALC */
20125            TCGv tbase = tcg_temp_new();
20126            TCGv toffset = tcg_temp_new();
20127
20128            gen_load_gpr(tbase, rt);
20129            tcg_gen_movi_tl(toffset, offset);
20130            gen_op_addr_add(ctx, btarget, tbase, toffset);
20131            tcg_temp_free(tbase);
20132            tcg_temp_free(toffset);
20133        }
20134        break;
20135    default:
20136        MIPS_INVAL("Compact branch/jump");
20137        generate_exception_end(ctx, EXCP_RI);
20138        goto out;
20139    }
20140
20141    if (bcond_compute == 0) {
20142        /* Uncoditional compact branch */
20143        switch (opc) {
20144        case OPC_BC:
20145            gen_goto_tb(ctx, 0, ctx->btarget);
20146            break;
20147        default:
20148            MIPS_INVAL("Compact branch/jump");
20149            generate_exception_end(ctx, EXCP_RI);
20150            goto out;
20151        }
20152    } else {
20153        /* Conditional compact branch */
20154        TCGLabel *fs = gen_new_label();
20155
20156        switch (opc) {
20157        case OPC_BGEUC:
20158            if (rs == 0 && rt != 0) {
20159                /* OPC_BLEZALC */
20160                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20161            } else if (rs != 0 && rt != 0 && rs == rt) {
20162                /* OPC_BGEZALC */
20163                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20164            } else {
20165                /* OPC_BGEUC */
20166                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
20167            }
20168            break;
20169        case OPC_BLTUC:
20170            if (rs == 0 && rt != 0) {
20171                /* OPC_BGTZALC */
20172                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20173            } else if (rs != 0 && rt != 0 && rs == rt) {
20174                /* OPC_BLTZALC */
20175                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20176            } else {
20177                /* OPC_BLTUC */
20178                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
20179            }
20180            break;
20181        case OPC_BGEC:
20182            if (rs == 0 && rt != 0) {
20183                /* OPC_BLEZC */
20184                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
20185            } else if (rs != 0 && rt != 0 && rs == rt) {
20186                /* OPC_BGEZC */
20187                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
20188            } else {
20189                /* OPC_BGEC */
20190                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
20191            }
20192            break;
20193        case OPC_BLTC:
20194            if (rs == 0 && rt != 0) {
20195                /* OPC_BGTZC */
20196                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
20197            } else if (rs != 0 && rt != 0 && rs == rt) {
20198                /* OPC_BLTZC */
20199                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
20200            } else {
20201                /* OPC_BLTC */
20202                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
20203            }
20204            break;
20205        case OPC_BEQZC:
20206            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
20207            break;
20208        default:
20209            MIPS_INVAL("Compact conditional branch/jump");
20210            generate_exception_end(ctx, EXCP_RI);
20211            goto out;
20212        }
20213
20214        /* branch completion */
20215        clear_branch_hflags(ctx);
20216        ctx->base.is_jmp = DISAS_NORETURN;
20217
20218        /* Generating branch here as compact branches don't have delay slot */
20219        gen_goto_tb(ctx, 1, ctx->btarget);
20220        gen_set_label(fs);
20221
20222        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
20223    }
20224
20225out:
20226    tcg_temp_free(t0);
20227    tcg_temp_free(t1);
20228}
20229
20230
20231/* nanoMIPS CP1 Branches */
20232static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
20233                                   int32_t ft, int32_t offset)
20234{
20235    target_ulong btarget;
20236    TCGv_i64 t0 = tcg_temp_new_i64();
20237
20238    gen_load_fpr64(ctx, t0, ft);
20239    tcg_gen_andi_i64(t0, t0, 1);
20240
20241    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
20242
20243    switch (op) {
20244    case NM_BC1EQZC:
20245        tcg_gen_xori_i64(t0, t0, 1);
20246        ctx->hflags |= MIPS_HFLAG_BC;
20247        break;
20248    case NM_BC1NEZC:
20249        /* t0 already set */
20250        ctx->hflags |= MIPS_HFLAG_BC;
20251        break;
20252    default:
20253        MIPS_INVAL("cp1 cond branch");
20254        generate_exception_end(ctx, EXCP_RI);
20255        goto out;
20256    }
20257
20258    tcg_gen_trunc_i64_tl(bcond, t0);
20259
20260    ctx->btarget = btarget;
20261
20262out:
20263    tcg_temp_free_i64(t0);
20264}
20265
20266
20267static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20268{
20269    TCGv t0, t1;
20270    t0 = tcg_temp_new();
20271    t1 = tcg_temp_new();
20272
20273    gen_load_gpr(t0, rs);
20274    gen_load_gpr(t1, rt);
20275
20276    if ((extract32(ctx->opcode, 6, 1)) == 1) {
20277        /* PP.LSXS instructions require shifting */
20278        switch (extract32(ctx->opcode, 7, 4)) {
20279        case NM_SHXS:
20280            check_nms(ctx);
20281            /* fall through */
20282        case NM_LHXS:
20283        case NM_LHUXS:
20284            tcg_gen_shli_tl(t0, t0, 1);
20285            break;
20286        case NM_SWXS:
20287            check_nms(ctx);
20288            /* fall through */
20289        case NM_LWXS:
20290        case NM_LWC1XS:
20291        case NM_SWC1XS:
20292            tcg_gen_shli_tl(t0, t0, 2);
20293            break;
20294        case NM_LDC1XS:
20295        case NM_SDC1XS:
20296            tcg_gen_shli_tl(t0, t0, 3);
20297            break;
20298        }
20299    }
20300    gen_op_addr_add(ctx, t0, t0, t1);
20301
20302    switch (extract32(ctx->opcode, 7, 4)) {
20303    case NM_LBX:
20304        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20305                           MO_SB);
20306        gen_store_gpr(t0, rd);
20307        break;
20308    case NM_LHX:
20309    /*case NM_LHXS:*/
20310        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20311                           MO_TESW);
20312        gen_store_gpr(t0, rd);
20313        break;
20314    case NM_LWX:
20315    /*case NM_LWXS:*/
20316        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20317                           MO_TESL);
20318        gen_store_gpr(t0, rd);
20319        break;
20320    case NM_LBUX:
20321        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20322                           MO_UB);
20323        gen_store_gpr(t0, rd);
20324        break;
20325    case NM_LHUX:
20326    /*case NM_LHUXS:*/
20327        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20328                           MO_TEUW);
20329        gen_store_gpr(t0, rd);
20330        break;
20331    case NM_SBX:
20332        check_nms(ctx);
20333        gen_load_gpr(t1, rd);
20334        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20335                           MO_8);
20336        break;
20337    case NM_SHX:
20338    /*case NM_SHXS:*/
20339        check_nms(ctx);
20340        gen_load_gpr(t1, rd);
20341        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20342                           MO_TEUW);
20343        break;
20344    case NM_SWX:
20345    /*case NM_SWXS:*/
20346        check_nms(ctx);
20347        gen_load_gpr(t1, rd);
20348        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20349                           MO_TEUL);
20350        break;
20351    case NM_LWC1X:
20352    /*case NM_LWC1XS:*/
20353    case NM_LDC1X:
20354    /*case NM_LDC1XS:*/
20355    case NM_SWC1X:
20356    /*case NM_SWC1XS:*/
20357    case NM_SDC1X:
20358    /*case NM_SDC1XS:*/
20359        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20360            check_cp1_enabled(ctx);
20361            switch (extract32(ctx->opcode, 7, 4)) {
20362            case NM_LWC1X:
20363            /*case NM_LWC1XS:*/
20364                gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20365                break;
20366            case NM_LDC1X:
20367            /*case NM_LDC1XS:*/
20368                gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20369                break;
20370            case NM_SWC1X:
20371            /*case NM_SWC1XS:*/
20372                gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20373                break;
20374            case NM_SDC1X:
20375            /*case NM_SDC1XS:*/
20376                gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20377                break;
20378            }
20379        } else {
20380            generate_exception_err(ctx, EXCP_CpU, 1);
20381        }
20382        break;
20383    default:
20384        generate_exception_end(ctx, EXCP_RI);
20385        break;
20386    }
20387
20388    tcg_temp_free(t0);
20389    tcg_temp_free(t1);
20390}
20391
20392static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20393{
20394    int rt, rs, rd;
20395
20396    rt = extract32(ctx->opcode, 21, 5);
20397    rs = extract32(ctx->opcode, 16, 5);
20398    rd = extract32(ctx->opcode, 11, 5);
20399
20400    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20401        generate_exception_end(ctx, EXCP_RI);
20402        return;
20403    }
20404    check_cp1_enabled(ctx);
20405    switch (extract32(ctx->opcode, 0, 3)) {
20406    case NM_POOL32F_0:
20407        switch (extract32(ctx->opcode, 3, 7)) {
20408        case NM_RINT_S:
20409            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20410            break;
20411        case NM_RINT_D:
20412            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20413            break;
20414        case NM_CLASS_S:
20415            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20416            break;
20417        case NM_CLASS_D:
20418            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20419            break;
20420        case NM_ADD_S:
20421            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20422            break;
20423        case NM_ADD_D:
20424            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20425            break;
20426        case NM_SUB_S:
20427            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20428            break;
20429        case NM_SUB_D:
20430            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20431            break;
20432        case NM_MUL_S:
20433            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20434            break;
20435        case NM_MUL_D:
20436            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20437            break;
20438        case NM_DIV_S:
20439            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20440            break;
20441        case NM_DIV_D:
20442            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20443            break;
20444        case NM_SELEQZ_S:
20445            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20446            break;
20447        case NM_SELEQZ_D:
20448            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20449            break;
20450        case NM_SELNEZ_S:
20451            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20452            break;
20453        case NM_SELNEZ_D:
20454            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20455            break;
20456        case NM_SEL_S:
20457            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20458            break;
20459        case NM_SEL_D:
20460            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20461            break;
20462        case NM_MADDF_S:
20463            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20464            break;
20465        case NM_MADDF_D:
20466            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20467            break;
20468        case NM_MSUBF_S:
20469            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20470            break;
20471        case NM_MSUBF_D:
20472            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20473            break;
20474        default:
20475            generate_exception_end(ctx, EXCP_RI);
20476            break;
20477        }
20478        break;
20479    case NM_POOL32F_3:
20480        switch (extract32(ctx->opcode, 3, 3)) {
20481        case NM_MIN_FMT:
20482            switch (extract32(ctx->opcode, 9, 1)) {
20483            case FMT_SDPS_S:
20484                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20485                break;
20486            case FMT_SDPS_D:
20487                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20488                break;
20489            }
20490            break;
20491        case NM_MAX_FMT:
20492            switch (extract32(ctx->opcode, 9, 1)) {
20493            case FMT_SDPS_S:
20494                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20495                break;
20496            case FMT_SDPS_D:
20497                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20498                break;
20499            }
20500            break;
20501        case NM_MINA_FMT:
20502            switch (extract32(ctx->opcode, 9, 1)) {
20503            case FMT_SDPS_S:
20504                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20505                break;
20506            case FMT_SDPS_D:
20507                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20508                break;
20509            }
20510            break;
20511        case NM_MAXA_FMT:
20512            switch (extract32(ctx->opcode, 9, 1)) {
20513            case FMT_SDPS_S:
20514                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20515                break;
20516            case FMT_SDPS_D:
20517                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20518                break;
20519            }
20520            break;
20521        case NM_POOL32FXF:
20522            switch (extract32(ctx->opcode, 6, 8)) {
20523            case NM_CFC1:
20524                gen_cp1(ctx, OPC_CFC1, rt, rs);
20525                break;
20526            case NM_CTC1:
20527                gen_cp1(ctx, OPC_CTC1, rt, rs);
20528                break;
20529            case NM_MFC1:
20530                gen_cp1(ctx, OPC_MFC1, rt, rs);
20531                break;
20532            case NM_MTC1:
20533                gen_cp1(ctx, OPC_MTC1, rt, rs);
20534                break;
20535            case NM_MFHC1:
20536                gen_cp1(ctx, OPC_MFHC1, rt, rs);
20537                break;
20538            case NM_MTHC1:
20539                gen_cp1(ctx, OPC_MTHC1, rt, rs);
20540                break;
20541            case NM_CVT_S_PL:
20542                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20543                break;
20544            case NM_CVT_S_PU:
20545                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20546                break;
20547            default:
20548                switch (extract32(ctx->opcode, 6, 9)) {
20549                case NM_CVT_L_S:
20550                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20551                    break;
20552                case NM_CVT_L_D:
20553                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20554                    break;
20555                case NM_CVT_W_S:
20556                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20557                    break;
20558                case NM_CVT_W_D:
20559                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20560                    break;
20561                case NM_RSQRT_S:
20562                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20563                    break;
20564                case NM_RSQRT_D:
20565                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20566                    break;
20567                case NM_SQRT_S:
20568                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20569                    break;
20570                case NM_SQRT_D:
20571                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20572                    break;
20573                case NM_RECIP_S:
20574                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20575                    break;
20576                case NM_RECIP_D:
20577                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20578                    break;
20579                case NM_FLOOR_L_S:
20580                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20581                    break;
20582                case NM_FLOOR_L_D:
20583                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20584                    break;
20585                case NM_FLOOR_W_S:
20586                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20587                    break;
20588                case NM_FLOOR_W_D:
20589                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20590                    break;
20591                case NM_CEIL_L_S:
20592                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20593                    break;
20594                case NM_CEIL_L_D:
20595                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20596                    break;
20597                case NM_CEIL_W_S:
20598                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20599                    break;
20600                case NM_CEIL_W_D:
20601                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20602                    break;
20603                case NM_TRUNC_L_S:
20604                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20605                    break;
20606                case NM_TRUNC_L_D:
20607                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20608                    break;
20609                case NM_TRUNC_W_S:
20610                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20611                    break;
20612                case NM_TRUNC_W_D:
20613                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20614                    break;
20615                case NM_ROUND_L_S:
20616                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20617                    break;
20618                case NM_ROUND_L_D:
20619                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20620                    break;
20621                case NM_ROUND_W_S:
20622                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20623                    break;
20624                case NM_ROUND_W_D:
20625                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20626                    break;
20627                case NM_MOV_S:
20628                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20629                    break;
20630                case NM_MOV_D:
20631                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20632                    break;
20633                case NM_ABS_S:
20634                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20635                    break;
20636                case NM_ABS_D:
20637                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20638                    break;
20639                case NM_NEG_S:
20640                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20641                    break;
20642                case NM_NEG_D:
20643                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20644                    break;
20645                case NM_CVT_D_S:
20646                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20647                    break;
20648                case NM_CVT_D_W:
20649                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20650                    break;
20651                case NM_CVT_D_L:
20652                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20653                    break;
20654                case NM_CVT_S_D:
20655                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20656                    break;
20657                case NM_CVT_S_W:
20658                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20659                    break;
20660                case NM_CVT_S_L:
20661                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20662                    break;
20663                default:
20664                    generate_exception_end(ctx, EXCP_RI);
20665                    break;
20666                }
20667                break;
20668            }
20669            break;
20670        }
20671        break;
20672    case NM_POOL32F_5:
20673        switch (extract32(ctx->opcode, 3, 3)) {
20674        case NM_CMP_CONDN_S:
20675            gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20676            break;
20677        case NM_CMP_CONDN_D:
20678            gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20679            break;
20680        default:
20681            generate_exception_end(ctx, EXCP_RI);
20682            break;
20683        }
20684        break;
20685    default:
20686        generate_exception_end(ctx, EXCP_RI);
20687        break;
20688    }
20689}
20690
20691static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20692                                       int rd, int rs, int rt)
20693{
20694    int ret = rd;
20695    TCGv t0 = tcg_temp_new();
20696    TCGv v1_t = tcg_temp_new();
20697    TCGv v2_t = tcg_temp_new();
20698
20699    gen_load_gpr(v1_t, rs);
20700    gen_load_gpr(v2_t, rt);
20701
20702    switch (opc) {
20703    case NM_CMP_EQ_PH:
20704        check_dsp(ctx);
20705        gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20706        break;
20707    case NM_CMP_LT_PH:
20708        check_dsp(ctx);
20709        gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20710        break;
20711    case NM_CMP_LE_PH:
20712        check_dsp(ctx);
20713        gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20714        break;
20715    case NM_CMPU_EQ_QB:
20716        check_dsp(ctx);
20717        gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20718        break;
20719    case NM_CMPU_LT_QB:
20720        check_dsp(ctx);
20721        gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20722        break;
20723    case NM_CMPU_LE_QB:
20724        check_dsp(ctx);
20725        gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20726        break;
20727    case NM_CMPGU_EQ_QB:
20728        check_dsp(ctx);
20729        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20730        gen_store_gpr(v1_t, ret);
20731        break;
20732    case NM_CMPGU_LT_QB:
20733        check_dsp(ctx);
20734        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20735        gen_store_gpr(v1_t, ret);
20736        break;
20737    case NM_CMPGU_LE_QB:
20738        check_dsp(ctx);
20739        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20740        gen_store_gpr(v1_t, ret);
20741        break;
20742    case NM_CMPGDU_EQ_QB:
20743        check_dsp_r2(ctx);
20744        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20745        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20746        gen_store_gpr(v1_t, ret);
20747        break;
20748    case NM_CMPGDU_LT_QB:
20749        check_dsp_r2(ctx);
20750        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20751        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20752        gen_store_gpr(v1_t, ret);
20753        break;
20754    case NM_CMPGDU_LE_QB:
20755        check_dsp_r2(ctx);
20756        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20757        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20758        gen_store_gpr(v1_t, ret);
20759        break;
20760    case NM_PACKRL_PH:
20761        check_dsp(ctx);
20762        gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20763        gen_store_gpr(v1_t, ret);
20764        break;
20765    case NM_PICK_QB:
20766        check_dsp(ctx);
20767        gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20768        gen_store_gpr(v1_t, ret);
20769        break;
20770    case NM_PICK_PH:
20771        check_dsp(ctx);
20772        gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20773        gen_store_gpr(v1_t, ret);
20774        break;
20775    case NM_ADDQ_S_W:
20776        check_dsp(ctx);
20777        gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20778        gen_store_gpr(v1_t, ret);
20779        break;
20780    case NM_SUBQ_S_W:
20781        check_dsp(ctx);
20782        gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20783        gen_store_gpr(v1_t, ret);
20784        break;
20785    case NM_ADDSC:
20786        check_dsp(ctx);
20787        gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20788        gen_store_gpr(v1_t, ret);
20789        break;
20790    case NM_ADDWC:
20791        check_dsp(ctx);
20792        gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20793        gen_store_gpr(v1_t, ret);
20794        break;
20795    case NM_ADDQ_S_PH:
20796        check_dsp(ctx);
20797        switch (extract32(ctx->opcode, 10, 1)) {
20798        case 0:
20799            /* ADDQ_PH */
20800            gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20801            gen_store_gpr(v1_t, ret);
20802            break;
20803        case 1:
20804            /* ADDQ_S_PH */
20805            gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20806            gen_store_gpr(v1_t, ret);
20807            break;
20808        }
20809        break;
20810    case NM_ADDQH_R_PH:
20811        check_dsp_r2(ctx);
20812        switch (extract32(ctx->opcode, 10, 1)) {
20813        case 0:
20814            /* ADDQH_PH */
20815            gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20816            gen_store_gpr(v1_t, ret);
20817            break;
20818        case 1:
20819            /* ADDQH_R_PH */
20820            gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20821            gen_store_gpr(v1_t, ret);
20822            break;
20823        }
20824        break;
20825    case NM_ADDQH_R_W:
20826        check_dsp_r2(ctx);
20827        switch (extract32(ctx->opcode, 10, 1)) {
20828        case 0:
20829            /* ADDQH_W */
20830            gen_helper_addqh_w(v1_t, v1_t, v2_t);
20831            gen_store_gpr(v1_t, ret);
20832            break;
20833        case 1:
20834            /* ADDQH_R_W */
20835            gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20836            gen_store_gpr(v1_t, ret);
20837            break;
20838        }
20839        break;
20840    case NM_ADDU_S_QB:
20841        check_dsp(ctx);
20842        switch (extract32(ctx->opcode, 10, 1)) {
20843        case 0:
20844            /* ADDU_QB */
20845            gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20846            gen_store_gpr(v1_t, ret);
20847            break;
20848        case 1:
20849            /* ADDU_S_QB */
20850            gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20851            gen_store_gpr(v1_t, ret);
20852            break;
20853        }
20854        break;
20855    case NM_ADDU_S_PH:
20856        check_dsp_r2(ctx);
20857        switch (extract32(ctx->opcode, 10, 1)) {
20858        case 0:
20859            /* ADDU_PH */
20860            gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20861            gen_store_gpr(v1_t, ret);
20862            break;
20863        case 1:
20864            /* ADDU_S_PH */
20865            gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20866            gen_store_gpr(v1_t, ret);
20867            break;
20868        }
20869        break;
20870    case NM_ADDUH_R_QB:
20871        check_dsp_r2(ctx);
20872        switch (extract32(ctx->opcode, 10, 1)) {
20873        case 0:
20874            /* ADDUH_QB */
20875            gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20876            gen_store_gpr(v1_t, ret);
20877            break;
20878        case 1:
20879            /* ADDUH_R_QB */
20880            gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20881            gen_store_gpr(v1_t, ret);
20882            break;
20883        }
20884        break;
20885    case NM_SHRAV_R_PH:
20886        check_dsp(ctx);
20887        switch (extract32(ctx->opcode, 10, 1)) {
20888        case 0:
20889            /* SHRAV_PH */
20890            gen_helper_shra_ph(v1_t, v1_t, v2_t);
20891            gen_store_gpr(v1_t, ret);
20892            break;
20893        case 1:
20894            /* SHRAV_R_PH */
20895            gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20896            gen_store_gpr(v1_t, ret);
20897            break;
20898        }
20899        break;
20900    case NM_SHRAV_R_QB:
20901        check_dsp_r2(ctx);
20902        switch (extract32(ctx->opcode, 10, 1)) {
20903        case 0:
20904            /* SHRAV_QB */
20905            gen_helper_shra_qb(v1_t, v1_t, v2_t);
20906            gen_store_gpr(v1_t, ret);
20907            break;
20908        case 1:
20909            /* SHRAV_R_QB */
20910            gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20911            gen_store_gpr(v1_t, ret);
20912            break;
20913        }
20914        break;
20915    case NM_SUBQ_S_PH:
20916        check_dsp(ctx);
20917        switch (extract32(ctx->opcode, 10, 1)) {
20918        case 0:
20919            /* SUBQ_PH */
20920            gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20921            gen_store_gpr(v1_t, ret);
20922            break;
20923        case 1:
20924            /* SUBQ_S_PH */
20925            gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20926            gen_store_gpr(v1_t, ret);
20927            break;
20928        }
20929        break;
20930    case NM_SUBQH_R_PH:
20931        check_dsp_r2(ctx);
20932        switch (extract32(ctx->opcode, 10, 1)) {
20933        case 0:
20934            /* SUBQH_PH */
20935            gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20936            gen_store_gpr(v1_t, ret);
20937            break;
20938        case 1:
20939            /* SUBQH_R_PH */
20940            gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20941            gen_store_gpr(v1_t, ret);
20942            break;
20943        }
20944        break;
20945    case NM_SUBQH_R_W:
20946        check_dsp_r2(ctx);
20947        switch (extract32(ctx->opcode, 10, 1)) {
20948        case 0:
20949            /* SUBQH_W */
20950            gen_helper_subqh_w(v1_t, v1_t, v2_t);
20951            gen_store_gpr(v1_t, ret);
20952            break;
20953        case 1:
20954            /* SUBQH_R_W */
20955            gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20956            gen_store_gpr(v1_t, ret);
20957            break;
20958        }
20959        break;
20960    case NM_SUBU_S_QB:
20961        check_dsp(ctx);
20962        switch (extract32(ctx->opcode, 10, 1)) {
20963        case 0:
20964            /* SUBU_QB */
20965            gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20966            gen_store_gpr(v1_t, ret);
20967            break;
20968        case 1:
20969            /* SUBU_S_QB */
20970            gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20971            gen_store_gpr(v1_t, ret);
20972            break;
20973        }
20974        break;
20975    case NM_SUBU_S_PH:
20976        check_dsp_r2(ctx);
20977        switch (extract32(ctx->opcode, 10, 1)) {
20978        case 0:
20979            /* SUBU_PH */
20980            gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20981            gen_store_gpr(v1_t, ret);
20982            break;
20983        case 1:
20984            /* SUBU_S_PH */
20985            gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20986            gen_store_gpr(v1_t, ret);
20987            break;
20988        }
20989        break;
20990    case NM_SUBUH_R_QB:
20991        check_dsp_r2(ctx);
20992        switch (extract32(ctx->opcode, 10, 1)) {
20993        case 0:
20994            /* SUBUH_QB */
20995            gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20996            gen_store_gpr(v1_t, ret);
20997            break;
20998        case 1:
20999            /* SUBUH_R_QB */
21000            gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
21001            gen_store_gpr(v1_t, ret);
21002            break;
21003        }
21004        break;
21005    case NM_SHLLV_S_PH:
21006        check_dsp(ctx);
21007        switch (extract32(ctx->opcode, 10, 1)) {
21008        case 0:
21009            /* SHLLV_PH */
21010            gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
21011            gen_store_gpr(v1_t, ret);
21012            break;
21013        case 1:
21014            /* SHLLV_S_PH */
21015            gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
21016            gen_store_gpr(v1_t, ret);
21017            break;
21018        }
21019        break;
21020    case NM_PRECR_SRA_R_PH_W:
21021        check_dsp_r2(ctx);
21022        switch (extract32(ctx->opcode, 10, 1)) {
21023        case 0:
21024            /* PRECR_SRA_PH_W */
21025            {
21026                TCGv_i32 sa_t = tcg_const_i32(rd);
21027                gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
21028                                          cpu_gpr[rt]);
21029                gen_store_gpr(v1_t, rt);
21030                tcg_temp_free_i32(sa_t);
21031            }
21032            break;
21033        case 1:
21034            /* PRECR_SRA_R_PH_W */
21035            {
21036                TCGv_i32 sa_t = tcg_const_i32(rd);
21037                gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
21038                                            cpu_gpr[rt]);
21039                gen_store_gpr(v1_t, rt);
21040                tcg_temp_free_i32(sa_t);
21041            }
21042            break;
21043       }
21044        break;
21045    case NM_MULEU_S_PH_QBL:
21046        check_dsp(ctx);
21047        gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
21048        gen_store_gpr(v1_t, ret);
21049        break;
21050    case NM_MULEU_S_PH_QBR:
21051        check_dsp(ctx);
21052        gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
21053        gen_store_gpr(v1_t, ret);
21054        break;
21055    case NM_MULQ_RS_PH:
21056        check_dsp(ctx);
21057        gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
21058        gen_store_gpr(v1_t, ret);
21059        break;
21060    case NM_MULQ_S_PH:
21061        check_dsp_r2(ctx);
21062        gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
21063        gen_store_gpr(v1_t, ret);
21064        break;
21065    case NM_MULQ_RS_W:
21066        check_dsp_r2(ctx);
21067        gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
21068        gen_store_gpr(v1_t, ret);
21069        break;
21070    case NM_MULQ_S_W:
21071        check_dsp_r2(ctx);
21072        gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
21073        gen_store_gpr(v1_t, ret);
21074        break;
21075    case NM_APPEND:
21076        check_dsp_r2(ctx);
21077        gen_load_gpr(t0, rs);
21078        if (rd != 0) {
21079            tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
21080        }
21081        tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21082        break;
21083    case NM_MODSUB:
21084        check_dsp(ctx);
21085        gen_helper_modsub(v1_t, v1_t, v2_t);
21086        gen_store_gpr(v1_t, ret);
21087        break;
21088    case NM_SHRAV_R_W:
21089        check_dsp(ctx);
21090        gen_helper_shra_r_w(v1_t, v1_t, v2_t);
21091        gen_store_gpr(v1_t, ret);
21092        break;
21093    case NM_SHRLV_PH:
21094        check_dsp_r2(ctx);
21095        gen_helper_shrl_ph(v1_t, v1_t, v2_t);
21096        gen_store_gpr(v1_t, ret);
21097        break;
21098    case NM_SHRLV_QB:
21099        check_dsp(ctx);
21100        gen_helper_shrl_qb(v1_t, v1_t, v2_t);
21101        gen_store_gpr(v1_t, ret);
21102        break;
21103    case NM_SHLLV_QB:
21104        check_dsp(ctx);
21105        gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
21106        gen_store_gpr(v1_t, ret);
21107        break;
21108    case NM_SHLLV_S_W:
21109        check_dsp(ctx);
21110        gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
21111        gen_store_gpr(v1_t, ret);
21112        break;
21113    case NM_SHILO:
21114        check_dsp(ctx);
21115        {
21116            TCGv tv0 = tcg_temp_new();
21117            TCGv tv1 = tcg_temp_new();
21118            int16_t imm = extract32(ctx->opcode, 16, 7);
21119
21120            tcg_gen_movi_tl(tv0, rd >> 3);
21121            tcg_gen_movi_tl(tv1, imm);
21122            gen_helper_shilo(tv0, tv1, cpu_env);
21123        }
21124        break;
21125    case NM_MULEQ_S_W_PHL:
21126        check_dsp(ctx);
21127        gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
21128        gen_store_gpr(v1_t, ret);
21129        break;
21130    case NM_MULEQ_S_W_PHR:
21131        check_dsp(ctx);
21132        gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
21133        gen_store_gpr(v1_t, ret);
21134        break;
21135    case NM_MUL_S_PH:
21136        check_dsp_r2(ctx);
21137        switch (extract32(ctx->opcode, 10, 1)) {
21138        case 0:
21139            /* MUL_PH */
21140            gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
21141            gen_store_gpr(v1_t, ret);
21142            break;
21143        case 1:
21144            /* MUL_S_PH */
21145            gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
21146            gen_store_gpr(v1_t, ret);
21147            break;
21148        }
21149        break;
21150    case NM_PRECR_QB_PH:
21151        check_dsp_r2(ctx);
21152        gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
21153        gen_store_gpr(v1_t, ret);
21154        break;
21155    case NM_PRECRQ_QB_PH:
21156        check_dsp(ctx);
21157        gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
21158        gen_store_gpr(v1_t, ret);
21159        break;
21160    case NM_PRECRQ_PH_W:
21161        check_dsp(ctx);
21162        gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
21163        gen_store_gpr(v1_t, ret);
21164        break;
21165    case NM_PRECRQ_RS_PH_W:
21166        check_dsp(ctx);
21167        gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
21168        gen_store_gpr(v1_t, ret);
21169        break;
21170    case NM_PRECRQU_S_QB_PH:
21171        check_dsp(ctx);
21172        gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
21173        gen_store_gpr(v1_t, ret);
21174        break;
21175    case NM_SHRA_R_W:
21176        check_dsp(ctx);
21177        tcg_gen_movi_tl(t0, rd);
21178        gen_helper_shra_r_w(v1_t, t0, v1_t);
21179        gen_store_gpr(v1_t, rt);
21180        break;
21181    case NM_SHRA_R_PH:
21182        check_dsp(ctx);
21183        tcg_gen_movi_tl(t0, rd >> 1);
21184        switch (extract32(ctx->opcode, 10, 1)) {
21185        case 0:
21186            /* SHRA_PH */
21187            gen_helper_shra_ph(v1_t, t0, v1_t);
21188            gen_store_gpr(v1_t, rt);
21189            break;
21190        case 1:
21191            /* SHRA_R_PH */
21192            gen_helper_shra_r_ph(v1_t, t0, v1_t);
21193            gen_store_gpr(v1_t, rt);
21194            break;
21195        }
21196        break;
21197    case NM_SHLL_S_PH:
21198        check_dsp(ctx);
21199        tcg_gen_movi_tl(t0, rd >> 1);
21200        switch (extract32(ctx->opcode, 10, 2)) {
21201        case 0:
21202            /* SHLL_PH */
21203            gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
21204            gen_store_gpr(v1_t, rt);
21205            break;
21206        case 2:
21207            /* SHLL_S_PH */
21208            gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
21209            gen_store_gpr(v1_t, rt);
21210            break;
21211        default:
21212            generate_exception_end(ctx, EXCP_RI);
21213            break;
21214        }
21215        break;
21216    case NM_SHLL_S_W:
21217        check_dsp(ctx);
21218        tcg_gen_movi_tl(t0, rd);
21219        gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
21220        gen_store_gpr(v1_t, rt);
21221        break;
21222    case NM_REPL_PH:
21223        check_dsp(ctx);
21224        {
21225            int16_t imm;
21226            imm = sextract32(ctx->opcode, 11, 11);
21227            imm = (int16_t)(imm << 6) >> 6;
21228            if (rt != 0) {
21229                tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
21230            }
21231        }
21232        break;
21233    default:
21234        generate_exception_end(ctx, EXCP_RI);
21235        break;
21236    }
21237}
21238
21239static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
21240{
21241    uint16_t insn;
21242    uint32_t op;
21243    int rt, rs, rd;
21244    int offset;
21245    int imm;
21246
21247    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
21248    ctx->opcode = (ctx->opcode << 16) | insn;
21249
21250    rt = extract32(ctx->opcode, 21, 5);
21251    rs = extract32(ctx->opcode, 16, 5);
21252    rd = extract32(ctx->opcode, 11, 5);
21253
21254    op = extract32(ctx->opcode, 26, 6);
21255    switch (op) {
21256    case NM_P_ADDIU:
21257        if (rt == 0) {
21258            /* P.RI */
21259            switch (extract32(ctx->opcode, 19, 2)) {
21260            case NM_SIGRIE:
21261            default:
21262                generate_exception_end(ctx, EXCP_RI);
21263                break;
21264            case NM_P_SYSCALL:
21265                if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
21266                    generate_exception_end(ctx, EXCP_SYSCALL);
21267                } else {
21268                    generate_exception_end(ctx, EXCP_RI);
21269                }
21270                break;
21271            case NM_BREAK:
21272                generate_exception_end(ctx, EXCP_BREAK);
21273                break;
21274            case NM_SDBBP:
21275                if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21276                    gen_helper_do_semihosting(cpu_env);
21277                } else {
21278                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
21279                        generate_exception_end(ctx, EXCP_RI);
21280                    } else {
21281                        generate_exception_end(ctx, EXCP_DBp);
21282                    }
21283                }
21284                break;
21285            }
21286        } else {
21287            /* NM_ADDIU */
21288            imm = extract32(ctx->opcode, 0, 16);
21289            if (rs != 0) {
21290                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21291            } else {
21292                tcg_gen_movi_tl(cpu_gpr[rt], imm);
21293            }
21294            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21295        }
21296        break;
21297    case NM_ADDIUPC:
21298        if (rt != 0) {
21299            offset = sextract32(ctx->opcode, 0, 1) << 21 |
21300                     extract32(ctx->opcode, 1, 20) << 1;
21301            target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21302            tcg_gen_movi_tl(cpu_gpr[rt], addr);
21303        }
21304        break;
21305    case NM_POOL32A:
21306        switch (ctx->opcode & 0x07) {
21307        case NM_POOL32A0:
21308            gen_pool32a0_nanomips_insn(env, ctx);
21309            break;
21310        case NM_POOL32A5:
21311            {
21312                int32_t op1 = extract32(ctx->opcode, 3, 7);
21313                gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21314            }
21315            break;
21316        case NM_POOL32A7:
21317            switch (extract32(ctx->opcode, 3, 3)) {
21318            case NM_P_LSX:
21319                gen_p_lsx(ctx, rd, rs, rt);
21320                break;
21321            case NM_LSA:
21322                /*
21323                 * In nanoMIPS, the shift field directly encodes the shift
21324                 * amount, meaning that the supported shift values are in
21325                 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21326                 */
21327                gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21328                        extract32(ctx->opcode, 9, 2) - 1);
21329                break;
21330            case NM_EXTW:
21331                gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21332                break;
21333            case NM_POOL32AXF:
21334                gen_pool32axf_nanomips_insn(env, ctx);
21335                break;
21336            default:
21337                generate_exception_end(ctx, EXCP_RI);
21338                break;
21339            }
21340            break;
21341        default:
21342            generate_exception_end(ctx, EXCP_RI);
21343            break;
21344        }
21345        break;
21346    case NM_P_GP_W:
21347        switch (ctx->opcode & 0x03) {
21348        case NM_ADDIUGP_W:
21349            if (rt != 0) {
21350                offset = extract32(ctx->opcode, 0, 21);
21351                gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21352            }
21353            break;
21354        case NM_LWGP:
21355            gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21356            break;
21357        case NM_SWGP:
21358            gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21359            break;
21360        default:
21361            generate_exception_end(ctx, EXCP_RI);
21362            break;
21363        }
21364        break;
21365    case NM_P48I:
21366        {
21367            insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21368            target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21369            switch (extract32(ctx->opcode, 16, 5)) {
21370            case NM_LI48:
21371                check_nms(ctx);
21372                if (rt != 0) {
21373                    tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21374                }
21375                break;
21376            case NM_ADDIU48:
21377                check_nms(ctx);
21378                if (rt != 0) {
21379                    tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21380                    tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21381                }
21382                break;
21383            case NM_ADDIUGP48:
21384                check_nms(ctx);
21385                if (rt != 0) {
21386                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21387                }
21388                break;
21389            case NM_ADDIUPC48:
21390                check_nms(ctx);
21391                if (rt != 0) {
21392                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21393                                                addr_off);
21394
21395                    tcg_gen_movi_tl(cpu_gpr[rt], addr);
21396                }
21397                break;
21398            case NM_LWPC48:
21399                check_nms(ctx);
21400                if (rt != 0) {
21401                    TCGv t0;
21402                    t0 = tcg_temp_new();
21403
21404                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21405                                                addr_off);
21406
21407                    tcg_gen_movi_tl(t0, addr);
21408                    tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21409                    tcg_temp_free(t0);
21410                }
21411                break;
21412            case NM_SWPC48:
21413                check_nms(ctx);
21414                {
21415                    TCGv t0, t1;
21416                    t0 = tcg_temp_new();
21417                    t1 = tcg_temp_new();
21418
21419                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21420                                                addr_off);
21421
21422                    tcg_gen_movi_tl(t0, addr);
21423                    gen_load_gpr(t1, rt);
21424
21425                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21426
21427                    tcg_temp_free(t0);
21428                    tcg_temp_free(t1);
21429                }
21430                break;
21431            default:
21432                generate_exception_end(ctx, EXCP_RI);
21433                break;
21434            }
21435            return 6;
21436        }
21437    case NM_P_U12:
21438        switch (extract32(ctx->opcode, 12, 4)) {
21439        case NM_ORI:
21440            gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21441            break;
21442        case NM_XORI:
21443            gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21444            break;
21445        case NM_ANDI:
21446            gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21447            break;
21448        case NM_P_SR:
21449            switch (extract32(ctx->opcode, 20, 1)) {
21450            case NM_PP_SR:
21451                switch (ctx->opcode & 3) {
21452                case NM_SAVE:
21453                    gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21454                             extract32(ctx->opcode, 2, 1),
21455                             extract32(ctx->opcode, 3, 9) << 3);
21456                    break;
21457                case NM_RESTORE:
21458                case NM_RESTORE_JRC:
21459                    gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21460                                extract32(ctx->opcode, 2, 1),
21461                                extract32(ctx->opcode, 3, 9) << 3);
21462                    if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21463                        gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21464                    }
21465                    break;
21466                default:
21467                    generate_exception_end(ctx, EXCP_RI);
21468                    break;
21469                }
21470                break;
21471            case NM_P_SR_F:
21472                generate_exception_end(ctx, EXCP_RI);
21473                break;
21474            }
21475            break;
21476        case NM_SLTI:
21477            gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21478            break;
21479        case NM_SLTIU:
21480            gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21481            break;
21482        case NM_SEQI:
21483            {
21484                TCGv t0 = tcg_temp_new();
21485
21486                imm = extract32(ctx->opcode, 0, 12);
21487                gen_load_gpr(t0, rs);
21488                tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21489                gen_store_gpr(t0, rt);
21490
21491                tcg_temp_free(t0);
21492            }
21493            break;
21494        case NM_ADDIUNEG:
21495            imm = (int16_t) extract32(ctx->opcode, 0, 12);
21496            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21497            break;
21498        case NM_P_SHIFT:
21499            {
21500                int shift = extract32(ctx->opcode, 0, 5);
21501                switch (extract32(ctx->opcode, 5, 4)) {
21502                case NM_P_SLL:
21503                    if (rt == 0 && shift == 0) {
21504                        /* NOP */
21505                    } else if (rt == 0 && shift == 3) {
21506                        /* EHB - treat as NOP */
21507                    } else if (rt == 0 && shift == 5) {
21508                        /* PAUSE - treat as NOP */
21509                    } else if (rt == 0 && shift == 6) {
21510                        /* SYNC */
21511                        gen_sync(extract32(ctx->opcode, 16, 5));
21512                    } else {
21513                        /* SLL */
21514                        gen_shift_imm(ctx, OPC_SLL, rt, rs,
21515                                      extract32(ctx->opcode, 0, 5));
21516                    }
21517                    break;
21518                case NM_SRL:
21519                    gen_shift_imm(ctx, OPC_SRL, rt, rs,
21520                                  extract32(ctx->opcode, 0, 5));
21521                    break;
21522                case NM_SRA:
21523                    gen_shift_imm(ctx, OPC_SRA, rt, rs,
21524                                  extract32(ctx->opcode, 0, 5));
21525                    break;
21526                case NM_ROTR:
21527                    gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21528                                  extract32(ctx->opcode, 0, 5));
21529                    break;
21530                }
21531            }
21532            break;
21533        case NM_P_ROTX:
21534            check_nms(ctx);
21535            if (rt != 0) {
21536                TCGv t0 = tcg_temp_new();
21537                TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21538                TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21539                                                << 1);
21540                TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21541
21542                gen_load_gpr(t0, rs);
21543                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21544                tcg_temp_free(t0);
21545
21546                tcg_temp_free_i32(shift);
21547                tcg_temp_free_i32(shiftx);
21548                tcg_temp_free_i32(stripe);
21549            }
21550            break;
21551        case NM_P_INS:
21552            switch (((ctx->opcode >> 10) & 2) |
21553                    (extract32(ctx->opcode, 5, 1))) {
21554            case NM_INS:
21555                check_nms(ctx);
21556                gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21557                           extract32(ctx->opcode, 6, 5));
21558                break;
21559            default:
21560                generate_exception_end(ctx, EXCP_RI);
21561                break;
21562            }
21563            break;
21564        case NM_P_EXT:
21565            switch (((ctx->opcode >> 10) & 2) |
21566                    (extract32(ctx->opcode, 5, 1))) {
21567            case NM_EXT:
21568                check_nms(ctx);
21569                gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21570                           extract32(ctx->opcode, 6, 5));
21571                break;
21572            default:
21573                generate_exception_end(ctx, EXCP_RI);
21574                break;
21575            }
21576            break;
21577        default:
21578            generate_exception_end(ctx, EXCP_RI);
21579            break;
21580        }
21581        break;
21582    case NM_POOL32F:
21583        gen_pool32f_nanomips_insn(ctx);
21584        break;
21585    case NM_POOL32S:
21586        break;
21587    case NM_P_LUI:
21588        switch (extract32(ctx->opcode, 1, 1)) {
21589        case NM_LUI:
21590            if (rt != 0) {
21591                tcg_gen_movi_tl(cpu_gpr[rt],
21592                                sextract32(ctx->opcode, 0, 1) << 31 |
21593                                extract32(ctx->opcode, 2, 10) << 21 |
21594                                extract32(ctx->opcode, 12, 9) << 12);
21595            }
21596            break;
21597        case NM_ALUIPC:
21598            if (rt != 0) {
21599                offset = sextract32(ctx->opcode, 0, 1) << 31 |
21600                         extract32(ctx->opcode, 2, 10) << 21 |
21601                         extract32(ctx->opcode, 12, 9) << 12;
21602                target_long addr;
21603                addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21604                tcg_gen_movi_tl(cpu_gpr[rt], addr);
21605            }
21606            break;
21607        }
21608        break;
21609    case NM_P_GP_BH:
21610        {
21611            uint32_t u = extract32(ctx->opcode, 0, 18);
21612
21613            switch (extract32(ctx->opcode, 18, 3)) {
21614            case NM_LBGP:
21615                gen_ld(ctx, OPC_LB, rt, 28, u);
21616                break;
21617            case NM_SBGP:
21618                gen_st(ctx, OPC_SB, rt, 28, u);
21619                break;
21620            case NM_LBUGP:
21621                gen_ld(ctx, OPC_LBU, rt, 28, u);
21622                break;
21623            case NM_ADDIUGP_B:
21624                if (rt != 0) {
21625                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21626                }
21627                break;
21628            case NM_P_GP_LH:
21629                u &= ~1;
21630                switch (ctx->opcode & 1) {
21631                case NM_LHGP:
21632                    gen_ld(ctx, OPC_LH, rt, 28, u);
21633                    break;
21634                case NM_LHUGP:
21635                    gen_ld(ctx, OPC_LHU, rt, 28, u);
21636                    break;
21637                }
21638                break;
21639            case NM_P_GP_SH:
21640                u &= ~1;
21641                switch (ctx->opcode & 1) {
21642                case NM_SHGP:
21643                    gen_st(ctx, OPC_SH, rt, 28, u);
21644                    break;
21645                default:
21646                    generate_exception_end(ctx, EXCP_RI);
21647                    break;
21648                }
21649                break;
21650            case NM_P_GP_CP1:
21651                u &= ~0x3;
21652                switch (ctx->opcode & 0x3) {
21653                case NM_LWC1GP:
21654                    gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21655                    break;
21656                case NM_LDC1GP:
21657                    gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21658                    break;
21659                case NM_SWC1GP:
21660                    gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21661                    break;
21662                case NM_SDC1GP:
21663                    gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21664                    break;
21665                }
21666                break;
21667            default:
21668                generate_exception_end(ctx, EXCP_RI);
21669                break;
21670            }
21671        }
21672        break;
21673    case NM_P_LS_U12:
21674        {
21675            uint32_t u = extract32(ctx->opcode, 0, 12);
21676
21677            switch (extract32(ctx->opcode, 12, 4)) {
21678            case NM_P_PREFU12:
21679                if (rt == 31) {
21680                    /* SYNCI */
21681                    /*
21682                     * Break the TB to be able to sync copied instructions
21683                     * immediately.
21684                     */
21685                    ctx->base.is_jmp = DISAS_STOP;
21686                } else {
21687                    /* PREF */
21688                    /* Treat as NOP. */
21689                }
21690                break;
21691            case NM_LB:
21692                gen_ld(ctx, OPC_LB, rt, rs, u);
21693                break;
21694            case NM_LH:
21695                gen_ld(ctx, OPC_LH, rt, rs, u);
21696                break;
21697            case NM_LW:
21698                gen_ld(ctx, OPC_LW, rt, rs, u);
21699                break;
21700            case NM_LBU:
21701                gen_ld(ctx, OPC_LBU, rt, rs, u);
21702                break;
21703            case NM_LHU:
21704                gen_ld(ctx, OPC_LHU, rt, rs, u);
21705                break;
21706            case NM_SB:
21707                gen_st(ctx, OPC_SB, rt, rs, u);
21708                break;
21709            case NM_SH:
21710                gen_st(ctx, OPC_SH, rt, rs, u);
21711                break;
21712            case NM_SW:
21713                gen_st(ctx, OPC_SW, rt, rs, u);
21714                break;
21715            case NM_LWC1:
21716                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21717                break;
21718            case NM_LDC1:
21719                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21720                break;
21721            case NM_SWC1:
21722                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21723                break;
21724            case NM_SDC1:
21725                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21726                break;
21727            default:
21728                generate_exception_end(ctx, EXCP_RI);
21729                break;
21730            }
21731        }
21732        break;
21733    case NM_P_LS_S9:
21734        {
21735            int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21736                        extract32(ctx->opcode, 0, 8);
21737
21738            switch (extract32(ctx->opcode, 8, 3)) {
21739            case NM_P_LS_S0:
21740                switch (extract32(ctx->opcode, 11, 4)) {
21741                case NM_LBS9:
21742                    gen_ld(ctx, OPC_LB, rt, rs, s);
21743                    break;
21744                case NM_LHS9:
21745                    gen_ld(ctx, OPC_LH, rt, rs, s);
21746                    break;
21747                case NM_LWS9:
21748                    gen_ld(ctx, OPC_LW, rt, rs, s);
21749                    break;
21750                case NM_LBUS9:
21751                    gen_ld(ctx, OPC_LBU, rt, rs, s);
21752                    break;
21753                case NM_LHUS9:
21754                    gen_ld(ctx, OPC_LHU, rt, rs, s);
21755                    break;
21756                case NM_SBS9:
21757                    gen_st(ctx, OPC_SB, rt, rs, s);
21758                    break;
21759                case NM_SHS9:
21760                    gen_st(ctx, OPC_SH, rt, rs, s);
21761                    break;
21762                case NM_SWS9:
21763                    gen_st(ctx, OPC_SW, rt, rs, s);
21764                    break;
21765                case NM_LWC1S9:
21766                    gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21767                    break;
21768                case NM_LDC1S9:
21769                    gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21770                    break;
21771                case NM_SWC1S9:
21772                    gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21773                    break;
21774                case NM_SDC1S9:
21775                    gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21776                    break;
21777                case NM_P_PREFS9:
21778                    if (rt == 31) {
21779                        /* SYNCI */
21780                        /*
21781                         * Break the TB to be able to sync copied instructions
21782                         * immediately.
21783                         */
21784                        ctx->base.is_jmp = DISAS_STOP;
21785                    } else {
21786                        /* PREF */
21787                        /* Treat as NOP. */
21788                    }
21789                    break;
21790                default:
21791                    generate_exception_end(ctx, EXCP_RI);
21792                    break;
21793                }
21794                break;
21795            case NM_P_LS_S1:
21796                switch (extract32(ctx->opcode, 11, 4)) {
21797                case NM_UALH:
21798                case NM_UASH:
21799                    check_nms(ctx);
21800                    {
21801                        TCGv t0 = tcg_temp_new();
21802                        TCGv t1 = tcg_temp_new();
21803
21804                        gen_base_offset_addr(ctx, t0, rs, s);
21805
21806                        switch (extract32(ctx->opcode, 11, 4)) {
21807                        case NM_UALH:
21808                            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21809                                               MO_UNALN);
21810                            gen_store_gpr(t0, rt);
21811                            break;
21812                        case NM_UASH:
21813                            gen_load_gpr(t1, rt);
21814                            tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21815                                               MO_UNALN);
21816                            break;
21817                        }
21818                        tcg_temp_free(t0);
21819                        tcg_temp_free(t1);
21820                    }
21821                    break;
21822                case NM_P_LL:
21823                    switch (ctx->opcode & 0x03) {
21824                    case NM_LL:
21825                        gen_ld(ctx, OPC_LL, rt, rs, s);
21826                        break;
21827                    case NM_LLWP:
21828                        check_xnp(ctx);
21829                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21830                        break;
21831                    }
21832                    break;
21833                case NM_P_SC:
21834                    switch (ctx->opcode & 0x03) {
21835                    case NM_SC:
21836                        gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21837                        break;
21838                    case NM_SCWP:
21839                        check_xnp(ctx);
21840                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21841                                 false);
21842                        break;
21843                    }
21844                    break;
21845                case NM_CACHE:
21846                    check_cp0_enabled(ctx);
21847                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21848                        gen_cache_operation(ctx, rt, rs, s);
21849                    }
21850                    break;
21851                }
21852                break;
21853            case NM_P_LS_E0:
21854                switch (extract32(ctx->opcode, 11, 4)) {
21855                case NM_LBE:
21856                    check_eva(ctx);
21857                    check_cp0_enabled(ctx);
21858                    gen_ld(ctx, OPC_LBE, rt, rs, s);
21859                    break;
21860                case NM_SBE:
21861                    check_eva(ctx);
21862                    check_cp0_enabled(ctx);
21863                    gen_st(ctx, OPC_SBE, rt, rs, s);
21864                    break;
21865                case NM_LBUE:
21866                    check_eva(ctx);
21867                    check_cp0_enabled(ctx);
21868                    gen_ld(ctx, OPC_LBUE, rt, rs, s);
21869                    break;
21870                case NM_P_PREFE:
21871                    if (rt == 31) {
21872                        /* case NM_SYNCIE */
21873                        check_eva(ctx);
21874                        check_cp0_enabled(ctx);
21875                        /*
21876                         * Break the TB to be able to sync copied instructions
21877                         * immediately.
21878                         */
21879                        ctx->base.is_jmp = DISAS_STOP;
21880                    } else {
21881                        /* case NM_PREFE */
21882                        check_eva(ctx);
21883                        check_cp0_enabled(ctx);
21884                        /* Treat as NOP. */
21885                    }
21886                    break;
21887                case NM_LHE:
21888                    check_eva(ctx);
21889                    check_cp0_enabled(ctx);
21890                    gen_ld(ctx, OPC_LHE, rt, rs, s);
21891                    break;
21892                case NM_SHE:
21893                    check_eva(ctx);
21894                    check_cp0_enabled(ctx);
21895                    gen_st(ctx, OPC_SHE, rt, rs, s);
21896                    break;
21897                case NM_LHUE:
21898                    check_eva(ctx);
21899                    check_cp0_enabled(ctx);
21900                    gen_ld(ctx, OPC_LHUE, rt, rs, s);
21901                    break;
21902                case NM_CACHEE:
21903                    check_nms_dl_il_sl_tl_l2c(ctx);
21904                    gen_cache_operation(ctx, rt, rs, s);
21905                    break;
21906                case NM_LWE:
21907                    check_eva(ctx);
21908                    check_cp0_enabled(ctx);
21909                    gen_ld(ctx, OPC_LWE, rt, rs, s);
21910                    break;
21911                case NM_SWE:
21912                    check_eva(ctx);
21913                    check_cp0_enabled(ctx);
21914                    gen_st(ctx, OPC_SWE, rt, rs, s);
21915                    break;
21916                case NM_P_LLE:
21917                    switch (extract32(ctx->opcode, 2, 2)) {
21918                    case NM_LLE:
21919                        check_xnp(ctx);
21920                        check_eva(ctx);
21921                        check_cp0_enabled(ctx);
21922                        gen_ld(ctx, OPC_LLE, rt, rs, s);
21923                        break;
21924                    case NM_LLWPE:
21925                        check_xnp(ctx);
21926                        check_eva(ctx);
21927                        check_cp0_enabled(ctx);
21928                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21929                        break;
21930                    default:
21931                        generate_exception_end(ctx, EXCP_RI);
21932                        break;
21933                    }
21934                    break;
21935                case NM_P_SCE:
21936                    switch (extract32(ctx->opcode, 2, 2)) {
21937                    case NM_SCE:
21938                        check_xnp(ctx);
21939                        check_eva(ctx);
21940                        check_cp0_enabled(ctx);
21941                        gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21942                        break;
21943                    case NM_SCWPE:
21944                        check_xnp(ctx);
21945                        check_eva(ctx);
21946                        check_cp0_enabled(ctx);
21947                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21948                                 true);
21949                        break;
21950                    default:
21951                        generate_exception_end(ctx, EXCP_RI);
21952                        break;
21953                    }
21954                    break;
21955                }
21956                break;
21957            case NM_P_LS_WM:
21958            case NM_P_LS_UAWM:
21959                check_nms(ctx);
21960                {
21961                    int count = extract32(ctx->opcode, 12, 3);
21962                    int counter = 0;
21963
21964                    offset = sextract32(ctx->opcode, 15, 1) << 8 |
21965                             extract32(ctx->opcode, 0, 8);
21966                    TCGv va = tcg_temp_new();
21967                    TCGv t1 = tcg_temp_new();
21968                    MemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21969                                      NM_P_LS_UAWM ? MO_UNALN : 0;
21970
21971                    count = (count == 0) ? 8 : count;
21972                    while (counter != count) {
21973                        int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21974                        int this_offset = offset + (counter << 2);
21975
21976                        gen_base_offset_addr(ctx, va, rs, this_offset);
21977
21978                        switch (extract32(ctx->opcode, 11, 1)) {
21979                        case NM_LWM:
21980                            tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21981                                               memop | MO_TESL);
21982                            gen_store_gpr(t1, this_rt);
21983                            if ((this_rt == rs) &&
21984                                (counter != (count - 1))) {
21985                                /* UNPREDICTABLE */
21986                            }
21987                            break;
21988                        case NM_SWM:
21989                            this_rt = (rt == 0) ? 0 : this_rt;
21990                            gen_load_gpr(t1, this_rt);
21991                            tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21992                                               memop | MO_TEUL);
21993                            break;
21994                        }
21995                        counter++;
21996                    }
21997                    tcg_temp_free(va);
21998                    tcg_temp_free(t1);
21999                }
22000                break;
22001            default:
22002                generate_exception_end(ctx, EXCP_RI);
22003                break;
22004            }
22005        }
22006        break;
22007    case NM_MOVE_BALC:
22008        check_nms(ctx);
22009        {
22010            TCGv t0 = tcg_temp_new();
22011            int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
22012                        extract32(ctx->opcode, 1, 20) << 1;
22013            rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
22014            rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
22015                            extract32(ctx->opcode, 21, 3));
22016            gen_load_gpr(t0, rt);
22017            tcg_gen_mov_tl(cpu_gpr[rd], t0);
22018            gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22019            tcg_temp_free(t0);
22020        }
22021        break;
22022    case NM_P_BAL:
22023        {
22024            int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
22025                        extract32(ctx->opcode, 1, 24) << 1;
22026
22027            if ((extract32(ctx->opcode, 25, 1)) == 0) {
22028                /* BC */
22029                gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
22030            } else {
22031                /* BALC */
22032                gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
22033            }
22034        }
22035        break;
22036    case NM_P_J:
22037        switch (extract32(ctx->opcode, 12, 4)) {
22038        case NM_JALRC:
22039        case NM_JALRC_HB:
22040            gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
22041            break;
22042        case NM_P_BALRSC:
22043            gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
22044            break;
22045        default:
22046            generate_exception_end(ctx, EXCP_RI);
22047            break;
22048        }
22049        break;
22050    case NM_P_BR1:
22051        {
22052            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22053                        extract32(ctx->opcode, 1, 13) << 1;
22054            switch (extract32(ctx->opcode, 14, 2)) {
22055            case NM_BEQC:
22056                check_nms(ctx);
22057                gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
22058                break;
22059            case NM_P_BR3A:
22060                s = sextract32(ctx->opcode, 0, 1) << 14 |
22061                    extract32(ctx->opcode, 1, 13) << 1;
22062                check_cp1_enabled(ctx);
22063                switch (extract32(ctx->opcode, 16, 5)) {
22064                case NM_BC1EQZC:
22065                    gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
22066                    break;
22067                case NM_BC1NEZC:
22068                    gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
22069                    break;
22070                case NM_BPOSGE32C:
22071                    check_dsp_r3(ctx);
22072                    {
22073                        int32_t imm = extract32(ctx->opcode, 1, 13) |
22074                                      extract32(ctx->opcode, 0, 1) << 13;
22075
22076                        gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
22077                                              imm);
22078                    }
22079                    break;
22080                default:
22081                    generate_exception_end(ctx, EXCP_RI);
22082                    break;
22083                }
22084                break;
22085            case NM_BGEC:
22086                if (rs == rt) {
22087                    gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
22088                } else {
22089                    gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
22090                }
22091                break;
22092            case NM_BGEUC:
22093                if (rs == rt || rt == 0) {
22094                    gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
22095                } else if (rs == 0) {
22096                    gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
22097                } else {
22098                    gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
22099                }
22100                break;
22101            }
22102        }
22103        break;
22104    case NM_P_BR2:
22105        {
22106            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
22107                        extract32(ctx->opcode, 1, 13) << 1;
22108            switch (extract32(ctx->opcode, 14, 2)) {
22109            case NM_BNEC:
22110                check_nms(ctx);
22111                gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
22112                break;
22113            case NM_BLTC:
22114                if (rs != 0 && rt != 0 && rs == rt) {
22115                    /* NOP */
22116                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22117                } else {
22118                    gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
22119                }
22120                break;
22121            case NM_BLTUC:
22122                if (rs == 0 || rs == rt) {
22123                    /* NOP */
22124                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
22125                } else {
22126                    gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
22127                }
22128                break;
22129            default:
22130                generate_exception_end(ctx, EXCP_RI);
22131                break;
22132            }
22133        }
22134        break;
22135    case NM_P_BRI:
22136        {
22137            int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
22138                        extract32(ctx->opcode, 1, 10) << 1;
22139            uint32_t u = extract32(ctx->opcode, 11, 7);
22140
22141            gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
22142                                   rt, u, s);
22143        }
22144        break;
22145    default:
22146        generate_exception_end(ctx, EXCP_RI);
22147        break;
22148    }
22149    return 4;
22150}
22151
22152static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
22153{
22154    uint32_t op;
22155    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
22156    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22157    int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
22158    int offset;
22159    int imm;
22160
22161    /* make sure instructions are on a halfword boundary */
22162    if (ctx->base.pc_next & 0x1) {
22163        TCGv tmp = tcg_const_tl(ctx->base.pc_next);
22164        tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
22165        tcg_temp_free(tmp);
22166        generate_exception_end(ctx, EXCP_AdEL);
22167        return 2;
22168    }
22169
22170    op = extract32(ctx->opcode, 10, 6);
22171    switch (op) {
22172    case NM_P16_MV:
22173        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22174        if (rt != 0) {
22175            /* MOVE */
22176            rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
22177            gen_arith(ctx, OPC_ADDU, rt, rs, 0);
22178        } else {
22179            /* P16.RI */
22180            switch (extract32(ctx->opcode, 3, 2)) {
22181            case NM_P16_SYSCALL:
22182                if (extract32(ctx->opcode, 2, 1) == 0) {
22183                    generate_exception_end(ctx, EXCP_SYSCALL);
22184                } else {
22185                    generate_exception_end(ctx, EXCP_RI);
22186                }
22187                break;
22188            case NM_BREAK16:
22189                generate_exception_end(ctx, EXCP_BREAK);
22190                break;
22191            case NM_SDBBP16:
22192                if (is_uhi(extract32(ctx->opcode, 0, 3))) {
22193                    gen_helper_do_semihosting(cpu_env);
22194                } else {
22195                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
22196                        generate_exception_end(ctx, EXCP_RI);
22197                    } else {
22198                        generate_exception_end(ctx, EXCP_DBp);
22199                    }
22200                }
22201                break;
22202            default:
22203                generate_exception_end(ctx, EXCP_RI);
22204                break;
22205            }
22206        }
22207        break;
22208    case NM_P16_SHIFT:
22209        {
22210            int shift = extract32(ctx->opcode, 0, 3);
22211            uint32_t opc = 0;
22212            shift = (shift == 0) ? 8 : shift;
22213
22214            switch (extract32(ctx->opcode, 3, 1)) {
22215            case NM_SLL16:
22216                opc = OPC_SLL;
22217                break;
22218            case NM_SRL16:
22219                opc = OPC_SRL;
22220                break;
22221            }
22222            gen_shift_imm(ctx, opc, rt, rs, shift);
22223        }
22224        break;
22225    case NM_P16C:
22226        switch (ctx->opcode & 1) {
22227        case NM_POOL16C_0:
22228            gen_pool16c_nanomips_insn(ctx);
22229            break;
22230        case NM_LWXS16:
22231            gen_ldxs(ctx, rt, rs, rd);
22232            break;
22233        }
22234        break;
22235    case NM_P16_A1:
22236        switch (extract32(ctx->opcode, 6, 1)) {
22237        case NM_ADDIUR1SP:
22238            imm = extract32(ctx->opcode, 0, 6) << 2;
22239            gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
22240            break;
22241        default:
22242            generate_exception_end(ctx, EXCP_RI);
22243            break;
22244        }
22245        break;
22246    case NM_P16_A2:
22247        switch (extract32(ctx->opcode, 3, 1)) {
22248        case NM_ADDIUR2:
22249            imm = extract32(ctx->opcode, 0, 3) << 2;
22250            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
22251            break;
22252        case NM_P_ADDIURS5:
22253            rt = extract32(ctx->opcode, 5, 5);
22254            if (rt != 0) {
22255                /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22256                imm = (sextract32(ctx->opcode, 4, 1) << 3) |
22257                      (extract32(ctx->opcode, 0, 3));
22258                gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
22259            }
22260            break;
22261        }
22262        break;
22263    case NM_P16_ADDU:
22264        switch (ctx->opcode & 0x1) {
22265        case NM_ADDU16:
22266            gen_arith(ctx, OPC_ADDU, rd, rs, rt);
22267            break;
22268        case NM_SUBU16:
22269            gen_arith(ctx, OPC_SUBU, rd, rs, rt);
22270            break;
22271        }
22272        break;
22273    case NM_P16_4X4:
22274        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22275              extract32(ctx->opcode, 5, 3);
22276        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22277              extract32(ctx->opcode, 0, 3);
22278        rt = decode_gpr_gpr4(rt);
22279        rs = decode_gpr_gpr4(rs);
22280        switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22281                (extract32(ctx->opcode, 3, 1))) {
22282        case NM_ADDU4X4:
22283            check_nms(ctx);
22284            gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22285            break;
22286        case NM_MUL4X4:
22287            check_nms(ctx);
22288            gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22289            break;
22290        default:
22291            generate_exception_end(ctx, EXCP_RI);
22292            break;
22293        }
22294        break;
22295    case NM_LI16:
22296        {
22297            int imm = extract32(ctx->opcode, 0, 7);
22298            imm = (imm == 0x7f ? -1 : imm);
22299            if (rt != 0) {
22300                tcg_gen_movi_tl(cpu_gpr[rt], imm);
22301            }
22302        }
22303        break;
22304    case NM_ANDI16:
22305        {
22306            uint32_t u = extract32(ctx->opcode, 0, 4);
22307            u = (u == 12) ? 0xff :
22308                (u == 13) ? 0xffff : u;
22309            gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22310        }
22311        break;
22312    case NM_P16_LB:
22313        offset = extract32(ctx->opcode, 0, 2);
22314        switch (extract32(ctx->opcode, 2, 2)) {
22315        case NM_LB16:
22316            gen_ld(ctx, OPC_LB, rt, rs, offset);
22317            break;
22318        case NM_SB16:
22319            rt = decode_gpr_gpr3_src_store(
22320                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22321            gen_st(ctx, OPC_SB, rt, rs, offset);
22322            break;
22323        case NM_LBU16:
22324            gen_ld(ctx, OPC_LBU, rt, rs, offset);
22325            break;
22326        default:
22327            generate_exception_end(ctx, EXCP_RI);
22328            break;
22329        }
22330        break;
22331    case NM_P16_LH:
22332        offset = extract32(ctx->opcode, 1, 2) << 1;
22333        switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22334        case NM_LH16:
22335            gen_ld(ctx, OPC_LH, rt, rs, offset);
22336            break;
22337        case NM_SH16:
22338            rt = decode_gpr_gpr3_src_store(
22339                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22340            gen_st(ctx, OPC_SH, rt, rs, offset);
22341            break;
22342        case NM_LHU16:
22343            gen_ld(ctx, OPC_LHU, rt, rs, offset);
22344            break;
22345        default:
22346            generate_exception_end(ctx, EXCP_RI);
22347            break;
22348        }
22349        break;
22350    case NM_LW16:
22351        offset = extract32(ctx->opcode, 0, 4) << 2;
22352        gen_ld(ctx, OPC_LW, rt, rs, offset);
22353        break;
22354    case NM_LWSP16:
22355        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22356        offset = extract32(ctx->opcode, 0, 5) << 2;
22357        gen_ld(ctx, OPC_LW, rt, 29, offset);
22358        break;
22359    case NM_LW4X4:
22360        check_nms(ctx);
22361        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22362             extract32(ctx->opcode, 5, 3);
22363        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22364             extract32(ctx->opcode, 0, 3);
22365        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22366                 (extract32(ctx->opcode, 8, 1) << 2);
22367        rt = decode_gpr_gpr4(rt);
22368        rs = decode_gpr_gpr4(rs);
22369        gen_ld(ctx, OPC_LW, rt, rs, offset);
22370        break;
22371    case NM_SW4X4:
22372        check_nms(ctx);
22373        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22374             extract32(ctx->opcode, 5, 3);
22375        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22376             extract32(ctx->opcode, 0, 3);
22377        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22378                 (extract32(ctx->opcode, 8, 1) << 2);
22379        rt = decode_gpr_gpr4_zero(rt);
22380        rs = decode_gpr_gpr4(rs);
22381        gen_st(ctx, OPC_SW, rt, rs, offset);
22382        break;
22383    case NM_LWGP16:
22384        offset = extract32(ctx->opcode, 0, 7) << 2;
22385        gen_ld(ctx, OPC_LW, rt, 28, offset);
22386        break;
22387    case NM_SWSP16:
22388        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22389        offset = extract32(ctx->opcode, 0, 5) << 2;
22390        gen_st(ctx, OPC_SW, rt, 29, offset);
22391        break;
22392    case NM_SW16:
22393        rt = decode_gpr_gpr3_src_store(
22394                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22395        rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22396        offset = extract32(ctx->opcode, 0, 4) << 2;
22397        gen_st(ctx, OPC_SW, rt, rs, offset);
22398        break;
22399    case NM_SWGP16:
22400        rt = decode_gpr_gpr3_src_store(
22401                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22402        offset = extract32(ctx->opcode, 0, 7) << 2;
22403        gen_st(ctx, OPC_SW, rt, 28, offset);
22404        break;
22405    case NM_BC16:
22406        gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22407                           (sextract32(ctx->opcode, 0, 1) << 10) |
22408                           (extract32(ctx->opcode, 1, 9) << 1));
22409        break;
22410    case NM_BALC16:
22411        gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22412                           (sextract32(ctx->opcode, 0, 1) << 10) |
22413                           (extract32(ctx->opcode, 1, 9) << 1));
22414        break;
22415    case NM_BEQZC16:
22416        gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22417                           (sextract32(ctx->opcode, 0, 1) << 7) |
22418                           (extract32(ctx->opcode, 1, 6) << 1));
22419        break;
22420    case NM_BNEZC16:
22421        gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22422                           (sextract32(ctx->opcode, 0, 1) << 7) |
22423                           (extract32(ctx->opcode, 1, 6) << 1));
22424        break;
22425    case NM_P16_BR:
22426        switch (ctx->opcode & 0xf) {
22427        case 0:
22428            /* P16.JRC */
22429            switch (extract32(ctx->opcode, 4, 1)) {
22430            case NM_JRC:
22431                gen_compute_branch_nm(ctx, OPC_JR, 2,
22432                                   extract32(ctx->opcode, 5, 5), 0, 0);
22433                break;
22434            case NM_JALRC16:
22435                gen_compute_branch_nm(ctx, OPC_JALR, 2,
22436                                   extract32(ctx->opcode, 5, 5), 31, 0);
22437                break;
22438            }
22439            break;
22440        default:
22441            {
22442                /* P16.BRI */
22443                uint32_t opc = extract32(ctx->opcode, 4, 3) <
22444                               extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22445                gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22446                                   extract32(ctx->opcode, 0, 4) << 1);
22447            }
22448            break;
22449        }
22450        break;
22451    case NM_P16_SR:
22452        {
22453            int count = extract32(ctx->opcode, 0, 4);
22454            int u = extract32(ctx->opcode, 4, 4) << 4;
22455
22456            rt = 30 + extract32(ctx->opcode, 9, 1);
22457            switch (extract32(ctx->opcode, 8, 1)) {
22458            case NM_SAVE16:
22459                gen_save(ctx, rt, count, 0, u);
22460                break;
22461            case NM_RESTORE_JRC16:
22462                gen_restore(ctx, rt, count, 0, u);
22463                gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22464                break;
22465            }
22466        }
22467        break;
22468    case NM_MOVEP:
22469    case NM_MOVEPREV:
22470        check_nms(ctx);
22471        {
22472            static const int gpr2reg1[] = {4, 5, 6, 7};
22473            static const int gpr2reg2[] = {5, 6, 7, 8};
22474            int re;
22475            int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22476                      extract32(ctx->opcode, 8, 1);
22477            int r1 = gpr2reg1[rd2];
22478            int r2 = gpr2reg2[rd2];
22479            int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22480                     extract32(ctx->opcode, 0, 3);
22481            int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22482                     extract32(ctx->opcode, 5, 3);
22483            TCGv t0 = tcg_temp_new();
22484            TCGv t1 = tcg_temp_new();
22485            if (op == NM_MOVEP) {
22486                rd = r1;
22487                re = r2;
22488                rs = decode_gpr_gpr4_zero(r3);
22489                rt = decode_gpr_gpr4_zero(r4);
22490            } else {
22491                rd = decode_gpr_gpr4(r3);
22492                re = decode_gpr_gpr4(r4);
22493                rs = r1;
22494                rt = r2;
22495            }
22496            gen_load_gpr(t0, rs);
22497            gen_load_gpr(t1, rt);
22498            tcg_gen_mov_tl(cpu_gpr[rd], t0);
22499            tcg_gen_mov_tl(cpu_gpr[re], t1);
22500            tcg_temp_free(t0);
22501            tcg_temp_free(t1);
22502        }
22503        break;
22504    default:
22505        return decode_nanomips_32_48_opc(env, ctx);
22506    }
22507
22508    return 2;
22509}
22510
22511
22512/* SmartMIPS extension to MIPS32 */
22513
22514#if defined(TARGET_MIPS64)
22515
22516/* MDMX extension to MIPS64 */
22517
22518#endif
22519
22520/* MIPSDSP functions. */
22521static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22522                           int rd, int base, int offset)
22523{
22524    TCGv t0;
22525
22526    check_dsp(ctx);
22527    t0 = tcg_temp_new();
22528
22529    if (base == 0) {
22530        gen_load_gpr(t0, offset);
22531    } else if (offset == 0) {
22532        gen_load_gpr(t0, base);
22533    } else {
22534        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22535    }
22536
22537    switch (opc) {
22538    case OPC_LBUX:
22539        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22540        gen_store_gpr(t0, rd);
22541        break;
22542    case OPC_LHX:
22543        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22544        gen_store_gpr(t0, rd);
22545        break;
22546    case OPC_LWX:
22547        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22548        gen_store_gpr(t0, rd);
22549        break;
22550#if defined(TARGET_MIPS64)
22551    case OPC_LDX:
22552        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22553        gen_store_gpr(t0, rd);
22554        break;
22555#endif
22556    }
22557    tcg_temp_free(t0);
22558}
22559
22560static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22561                              int ret, int v1, int v2)
22562{
22563    TCGv v1_t;
22564    TCGv v2_t;
22565
22566    if (ret == 0) {
22567        /* Treat as NOP. */
22568        return;
22569    }
22570
22571    v1_t = tcg_temp_new();
22572    v2_t = tcg_temp_new();
22573
22574    gen_load_gpr(v1_t, v1);
22575    gen_load_gpr(v2_t, v2);
22576
22577    switch (op1) {
22578    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22579    case OPC_MULT_G_2E:
22580        check_dsp_r2(ctx);
22581        switch (op2) {
22582        case OPC_ADDUH_QB:
22583            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22584            break;
22585        case OPC_ADDUH_R_QB:
22586            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22587            break;
22588        case OPC_ADDQH_PH:
22589            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22590            break;
22591        case OPC_ADDQH_R_PH:
22592            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22593            break;
22594        case OPC_ADDQH_W:
22595            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22596            break;
22597        case OPC_ADDQH_R_W:
22598            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22599            break;
22600        case OPC_SUBUH_QB:
22601            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22602            break;
22603        case OPC_SUBUH_R_QB:
22604            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22605            break;
22606        case OPC_SUBQH_PH:
22607            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22608            break;
22609        case OPC_SUBQH_R_PH:
22610            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22611            break;
22612        case OPC_SUBQH_W:
22613            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22614            break;
22615        case OPC_SUBQH_R_W:
22616            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22617            break;
22618        }
22619        break;
22620    case OPC_ABSQ_S_PH_DSP:
22621        switch (op2) {
22622        case OPC_ABSQ_S_QB:
22623            check_dsp_r2(ctx);
22624            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22625            break;
22626        case OPC_ABSQ_S_PH:
22627            check_dsp(ctx);
22628            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22629            break;
22630        case OPC_ABSQ_S_W:
22631            check_dsp(ctx);
22632            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22633            break;
22634        case OPC_PRECEQ_W_PHL:
22635            check_dsp(ctx);
22636            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22637            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22638            break;
22639        case OPC_PRECEQ_W_PHR:
22640            check_dsp(ctx);
22641            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22642            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22643            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22644            break;
22645        case OPC_PRECEQU_PH_QBL:
22646            check_dsp(ctx);
22647            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22648            break;
22649        case OPC_PRECEQU_PH_QBR:
22650            check_dsp(ctx);
22651            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22652            break;
22653        case OPC_PRECEQU_PH_QBLA:
22654            check_dsp(ctx);
22655            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22656            break;
22657        case OPC_PRECEQU_PH_QBRA:
22658            check_dsp(ctx);
22659            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22660            break;
22661        case OPC_PRECEU_PH_QBL:
22662            check_dsp(ctx);
22663            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22664            break;
22665        case OPC_PRECEU_PH_QBR:
22666            check_dsp(ctx);
22667            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22668            break;
22669        case OPC_PRECEU_PH_QBLA:
22670            check_dsp(ctx);
22671            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22672            break;
22673        case OPC_PRECEU_PH_QBRA:
22674            check_dsp(ctx);
22675            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22676            break;
22677        }
22678        break;
22679    case OPC_ADDU_QB_DSP:
22680        switch (op2) {
22681        case OPC_ADDQ_PH:
22682            check_dsp(ctx);
22683            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22684            break;
22685        case OPC_ADDQ_S_PH:
22686            check_dsp(ctx);
22687            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22688            break;
22689        case OPC_ADDQ_S_W:
22690            check_dsp(ctx);
22691            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22692            break;
22693        case OPC_ADDU_QB:
22694            check_dsp(ctx);
22695            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22696            break;
22697        case OPC_ADDU_S_QB:
22698            check_dsp(ctx);
22699            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22700            break;
22701        case OPC_ADDU_PH:
22702            check_dsp_r2(ctx);
22703            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22704            break;
22705        case OPC_ADDU_S_PH:
22706            check_dsp_r2(ctx);
22707            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22708            break;
22709        case OPC_SUBQ_PH:
22710            check_dsp(ctx);
22711            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22712            break;
22713        case OPC_SUBQ_S_PH:
22714            check_dsp(ctx);
22715            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22716            break;
22717        case OPC_SUBQ_S_W:
22718            check_dsp(ctx);
22719            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22720            break;
22721        case OPC_SUBU_QB:
22722            check_dsp(ctx);
22723            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22724            break;
22725        case OPC_SUBU_S_QB:
22726            check_dsp(ctx);
22727            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22728            break;
22729        case OPC_SUBU_PH:
22730            check_dsp_r2(ctx);
22731            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22732            break;
22733        case OPC_SUBU_S_PH:
22734            check_dsp_r2(ctx);
22735            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22736            break;
22737        case OPC_ADDSC:
22738            check_dsp(ctx);
22739            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22740            break;
22741        case OPC_ADDWC:
22742            check_dsp(ctx);
22743            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22744            break;
22745        case OPC_MODSUB:
22746            check_dsp(ctx);
22747            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22748            break;
22749        case OPC_RADDU_W_QB:
22750            check_dsp(ctx);
22751            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22752            break;
22753        }
22754        break;
22755    case OPC_CMPU_EQ_QB_DSP:
22756        switch (op2) {
22757        case OPC_PRECR_QB_PH:
22758            check_dsp_r2(ctx);
22759            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22760            break;
22761        case OPC_PRECRQ_QB_PH:
22762            check_dsp(ctx);
22763            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22764            break;
22765        case OPC_PRECR_SRA_PH_W:
22766            check_dsp_r2(ctx);
22767            {
22768                TCGv_i32 sa_t = tcg_const_i32(v2);
22769                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22770                                          cpu_gpr[ret]);
22771                tcg_temp_free_i32(sa_t);
22772                break;
22773            }
22774        case OPC_PRECR_SRA_R_PH_W:
22775            check_dsp_r2(ctx);
22776            {
22777                TCGv_i32 sa_t = tcg_const_i32(v2);
22778                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22779                                            cpu_gpr[ret]);
22780                tcg_temp_free_i32(sa_t);
22781                break;
22782            }
22783        case OPC_PRECRQ_PH_W:
22784            check_dsp(ctx);
22785            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22786            break;
22787        case OPC_PRECRQ_RS_PH_W:
22788            check_dsp(ctx);
22789            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22790            break;
22791        case OPC_PRECRQU_S_QB_PH:
22792            check_dsp(ctx);
22793            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22794            break;
22795        }
22796        break;
22797#ifdef TARGET_MIPS64
22798    case OPC_ABSQ_S_QH_DSP:
22799        switch (op2) {
22800        case OPC_PRECEQ_L_PWL:
22801            check_dsp(ctx);
22802            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22803            break;
22804        case OPC_PRECEQ_L_PWR:
22805            check_dsp(ctx);
22806            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22807            break;
22808        case OPC_PRECEQ_PW_QHL:
22809            check_dsp(ctx);
22810            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22811            break;
22812        case OPC_PRECEQ_PW_QHR:
22813            check_dsp(ctx);
22814            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22815            break;
22816        case OPC_PRECEQ_PW_QHLA:
22817            check_dsp(ctx);
22818            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22819            break;
22820        case OPC_PRECEQ_PW_QHRA:
22821            check_dsp(ctx);
22822            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22823            break;
22824        case OPC_PRECEQU_QH_OBL:
22825            check_dsp(ctx);
22826            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22827            break;
22828        case OPC_PRECEQU_QH_OBR:
22829            check_dsp(ctx);
22830            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22831            break;
22832        case OPC_PRECEQU_QH_OBLA:
22833            check_dsp(ctx);
22834            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22835            break;
22836        case OPC_PRECEQU_QH_OBRA:
22837            check_dsp(ctx);
22838            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22839            break;
22840        case OPC_PRECEU_QH_OBL:
22841            check_dsp(ctx);
22842            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22843            break;
22844        case OPC_PRECEU_QH_OBR:
22845            check_dsp(ctx);
22846            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22847            break;
22848        case OPC_PRECEU_QH_OBLA:
22849            check_dsp(ctx);
22850            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22851            break;
22852        case OPC_PRECEU_QH_OBRA:
22853            check_dsp(ctx);
22854            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22855            break;
22856        case OPC_ABSQ_S_OB:
22857            check_dsp_r2(ctx);
22858            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22859            break;
22860        case OPC_ABSQ_S_PW:
22861            check_dsp(ctx);
22862            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22863            break;
22864        case OPC_ABSQ_S_QH:
22865            check_dsp(ctx);
22866            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22867            break;
22868        }
22869        break;
22870    case OPC_ADDU_OB_DSP:
22871        switch (op2) {
22872        case OPC_RADDU_L_OB:
22873            check_dsp(ctx);
22874            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22875            break;
22876        case OPC_SUBQ_PW:
22877            check_dsp(ctx);
22878            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22879            break;
22880        case OPC_SUBQ_S_PW:
22881            check_dsp(ctx);
22882            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22883            break;
22884        case OPC_SUBQ_QH:
22885            check_dsp(ctx);
22886            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22887            break;
22888        case OPC_SUBQ_S_QH:
22889            check_dsp(ctx);
22890            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22891            break;
22892        case OPC_SUBU_OB:
22893            check_dsp(ctx);
22894            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22895            break;
22896        case OPC_SUBU_S_OB:
22897            check_dsp(ctx);
22898            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22899            break;
22900        case OPC_SUBU_QH:
22901            check_dsp_r2(ctx);
22902            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22903            break;
22904        case OPC_SUBU_S_QH:
22905            check_dsp_r2(ctx);
22906            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22907            break;
22908        case OPC_SUBUH_OB:
22909            check_dsp_r2(ctx);
22910            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22911            break;
22912        case OPC_SUBUH_R_OB:
22913            check_dsp_r2(ctx);
22914            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22915            break;
22916        case OPC_ADDQ_PW:
22917            check_dsp(ctx);
22918            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22919            break;
22920        case OPC_ADDQ_S_PW:
22921            check_dsp(ctx);
22922            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22923            break;
22924        case OPC_ADDQ_QH:
22925            check_dsp(ctx);
22926            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22927            break;
22928        case OPC_ADDQ_S_QH:
22929            check_dsp(ctx);
22930            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22931            break;
22932        case OPC_ADDU_OB:
22933            check_dsp(ctx);
22934            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22935            break;
22936        case OPC_ADDU_S_OB:
22937            check_dsp(ctx);
22938            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22939            break;
22940        case OPC_ADDU_QH:
22941            check_dsp_r2(ctx);
22942            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22943            break;
22944        case OPC_ADDU_S_QH:
22945            check_dsp_r2(ctx);
22946            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22947            break;
22948        case OPC_ADDUH_OB:
22949            check_dsp_r2(ctx);
22950            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22951            break;
22952        case OPC_ADDUH_R_OB:
22953            check_dsp_r2(ctx);
22954            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22955            break;
22956        }
22957        break;
22958    case OPC_CMPU_EQ_OB_DSP:
22959        switch (op2) {
22960        case OPC_PRECR_OB_QH:
22961            check_dsp_r2(ctx);
22962            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22963            break;
22964        case OPC_PRECR_SRA_QH_PW:
22965            check_dsp_r2(ctx);
22966            {
22967                TCGv_i32 ret_t = tcg_const_i32(ret);
22968                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22969                tcg_temp_free_i32(ret_t);
22970                break;
22971            }
22972        case OPC_PRECR_SRA_R_QH_PW:
22973            check_dsp_r2(ctx);
22974            {
22975                TCGv_i32 sa_v = tcg_const_i32(ret);
22976                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22977                tcg_temp_free_i32(sa_v);
22978                break;
22979            }
22980        case OPC_PRECRQ_OB_QH:
22981            check_dsp(ctx);
22982            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22983            break;
22984        case OPC_PRECRQ_PW_L:
22985            check_dsp(ctx);
22986            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22987            break;
22988        case OPC_PRECRQ_QH_PW:
22989            check_dsp(ctx);
22990            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22991            break;
22992        case OPC_PRECRQ_RS_QH_PW:
22993            check_dsp(ctx);
22994            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22995            break;
22996        case OPC_PRECRQU_S_OB_QH:
22997            check_dsp(ctx);
22998            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22999            break;
23000        }
23001        break;
23002#endif
23003    }
23004
23005    tcg_temp_free(v1_t);
23006    tcg_temp_free(v2_t);
23007}
23008
23009static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
23010                              int ret, int v1, int v2)
23011{
23012    uint32_t op2;
23013    TCGv t0;
23014    TCGv v1_t;
23015    TCGv v2_t;
23016
23017    if (ret == 0) {
23018        /* Treat as NOP. */
23019        return;
23020    }
23021
23022    t0 = tcg_temp_new();
23023    v1_t = tcg_temp_new();
23024    v2_t = tcg_temp_new();
23025
23026    tcg_gen_movi_tl(t0, v1);
23027    gen_load_gpr(v1_t, v1);
23028    gen_load_gpr(v2_t, v2);
23029
23030    switch (opc) {
23031    case OPC_SHLL_QB_DSP:
23032        {
23033            op2 = MASK_SHLL_QB(ctx->opcode);
23034            switch (op2) {
23035            case OPC_SHLL_QB:
23036                check_dsp(ctx);
23037                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
23038                break;
23039            case OPC_SHLLV_QB:
23040                check_dsp(ctx);
23041                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23042                break;
23043            case OPC_SHLL_PH:
23044                check_dsp(ctx);
23045                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23046                break;
23047            case OPC_SHLLV_PH:
23048                check_dsp(ctx);
23049                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23050                break;
23051            case OPC_SHLL_S_PH:
23052                check_dsp(ctx);
23053                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
23054                break;
23055            case OPC_SHLLV_S_PH:
23056                check_dsp(ctx);
23057                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23058                break;
23059            case OPC_SHLL_S_W:
23060                check_dsp(ctx);
23061                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
23062                break;
23063            case OPC_SHLLV_S_W:
23064                check_dsp(ctx);
23065                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23066                break;
23067            case OPC_SHRL_QB:
23068                check_dsp(ctx);
23069                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
23070                break;
23071            case OPC_SHRLV_QB:
23072                check_dsp(ctx);
23073                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
23074                break;
23075            case OPC_SHRL_PH:
23076                check_dsp_r2(ctx);
23077                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
23078                break;
23079            case OPC_SHRLV_PH:
23080                check_dsp_r2(ctx);
23081                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
23082                break;
23083            case OPC_SHRA_QB:
23084                check_dsp_r2(ctx);
23085                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
23086                break;
23087            case OPC_SHRA_R_QB:
23088                check_dsp_r2(ctx);
23089                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
23090                break;
23091            case OPC_SHRAV_QB:
23092                check_dsp_r2(ctx);
23093                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
23094                break;
23095            case OPC_SHRAV_R_QB:
23096                check_dsp_r2(ctx);
23097                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
23098                break;
23099            case OPC_SHRA_PH:
23100                check_dsp(ctx);
23101                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
23102                break;
23103            case OPC_SHRA_R_PH:
23104                check_dsp(ctx);
23105                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
23106                break;
23107            case OPC_SHRAV_PH:
23108                check_dsp(ctx);
23109                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
23110                break;
23111            case OPC_SHRAV_R_PH:
23112                check_dsp(ctx);
23113                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
23114                break;
23115            case OPC_SHRA_R_W:
23116                check_dsp(ctx);
23117                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
23118                break;
23119            case OPC_SHRAV_R_W:
23120                check_dsp(ctx);
23121                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
23122                break;
23123            default:            /* Invalid */
23124                MIPS_INVAL("MASK SHLL.QB");
23125                generate_exception_end(ctx, EXCP_RI);
23126                break;
23127            }
23128            break;
23129        }
23130#ifdef TARGET_MIPS64
23131    case OPC_SHLL_OB_DSP:
23132        op2 = MASK_SHLL_OB(ctx->opcode);
23133        switch (op2) {
23134        case OPC_SHLL_PW:
23135            check_dsp(ctx);
23136            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23137            break;
23138        case OPC_SHLLV_PW:
23139            check_dsp(ctx);
23140            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23141            break;
23142        case OPC_SHLL_S_PW:
23143            check_dsp(ctx);
23144            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
23145            break;
23146        case OPC_SHLLV_S_PW:
23147            check_dsp(ctx);
23148            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23149            break;
23150        case OPC_SHLL_OB:
23151            check_dsp(ctx);
23152            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
23153            break;
23154        case OPC_SHLLV_OB:
23155            check_dsp(ctx);
23156            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23157            break;
23158        case OPC_SHLL_QH:
23159            check_dsp(ctx);
23160            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23161            break;
23162        case OPC_SHLLV_QH:
23163            check_dsp(ctx);
23164            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23165            break;
23166        case OPC_SHLL_S_QH:
23167            check_dsp(ctx);
23168            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
23169            break;
23170        case OPC_SHLLV_S_QH:
23171            check_dsp(ctx);
23172            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
23173            break;
23174        case OPC_SHRA_OB:
23175            check_dsp_r2(ctx);
23176            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
23177            break;
23178        case OPC_SHRAV_OB:
23179            check_dsp_r2(ctx);
23180            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
23181            break;
23182        case OPC_SHRA_R_OB:
23183            check_dsp_r2(ctx);
23184            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
23185            break;
23186        case OPC_SHRAV_R_OB:
23187            check_dsp_r2(ctx);
23188            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
23189            break;
23190        case OPC_SHRA_PW:
23191            check_dsp(ctx);
23192            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
23193            break;
23194        case OPC_SHRAV_PW:
23195            check_dsp(ctx);
23196            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
23197            break;
23198        case OPC_SHRA_R_PW:
23199            check_dsp(ctx);
23200            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
23201            break;
23202        case OPC_SHRAV_R_PW:
23203            check_dsp(ctx);
23204            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
23205            break;
23206        case OPC_SHRA_QH:
23207            check_dsp(ctx);
23208            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
23209            break;
23210        case OPC_SHRAV_QH:
23211            check_dsp(ctx);
23212            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
23213            break;
23214        case OPC_SHRA_R_QH:
23215            check_dsp(ctx);
23216            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
23217            break;
23218        case OPC_SHRAV_R_QH:
23219            check_dsp(ctx);
23220            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
23221            break;
23222        case OPC_SHRL_OB:
23223            check_dsp(ctx);
23224            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
23225            break;
23226        case OPC_SHRLV_OB:
23227            check_dsp(ctx);
23228            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
23229            break;
23230        case OPC_SHRL_QH:
23231            check_dsp_r2(ctx);
23232            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
23233            break;
23234        case OPC_SHRLV_QH:
23235            check_dsp_r2(ctx);
23236            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
23237            break;
23238        default:            /* Invalid */
23239            MIPS_INVAL("MASK SHLL.OB");
23240            generate_exception_end(ctx, EXCP_RI);
23241            break;
23242        }
23243        break;
23244#endif
23245    }
23246
23247    tcg_temp_free(t0);
23248    tcg_temp_free(v1_t);
23249    tcg_temp_free(v2_t);
23250}
23251
23252static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
23253                                 int ret, int v1, int v2, int check_ret)
23254{
23255    TCGv_i32 t0;
23256    TCGv v1_t;
23257    TCGv v2_t;
23258
23259    if ((ret == 0) && (check_ret == 1)) {
23260        /* Treat as NOP. */
23261        return;
23262    }
23263
23264    t0 = tcg_temp_new_i32();
23265    v1_t = tcg_temp_new();
23266    v2_t = tcg_temp_new();
23267
23268    tcg_gen_movi_i32(t0, ret);
23269    gen_load_gpr(v1_t, v1);
23270    gen_load_gpr(v2_t, v2);
23271
23272    switch (op1) {
23273    /*
23274     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23275     * the same mask and op1.
23276     */
23277    case OPC_MULT_G_2E:
23278        check_dsp_r2(ctx);
23279        switch (op2) {
23280        case  OPC_MUL_PH:
23281            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23282            break;
23283        case  OPC_MUL_S_PH:
23284            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23285            break;
23286        case OPC_MULQ_S_W:
23287            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23288            break;
23289        case OPC_MULQ_RS_W:
23290            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23291            break;
23292        }
23293        break;
23294    case OPC_DPA_W_PH_DSP:
23295        switch (op2) {
23296        case OPC_DPAU_H_QBL:
23297            check_dsp(ctx);
23298            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23299            break;
23300        case OPC_DPAU_H_QBR:
23301            check_dsp(ctx);
23302            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23303            break;
23304        case OPC_DPSU_H_QBL:
23305            check_dsp(ctx);
23306            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23307            break;
23308        case OPC_DPSU_H_QBR:
23309            check_dsp(ctx);
23310            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23311            break;
23312        case OPC_DPA_W_PH:
23313            check_dsp_r2(ctx);
23314            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23315            break;
23316        case OPC_DPAX_W_PH:
23317            check_dsp_r2(ctx);
23318            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23319            break;
23320        case OPC_DPAQ_S_W_PH:
23321            check_dsp(ctx);
23322            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23323            break;
23324        case OPC_DPAQX_S_W_PH:
23325            check_dsp_r2(ctx);
23326            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23327            break;
23328        case OPC_DPAQX_SA_W_PH:
23329            check_dsp_r2(ctx);
23330            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23331            break;
23332        case OPC_DPS_W_PH:
23333            check_dsp_r2(ctx);
23334            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23335            break;
23336        case OPC_DPSX_W_PH:
23337            check_dsp_r2(ctx);
23338            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23339            break;
23340        case OPC_DPSQ_S_W_PH:
23341            check_dsp(ctx);
23342            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23343            break;
23344        case OPC_DPSQX_S_W_PH:
23345            check_dsp_r2(ctx);
23346            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23347            break;
23348        case OPC_DPSQX_SA_W_PH:
23349            check_dsp_r2(ctx);
23350            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23351            break;
23352        case OPC_MULSAQ_S_W_PH:
23353            check_dsp(ctx);
23354            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23355            break;
23356        case OPC_DPAQ_SA_L_W:
23357            check_dsp(ctx);
23358            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23359            break;
23360        case OPC_DPSQ_SA_L_W:
23361            check_dsp(ctx);
23362            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23363            break;
23364        case OPC_MAQ_S_W_PHL:
23365            check_dsp(ctx);
23366            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23367            break;
23368        case OPC_MAQ_S_W_PHR:
23369            check_dsp(ctx);
23370            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23371            break;
23372        case OPC_MAQ_SA_W_PHL:
23373            check_dsp(ctx);
23374            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23375            break;
23376        case OPC_MAQ_SA_W_PHR:
23377            check_dsp(ctx);
23378            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23379            break;
23380        case OPC_MULSA_W_PH:
23381            check_dsp_r2(ctx);
23382            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23383            break;
23384        }
23385        break;
23386#ifdef TARGET_MIPS64
23387    case OPC_DPAQ_W_QH_DSP:
23388        {
23389            int ac = ret & 0x03;
23390            tcg_gen_movi_i32(t0, ac);
23391
23392            switch (op2) {
23393            case OPC_DMADD:
23394                check_dsp(ctx);
23395                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23396                break;
23397            case OPC_DMADDU:
23398                check_dsp(ctx);
23399                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23400                break;
23401            case OPC_DMSUB:
23402                check_dsp(ctx);
23403                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23404                break;
23405            case OPC_DMSUBU:
23406                check_dsp(ctx);
23407                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23408                break;
23409            case OPC_DPA_W_QH:
23410                check_dsp_r2(ctx);
23411                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23412                break;
23413            case OPC_DPAQ_S_W_QH:
23414                check_dsp(ctx);
23415                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23416                break;
23417            case OPC_DPAQ_SA_L_PW:
23418                check_dsp(ctx);
23419                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23420                break;
23421            case OPC_DPAU_H_OBL:
23422                check_dsp(ctx);
23423                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23424                break;
23425            case OPC_DPAU_H_OBR:
23426                check_dsp(ctx);
23427                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23428                break;
23429            case OPC_DPS_W_QH:
23430                check_dsp_r2(ctx);
23431                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23432                break;
23433            case OPC_DPSQ_S_W_QH:
23434                check_dsp(ctx);
23435                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23436                break;
23437            case OPC_DPSQ_SA_L_PW:
23438                check_dsp(ctx);
23439                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23440                break;
23441            case OPC_DPSU_H_OBL:
23442                check_dsp(ctx);
23443                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23444                break;
23445            case OPC_DPSU_H_OBR:
23446                check_dsp(ctx);
23447                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23448                break;
23449            case OPC_MAQ_S_L_PWL:
23450                check_dsp(ctx);
23451                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23452                break;
23453            case OPC_MAQ_S_L_PWR:
23454                check_dsp(ctx);
23455                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23456                break;
23457            case OPC_MAQ_S_W_QHLL:
23458                check_dsp(ctx);
23459                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23460                break;
23461            case OPC_MAQ_SA_W_QHLL:
23462                check_dsp(ctx);
23463                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23464                break;
23465            case OPC_MAQ_S_W_QHLR:
23466                check_dsp(ctx);
23467                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23468                break;
23469            case OPC_MAQ_SA_W_QHLR:
23470                check_dsp(ctx);
23471                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23472                break;
23473            case OPC_MAQ_S_W_QHRL:
23474                check_dsp(ctx);
23475                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23476                break;
23477            case OPC_MAQ_SA_W_QHRL:
23478                check_dsp(ctx);
23479                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23480                break;
23481            case OPC_MAQ_S_W_QHRR:
23482                check_dsp(ctx);
23483                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23484                break;
23485            case OPC_MAQ_SA_W_QHRR:
23486                check_dsp(ctx);
23487                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23488                break;
23489            case OPC_MULSAQ_S_L_PW:
23490                check_dsp(ctx);
23491                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23492                break;
23493            case OPC_MULSAQ_S_W_QH:
23494                check_dsp(ctx);
23495                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23496                break;
23497            }
23498        }
23499        break;
23500#endif
23501    case OPC_ADDU_QB_DSP:
23502        switch (op2) {
23503        case OPC_MULEU_S_PH_QBL:
23504            check_dsp(ctx);
23505            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23506            break;
23507        case OPC_MULEU_S_PH_QBR:
23508            check_dsp(ctx);
23509            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23510            break;
23511        case OPC_MULQ_RS_PH:
23512            check_dsp(ctx);
23513            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23514            break;
23515        case OPC_MULEQ_S_W_PHL:
23516            check_dsp(ctx);
23517            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23518            break;
23519        case OPC_MULEQ_S_W_PHR:
23520            check_dsp(ctx);
23521            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23522            break;
23523        case OPC_MULQ_S_PH:
23524            check_dsp_r2(ctx);
23525            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23526            break;
23527        }
23528        break;
23529#ifdef TARGET_MIPS64
23530    case OPC_ADDU_OB_DSP:
23531        switch (op2) {
23532        case OPC_MULEQ_S_PW_QHL:
23533            check_dsp(ctx);
23534            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23535            break;
23536        case OPC_MULEQ_S_PW_QHR:
23537            check_dsp(ctx);
23538            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23539            break;
23540        case OPC_MULEU_S_QH_OBL:
23541            check_dsp(ctx);
23542            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23543            break;
23544        case OPC_MULEU_S_QH_OBR:
23545            check_dsp(ctx);
23546            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23547            break;
23548        case OPC_MULQ_RS_QH:
23549            check_dsp(ctx);
23550            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23551            break;
23552        }
23553        break;
23554#endif
23555    }
23556
23557    tcg_temp_free_i32(t0);
23558    tcg_temp_free(v1_t);
23559    tcg_temp_free(v2_t);
23560}
23561
23562static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23563                                int ret, int val)
23564{
23565    int16_t imm;
23566    TCGv t0;
23567    TCGv val_t;
23568
23569    if (ret == 0) {
23570        /* Treat as NOP. */
23571        return;
23572    }
23573
23574    t0 = tcg_temp_new();
23575    val_t = tcg_temp_new();
23576    gen_load_gpr(val_t, val);
23577
23578    switch (op1) {
23579    case OPC_ABSQ_S_PH_DSP:
23580        switch (op2) {
23581        case OPC_BITREV:
23582            check_dsp(ctx);
23583            gen_helper_bitrev(cpu_gpr[ret], val_t);
23584            break;
23585        case OPC_REPL_QB:
23586            check_dsp(ctx);
23587            {
23588                target_long result;
23589                imm = (ctx->opcode >> 16) & 0xFF;
23590                result = (uint32_t)imm << 24 |
23591                         (uint32_t)imm << 16 |
23592                         (uint32_t)imm << 8  |
23593                         (uint32_t)imm;
23594                result = (int32_t)result;
23595                tcg_gen_movi_tl(cpu_gpr[ret], result);
23596            }
23597            break;
23598        case OPC_REPLV_QB:
23599            check_dsp(ctx);
23600            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23601            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23602            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23603            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23604            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23605            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23606            break;
23607        case OPC_REPL_PH:
23608            check_dsp(ctx);
23609            {
23610                imm = (ctx->opcode >> 16) & 0x03FF;
23611                imm = (int16_t)(imm << 6) >> 6;
23612                tcg_gen_movi_tl(cpu_gpr[ret], \
23613                                (target_long)((int32_t)imm << 16 | \
23614                                (uint16_t)imm));
23615            }
23616            break;
23617        case OPC_REPLV_PH:
23618            check_dsp(ctx);
23619            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23620            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23621            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23622            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23623            break;
23624        }
23625        break;
23626#ifdef TARGET_MIPS64
23627    case OPC_ABSQ_S_QH_DSP:
23628        switch (op2) {
23629        case OPC_REPL_OB:
23630            check_dsp(ctx);
23631            {
23632                target_long temp;
23633
23634                imm = (ctx->opcode >> 16) & 0xFF;
23635                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23636                temp = (temp << 16) | temp;
23637                temp = (temp << 32) | temp;
23638                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23639                break;
23640            }
23641        case OPC_REPL_PW:
23642            check_dsp(ctx);
23643            {
23644                target_long temp;
23645
23646                imm = (ctx->opcode >> 16) & 0x03FF;
23647                imm = (int16_t)(imm << 6) >> 6;
23648                temp = ((target_long)imm << 32) \
23649                       | ((target_long)imm & 0xFFFFFFFF);
23650                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23651                break;
23652            }
23653        case OPC_REPL_QH:
23654            check_dsp(ctx);
23655            {
23656                target_long temp;
23657
23658                imm = (ctx->opcode >> 16) & 0x03FF;
23659                imm = (int16_t)(imm << 6) >> 6;
23660
23661                temp = ((uint64_t)(uint16_t)imm << 48) |
23662                       ((uint64_t)(uint16_t)imm << 32) |
23663                       ((uint64_t)(uint16_t)imm << 16) |
23664                       (uint64_t)(uint16_t)imm;
23665                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23666                break;
23667            }
23668        case OPC_REPLV_OB:
23669            check_dsp(ctx);
23670            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23671            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23672            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23673            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23674            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23675            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23676            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23677            break;
23678        case OPC_REPLV_PW:
23679            check_dsp(ctx);
23680            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23681            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23682            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23683            break;
23684        case OPC_REPLV_QH:
23685            check_dsp(ctx);
23686            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23687            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23688            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23689            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23690            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23691            break;
23692        }
23693        break;
23694#endif
23695    }
23696    tcg_temp_free(t0);
23697    tcg_temp_free(val_t);
23698}
23699
23700static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23701                                     uint32_t op1, uint32_t op2,
23702                                     int ret, int v1, int v2, int check_ret)
23703{
23704    TCGv t1;
23705    TCGv v1_t;
23706    TCGv v2_t;
23707
23708    if ((ret == 0) && (check_ret == 1)) {
23709        /* Treat as NOP. */
23710        return;
23711    }
23712
23713    t1 = tcg_temp_new();
23714    v1_t = tcg_temp_new();
23715    v2_t = tcg_temp_new();
23716
23717    gen_load_gpr(v1_t, v1);
23718    gen_load_gpr(v2_t, v2);
23719
23720    switch (op1) {
23721    case OPC_CMPU_EQ_QB_DSP:
23722        switch (op2) {
23723        case OPC_CMPU_EQ_QB:
23724            check_dsp(ctx);
23725            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23726            break;
23727        case OPC_CMPU_LT_QB:
23728            check_dsp(ctx);
23729            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23730            break;
23731        case OPC_CMPU_LE_QB:
23732            check_dsp(ctx);
23733            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23734            break;
23735        case OPC_CMPGU_EQ_QB:
23736            check_dsp(ctx);
23737            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23738            break;
23739        case OPC_CMPGU_LT_QB:
23740            check_dsp(ctx);
23741            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23742            break;
23743        case OPC_CMPGU_LE_QB:
23744            check_dsp(ctx);
23745            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23746            break;
23747        case OPC_CMPGDU_EQ_QB:
23748            check_dsp_r2(ctx);
23749            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23750            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23751            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23752            tcg_gen_shli_tl(t1, t1, 24);
23753            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23754            break;
23755        case OPC_CMPGDU_LT_QB:
23756            check_dsp_r2(ctx);
23757            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23758            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23759            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23760            tcg_gen_shli_tl(t1, t1, 24);
23761            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23762            break;
23763        case OPC_CMPGDU_LE_QB:
23764            check_dsp_r2(ctx);
23765            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23766            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23767            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23768            tcg_gen_shli_tl(t1, t1, 24);
23769            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23770            break;
23771        case OPC_CMP_EQ_PH:
23772            check_dsp(ctx);
23773            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23774            break;
23775        case OPC_CMP_LT_PH:
23776            check_dsp(ctx);
23777            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23778            break;
23779        case OPC_CMP_LE_PH:
23780            check_dsp(ctx);
23781            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23782            break;
23783        case OPC_PICK_QB:
23784            check_dsp(ctx);
23785            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23786            break;
23787        case OPC_PICK_PH:
23788            check_dsp(ctx);
23789            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23790            break;
23791        case OPC_PACKRL_PH:
23792            check_dsp(ctx);
23793            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23794            break;
23795        }
23796        break;
23797#ifdef TARGET_MIPS64
23798    case OPC_CMPU_EQ_OB_DSP:
23799        switch (op2) {
23800        case OPC_CMP_EQ_PW:
23801            check_dsp(ctx);
23802            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23803            break;
23804        case OPC_CMP_LT_PW:
23805            check_dsp(ctx);
23806            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23807            break;
23808        case OPC_CMP_LE_PW:
23809            check_dsp(ctx);
23810            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23811            break;
23812        case OPC_CMP_EQ_QH:
23813            check_dsp(ctx);
23814            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23815            break;
23816        case OPC_CMP_LT_QH:
23817            check_dsp(ctx);
23818            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23819            break;
23820        case OPC_CMP_LE_QH:
23821            check_dsp(ctx);
23822            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23823            break;
23824        case OPC_CMPGDU_EQ_OB:
23825            check_dsp_r2(ctx);
23826            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23827            break;
23828        case OPC_CMPGDU_LT_OB:
23829            check_dsp_r2(ctx);
23830            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23831            break;
23832        case OPC_CMPGDU_LE_OB:
23833            check_dsp_r2(ctx);
23834            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23835            break;
23836        case OPC_CMPGU_EQ_OB:
23837            check_dsp(ctx);
23838            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23839            break;
23840        case OPC_CMPGU_LT_OB:
23841            check_dsp(ctx);
23842            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23843            break;
23844        case OPC_CMPGU_LE_OB:
23845            check_dsp(ctx);
23846            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23847            break;
23848        case OPC_CMPU_EQ_OB:
23849            check_dsp(ctx);
23850            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23851            break;
23852        case OPC_CMPU_LT_OB:
23853            check_dsp(ctx);
23854            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23855            break;
23856        case OPC_CMPU_LE_OB:
23857            check_dsp(ctx);
23858            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23859            break;
23860        case OPC_PACKRL_PW:
23861            check_dsp(ctx);
23862            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23863            break;
23864        case OPC_PICK_OB:
23865            check_dsp(ctx);
23866            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23867            break;
23868        case OPC_PICK_PW:
23869            check_dsp(ctx);
23870            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23871            break;
23872        case OPC_PICK_QH:
23873            check_dsp(ctx);
23874            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23875            break;
23876        }
23877        break;
23878#endif
23879    }
23880
23881    tcg_temp_free(t1);
23882    tcg_temp_free(v1_t);
23883    tcg_temp_free(v2_t);
23884}
23885
23886static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23887                               uint32_t op1, int rt, int rs, int sa)
23888{
23889    TCGv t0;
23890
23891    check_dsp_r2(ctx);
23892
23893    if (rt == 0) {
23894        /* Treat as NOP. */
23895        return;
23896    }
23897
23898    t0 = tcg_temp_new();
23899    gen_load_gpr(t0, rs);
23900
23901    switch (op1) {
23902    case OPC_APPEND_DSP:
23903        switch (MASK_APPEND(ctx->opcode)) {
23904        case OPC_APPEND:
23905            if (sa != 0) {
23906                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23907            }
23908            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23909            break;
23910        case OPC_PREPEND:
23911            if (sa != 0) {
23912                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23913                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23914                tcg_gen_shli_tl(t0, t0, 32 - sa);
23915                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23916            }
23917            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23918            break;
23919        case OPC_BALIGN:
23920            sa &= 3;
23921            if (sa != 0 && sa != 2) {
23922                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23923                tcg_gen_ext32u_tl(t0, t0);
23924                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23925                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23926            }
23927            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23928            break;
23929        default:            /* Invalid */
23930            MIPS_INVAL("MASK APPEND");
23931            generate_exception_end(ctx, EXCP_RI);
23932            break;
23933        }
23934        break;
23935#ifdef TARGET_MIPS64
23936    case OPC_DAPPEND_DSP:
23937        switch (MASK_DAPPEND(ctx->opcode)) {
23938        case OPC_DAPPEND:
23939            if (sa != 0) {
23940                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23941            }
23942            break;
23943        case OPC_PREPENDD:
23944            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23945            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23946            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23947            break;
23948        case OPC_PREPENDW:
23949            if (sa != 0) {
23950                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23951                tcg_gen_shli_tl(t0, t0, 64 - sa);
23952                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23953            }
23954            break;
23955        case OPC_DBALIGN:
23956            sa &= 7;
23957            if (sa != 0 && sa != 2 && sa != 4) {
23958                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23959                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23960                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23961            }
23962            break;
23963        default:            /* Invalid */
23964            MIPS_INVAL("MASK DAPPEND");
23965            generate_exception_end(ctx, EXCP_RI);
23966            break;
23967        }
23968        break;
23969#endif
23970    }
23971    tcg_temp_free(t0);
23972}
23973
23974static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23975                                int ret, int v1, int v2, int check_ret)
23976
23977{
23978    TCGv t0;
23979    TCGv t1;
23980    TCGv v1_t;
23981    TCGv v2_t;
23982    int16_t imm;
23983
23984    if ((ret == 0) && (check_ret == 1)) {
23985        /* Treat as NOP. */
23986        return;
23987    }
23988
23989    t0 = tcg_temp_new();
23990    t1 = tcg_temp_new();
23991    v1_t = tcg_temp_new();
23992    v2_t = tcg_temp_new();
23993
23994    gen_load_gpr(v1_t, v1);
23995    gen_load_gpr(v2_t, v2);
23996
23997    switch (op1) {
23998    case OPC_EXTR_W_DSP:
23999        check_dsp(ctx);
24000        switch (op2) {
24001        case OPC_EXTR_W:
24002            tcg_gen_movi_tl(t0, v2);
24003            tcg_gen_movi_tl(t1, v1);
24004            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
24005            break;
24006        case OPC_EXTR_R_W:
24007            tcg_gen_movi_tl(t0, v2);
24008            tcg_gen_movi_tl(t1, v1);
24009            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24010            break;
24011        case OPC_EXTR_RS_W:
24012            tcg_gen_movi_tl(t0, v2);
24013            tcg_gen_movi_tl(t1, v1);
24014            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24015            break;
24016        case OPC_EXTR_S_H:
24017            tcg_gen_movi_tl(t0, v2);
24018            tcg_gen_movi_tl(t1, v1);
24019            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24020            break;
24021        case OPC_EXTRV_S_H:
24022            tcg_gen_movi_tl(t0, v2);
24023            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
24024            break;
24025        case OPC_EXTRV_W:
24026            tcg_gen_movi_tl(t0, v2);
24027            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24028            break;
24029        case OPC_EXTRV_R_W:
24030            tcg_gen_movi_tl(t0, v2);
24031            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24032            break;
24033        case OPC_EXTRV_RS_W:
24034            tcg_gen_movi_tl(t0, v2);
24035            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24036            break;
24037        case OPC_EXTP:
24038            tcg_gen_movi_tl(t0, v2);
24039            tcg_gen_movi_tl(t1, v1);
24040            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
24041            break;
24042        case OPC_EXTPV:
24043            tcg_gen_movi_tl(t0, v2);
24044            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
24045            break;
24046        case OPC_EXTPDP:
24047            tcg_gen_movi_tl(t0, v2);
24048            tcg_gen_movi_tl(t1, v1);
24049            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
24050            break;
24051        case OPC_EXTPDPV:
24052            tcg_gen_movi_tl(t0, v2);
24053            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24054            break;
24055        case OPC_SHILO:
24056            imm = (ctx->opcode >> 20) & 0x3F;
24057            tcg_gen_movi_tl(t0, ret);
24058            tcg_gen_movi_tl(t1, imm);
24059            gen_helper_shilo(t0, t1, cpu_env);
24060            break;
24061        case OPC_SHILOV:
24062            tcg_gen_movi_tl(t0, ret);
24063            gen_helper_shilo(t0, v1_t, cpu_env);
24064            break;
24065        case OPC_MTHLIP:
24066            tcg_gen_movi_tl(t0, ret);
24067            gen_helper_mthlip(t0, v1_t, cpu_env);
24068            break;
24069        case OPC_WRDSP:
24070            imm = (ctx->opcode >> 11) & 0x3FF;
24071            tcg_gen_movi_tl(t0, imm);
24072            gen_helper_wrdsp(v1_t, t0, cpu_env);
24073            break;
24074        case OPC_RDDSP:
24075            imm = (ctx->opcode >> 16) & 0x03FF;
24076            tcg_gen_movi_tl(t0, imm);
24077            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
24078            break;
24079        }
24080        break;
24081#ifdef TARGET_MIPS64
24082    case OPC_DEXTR_W_DSP:
24083        check_dsp(ctx);
24084        switch (op2) {
24085        case OPC_DMTHLIP:
24086            tcg_gen_movi_tl(t0, ret);
24087            gen_helper_dmthlip(v1_t, t0, cpu_env);
24088            break;
24089        case OPC_DSHILO:
24090            {
24091                int shift = (ctx->opcode >> 19) & 0x7F;
24092                int ac = (ctx->opcode >> 11) & 0x03;
24093                tcg_gen_movi_tl(t0, shift);
24094                tcg_gen_movi_tl(t1, ac);
24095                gen_helper_dshilo(t0, t1, cpu_env);
24096                break;
24097            }
24098        case OPC_DSHILOV:
24099            {
24100                int ac = (ctx->opcode >> 11) & 0x03;
24101                tcg_gen_movi_tl(t0, ac);
24102                gen_helper_dshilo(v1_t, t0, cpu_env);
24103                break;
24104            }
24105        case OPC_DEXTP:
24106            tcg_gen_movi_tl(t0, v2);
24107            tcg_gen_movi_tl(t1, v1);
24108
24109            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
24110            break;
24111        case OPC_DEXTPV:
24112            tcg_gen_movi_tl(t0, v2);
24113            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
24114            break;
24115        case OPC_DEXTPDP:
24116            tcg_gen_movi_tl(t0, v2);
24117            tcg_gen_movi_tl(t1, v1);
24118            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
24119            break;
24120        case OPC_DEXTPDPV:
24121            tcg_gen_movi_tl(t0, v2);
24122            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
24123            break;
24124        case OPC_DEXTR_L:
24125            tcg_gen_movi_tl(t0, v2);
24126            tcg_gen_movi_tl(t1, v1);
24127            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
24128            break;
24129        case OPC_DEXTR_R_L:
24130            tcg_gen_movi_tl(t0, v2);
24131            tcg_gen_movi_tl(t1, v1);
24132            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
24133            break;
24134        case OPC_DEXTR_RS_L:
24135            tcg_gen_movi_tl(t0, v2);
24136            tcg_gen_movi_tl(t1, v1);
24137            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
24138            break;
24139        case OPC_DEXTR_W:
24140            tcg_gen_movi_tl(t0, v2);
24141            tcg_gen_movi_tl(t1, v1);
24142            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
24143            break;
24144        case OPC_DEXTR_R_W:
24145            tcg_gen_movi_tl(t0, v2);
24146            tcg_gen_movi_tl(t1, v1);
24147            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
24148            break;
24149        case OPC_DEXTR_RS_W:
24150            tcg_gen_movi_tl(t0, v2);
24151            tcg_gen_movi_tl(t1, v1);
24152            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
24153            break;
24154        case OPC_DEXTR_S_H:
24155            tcg_gen_movi_tl(t0, v2);
24156            tcg_gen_movi_tl(t1, v1);
24157            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24158            break;
24159        case OPC_DEXTRV_S_H:
24160            tcg_gen_movi_tl(t0, v2);
24161            tcg_gen_movi_tl(t1, v1);
24162            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
24163            break;
24164        case OPC_DEXTRV_L:
24165            tcg_gen_movi_tl(t0, v2);
24166            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24167            break;
24168        case OPC_DEXTRV_R_L:
24169            tcg_gen_movi_tl(t0, v2);
24170            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24171            break;
24172        case OPC_DEXTRV_RS_L:
24173            tcg_gen_movi_tl(t0, v2);
24174            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
24175            break;
24176        case OPC_DEXTRV_W:
24177            tcg_gen_movi_tl(t0, v2);
24178            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24179            break;
24180        case OPC_DEXTRV_R_W:
24181            tcg_gen_movi_tl(t0, v2);
24182            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24183            break;
24184        case OPC_DEXTRV_RS_W:
24185            tcg_gen_movi_tl(t0, v2);
24186            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
24187            break;
24188        }
24189        break;
24190#endif
24191    }
24192
24193    tcg_temp_free(t0);
24194    tcg_temp_free(t1);
24195    tcg_temp_free(v1_t);
24196    tcg_temp_free(v2_t);
24197}
24198
24199/* End MIPSDSP functions. */
24200
24201static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
24202{
24203    int rs, rt, rd, sa;
24204    uint32_t op1, op2;
24205
24206    rs = (ctx->opcode >> 21) & 0x1f;
24207    rt = (ctx->opcode >> 16) & 0x1f;
24208    rd = (ctx->opcode >> 11) & 0x1f;
24209    sa = (ctx->opcode >> 6) & 0x1f;
24210
24211    op1 = MASK_SPECIAL(ctx->opcode);
24212    switch (op1) {
24213    case OPC_LSA:
24214        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24215        break;
24216    case OPC_MULT:
24217    case OPC_MULTU:
24218    case OPC_DIV:
24219    case OPC_DIVU:
24220        op2 = MASK_R6_MULDIV(ctx->opcode);
24221        switch (op2) {
24222        case R6_OPC_MUL:
24223        case R6_OPC_MUH:
24224        case R6_OPC_MULU:
24225        case R6_OPC_MUHU:
24226        case R6_OPC_DIV:
24227        case R6_OPC_MOD:
24228        case R6_OPC_DIVU:
24229        case R6_OPC_MODU:
24230            gen_r6_muldiv(ctx, op2, rd, rs, rt);
24231            break;
24232        default:
24233            MIPS_INVAL("special_r6 muldiv");
24234            generate_exception_end(ctx, EXCP_RI);
24235            break;
24236        }
24237        break;
24238    case OPC_SELEQZ:
24239    case OPC_SELNEZ:
24240        gen_cond_move(ctx, op1, rd, rs, rt);
24241        break;
24242    case R6_OPC_CLO:
24243    case R6_OPC_CLZ:
24244        if (rt == 0 && sa == 1) {
24245            /*
24246             * Major opcode and function field is shared with preR6 MFHI/MTHI.
24247             * We need additionally to check other fields.
24248             */
24249            gen_cl(ctx, op1, rd, rs);
24250        } else {
24251            generate_exception_end(ctx, EXCP_RI);
24252        }
24253        break;
24254    case R6_OPC_SDBBP:
24255        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24256            gen_helper_do_semihosting(cpu_env);
24257        } else {
24258            if (ctx->hflags & MIPS_HFLAG_SBRI) {
24259                generate_exception_end(ctx, EXCP_RI);
24260            } else {
24261                generate_exception_end(ctx, EXCP_DBp);
24262            }
24263        }
24264        break;
24265#if defined(TARGET_MIPS64)
24266    case OPC_DLSA:
24267        check_mips_64(ctx);
24268        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
24269        break;
24270    case R6_OPC_DCLO:
24271    case R6_OPC_DCLZ:
24272        if (rt == 0 && sa == 1) {
24273            /*
24274             * Major opcode and function field is shared with preR6 MFHI/MTHI.
24275             * We need additionally to check other fields.
24276             */
24277            check_mips_64(ctx);
24278            gen_cl(ctx, op1, rd, rs);
24279        } else {
24280            generate_exception_end(ctx, EXCP_RI);
24281        }
24282        break;
24283    case OPC_DMULT:
24284    case OPC_DMULTU:
24285    case OPC_DDIV:
24286    case OPC_DDIVU:
24287
24288        op2 = MASK_R6_MULDIV(ctx->opcode);
24289        switch (op2) {
24290        case R6_OPC_DMUL:
24291        case R6_OPC_DMUH:
24292        case R6_OPC_DMULU:
24293        case R6_OPC_DMUHU:
24294        case R6_OPC_DDIV:
24295        case R6_OPC_DMOD:
24296        case R6_OPC_DDIVU:
24297        case R6_OPC_DMODU:
24298            check_mips_64(ctx);
24299            gen_r6_muldiv(ctx, op2, rd, rs, rt);
24300            break;
24301        default:
24302            MIPS_INVAL("special_r6 muldiv");
24303            generate_exception_end(ctx, EXCP_RI);
24304            break;
24305        }
24306        break;
24307#endif
24308    default:            /* Invalid */
24309        MIPS_INVAL("special_r6");
24310        generate_exception_end(ctx, EXCP_RI);
24311        break;
24312    }
24313}
24314
24315static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24316{
24317    int rs = extract32(ctx->opcode, 21, 5);
24318    int rt = extract32(ctx->opcode, 16, 5);
24319    int rd = extract32(ctx->opcode, 11, 5);
24320    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24321
24322    switch (op1) {
24323    case OPC_MOVN:         /* Conditional move */
24324    case OPC_MOVZ:
24325        gen_cond_move(ctx, op1, rd, rs, rt);
24326        break;
24327    case OPC_MFHI:          /* Move from HI/LO */
24328    case OPC_MFLO:
24329        gen_HILO(ctx, op1, 0, rd);
24330        break;
24331    case OPC_MTHI:
24332    case OPC_MTLO:          /* Move to HI/LO */
24333        gen_HILO(ctx, op1, 0, rs);
24334        break;
24335    case OPC_MULT:
24336    case OPC_MULTU:
24337        gen_mul_txx9(ctx, op1, rd, rs, rt);
24338        break;
24339    case OPC_DIV:
24340    case OPC_DIVU:
24341        gen_muldiv(ctx, op1, 0, rs, rt);
24342        break;
24343#if defined(TARGET_MIPS64)
24344    case OPC_DMULT:
24345    case OPC_DMULTU:
24346    case OPC_DDIV:
24347    case OPC_DDIVU:
24348        check_insn_opc_user_only(ctx, INSN_R5900);
24349        gen_muldiv(ctx, op1, 0, rs, rt);
24350        break;
24351#endif
24352    case OPC_JR:
24353        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24354        break;
24355    default:            /* Invalid */
24356        MIPS_INVAL("special_tx79");
24357        generate_exception_end(ctx, EXCP_RI);
24358        break;
24359    }
24360}
24361
24362static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24363{
24364    int rs, rt, rd, sa;
24365    uint32_t op1;
24366
24367    rs = (ctx->opcode >> 21) & 0x1f;
24368    rt = (ctx->opcode >> 16) & 0x1f;
24369    rd = (ctx->opcode >> 11) & 0x1f;
24370    sa = (ctx->opcode >> 6) & 0x1f;
24371
24372    op1 = MASK_SPECIAL(ctx->opcode);
24373    switch (op1) {
24374    case OPC_MOVN:         /* Conditional move */
24375    case OPC_MOVZ:
24376        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24377                   INSN_LOONGSON2E | INSN_LOONGSON2F);
24378        gen_cond_move(ctx, op1, rd, rs, rt);
24379        break;
24380    case OPC_MFHI:          /* Move from HI/LO */
24381    case OPC_MFLO:
24382        gen_HILO(ctx, op1, rs & 3, rd);
24383        break;
24384    case OPC_MTHI:
24385    case OPC_MTLO:          /* Move to HI/LO */
24386        gen_HILO(ctx, op1, rd & 3, rs);
24387        break;
24388    case OPC_MOVCI:
24389        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24390        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24391            check_cp1_enabled(ctx);
24392            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24393                      (ctx->opcode >> 16) & 1);
24394        } else {
24395            generate_exception_err(ctx, EXCP_CpU, 1);
24396        }
24397        break;
24398    case OPC_MULT:
24399    case OPC_MULTU:
24400        if (sa) {
24401            check_insn(ctx, INSN_VR54XX);
24402            op1 = MASK_MUL_VR54XX(ctx->opcode);
24403            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24404        } else {
24405            gen_muldiv(ctx, op1, rd & 3, rs, rt);
24406        }
24407        break;
24408    case OPC_DIV:
24409    case OPC_DIVU:
24410        gen_muldiv(ctx, op1, 0, rs, rt);
24411        break;
24412#if defined(TARGET_MIPS64)
24413    case OPC_DMULT:
24414    case OPC_DMULTU:
24415    case OPC_DDIV:
24416    case OPC_DDIVU:
24417        check_insn(ctx, ISA_MIPS3);
24418        check_mips_64(ctx);
24419        gen_muldiv(ctx, op1, 0, rs, rt);
24420        break;
24421#endif
24422    case OPC_JR:
24423        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24424        break;
24425    case OPC_SPIM:
24426#ifdef MIPS_STRICT_STANDARD
24427        MIPS_INVAL("SPIM");
24428        generate_exception_end(ctx, EXCP_RI);
24429#else
24430        /* Implemented as RI exception for now. */
24431        MIPS_INVAL("spim (unofficial)");
24432        generate_exception_end(ctx, EXCP_RI);
24433#endif
24434        break;
24435    default:            /* Invalid */
24436        MIPS_INVAL("special_legacy");
24437        generate_exception_end(ctx, EXCP_RI);
24438        break;
24439    }
24440}
24441
24442static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24443{
24444    int rs, rt, rd, sa;
24445    uint32_t op1;
24446
24447    rs = (ctx->opcode >> 21) & 0x1f;
24448    rt = (ctx->opcode >> 16) & 0x1f;
24449    rd = (ctx->opcode >> 11) & 0x1f;
24450    sa = (ctx->opcode >> 6) & 0x1f;
24451
24452    op1 = MASK_SPECIAL(ctx->opcode);
24453    switch (op1) {
24454    case OPC_SLL:          /* Shift with immediate */
24455        if (sa == 5 && rd == 0 &&
24456            rs == 0 && rt == 0) { /* PAUSE */
24457            if ((ctx->insn_flags & ISA_MIPS32R6) &&
24458                (ctx->hflags & MIPS_HFLAG_BMASK)) {
24459                generate_exception_end(ctx, EXCP_RI);
24460                break;
24461            }
24462        }
24463        /* Fallthrough */
24464    case OPC_SRA:
24465        gen_shift_imm(ctx, op1, rd, rt, sa);
24466        break;
24467    case OPC_SRL:
24468        switch ((ctx->opcode >> 21) & 0x1f) {
24469        case 1:
24470            /* rotr is decoded as srl on non-R2 CPUs */
24471            if (ctx->insn_flags & ISA_MIPS32R2) {
24472                op1 = OPC_ROTR;
24473            }
24474            /* Fallthrough */
24475        case 0:
24476            gen_shift_imm(ctx, op1, rd, rt, sa);
24477            break;
24478        default:
24479            generate_exception_end(ctx, EXCP_RI);
24480            break;
24481        }
24482        break;
24483    case OPC_ADD:
24484    case OPC_ADDU:
24485    case OPC_SUB:
24486    case OPC_SUBU:
24487        gen_arith(ctx, op1, rd, rs, rt);
24488        break;
24489    case OPC_SLLV:         /* Shifts */
24490    case OPC_SRAV:
24491        gen_shift(ctx, op1, rd, rs, rt);
24492        break;
24493    case OPC_SRLV:
24494        switch ((ctx->opcode >> 6) & 0x1f) {
24495        case 1:
24496            /* rotrv is decoded as srlv on non-R2 CPUs */
24497            if (ctx->insn_flags & ISA_MIPS32R2) {
24498                op1 = OPC_ROTRV;
24499            }
24500            /* Fallthrough */
24501        case 0:
24502            gen_shift(ctx, op1, rd, rs, rt);
24503            break;
24504        default:
24505            generate_exception_end(ctx, EXCP_RI);
24506            break;
24507        }
24508        break;
24509    case OPC_SLT:          /* Set on less than */
24510    case OPC_SLTU:
24511        gen_slt(ctx, op1, rd, rs, rt);
24512        break;
24513    case OPC_AND:          /* Logic*/
24514    case OPC_OR:
24515    case OPC_NOR:
24516    case OPC_XOR:
24517        gen_logic(ctx, op1, rd, rs, rt);
24518        break;
24519    case OPC_JALR:
24520        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24521        break;
24522    case OPC_TGE: /* Traps */
24523    case OPC_TGEU:
24524    case OPC_TLT:
24525    case OPC_TLTU:
24526    case OPC_TEQ:
24527    case OPC_TNE:
24528        check_insn(ctx, ISA_MIPS2);
24529        gen_trap(ctx, op1, rs, rt, -1);
24530        break;
24531    case OPC_LSA: /* OPC_PMON */
24532        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24533            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24534            decode_opc_special_r6(env, ctx);
24535        } else {
24536            /* Pmon entry point, also R4010 selsl */
24537#ifdef MIPS_STRICT_STANDARD
24538            MIPS_INVAL("PMON / selsl");
24539            generate_exception_end(ctx, EXCP_RI);
24540#else
24541            gen_helper_0e0i(pmon, sa);
24542#endif
24543        }
24544        break;
24545    case OPC_SYSCALL:
24546        generate_exception_end(ctx, EXCP_SYSCALL);
24547        break;
24548    case OPC_BREAK:
24549        generate_exception_end(ctx, EXCP_BREAK);
24550        break;
24551    case OPC_SYNC:
24552        check_insn(ctx, ISA_MIPS2);
24553        gen_sync(extract32(ctx->opcode, 6, 5));
24554        break;
24555
24556#if defined(TARGET_MIPS64)
24557        /* MIPS64 specific opcodes */
24558    case OPC_DSLL:
24559    case OPC_DSRA:
24560    case OPC_DSLL32:
24561    case OPC_DSRA32:
24562        check_insn(ctx, ISA_MIPS3);
24563        check_mips_64(ctx);
24564        gen_shift_imm(ctx, op1, rd, rt, sa);
24565        break;
24566    case OPC_DSRL:
24567        switch ((ctx->opcode >> 21) & 0x1f) {
24568        case 1:
24569            /* drotr is decoded as dsrl on non-R2 CPUs */
24570            if (ctx->insn_flags & ISA_MIPS32R2) {
24571                op1 = OPC_DROTR;
24572            }
24573            /* Fallthrough */
24574        case 0:
24575            check_insn(ctx, ISA_MIPS3);
24576            check_mips_64(ctx);
24577            gen_shift_imm(ctx, op1, rd, rt, sa);
24578            break;
24579        default:
24580            generate_exception_end(ctx, EXCP_RI);
24581            break;
24582        }
24583        break;
24584    case OPC_DSRL32:
24585        switch ((ctx->opcode >> 21) & 0x1f) {
24586        case 1:
24587            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24588            if (ctx->insn_flags & ISA_MIPS32R2) {
24589                op1 = OPC_DROTR32;
24590            }
24591            /* Fallthrough */
24592        case 0:
24593            check_insn(ctx, ISA_MIPS3);
24594            check_mips_64(ctx);
24595            gen_shift_imm(ctx, op1, rd, rt, sa);
24596            break;
24597        default:
24598            generate_exception_end(ctx, EXCP_RI);
24599            break;
24600        }
24601        break;
24602    case OPC_DADD:
24603    case OPC_DADDU:
24604    case OPC_DSUB:
24605    case OPC_DSUBU:
24606        check_insn(ctx, ISA_MIPS3);
24607        check_mips_64(ctx);
24608        gen_arith(ctx, op1, rd, rs, rt);
24609        break;
24610    case OPC_DSLLV:
24611    case OPC_DSRAV:
24612        check_insn(ctx, ISA_MIPS3);
24613        check_mips_64(ctx);
24614        gen_shift(ctx, op1, rd, rs, rt);
24615        break;
24616    case OPC_DSRLV:
24617        switch ((ctx->opcode >> 6) & 0x1f) {
24618        case 1:
24619            /* drotrv is decoded as dsrlv on non-R2 CPUs */
24620            if (ctx->insn_flags & ISA_MIPS32R2) {
24621                op1 = OPC_DROTRV;
24622            }
24623            /* Fallthrough */
24624        case 0:
24625            check_insn(ctx, ISA_MIPS3);
24626            check_mips_64(ctx);
24627            gen_shift(ctx, op1, rd, rs, rt);
24628            break;
24629        default:
24630            generate_exception_end(ctx, EXCP_RI);
24631            break;
24632        }
24633        break;
24634    case OPC_DLSA:
24635        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24636            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24637            decode_opc_special_r6(env, ctx);
24638        }
24639        break;
24640#endif
24641    default:
24642        if (ctx->insn_flags & ISA_MIPS32R6) {
24643            decode_opc_special_r6(env, ctx);
24644        } else if (ctx->insn_flags & INSN_R5900) {
24645            decode_opc_special_tx79(env, ctx);
24646        } else {
24647            decode_opc_special_legacy(env, ctx);
24648        }
24649    }
24650}
24651
24652
24653#if defined(TARGET_MIPS64)
24654
24655/*
24656 *
24657 *           MMI (MultiMedia Interface) ASE instructions
24658 *           ===========================================
24659 */
24660
24661/*
24662 *          MMI instructions category: data communication
24663 *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24664 *
24665 *   PCPYH    PEXCH    PEXTLB   PINTH    PPACB    PEXT5    PREVH
24666 *   PCPYLD   PEXCW    PEXTLH   PINTEH   PPACH    PPAC5    PROT3W
24667 *   PCPYUD   PEXEH    PEXTLW            PPACW
24668 *            PEXEW    PEXTUB
24669 *                     PEXTUH
24670 *                     PEXTUW
24671 */
24672
24673/*
24674 *  PCPYH rd, rt
24675 *
24676 *    Parallel Copy Halfword
24677 *
24678 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24679 *  +-----------+---------+---------+---------+---------+-----------+
24680 *  |    MMI    |0 0 0 0 0|   rt    |   rd    |  PCPYH  |    MMI3   |
24681 *  +-----------+---------+---------+---------+---------+-----------+
24682 */
24683static void gen_mmi_pcpyh(DisasContext *ctx)
24684{
24685    uint32_t pd, rt, rd;
24686    uint32_t opcode;
24687
24688    opcode = ctx->opcode;
24689
24690    pd = extract32(opcode, 21, 5);
24691    rt = extract32(opcode, 16, 5);
24692    rd = extract32(opcode, 11, 5);
24693
24694    if (unlikely(pd != 0)) {
24695        generate_exception_end(ctx, EXCP_RI);
24696    } else if (rd == 0) {
24697        /* nop */
24698    } else if (rt == 0) {
24699        tcg_gen_movi_i64(cpu_gpr[rd], 0);
24700        tcg_gen_movi_i64(cpu_mmr[rd], 0);
24701    } else {
24702        TCGv_i64 t0 = tcg_temp_new();
24703        TCGv_i64 t1 = tcg_temp_new();
24704        uint64_t mask = (1ULL << 16) - 1;
24705
24706        tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24707        tcg_gen_movi_i64(t1, 0);
24708        tcg_gen_or_i64(t1, t0, t1);
24709        tcg_gen_shli_i64(t0, t0, 16);
24710        tcg_gen_or_i64(t1, t0, t1);
24711        tcg_gen_shli_i64(t0, t0, 16);
24712        tcg_gen_or_i64(t1, t0, t1);
24713        tcg_gen_shli_i64(t0, t0, 16);
24714        tcg_gen_or_i64(t1, t0, t1);
24715
24716        tcg_gen_mov_i64(cpu_gpr[rd], t1);
24717
24718        tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24719        tcg_gen_movi_i64(t1, 0);
24720        tcg_gen_or_i64(t1, t0, t1);
24721        tcg_gen_shli_i64(t0, t0, 16);
24722        tcg_gen_or_i64(t1, t0, t1);
24723        tcg_gen_shli_i64(t0, t0, 16);
24724        tcg_gen_or_i64(t1, t0, t1);
24725        tcg_gen_shli_i64(t0, t0, 16);
24726        tcg_gen_or_i64(t1, t0, t1);
24727
24728        tcg_gen_mov_i64(cpu_mmr[rd], t1);
24729
24730        tcg_temp_free(t0);
24731        tcg_temp_free(t1);
24732    }
24733}
24734
24735/*
24736 *  PCPYLD rd, rs, rt
24737 *
24738 *    Parallel Copy Lower Doubleword
24739 *
24740 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24741 *  +-----------+---------+---------+---------+---------+-----------+
24742 *  |    MMI    |   rs    |   rt    |   rd    | PCPYLD  |    MMI2   |
24743 *  +-----------+---------+---------+---------+---------+-----------+
24744 */
24745static void gen_mmi_pcpyld(DisasContext *ctx)
24746{
24747    uint32_t rs, rt, rd;
24748    uint32_t opcode;
24749
24750    opcode = ctx->opcode;
24751
24752    rs = extract32(opcode, 21, 5);
24753    rt = extract32(opcode, 16, 5);
24754    rd = extract32(opcode, 11, 5);
24755
24756    if (rd == 0) {
24757        /* nop */
24758    } else {
24759        if (rs == 0) {
24760            tcg_gen_movi_i64(cpu_mmr[rd], 0);
24761        } else {
24762            tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24763        }
24764        if (rt == 0) {
24765            tcg_gen_movi_i64(cpu_gpr[rd], 0);
24766        } else {
24767            if (rd != rt) {
24768                tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24769            }
24770        }
24771    }
24772}
24773
24774/*
24775 *  PCPYUD rd, rs, rt
24776 *
24777 *    Parallel Copy Upper Doubleword
24778 *
24779 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24780 *  +-----------+---------+---------+---------+---------+-----------+
24781 *  |    MMI    |   rs    |   rt    |   rd    | PCPYUD  |    MMI3   |
24782 *  +-----------+---------+---------+---------+---------+-----------+
24783 */
24784static void gen_mmi_pcpyud(DisasContext *ctx)
24785{
24786    uint32_t rs, rt, rd;
24787    uint32_t opcode;
24788
24789    opcode = ctx->opcode;
24790
24791    rs = extract32(opcode, 21, 5);
24792    rt = extract32(opcode, 16, 5);
24793    rd = extract32(opcode, 11, 5);
24794
24795    if (rd == 0) {
24796        /* nop */
24797    } else {
24798        if (rs == 0) {
24799            tcg_gen_movi_i64(cpu_gpr[rd], 0);
24800        } else {
24801            tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24802        }
24803        if (rt == 0) {
24804            tcg_gen_movi_i64(cpu_mmr[rd], 0);
24805        } else {
24806            if (rd != rt) {
24807                tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24808            }
24809        }
24810    }
24811}
24812
24813#endif
24814
24815
24816#if !defined(TARGET_MIPS64)
24817
24818/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24819#define MXU_APTN1_A    0
24820#define MXU_APTN1_S    1
24821
24822/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24823#define MXU_APTN2_AA    0
24824#define MXU_APTN2_AS    1
24825#define MXU_APTN2_SA    2
24826#define MXU_APTN2_SS    3
24827
24828/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24829#define MXU_EPTN2_AA    0
24830#define MXU_EPTN2_AS    1
24831#define MXU_EPTN2_SA    2
24832#define MXU_EPTN2_SS    3
24833
24834/* MXU operand getting pattern 'optn2' */
24835#define MXU_OPTN2_PTN0  0
24836#define MXU_OPTN2_PTN1  1
24837#define MXU_OPTN2_PTN2  2
24838#define MXU_OPTN2_PTN3  3
24839/* alternative naming scheme for 'optn2' */
24840#define MXU_OPTN2_WW    0
24841#define MXU_OPTN2_LW    1
24842#define MXU_OPTN2_HW    2
24843#define MXU_OPTN2_XW    3
24844
24845/* MXU operand getting pattern 'optn3' */
24846#define MXU_OPTN3_PTN0  0
24847#define MXU_OPTN3_PTN1  1
24848#define MXU_OPTN3_PTN2  2
24849#define MXU_OPTN3_PTN3  3
24850#define MXU_OPTN3_PTN4  4
24851#define MXU_OPTN3_PTN5  5
24852#define MXU_OPTN3_PTN6  6
24853#define MXU_OPTN3_PTN7  7
24854
24855
24856/*
24857 * S32I2M XRa, rb - Register move from GRF to XRF
24858 */
24859static void gen_mxu_s32i2m(DisasContext *ctx)
24860{
24861    TCGv t0;
24862    uint32_t XRa, Rb;
24863
24864    t0 = tcg_temp_new();
24865
24866    XRa = extract32(ctx->opcode, 6, 5);
24867    Rb = extract32(ctx->opcode, 16, 5);
24868
24869    gen_load_gpr(t0, Rb);
24870    if (XRa <= 15) {
24871        gen_store_mxu_gpr(t0, XRa);
24872    } else if (XRa == 16) {
24873        gen_store_mxu_cr(t0);
24874    }
24875
24876    tcg_temp_free(t0);
24877}
24878
24879/*
24880 * S32M2I XRa, rb - Register move from XRF to GRF
24881 */
24882static void gen_mxu_s32m2i(DisasContext *ctx)
24883{
24884    TCGv t0;
24885    uint32_t XRa, Rb;
24886
24887    t0 = tcg_temp_new();
24888
24889    XRa = extract32(ctx->opcode, 6, 5);
24890    Rb = extract32(ctx->opcode, 16, 5);
24891
24892    if (XRa <= 15) {
24893        gen_load_mxu_gpr(t0, XRa);
24894    } else if (XRa == 16) {
24895        gen_load_mxu_cr(t0);
24896    }
24897
24898    gen_store_gpr(t0, Rb);
24899
24900    tcg_temp_free(t0);
24901}
24902
24903/*
24904 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24905 */
24906static void gen_mxu_s8ldd(DisasContext *ctx)
24907{
24908    TCGv t0, t1;
24909    uint32_t XRa, Rb, s8, optn3;
24910
24911    t0 = tcg_temp_new();
24912    t1 = tcg_temp_new();
24913
24914    XRa = extract32(ctx->opcode, 6, 4);
24915    s8 = extract32(ctx->opcode, 10, 8);
24916    optn3 = extract32(ctx->opcode, 18, 3);
24917    Rb = extract32(ctx->opcode, 21, 5);
24918
24919    gen_load_gpr(t0, Rb);
24920    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24921
24922    switch (optn3) {
24923    /* XRa[7:0] = tmp8 */
24924    case MXU_OPTN3_PTN0:
24925        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24926        gen_load_mxu_gpr(t0, XRa);
24927        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24928        break;
24929    /* XRa[15:8] = tmp8 */
24930    case MXU_OPTN3_PTN1:
24931        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24932        gen_load_mxu_gpr(t0, XRa);
24933        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24934        break;
24935    /* XRa[23:16] = tmp8 */
24936    case MXU_OPTN3_PTN2:
24937        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24938        gen_load_mxu_gpr(t0, XRa);
24939        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24940        break;
24941    /* XRa[31:24] = tmp8 */
24942    case MXU_OPTN3_PTN3:
24943        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24944        gen_load_mxu_gpr(t0, XRa);
24945        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24946        break;
24947    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24948    case MXU_OPTN3_PTN4:
24949        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24950        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24951        break;
24952    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24953    case MXU_OPTN3_PTN5:
24954        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24955        tcg_gen_shli_tl(t1, t1, 8);
24956        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24957        break;
24958    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24959    case MXU_OPTN3_PTN6:
24960        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24961        tcg_gen_mov_tl(t0, t1);
24962        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24963        tcg_gen_shli_tl(t1, t1, 16);
24964        tcg_gen_or_tl(t0, t0, t1);
24965        break;
24966    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24967    case MXU_OPTN3_PTN7:
24968        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24969        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24970        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24971        break;
24972    }
24973
24974    gen_store_mxu_gpr(t0, XRa);
24975
24976    tcg_temp_free(t0);
24977    tcg_temp_free(t1);
24978}
24979
24980/*
24981 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24982 */
24983static void gen_mxu_d16mul(DisasContext *ctx)
24984{
24985    TCGv t0, t1, t2, t3;
24986    uint32_t XRa, XRb, XRc, XRd, optn2;
24987
24988    t0 = tcg_temp_new();
24989    t1 = tcg_temp_new();
24990    t2 = tcg_temp_new();
24991    t3 = tcg_temp_new();
24992
24993    XRa = extract32(ctx->opcode, 6, 4);
24994    XRb = extract32(ctx->opcode, 10, 4);
24995    XRc = extract32(ctx->opcode, 14, 4);
24996    XRd = extract32(ctx->opcode, 18, 4);
24997    optn2 = extract32(ctx->opcode, 22, 2);
24998
24999    gen_load_mxu_gpr(t1, XRb);
25000    tcg_gen_sextract_tl(t0, t1, 0, 16);
25001    tcg_gen_sextract_tl(t1, t1, 16, 16);
25002    gen_load_mxu_gpr(t3, XRc);
25003    tcg_gen_sextract_tl(t2, t3, 0, 16);
25004    tcg_gen_sextract_tl(t3, t3, 16, 16);
25005
25006    switch (optn2) {
25007    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25008        tcg_gen_mul_tl(t3, t1, t3);
25009        tcg_gen_mul_tl(t2, t0, t2);
25010        break;
25011    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25012        tcg_gen_mul_tl(t3, t0, t3);
25013        tcg_gen_mul_tl(t2, t0, t2);
25014        break;
25015    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25016        tcg_gen_mul_tl(t3, t1, t3);
25017        tcg_gen_mul_tl(t2, t1, t2);
25018        break;
25019    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25020        tcg_gen_mul_tl(t3, t0, t3);
25021        tcg_gen_mul_tl(t2, t1, t2);
25022        break;
25023    }
25024    gen_store_mxu_gpr(t3, XRa);
25025    gen_store_mxu_gpr(t2, XRd);
25026
25027    tcg_temp_free(t0);
25028    tcg_temp_free(t1);
25029    tcg_temp_free(t2);
25030    tcg_temp_free(t3);
25031}
25032
25033/*
25034 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25035 *                                           and accumulate
25036 */
25037static void gen_mxu_d16mac(DisasContext *ctx)
25038{
25039    TCGv t0, t1, t2, t3;
25040    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
25041
25042    t0 = tcg_temp_new();
25043    t1 = tcg_temp_new();
25044    t2 = tcg_temp_new();
25045    t3 = tcg_temp_new();
25046
25047    XRa = extract32(ctx->opcode, 6, 4);
25048    XRb = extract32(ctx->opcode, 10, 4);
25049    XRc = extract32(ctx->opcode, 14, 4);
25050    XRd = extract32(ctx->opcode, 18, 4);
25051    optn2 = extract32(ctx->opcode, 22, 2);
25052    aptn2 = extract32(ctx->opcode, 24, 2);
25053
25054    gen_load_mxu_gpr(t1, XRb);
25055    tcg_gen_sextract_tl(t0, t1, 0, 16);
25056    tcg_gen_sextract_tl(t1, t1, 16, 16);
25057
25058    gen_load_mxu_gpr(t3, XRc);
25059    tcg_gen_sextract_tl(t2, t3, 0, 16);
25060    tcg_gen_sextract_tl(t3, t3, 16, 16);
25061
25062    switch (optn2) {
25063    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25064        tcg_gen_mul_tl(t3, t1, t3);
25065        tcg_gen_mul_tl(t2, t0, t2);
25066        break;
25067    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25068        tcg_gen_mul_tl(t3, t0, t3);
25069        tcg_gen_mul_tl(t2, t0, t2);
25070        break;
25071    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25072        tcg_gen_mul_tl(t3, t1, t3);
25073        tcg_gen_mul_tl(t2, t1, t2);
25074        break;
25075    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25076        tcg_gen_mul_tl(t3, t0, t3);
25077        tcg_gen_mul_tl(t2, t1, t2);
25078        break;
25079    }
25080    gen_load_mxu_gpr(t0, XRa);
25081    gen_load_mxu_gpr(t1, XRd);
25082
25083    switch (aptn2) {
25084    case MXU_APTN2_AA:
25085        tcg_gen_add_tl(t3, t0, t3);
25086        tcg_gen_add_tl(t2, t1, t2);
25087        break;
25088    case MXU_APTN2_AS:
25089        tcg_gen_add_tl(t3, t0, t3);
25090        tcg_gen_sub_tl(t2, t1, t2);
25091        break;
25092    case MXU_APTN2_SA:
25093        tcg_gen_sub_tl(t3, t0, t3);
25094        tcg_gen_add_tl(t2, t1, t2);
25095        break;
25096    case MXU_APTN2_SS:
25097        tcg_gen_sub_tl(t3, t0, t3);
25098        tcg_gen_sub_tl(t2, t1, t2);
25099        break;
25100    }
25101    gen_store_mxu_gpr(t3, XRa);
25102    gen_store_mxu_gpr(t2, XRd);
25103
25104    tcg_temp_free(t0);
25105    tcg_temp_free(t1);
25106    tcg_temp_free(t2);
25107    tcg_temp_free(t3);
25108}
25109
25110/*
25111 * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25112 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25113 */
25114static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
25115{
25116    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
25117    uint32_t XRa, XRb, XRc, XRd, sel;
25118
25119    t0 = tcg_temp_new();
25120    t1 = tcg_temp_new();
25121    t2 = tcg_temp_new();
25122    t3 = tcg_temp_new();
25123    t4 = tcg_temp_new();
25124    t5 = tcg_temp_new();
25125    t6 = tcg_temp_new();
25126    t7 = tcg_temp_new();
25127
25128    XRa = extract32(ctx->opcode, 6, 4);
25129    XRb = extract32(ctx->opcode, 10, 4);
25130    XRc = extract32(ctx->opcode, 14, 4);
25131    XRd = extract32(ctx->opcode, 18, 4);
25132    sel = extract32(ctx->opcode, 22, 2);
25133
25134    gen_load_mxu_gpr(t3, XRb);
25135    gen_load_mxu_gpr(t7, XRc);
25136
25137    if (sel == 0x2) {
25138        /* Q8MULSU */
25139        tcg_gen_ext8s_tl(t0, t3);
25140        tcg_gen_shri_tl(t3, t3, 8);
25141        tcg_gen_ext8s_tl(t1, t3);
25142        tcg_gen_shri_tl(t3, t3, 8);
25143        tcg_gen_ext8s_tl(t2, t3);
25144        tcg_gen_shri_tl(t3, t3, 8);
25145        tcg_gen_ext8s_tl(t3, t3);
25146    } else {
25147        /* Q8MUL */
25148        tcg_gen_ext8u_tl(t0, t3);
25149        tcg_gen_shri_tl(t3, t3, 8);
25150        tcg_gen_ext8u_tl(t1, t3);
25151        tcg_gen_shri_tl(t3, t3, 8);
25152        tcg_gen_ext8u_tl(t2, t3);
25153        tcg_gen_shri_tl(t3, t3, 8);
25154        tcg_gen_ext8u_tl(t3, t3);
25155    }
25156
25157    tcg_gen_ext8u_tl(t4, t7);
25158    tcg_gen_shri_tl(t7, t7, 8);
25159    tcg_gen_ext8u_tl(t5, t7);
25160    tcg_gen_shri_tl(t7, t7, 8);
25161    tcg_gen_ext8u_tl(t6, t7);
25162    tcg_gen_shri_tl(t7, t7, 8);
25163    tcg_gen_ext8u_tl(t7, t7);
25164
25165    tcg_gen_mul_tl(t0, t0, t4);
25166    tcg_gen_mul_tl(t1, t1, t5);
25167    tcg_gen_mul_tl(t2, t2, t6);
25168    tcg_gen_mul_tl(t3, t3, t7);
25169
25170    tcg_gen_andi_tl(t0, t0, 0xFFFF);
25171    tcg_gen_andi_tl(t1, t1, 0xFFFF);
25172    tcg_gen_andi_tl(t2, t2, 0xFFFF);
25173    tcg_gen_andi_tl(t3, t3, 0xFFFF);
25174
25175    tcg_gen_shli_tl(t1, t1, 16);
25176    tcg_gen_shli_tl(t3, t3, 16);
25177
25178    tcg_gen_or_tl(t0, t0, t1);
25179    tcg_gen_or_tl(t1, t2, t3);
25180
25181    gen_store_mxu_gpr(t0, XRd);
25182    gen_store_mxu_gpr(t1, XRa);
25183
25184    tcg_temp_free(t0);
25185    tcg_temp_free(t1);
25186    tcg_temp_free(t2);
25187    tcg_temp_free(t3);
25188    tcg_temp_free(t4);
25189    tcg_temp_free(t5);
25190    tcg_temp_free(t6);
25191    tcg_temp_free(t7);
25192}
25193
25194/*
25195 * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
25196 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25197 */
25198static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
25199{
25200    TCGv t0, t1;
25201    uint32_t XRa, Rb, s12, sel;
25202
25203    t0 = tcg_temp_new();
25204    t1 = tcg_temp_new();
25205
25206    XRa = extract32(ctx->opcode, 6, 4);
25207    s12 = extract32(ctx->opcode, 10, 10);
25208    sel = extract32(ctx->opcode, 20, 1);
25209    Rb = extract32(ctx->opcode, 21, 5);
25210
25211    gen_load_gpr(t0, Rb);
25212
25213    tcg_gen_movi_tl(t1, s12);
25214    tcg_gen_shli_tl(t1, t1, 2);
25215    if (s12 & 0x200) {
25216        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
25217    }
25218    tcg_gen_add_tl(t1, t0, t1);
25219    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
25220
25221    if (sel == 1) {
25222        /* S32LDDR */
25223        tcg_gen_bswap32_tl(t1, t1);
25224    }
25225    gen_store_mxu_gpr(t1, XRa);
25226
25227    tcg_temp_free(t0);
25228    tcg_temp_free(t1);
25229}
25230
25231
25232/*
25233 *                 MXU instruction category: logic
25234 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25235 *
25236 *               S32NOR    S32AND    S32OR    S32XOR
25237 */
25238
25239/*
25240 *  S32NOR XRa, XRb, XRc
25241 *    Update XRa with the result of logical bitwise 'nor' operation
25242 *    applied to the content of XRb and XRc.
25243 *
25244 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25245 *  +-----------+---------+-----+-------+-------+-------+-----------+
25246 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25247 *  +-----------+---------+-----+-------+-------+-------+-----------+
25248 */
25249static void gen_mxu_S32NOR(DisasContext *ctx)
25250{
25251    uint32_t pad, XRc, XRb, XRa;
25252
25253    pad = extract32(ctx->opcode, 21, 5);
25254    XRc = extract32(ctx->opcode, 14, 4);
25255    XRb = extract32(ctx->opcode, 10, 4);
25256    XRa = extract32(ctx->opcode,  6, 4);
25257
25258    if (unlikely(pad != 0)) {
25259        /* opcode padding incorrect -> do nothing */
25260    } else if (unlikely(XRa == 0)) {
25261        /* destination is zero register -> do nothing */
25262    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25263        /* both operands zero registers -> just set destination to all 1s */
25264        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
25265    } else if (unlikely(XRb == 0)) {
25266        /* XRb zero register -> just set destination to the negation of XRc */
25267        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25268    } else if (unlikely(XRc == 0)) {
25269        /* XRa zero register -> just set destination to the negation of XRb */
25270        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25271    } else if (unlikely(XRb == XRc)) {
25272        /* both operands same -> just set destination to the negation of XRb */
25273        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25274    } else {
25275        /* the most general case */
25276        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25277    }
25278}
25279
25280/*
25281 *  S32AND XRa, XRb, XRc
25282 *    Update XRa with the result of logical bitwise 'and' operation
25283 *    applied to the content of XRb and XRc.
25284 *
25285 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25286 *  +-----------+---------+-----+-------+-------+-------+-----------+
25287 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25288 *  +-----------+---------+-----+-------+-------+-------+-----------+
25289 */
25290static void gen_mxu_S32AND(DisasContext *ctx)
25291{
25292    uint32_t pad, XRc, XRb, XRa;
25293
25294    pad = extract32(ctx->opcode, 21, 5);
25295    XRc = extract32(ctx->opcode, 14, 4);
25296    XRb = extract32(ctx->opcode, 10, 4);
25297    XRa = extract32(ctx->opcode,  6, 4);
25298
25299    if (unlikely(pad != 0)) {
25300        /* opcode padding incorrect -> do nothing */
25301    } else if (unlikely(XRa == 0)) {
25302        /* destination is zero register -> do nothing */
25303    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25304        /* one of operands zero register -> just set destination to all 0s */
25305        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25306    } else if (unlikely(XRb == XRc)) {
25307        /* both operands same -> just set destination to one of them */
25308        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25309    } else {
25310        /* the most general case */
25311        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25312    }
25313}
25314
25315/*
25316 *  S32OR XRa, XRb, XRc
25317 *    Update XRa with the result of logical bitwise 'or' operation
25318 *    applied to the content of XRb and XRc.
25319 *
25320 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25321 *  +-----------+---------+-----+-------+-------+-------+-----------+
25322 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25323 *  +-----------+---------+-----+-------+-------+-------+-----------+
25324 */
25325static void gen_mxu_S32OR(DisasContext *ctx)
25326{
25327    uint32_t pad, XRc, XRb, XRa;
25328
25329    pad = extract32(ctx->opcode, 21, 5);
25330    XRc = extract32(ctx->opcode, 14, 4);
25331    XRb = extract32(ctx->opcode, 10, 4);
25332    XRa = extract32(ctx->opcode,  6, 4);
25333
25334    if (unlikely(pad != 0)) {
25335        /* opcode padding incorrect -> do nothing */
25336    } else if (unlikely(XRa == 0)) {
25337        /* destination is zero register -> do nothing */
25338    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25339        /* both operands zero registers -> just set destination to all 0s */
25340        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25341    } else if (unlikely(XRb == 0)) {
25342        /* XRb zero register -> just set destination to the content of XRc */
25343        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25344    } else if (unlikely(XRc == 0)) {
25345        /* XRc zero register -> just set destination to the content of XRb */
25346        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25347    } else if (unlikely(XRb == XRc)) {
25348        /* both operands same -> just set destination to one of them */
25349        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25350    } else {
25351        /* the most general case */
25352        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25353    }
25354}
25355
25356/*
25357 *  S32XOR XRa, XRb, XRc
25358 *    Update XRa with the result of logical bitwise 'xor' operation
25359 *    applied to the content of XRb and XRc.
25360 *
25361 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25362 *  +-----------+---------+-----+-------+-------+-------+-----------+
25363 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
25364 *  +-----------+---------+-----+-------+-------+-------+-----------+
25365 */
25366static void gen_mxu_S32XOR(DisasContext *ctx)
25367{
25368    uint32_t pad, XRc, XRb, XRa;
25369
25370    pad = extract32(ctx->opcode, 21, 5);
25371    XRc = extract32(ctx->opcode, 14, 4);
25372    XRb = extract32(ctx->opcode, 10, 4);
25373    XRa = extract32(ctx->opcode,  6, 4);
25374
25375    if (unlikely(pad != 0)) {
25376        /* opcode padding incorrect -> do nothing */
25377    } else if (unlikely(XRa == 0)) {
25378        /* destination is zero register -> do nothing */
25379    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25380        /* both operands zero registers -> just set destination to all 0s */
25381        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25382    } else if (unlikely(XRb == 0)) {
25383        /* XRb zero register -> just set destination to the content of XRc */
25384        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25385    } else if (unlikely(XRc == 0)) {
25386        /* XRc zero register -> just set destination to the content of XRb */
25387        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25388    } else if (unlikely(XRb == XRc)) {
25389        /* both operands same -> just set destination to all 0s */
25390        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25391    } else {
25392        /* the most general case */
25393        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25394    }
25395}
25396
25397
25398/*
25399 *                   MXU instruction category max/min
25400 *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25401 *
25402 *                     S32MAX     D16MAX     Q8MAX
25403 *                     S32MIN     D16MIN     Q8MIN
25404 */
25405
25406/*
25407 *  S32MAX XRa, XRb, XRc
25408 *    Update XRa with the maximum of signed 32-bit integers contained
25409 *    in XRb and XRc.
25410 *
25411 *  S32MIN XRa, XRb, XRc
25412 *    Update XRa with the minimum of signed 32-bit integers contained
25413 *    in XRb and XRc.
25414 *
25415 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25416 *  +-----------+---------+-----+-------+-------+-------+-----------+
25417 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25418 *  +-----------+---------+-----+-------+-------+-------+-----------+
25419 */
25420static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25421{
25422    uint32_t pad, opc, XRc, XRb, XRa;
25423
25424    pad = extract32(ctx->opcode, 21, 5);
25425    opc = extract32(ctx->opcode, 18, 3);
25426    XRc = extract32(ctx->opcode, 14, 4);
25427    XRb = extract32(ctx->opcode, 10, 4);
25428    XRa = extract32(ctx->opcode,  6, 4);
25429
25430    if (unlikely(pad != 0)) {
25431        /* opcode padding incorrect -> do nothing */
25432    } else if (unlikely(XRa == 0)) {
25433        /* destination is zero register -> do nothing */
25434    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25435        /* both operands zero registers -> just set destination to zero */
25436        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25437    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25438        /* exactly one operand is zero register - find which one is not...*/
25439        uint32_t XRx = XRb ? XRb : XRc;
25440        /* ...and do max/min operation with one operand 0 */
25441        if (opc == OPC_MXU_S32MAX) {
25442            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25443        } else {
25444            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25445        }
25446    } else if (unlikely(XRb == XRc)) {
25447        /* both operands same -> just set destination to one of them */
25448        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25449    } else {
25450        /* the most general case */
25451        if (opc == OPC_MXU_S32MAX) {
25452            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25453                                               mxu_gpr[XRc - 1]);
25454        } else {
25455            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25456                                               mxu_gpr[XRc - 1]);
25457        }
25458    }
25459}
25460
25461/*
25462 *  D16MAX
25463 *    Update XRa with the 16-bit-wise maximums of signed integers
25464 *    contained in XRb and XRc.
25465 *
25466 *  D16MIN
25467 *    Update XRa with the 16-bit-wise minimums of signed integers
25468 *    contained in XRb and XRc.
25469 *
25470 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25471 *  +-----------+---------+-----+-------+-------+-------+-----------+
25472 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25473 *  +-----------+---------+-----+-------+-------+-------+-----------+
25474 */
25475static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25476{
25477    uint32_t pad, opc, XRc, XRb, XRa;
25478
25479    pad = extract32(ctx->opcode, 21, 5);
25480    opc = extract32(ctx->opcode, 18, 3);
25481    XRc = extract32(ctx->opcode, 14, 4);
25482    XRb = extract32(ctx->opcode, 10, 4);
25483    XRa = extract32(ctx->opcode,  6, 4);
25484
25485    if (unlikely(pad != 0)) {
25486        /* opcode padding incorrect -> do nothing */
25487    } else if (unlikely(XRc == 0)) {
25488        /* destination is zero register -> do nothing */
25489    } else if (unlikely((XRb == 0) && (XRa == 0))) {
25490        /* both operands zero registers -> just set destination to zero */
25491        tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25492    } else if (unlikely((XRb == 0) || (XRa == 0))) {
25493        /* exactly one operand is zero register - find which one is not...*/
25494        uint32_t XRx = XRb ? XRb : XRc;
25495        /* ...and do half-word-wise max/min with one operand 0 */
25496        TCGv_i32 t0 = tcg_temp_new();
25497        TCGv_i32 t1 = tcg_const_i32(0);
25498
25499        /* the left half-word first */
25500        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25501        if (opc == OPC_MXU_D16MAX) {
25502            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25503        } else {
25504            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25505        }
25506
25507        /* the right half-word */
25508        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25509        /* move half-words to the leftmost position */
25510        tcg_gen_shli_i32(t0, t0, 16);
25511        /* t0 will be max/min of t0 and t1 */
25512        if (opc == OPC_MXU_D16MAX) {
25513            tcg_gen_smax_i32(t0, t0, t1);
25514        } else {
25515            tcg_gen_smin_i32(t0, t0, t1);
25516        }
25517        /* return resulting half-words to its original position */
25518        tcg_gen_shri_i32(t0, t0, 16);
25519        /* finaly update the destination */
25520        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25521
25522        tcg_temp_free(t1);
25523        tcg_temp_free(t0);
25524    } else if (unlikely(XRb == XRc)) {
25525        /* both operands same -> just set destination to one of them */
25526        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25527    } else {
25528        /* the most general case */
25529        TCGv_i32 t0 = tcg_temp_new();
25530        TCGv_i32 t1 = tcg_temp_new();
25531
25532        /* the left half-word first */
25533        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25534        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25535        if (opc == OPC_MXU_D16MAX) {
25536            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25537        } else {
25538            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25539        }
25540
25541        /* the right half-word */
25542        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25543        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25544        /* move half-words to the leftmost position */
25545        tcg_gen_shli_i32(t0, t0, 16);
25546        tcg_gen_shli_i32(t1, t1, 16);
25547        /* t0 will be max/min of t0 and t1 */
25548        if (opc == OPC_MXU_D16MAX) {
25549            tcg_gen_smax_i32(t0, t0, t1);
25550        } else {
25551            tcg_gen_smin_i32(t0, t0, t1);
25552        }
25553        /* return resulting half-words to its original position */
25554        tcg_gen_shri_i32(t0, t0, 16);
25555        /* finaly update the destination */
25556        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25557
25558        tcg_temp_free(t1);
25559        tcg_temp_free(t0);
25560    }
25561}
25562
25563/*
25564 *  Q8MAX
25565 *    Update XRa with the 8-bit-wise maximums of signed integers
25566 *    contained in XRb and XRc.
25567 *
25568 *  Q8MIN
25569 *    Update XRa with the 8-bit-wise minimums of signed integers
25570 *    contained in XRb and XRc.
25571 *
25572 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25573 *  +-----------+---------+-----+-------+-------+-------+-----------+
25574 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25575 *  +-----------+---------+-----+-------+-------+-------+-----------+
25576 */
25577static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25578{
25579    uint32_t pad, opc, XRc, XRb, XRa;
25580
25581    pad = extract32(ctx->opcode, 21, 5);
25582    opc = extract32(ctx->opcode, 18, 3);
25583    XRc = extract32(ctx->opcode, 14, 4);
25584    XRb = extract32(ctx->opcode, 10, 4);
25585    XRa = extract32(ctx->opcode,  6, 4);
25586
25587    if (unlikely(pad != 0)) {
25588        /* opcode padding incorrect -> do nothing */
25589    } else if (unlikely(XRa == 0)) {
25590        /* destination is zero register -> do nothing */
25591    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25592        /* both operands zero registers -> just set destination to zero */
25593        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25594    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25595        /* exactly one operand is zero register - make it be the first...*/
25596        uint32_t XRx = XRb ? XRb : XRc;
25597        /* ...and do byte-wise max/min with one operand 0 */
25598        TCGv_i32 t0 = tcg_temp_new();
25599        TCGv_i32 t1 = tcg_const_i32(0);
25600        int32_t i;
25601
25602        /* the leftmost byte (byte 3) first */
25603        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25604        if (opc == OPC_MXU_Q8MAX) {
25605            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25606        } else {
25607            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25608        }
25609
25610        /* bytes 2, 1, 0 */
25611        for (i = 2; i >= 0; i--) {
25612            /* extract the byte */
25613            tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25614            /* move the byte to the leftmost position */
25615            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25616            /* t0 will be max/min of t0 and t1 */
25617            if (opc == OPC_MXU_Q8MAX) {
25618                tcg_gen_smax_i32(t0, t0, t1);
25619            } else {
25620                tcg_gen_smin_i32(t0, t0, t1);
25621            }
25622            /* return resulting byte to its original position */
25623            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25624            /* finaly update the destination */
25625            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25626        }
25627
25628        tcg_temp_free(t1);
25629        tcg_temp_free(t0);
25630    } else if (unlikely(XRb == XRc)) {
25631        /* both operands same -> just set destination to one of them */
25632        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25633    } else {
25634        /* the most general case */
25635        TCGv_i32 t0 = tcg_temp_new();
25636        TCGv_i32 t1 = tcg_temp_new();
25637        int32_t i;
25638
25639        /* the leftmost bytes (bytes 3) first */
25640        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25641        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25642        if (opc == OPC_MXU_Q8MAX) {
25643            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25644        } else {
25645            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25646        }
25647
25648        /* bytes 2, 1, 0 */
25649        for (i = 2; i >= 0; i--) {
25650            /* extract corresponding bytes */
25651            tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25652            tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25653            /* move the bytes to the leftmost position */
25654            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25655            tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25656            /* t0 will be max/min of t0 and t1 */
25657            if (opc == OPC_MXU_Q8MAX) {
25658                tcg_gen_smax_i32(t0, t0, t1);
25659            } else {
25660                tcg_gen_smin_i32(t0, t0, t1);
25661            }
25662            /* return resulting byte to its original position */
25663            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25664            /* finaly update the destination */
25665            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25666        }
25667
25668        tcg_temp_free(t1);
25669        tcg_temp_free(t0);
25670    }
25671}
25672
25673
25674/*
25675 *                 MXU instruction category: align
25676 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25677 *
25678 *                       S32ALN     S32ALNI
25679 */
25680
25681/*
25682 *  S32ALNI XRc, XRb, XRa, optn3
25683 *    Arrange bytes from XRb and XRc according to one of five sets of
25684 *    rules determined by optn3, and place the result in XRa.
25685 *
25686 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25687 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25688 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25689 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25690 *
25691 */
25692static void gen_mxu_S32ALNI(DisasContext *ctx)
25693{
25694    uint32_t optn3, pad, XRc, XRb, XRa;
25695
25696    optn3 = extract32(ctx->opcode,  23, 3);
25697    pad   = extract32(ctx->opcode,  21, 2);
25698    XRc   = extract32(ctx->opcode, 14, 4);
25699    XRb   = extract32(ctx->opcode, 10, 4);
25700    XRa   = extract32(ctx->opcode,  6, 4);
25701
25702    if (unlikely(pad != 0)) {
25703        /* opcode padding incorrect -> do nothing */
25704    } else if (unlikely(XRa == 0)) {
25705        /* destination is zero register -> do nothing */
25706    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25707        /* both operands zero registers -> just set destination to all 0s */
25708        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25709    } else if (unlikely(XRb == 0)) {
25710        /* XRb zero register -> just appropriatelly shift XRc into XRa */
25711        switch (optn3) {
25712        case MXU_OPTN3_PTN0:
25713            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25714            break;
25715        case MXU_OPTN3_PTN1:
25716        case MXU_OPTN3_PTN2:
25717        case MXU_OPTN3_PTN3:
25718            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25719                             8 * (4 - optn3));
25720            break;
25721        case MXU_OPTN3_PTN4:
25722            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25723            break;
25724        }
25725    } else if (unlikely(XRc == 0)) {
25726        /* XRc zero register -> just appropriatelly shift XRb into XRa */
25727        switch (optn3) {
25728        case MXU_OPTN3_PTN0:
25729            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25730            break;
25731        case MXU_OPTN3_PTN1:
25732        case MXU_OPTN3_PTN2:
25733        case MXU_OPTN3_PTN3:
25734            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25735            break;
25736        case MXU_OPTN3_PTN4:
25737            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25738            break;
25739        }
25740    } else if (unlikely(XRb == XRc)) {
25741        /* both operands same -> just rotation or moving from any of them */
25742        switch (optn3) {
25743        case MXU_OPTN3_PTN0:
25744        case MXU_OPTN3_PTN4:
25745            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25746            break;
25747        case MXU_OPTN3_PTN1:
25748        case MXU_OPTN3_PTN2:
25749        case MXU_OPTN3_PTN3:
25750            tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25751            break;
25752        }
25753    } else {
25754        /* the most general case */
25755        switch (optn3) {
25756        case MXU_OPTN3_PTN0:
25757            {
25758                /*                                         */
25759                /*         XRb                XRc          */
25760                /*  +---------------+                      */
25761                /*  | A   B   C   D |    E   F   G   H     */
25762                /*  +-------+-------+                      */
25763                /*          |                              */
25764                /*         XRa                             */
25765                /*                                         */
25766
25767                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25768            }
25769            break;
25770        case MXU_OPTN3_PTN1:
25771            {
25772                /*                                         */
25773                /*         XRb                 XRc         */
25774                /*      +-------------------+              */
25775                /*    A | B   C   D       E | F   G   H    */
25776                /*      +---------+---------+              */
25777                /*                |                        */
25778                /*               XRa                       */
25779                /*                                         */
25780
25781                TCGv_i32 t0 = tcg_temp_new();
25782                TCGv_i32 t1 = tcg_temp_new();
25783
25784                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25785                tcg_gen_shli_i32(t0, t0, 8);
25786
25787                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25788                tcg_gen_shri_i32(t1, t1, 24);
25789
25790                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25791
25792                tcg_temp_free(t1);
25793                tcg_temp_free(t0);
25794            }
25795            break;
25796        case MXU_OPTN3_PTN2:
25797            {
25798                /*                                         */
25799                /*         XRb                 XRc         */
25800                /*          +-------------------+          */
25801                /*    A   B | C   D       E   F | G   H    */
25802                /*          +---------+---------+          */
25803                /*                    |                    */
25804                /*                   XRa                   */
25805                /*                                         */
25806
25807                TCGv_i32 t0 = tcg_temp_new();
25808                TCGv_i32 t1 = tcg_temp_new();
25809
25810                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25811                tcg_gen_shli_i32(t0, t0, 16);
25812
25813                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25814                tcg_gen_shri_i32(t1, t1, 16);
25815
25816                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25817
25818                tcg_temp_free(t1);
25819                tcg_temp_free(t0);
25820            }
25821            break;
25822        case MXU_OPTN3_PTN3:
25823            {
25824                /*                                         */
25825                /*         XRb                 XRc         */
25826                /*              +-------------------+      */
25827                /*    A   B   C | D       E   F   G | H    */
25828                /*              +---------+---------+      */
25829                /*                        |                */
25830                /*                       XRa               */
25831                /*                                         */
25832
25833                TCGv_i32 t0 = tcg_temp_new();
25834                TCGv_i32 t1 = tcg_temp_new();
25835
25836                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25837                tcg_gen_shli_i32(t0, t0, 24);
25838
25839                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25840                tcg_gen_shri_i32(t1, t1, 8);
25841
25842                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25843
25844                tcg_temp_free(t1);
25845                tcg_temp_free(t0);
25846            }
25847            break;
25848        case MXU_OPTN3_PTN4:
25849            {
25850                /*                                         */
25851                /*         XRb                 XRc         */
25852                /*                     +---------------+   */
25853                /*    A   B   C   D    | E   F   G   H |   */
25854                /*                     +-------+-------+   */
25855                /*                             |           */
25856                /*                            XRa          */
25857                /*                                         */
25858
25859                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25860            }
25861            break;
25862        }
25863    }
25864}
25865
25866
25867/*
25868 * Decoding engine for MXU
25869 * =======================
25870 */
25871
25872/*
25873 *
25874 * Decode MXU pool00
25875 *
25876 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25877 *  +-----------+---------+-----+-------+-------+-------+-----------+
25878 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25879 *  +-----------+---------+-----+-------+-------+-------+-----------+
25880 *
25881 */
25882static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25883{
25884    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25885
25886    switch (opcode) {
25887    case OPC_MXU_S32MAX:
25888    case OPC_MXU_S32MIN:
25889        gen_mxu_S32MAX_S32MIN(ctx);
25890        break;
25891    case OPC_MXU_D16MAX:
25892    case OPC_MXU_D16MIN:
25893        gen_mxu_D16MAX_D16MIN(ctx);
25894        break;
25895    case OPC_MXU_Q8MAX:
25896    case OPC_MXU_Q8MIN:
25897        gen_mxu_Q8MAX_Q8MIN(ctx);
25898        break;
25899    case OPC_MXU_Q8SLT:
25900        /* TODO: Implement emulation of Q8SLT instruction. */
25901        MIPS_INVAL("OPC_MXU_Q8SLT");
25902        generate_exception_end(ctx, EXCP_RI);
25903        break;
25904    case OPC_MXU_Q8SLTU:
25905        /* TODO: Implement emulation of Q8SLTU instruction. */
25906        MIPS_INVAL("OPC_MXU_Q8SLTU");
25907        generate_exception_end(ctx, EXCP_RI);
25908        break;
25909    default:
25910        MIPS_INVAL("decode_opc_mxu");
25911        generate_exception_end(ctx, EXCP_RI);
25912        break;
25913    }
25914}
25915
25916/*
25917 *
25918 * Decode MXU pool01
25919 *
25920 *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25921 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25922 *  +-----------+---------+-----+-------+-------+-------+-----------+
25923 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25924 *  +-----------+---------+-----+-------+-------+-------+-----------+
25925 *
25926 *  Q8ADD:
25927 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25928 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25929 *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25930 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25931 *
25932 */
25933static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25934{
25935    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25936
25937    switch (opcode) {
25938    case OPC_MXU_S32SLT:
25939        /* TODO: Implement emulation of S32SLT instruction. */
25940        MIPS_INVAL("OPC_MXU_S32SLT");
25941        generate_exception_end(ctx, EXCP_RI);
25942        break;
25943    case OPC_MXU_D16SLT:
25944        /* TODO: Implement emulation of D16SLT instruction. */
25945        MIPS_INVAL("OPC_MXU_D16SLT");
25946        generate_exception_end(ctx, EXCP_RI);
25947        break;
25948    case OPC_MXU_D16AVG:
25949        /* TODO: Implement emulation of D16AVG instruction. */
25950        MIPS_INVAL("OPC_MXU_D16AVG");
25951        generate_exception_end(ctx, EXCP_RI);
25952        break;
25953    case OPC_MXU_D16AVGR:
25954        /* TODO: Implement emulation of D16AVGR instruction. */
25955        MIPS_INVAL("OPC_MXU_D16AVGR");
25956        generate_exception_end(ctx, EXCP_RI);
25957        break;
25958    case OPC_MXU_Q8AVG:
25959        /* TODO: Implement emulation of Q8AVG instruction. */
25960        MIPS_INVAL("OPC_MXU_Q8AVG");
25961        generate_exception_end(ctx, EXCP_RI);
25962        break;
25963    case OPC_MXU_Q8AVGR:
25964        /* TODO: Implement emulation of Q8AVGR instruction. */
25965        MIPS_INVAL("OPC_MXU_Q8AVGR");
25966        generate_exception_end(ctx, EXCP_RI);
25967        break;
25968    case OPC_MXU_Q8ADD:
25969        /* TODO: Implement emulation of Q8ADD instruction. */
25970        MIPS_INVAL("OPC_MXU_Q8ADD");
25971        generate_exception_end(ctx, EXCP_RI);
25972        break;
25973    default:
25974        MIPS_INVAL("decode_opc_mxu");
25975        generate_exception_end(ctx, EXCP_RI);
25976        break;
25977    }
25978}
25979
25980/*
25981 *
25982 * Decode MXU pool02
25983 *
25984 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25985 *  +-----------+---------+-----+-------+-------+-------+-----------+
25986 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
25987 *  +-----------+---------+-----+-------+-------+-------+-----------+
25988 *
25989 */
25990static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25991{
25992    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25993
25994    switch (opcode) {
25995    case OPC_MXU_S32CPS:
25996        /* TODO: Implement emulation of S32CPS instruction. */
25997        MIPS_INVAL("OPC_MXU_S32CPS");
25998        generate_exception_end(ctx, EXCP_RI);
25999        break;
26000    case OPC_MXU_D16CPS:
26001        /* TODO: Implement emulation of D16CPS instruction. */
26002        MIPS_INVAL("OPC_MXU_D16CPS");
26003        generate_exception_end(ctx, EXCP_RI);
26004        break;
26005    case OPC_MXU_Q8ABD:
26006        /* TODO: Implement emulation of Q8ABD instruction. */
26007        MIPS_INVAL("OPC_MXU_Q8ABD");
26008        generate_exception_end(ctx, EXCP_RI);
26009        break;
26010    case OPC_MXU_Q16SAT:
26011        /* TODO: Implement emulation of Q16SAT instruction. */
26012        MIPS_INVAL("OPC_MXU_Q16SAT");
26013        generate_exception_end(ctx, EXCP_RI);
26014        break;
26015    default:
26016        MIPS_INVAL("decode_opc_mxu");
26017        generate_exception_end(ctx, EXCP_RI);
26018        break;
26019    }
26020}
26021
26022/*
26023 *
26024 * Decode MXU pool03
26025 *
26026 *  D16MULF:
26027 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26028 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26029 *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
26030 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26031 *
26032 *  D16MULE:
26033 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26034 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26035 *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
26036 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26037 *
26038 */
26039static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
26040{
26041    uint32_t opcode = extract32(ctx->opcode, 24, 2);
26042
26043    switch (opcode) {
26044    case OPC_MXU_D16MULF:
26045        /* TODO: Implement emulation of D16MULF instruction. */
26046        MIPS_INVAL("OPC_MXU_D16MULF");
26047        generate_exception_end(ctx, EXCP_RI);
26048        break;
26049    case OPC_MXU_D16MULE:
26050        /* TODO: Implement emulation of D16MULE instruction. */
26051        MIPS_INVAL("OPC_MXU_D16MULE");
26052        generate_exception_end(ctx, EXCP_RI);
26053        break;
26054    default:
26055        MIPS_INVAL("decode_opc_mxu");
26056        generate_exception_end(ctx, EXCP_RI);
26057        break;
26058    }
26059}
26060
26061/*
26062 *
26063 * Decode MXU pool04
26064 *
26065 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26066 *  +-----------+---------+-+-------------------+-------+-----------+
26067 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
26068 *  +-----------+---------+-+-------------------+-------+-----------+
26069 *
26070 */
26071static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
26072{
26073    uint32_t opcode = extract32(ctx->opcode, 20, 1);
26074
26075    switch (opcode) {
26076    case OPC_MXU_S32LDD:
26077    case OPC_MXU_S32LDDR:
26078        gen_mxu_s32ldd_s32lddr(ctx);
26079        break;
26080    default:
26081        MIPS_INVAL("decode_opc_mxu");
26082        generate_exception_end(ctx, EXCP_RI);
26083        break;
26084    }
26085}
26086
26087/*
26088 *
26089 * Decode MXU pool05
26090 *
26091 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26092 *  +-----------+---------+-+-------------------+-------+-----------+
26093 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
26094 *  +-----------+---------+-+-------------------+-------+-----------+
26095 *
26096 */
26097static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
26098{
26099    uint32_t opcode = extract32(ctx->opcode, 20, 1);
26100
26101    switch (opcode) {
26102    case OPC_MXU_S32STD:
26103        /* TODO: Implement emulation of S32STD instruction. */
26104        MIPS_INVAL("OPC_MXU_S32STD");
26105        generate_exception_end(ctx, EXCP_RI);
26106        break;
26107    case OPC_MXU_S32STDR:
26108        /* TODO: Implement emulation of S32STDR instruction. */
26109        MIPS_INVAL("OPC_MXU_S32STDR");
26110        generate_exception_end(ctx, EXCP_RI);
26111        break;
26112    default:
26113        MIPS_INVAL("decode_opc_mxu");
26114        generate_exception_end(ctx, EXCP_RI);
26115        break;
26116    }
26117}
26118
26119/*
26120 *
26121 * Decode MXU pool06
26122 *
26123 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26124 *  +-----------+---------+---------+---+-------+-------+-----------+
26125 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
26126 *  +-----------+---------+---------+---+-------+-------+-----------+
26127 *
26128 */
26129static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
26130{
26131    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26132
26133    switch (opcode) {
26134    case OPC_MXU_S32LDDV:
26135        /* TODO: Implement emulation of S32LDDV instruction. */
26136        MIPS_INVAL("OPC_MXU_S32LDDV");
26137        generate_exception_end(ctx, EXCP_RI);
26138        break;
26139    case OPC_MXU_S32LDDVR:
26140        /* TODO: Implement emulation of S32LDDVR instruction. */
26141        MIPS_INVAL("OPC_MXU_S32LDDVR");
26142        generate_exception_end(ctx, EXCP_RI);
26143        break;
26144    default:
26145        MIPS_INVAL("decode_opc_mxu");
26146        generate_exception_end(ctx, EXCP_RI);
26147        break;
26148    }
26149}
26150
26151/*
26152 *
26153 * Decode MXU pool07
26154 *
26155 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26156 *  +-----------+---------+---------+---+-------+-------+-----------+
26157 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
26158 *  +-----------+---------+---------+---+-------+-------+-----------+
26159 *
26160 */
26161static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
26162{
26163    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26164
26165    switch (opcode) {
26166    case OPC_MXU_S32STDV:
26167        /* TODO: Implement emulation of S32TDV instruction. */
26168        MIPS_INVAL("OPC_MXU_S32TDV");
26169        generate_exception_end(ctx, EXCP_RI);
26170        break;
26171    case OPC_MXU_S32STDVR:
26172        /* TODO: Implement emulation of S32TDVR instruction. */
26173        MIPS_INVAL("OPC_MXU_S32TDVR");
26174        generate_exception_end(ctx, EXCP_RI);
26175        break;
26176    default:
26177        MIPS_INVAL("decode_opc_mxu");
26178        generate_exception_end(ctx, EXCP_RI);
26179        break;
26180    }
26181}
26182
26183/*
26184 *
26185 * Decode MXU pool08
26186 *
26187 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26188 *  +-----------+---------+-+-------------------+-------+-----------+
26189 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
26190 *  +-----------+---------+-+-------------------+-------+-----------+
26191 *
26192 */
26193static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
26194{
26195    uint32_t opcode = extract32(ctx->opcode, 20, 1);
26196
26197    switch (opcode) {
26198    case OPC_MXU_S32LDI:
26199        /* TODO: Implement emulation of S32LDI instruction. */
26200        MIPS_INVAL("OPC_MXU_S32LDI");
26201        generate_exception_end(ctx, EXCP_RI);
26202        break;
26203    case OPC_MXU_S32LDIR:
26204        /* TODO: Implement emulation of S32LDIR instruction. */
26205        MIPS_INVAL("OPC_MXU_S32LDIR");
26206        generate_exception_end(ctx, EXCP_RI);
26207        break;
26208    default:
26209        MIPS_INVAL("decode_opc_mxu");
26210        generate_exception_end(ctx, EXCP_RI);
26211        break;
26212    }
26213}
26214
26215/*
26216 *
26217 * Decode MXU pool09
26218 *
26219 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26220 *  +-----------+---------+-+-------------------+-------+-----------+
26221 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
26222 *  +-----------+---------+-+-------------------+-------+-----------+
26223 *
26224 */
26225static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
26226{
26227    uint32_t opcode = extract32(ctx->opcode, 5, 0);
26228
26229    switch (opcode) {
26230    case OPC_MXU_S32SDI:
26231        /* TODO: Implement emulation of S32SDI instruction. */
26232        MIPS_INVAL("OPC_MXU_S32SDI");
26233        generate_exception_end(ctx, EXCP_RI);
26234        break;
26235    case OPC_MXU_S32SDIR:
26236        /* TODO: Implement emulation of S32SDIR instruction. */
26237        MIPS_INVAL("OPC_MXU_S32SDIR");
26238        generate_exception_end(ctx, EXCP_RI);
26239        break;
26240    default:
26241        MIPS_INVAL("decode_opc_mxu");
26242        generate_exception_end(ctx, EXCP_RI);
26243        break;
26244    }
26245}
26246
26247/*
26248 *
26249 * Decode MXU pool10
26250 *
26251 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26252 *  +-----------+---------+---------+---+-------+-------+-----------+
26253 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
26254 *  +-----------+---------+---------+---+-------+-------+-----------+
26255 *
26256 */
26257static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
26258{
26259    uint32_t opcode = extract32(ctx->opcode, 5, 0);
26260
26261    switch (opcode) {
26262    case OPC_MXU_S32LDIV:
26263        /* TODO: Implement emulation of S32LDIV instruction. */
26264        MIPS_INVAL("OPC_MXU_S32LDIV");
26265        generate_exception_end(ctx, EXCP_RI);
26266        break;
26267    case OPC_MXU_S32LDIVR:
26268        /* TODO: Implement emulation of S32LDIVR instruction. */
26269        MIPS_INVAL("OPC_MXU_S32LDIVR");
26270        generate_exception_end(ctx, EXCP_RI);
26271        break;
26272    default:
26273        MIPS_INVAL("decode_opc_mxu");
26274        generate_exception_end(ctx, EXCP_RI);
26275        break;
26276    }
26277}
26278
26279/*
26280 *
26281 * Decode MXU pool11
26282 *
26283 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26284 *  +-----------+---------+---------+---+-------+-------+-----------+
26285 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
26286 *  +-----------+---------+---------+---+-------+-------+-----------+
26287 *
26288 */
26289static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
26290{
26291    uint32_t opcode = extract32(ctx->opcode, 10, 4);
26292
26293    switch (opcode) {
26294    case OPC_MXU_S32SDIV:
26295        /* TODO: Implement emulation of S32SDIV instruction. */
26296        MIPS_INVAL("OPC_MXU_S32SDIV");
26297        generate_exception_end(ctx, EXCP_RI);
26298        break;
26299    case OPC_MXU_S32SDIVR:
26300        /* TODO: Implement emulation of S32SDIVR instruction. */
26301        MIPS_INVAL("OPC_MXU_S32SDIVR");
26302        generate_exception_end(ctx, EXCP_RI);
26303        break;
26304    default:
26305        MIPS_INVAL("decode_opc_mxu");
26306        generate_exception_end(ctx, EXCP_RI);
26307        break;
26308    }
26309}
26310
26311/*
26312 *
26313 * Decode MXU pool12
26314 *
26315 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26316 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26317 *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
26318 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26319 *
26320 */
26321static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26322{
26323    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26324
26325    switch (opcode) {
26326    case OPC_MXU_D32ACC:
26327        /* TODO: Implement emulation of D32ACC instruction. */
26328        MIPS_INVAL("OPC_MXU_D32ACC");
26329        generate_exception_end(ctx, EXCP_RI);
26330        break;
26331    case OPC_MXU_D32ACCM:
26332        /* TODO: Implement emulation of D32ACCM instruction. */
26333        MIPS_INVAL("OPC_MXU_D32ACCM");
26334        generate_exception_end(ctx, EXCP_RI);
26335        break;
26336    case OPC_MXU_D32ASUM:
26337        /* TODO: Implement emulation of D32ASUM instruction. */
26338        MIPS_INVAL("OPC_MXU_D32ASUM");
26339        generate_exception_end(ctx, EXCP_RI);
26340        break;
26341    default:
26342        MIPS_INVAL("decode_opc_mxu");
26343        generate_exception_end(ctx, EXCP_RI);
26344        break;
26345    }
26346}
26347
26348/*
26349 *
26350 * Decode MXU pool13
26351 *
26352 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26353 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26354 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
26355 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26356 *
26357 */
26358static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26359{
26360    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26361
26362    switch (opcode) {
26363    case OPC_MXU_Q16ACC:
26364        /* TODO: Implement emulation of Q16ACC instruction. */
26365        MIPS_INVAL("OPC_MXU_Q16ACC");
26366        generate_exception_end(ctx, EXCP_RI);
26367        break;
26368    case OPC_MXU_Q16ACCM:
26369        /* TODO: Implement emulation of Q16ACCM instruction. */
26370        MIPS_INVAL("OPC_MXU_Q16ACCM");
26371        generate_exception_end(ctx, EXCP_RI);
26372        break;
26373    case OPC_MXU_Q16ASUM:
26374        /* TODO: Implement emulation of Q16ASUM instruction. */
26375        MIPS_INVAL("OPC_MXU_Q16ASUM");
26376        generate_exception_end(ctx, EXCP_RI);
26377        break;
26378    default:
26379        MIPS_INVAL("decode_opc_mxu");
26380        generate_exception_end(ctx, EXCP_RI);
26381        break;
26382    }
26383}
26384
26385/*
26386 *
26387 * Decode MXU pool14
26388 *
26389 *  Q8ADDE, Q8ACCE:
26390 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26391 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26392 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
26393 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26394 *
26395 *  D8SUM, D8SUMC:
26396 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26397 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26398 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
26399 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26400 *
26401 */
26402static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26403{
26404    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26405
26406    switch (opcode) {
26407    case OPC_MXU_Q8ADDE:
26408        /* TODO: Implement emulation of Q8ADDE instruction. */
26409        MIPS_INVAL("OPC_MXU_Q8ADDE");
26410        generate_exception_end(ctx, EXCP_RI);
26411        break;
26412    case OPC_MXU_D8SUM:
26413        /* TODO: Implement emulation of D8SUM instruction. */
26414        MIPS_INVAL("OPC_MXU_D8SUM");
26415        generate_exception_end(ctx, EXCP_RI);
26416        break;
26417    case OPC_MXU_D8SUMC:
26418        /* TODO: Implement emulation of D8SUMC instruction. */
26419        MIPS_INVAL("OPC_MXU_D8SUMC");
26420        generate_exception_end(ctx, EXCP_RI);
26421        break;
26422    default:
26423        MIPS_INVAL("decode_opc_mxu");
26424        generate_exception_end(ctx, EXCP_RI);
26425        break;
26426    }
26427}
26428
26429/*
26430 *
26431 * Decode MXU pool15
26432 *
26433 *  S32MUL, S32MULU, S32EXTRV:
26434 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26435 *  +-----------+---------+---------+---+-------+-------+-----------+
26436 *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
26437 *  +-----------+---------+---------+---+-------+-------+-----------+
26438 *
26439 *  S32EXTR:
26440 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26441 *  +-----------+---------+---------+---+-------+-------+-----------+
26442 *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
26443 *  +-----------+---------+---------+---+-------+-------+-----------+
26444 *
26445 */
26446static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26447{
26448    uint32_t opcode = extract32(ctx->opcode, 14, 2);
26449
26450    switch (opcode) {
26451    case OPC_MXU_S32MUL:
26452        /* TODO: Implement emulation of S32MUL instruction. */
26453        MIPS_INVAL("OPC_MXU_S32MUL");
26454        generate_exception_end(ctx, EXCP_RI);
26455        break;
26456    case OPC_MXU_S32MULU:
26457        /* TODO: Implement emulation of S32MULU instruction. */
26458        MIPS_INVAL("OPC_MXU_S32MULU");
26459        generate_exception_end(ctx, EXCP_RI);
26460        break;
26461    case OPC_MXU_S32EXTR:
26462        /* TODO: Implement emulation of S32EXTR instruction. */
26463        MIPS_INVAL("OPC_MXU_S32EXTR");
26464        generate_exception_end(ctx, EXCP_RI);
26465        break;
26466    case OPC_MXU_S32EXTRV:
26467        /* TODO: Implement emulation of S32EXTRV instruction. */
26468        MIPS_INVAL("OPC_MXU_S32EXTRV");
26469        generate_exception_end(ctx, EXCP_RI);
26470        break;
26471    default:
26472        MIPS_INVAL("decode_opc_mxu");
26473        generate_exception_end(ctx, EXCP_RI);
26474        break;
26475    }
26476}
26477
26478/*
26479 *
26480 * Decode MXU pool16
26481 *
26482 *  D32SARW:
26483 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26484 *  +-----------+---------+-----+-------+-------+-------+-----------+
26485 *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26486 *  +-----------+---------+-----+-------+-------+-------+-----------+
26487 *
26488 *  S32ALN:
26489 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26490 *  +-----------+---------+-----+-------+-------+-------+-----------+
26491 *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26492 *  +-----------+---------+-----+-------+-------+-------+-----------+
26493 *
26494 *  S32ALNI:
26495 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26496 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26497 *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26498 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26499 *
26500 *  S32LUI:
26501 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26502 *  +-----------+-----+---+-----+-------+---------------+-----------+
26503 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26504 *  +-----------+-----+---+-----+-------+---------------+-----------+
26505 *
26506 *  S32NOR, S32AND, S32OR, S32XOR:
26507 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26508 *  +-----------+---------+-----+-------+-------+-------+-----------+
26509 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26510 *  +-----------+---------+-----+-------+-------+-------+-----------+
26511 *
26512 */
26513static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26514{
26515    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26516
26517    switch (opcode) {
26518    case OPC_MXU_D32SARW:
26519        /* TODO: Implement emulation of D32SARW instruction. */
26520        MIPS_INVAL("OPC_MXU_D32SARW");
26521        generate_exception_end(ctx, EXCP_RI);
26522        break;
26523    case OPC_MXU_S32ALN:
26524        /* TODO: Implement emulation of S32ALN instruction. */
26525        MIPS_INVAL("OPC_MXU_S32ALN");
26526        generate_exception_end(ctx, EXCP_RI);
26527        break;
26528    case OPC_MXU_S32ALNI:
26529        gen_mxu_S32ALNI(ctx);
26530        break;
26531    case OPC_MXU_S32LUI:
26532        /* TODO: Implement emulation of S32LUI instruction. */
26533        MIPS_INVAL("OPC_MXU_S32LUI");
26534        generate_exception_end(ctx, EXCP_RI);
26535        break;
26536    case OPC_MXU_S32NOR:
26537        gen_mxu_S32NOR(ctx);
26538        break;
26539    case OPC_MXU_S32AND:
26540        gen_mxu_S32AND(ctx);
26541        break;
26542    case OPC_MXU_S32OR:
26543        gen_mxu_S32OR(ctx);
26544        break;
26545    case OPC_MXU_S32XOR:
26546        gen_mxu_S32XOR(ctx);
26547        break;
26548    default:
26549        MIPS_INVAL("decode_opc_mxu");
26550        generate_exception_end(ctx, EXCP_RI);
26551        break;
26552    }
26553}
26554
26555/*
26556 *
26557 * Decode MXU pool17
26558 *
26559 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26560 *  +-----------+---------+---------+---+---------+-----+-----------+
26561 *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26562 *  +-----------+---------+---------+---+---------+-----+-----------+
26563 *
26564 */
26565static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26566{
26567    uint32_t opcode = extract32(ctx->opcode, 6, 2);
26568
26569    switch (opcode) {
26570    case OPC_MXU_LXW:
26571        /* TODO: Implement emulation of LXW instruction. */
26572        MIPS_INVAL("OPC_MXU_LXW");
26573        generate_exception_end(ctx, EXCP_RI);
26574        break;
26575    case OPC_MXU_LXH:
26576        /* TODO: Implement emulation of LXH instruction. */
26577        MIPS_INVAL("OPC_MXU_LXH");
26578        generate_exception_end(ctx, EXCP_RI);
26579        break;
26580    case OPC_MXU_LXHU:
26581        /* TODO: Implement emulation of LXHU instruction. */
26582        MIPS_INVAL("OPC_MXU_LXHU");
26583        generate_exception_end(ctx, EXCP_RI);
26584        break;
26585    case OPC_MXU_LXB:
26586        /* TODO: Implement emulation of LXB instruction. */
26587        MIPS_INVAL("OPC_MXU_LXB");
26588        generate_exception_end(ctx, EXCP_RI);
26589        break;
26590    case OPC_MXU_LXBU:
26591        /* TODO: Implement emulation of LXBU instruction. */
26592        MIPS_INVAL("OPC_MXU_LXBU");
26593        generate_exception_end(ctx, EXCP_RI);
26594        break;
26595    default:
26596        MIPS_INVAL("decode_opc_mxu");
26597        generate_exception_end(ctx, EXCP_RI);
26598        break;
26599    }
26600}
26601/*
26602 *
26603 * Decode MXU pool18
26604 *
26605 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26606 *  +-----------+---------+-----+-------+-------+-------+-----------+
26607 *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26608 *  +-----------+---------+-----+-------+-------+-------+-----------+
26609 *
26610 */
26611static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26612{
26613    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26614
26615    switch (opcode) {
26616    case OPC_MXU_D32SLLV:
26617        /* TODO: Implement emulation of D32SLLV instruction. */
26618        MIPS_INVAL("OPC_MXU_D32SLLV");
26619        generate_exception_end(ctx, EXCP_RI);
26620        break;
26621    case OPC_MXU_D32SLRV:
26622        /* TODO: Implement emulation of D32SLRV instruction. */
26623        MIPS_INVAL("OPC_MXU_D32SLRV");
26624        generate_exception_end(ctx, EXCP_RI);
26625        break;
26626    case OPC_MXU_D32SARV:
26627        /* TODO: Implement emulation of D32SARV instruction. */
26628        MIPS_INVAL("OPC_MXU_D32SARV");
26629        generate_exception_end(ctx, EXCP_RI);
26630        break;
26631    case OPC_MXU_Q16SLLV:
26632        /* TODO: Implement emulation of Q16SLLV instruction. */
26633        MIPS_INVAL("OPC_MXU_Q16SLLV");
26634        generate_exception_end(ctx, EXCP_RI);
26635        break;
26636    case OPC_MXU_Q16SLRV:
26637        /* TODO: Implement emulation of Q16SLRV instruction. */
26638        MIPS_INVAL("OPC_MXU_Q16SLRV");
26639        generate_exception_end(ctx, EXCP_RI);
26640        break;
26641    case OPC_MXU_Q16SARV:
26642        /* TODO: Implement emulation of Q16SARV instruction. */
26643        MIPS_INVAL("OPC_MXU_Q16SARV");
26644        generate_exception_end(ctx, EXCP_RI);
26645        break;
26646    default:
26647        MIPS_INVAL("decode_opc_mxu");
26648        generate_exception_end(ctx, EXCP_RI);
26649        break;
26650    }
26651}
26652
26653/*
26654 *
26655 * Decode MXU pool19
26656 *
26657 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26658 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26659 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26660 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26661 *
26662 */
26663static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26664{
26665    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26666
26667    switch (opcode) {
26668    case OPC_MXU_Q8MUL:
26669    case OPC_MXU_Q8MULSU:
26670        gen_mxu_q8mul_q8mulsu(ctx);
26671        break;
26672    default:
26673        MIPS_INVAL("decode_opc_mxu");
26674        generate_exception_end(ctx, EXCP_RI);
26675        break;
26676    }
26677}
26678
26679/*
26680 *
26681 * Decode MXU pool20
26682 *
26683 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26684 *  +-----------+---------+-----+-------+-------+-------+-----------+
26685 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26686 *  +-----------+---------+-----+-------+-------+-------+-----------+
26687 *
26688 */
26689static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26690{
26691    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26692
26693    switch (opcode) {
26694    case OPC_MXU_Q8MOVZ:
26695        /* TODO: Implement emulation of Q8MOVZ instruction. */
26696        MIPS_INVAL("OPC_MXU_Q8MOVZ");
26697        generate_exception_end(ctx, EXCP_RI);
26698        break;
26699    case OPC_MXU_Q8MOVN:
26700        /* TODO: Implement emulation of Q8MOVN instruction. */
26701        MIPS_INVAL("OPC_MXU_Q8MOVN");
26702        generate_exception_end(ctx, EXCP_RI);
26703        break;
26704    case OPC_MXU_D16MOVZ:
26705        /* TODO: Implement emulation of D16MOVZ instruction. */
26706        MIPS_INVAL("OPC_MXU_D16MOVZ");
26707        generate_exception_end(ctx, EXCP_RI);
26708        break;
26709    case OPC_MXU_D16MOVN:
26710        /* TODO: Implement emulation of D16MOVN instruction. */
26711        MIPS_INVAL("OPC_MXU_D16MOVN");
26712        generate_exception_end(ctx, EXCP_RI);
26713        break;
26714    case OPC_MXU_S32MOVZ:
26715        /* TODO: Implement emulation of S32MOVZ instruction. */
26716        MIPS_INVAL("OPC_MXU_S32MOVZ");
26717        generate_exception_end(ctx, EXCP_RI);
26718        break;
26719    case OPC_MXU_S32MOVN:
26720        /* TODO: Implement emulation of S32MOVN instruction. */
26721        MIPS_INVAL("OPC_MXU_S32MOVN");
26722        generate_exception_end(ctx, EXCP_RI);
26723        break;
26724    default:
26725        MIPS_INVAL("decode_opc_mxu");
26726        generate_exception_end(ctx, EXCP_RI);
26727        break;
26728    }
26729}
26730
26731/*
26732 *
26733 * Decode MXU pool21
26734 *
26735 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26736 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26737 *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26738 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26739 *
26740 */
26741static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26742{
26743    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26744
26745    switch (opcode) {
26746    case OPC_MXU_Q8MAC:
26747        /* TODO: Implement emulation of Q8MAC instruction. */
26748        MIPS_INVAL("OPC_MXU_Q8MAC");
26749        generate_exception_end(ctx, EXCP_RI);
26750        break;
26751    case OPC_MXU_Q8MACSU:
26752        /* TODO: Implement emulation of Q8MACSU instruction. */
26753        MIPS_INVAL("OPC_MXU_Q8MACSU");
26754        generate_exception_end(ctx, EXCP_RI);
26755        break;
26756    default:
26757        MIPS_INVAL("decode_opc_mxu");
26758        generate_exception_end(ctx, EXCP_RI);
26759        break;
26760    }
26761}
26762
26763
26764/*
26765 * Main MXU decoding function
26766 *
26767 *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26768 *  +-----------+---------------------------------------+-----------+
26769 *  |  SPECIAL2 |                                       |x x x x x x|
26770 *  +-----------+---------------------------------------+-----------+
26771 *
26772 */
26773static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26774{
26775    /*
26776     * TODO: Investigate necessity of including handling of
26777     * CLZ, CLO, SDBB in this function, as they belong to
26778     * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26779     */
26780    uint32_t opcode = extract32(ctx->opcode, 0, 6);
26781
26782    if (opcode == OPC__MXU_MUL) {
26783        uint32_t  rs, rt, rd, op1;
26784
26785        rs = extract32(ctx->opcode, 21, 5);
26786        rt = extract32(ctx->opcode, 16, 5);
26787        rd = extract32(ctx->opcode, 11, 5);
26788        op1 = MASK_SPECIAL2(ctx->opcode);
26789
26790        gen_arith(ctx, op1, rd, rs, rt);
26791
26792        return;
26793    }
26794
26795    if (opcode == OPC_MXU_S32M2I) {
26796        gen_mxu_s32m2i(ctx);
26797        return;
26798    }
26799
26800    if (opcode == OPC_MXU_S32I2M) {
26801        gen_mxu_s32i2m(ctx);
26802        return;
26803    }
26804
26805    {
26806        TCGv t_mxu_cr = tcg_temp_new();
26807        TCGLabel *l_exit = gen_new_label();
26808
26809        gen_load_mxu_cr(t_mxu_cr);
26810        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26811        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26812
26813        switch (opcode) {
26814        case OPC_MXU_S32MADD:
26815            /* TODO: Implement emulation of S32MADD instruction. */
26816            MIPS_INVAL("OPC_MXU_S32MADD");
26817            generate_exception_end(ctx, EXCP_RI);
26818            break;
26819        case OPC_MXU_S32MADDU:
26820            /* TODO: Implement emulation of S32MADDU instruction. */
26821            MIPS_INVAL("OPC_MXU_S32MADDU");
26822            generate_exception_end(ctx, EXCP_RI);
26823            break;
26824        case OPC_MXU__POOL00:
26825            decode_opc_mxu__pool00(env, ctx);
26826            break;
26827        case OPC_MXU_S32MSUB:
26828            /* TODO: Implement emulation of S32MSUB instruction. */
26829            MIPS_INVAL("OPC_MXU_S32MSUB");
26830            generate_exception_end(ctx, EXCP_RI);
26831            break;
26832        case OPC_MXU_S32MSUBU:
26833            /* TODO: Implement emulation of S32MSUBU instruction. */
26834            MIPS_INVAL("OPC_MXU_S32MSUBU");
26835            generate_exception_end(ctx, EXCP_RI);
26836            break;
26837        case OPC_MXU__POOL01:
26838            decode_opc_mxu__pool01(env, ctx);
26839            break;
26840        case OPC_MXU__POOL02:
26841            decode_opc_mxu__pool02(env, ctx);
26842            break;
26843        case OPC_MXU_D16MUL:
26844            gen_mxu_d16mul(ctx);
26845            break;
26846        case OPC_MXU__POOL03:
26847            decode_opc_mxu__pool03(env, ctx);
26848            break;
26849        case OPC_MXU_D16MAC:
26850            gen_mxu_d16mac(ctx);
26851            break;
26852        case OPC_MXU_D16MACF:
26853            /* TODO: Implement emulation of D16MACF instruction. */
26854            MIPS_INVAL("OPC_MXU_D16MACF");
26855            generate_exception_end(ctx, EXCP_RI);
26856            break;
26857        case OPC_MXU_D16MADL:
26858            /* TODO: Implement emulation of D16MADL instruction. */
26859            MIPS_INVAL("OPC_MXU_D16MADL");
26860            generate_exception_end(ctx, EXCP_RI);
26861            break;
26862        case OPC_MXU_S16MAD:
26863            /* TODO: Implement emulation of S16MAD instruction. */
26864            MIPS_INVAL("OPC_MXU_S16MAD");
26865            generate_exception_end(ctx, EXCP_RI);
26866            break;
26867        case OPC_MXU_Q16ADD:
26868            /* TODO: Implement emulation of Q16ADD instruction. */
26869            MIPS_INVAL("OPC_MXU_Q16ADD");
26870            generate_exception_end(ctx, EXCP_RI);
26871            break;
26872        case OPC_MXU_D16MACE:
26873            /* TODO: Implement emulation of D16MACE instruction. */
26874            MIPS_INVAL("OPC_MXU_D16MACE");
26875            generate_exception_end(ctx, EXCP_RI);
26876            break;
26877        case OPC_MXU__POOL04:
26878            decode_opc_mxu__pool04(env, ctx);
26879            break;
26880        case OPC_MXU__POOL05:
26881            decode_opc_mxu__pool05(env, ctx);
26882            break;
26883        case OPC_MXU__POOL06:
26884            decode_opc_mxu__pool06(env, ctx);
26885            break;
26886        case OPC_MXU__POOL07:
26887            decode_opc_mxu__pool07(env, ctx);
26888            break;
26889        case OPC_MXU__POOL08:
26890            decode_opc_mxu__pool08(env, ctx);
26891            break;
26892        case OPC_MXU__POOL09:
26893            decode_opc_mxu__pool09(env, ctx);
26894            break;
26895        case OPC_MXU__POOL10:
26896            decode_opc_mxu__pool10(env, ctx);
26897            break;
26898        case OPC_MXU__POOL11:
26899            decode_opc_mxu__pool11(env, ctx);
26900            break;
26901        case OPC_MXU_D32ADD:
26902            /* TODO: Implement emulation of D32ADD instruction. */
26903            MIPS_INVAL("OPC_MXU_D32ADD");
26904            generate_exception_end(ctx, EXCP_RI);
26905            break;
26906        case OPC_MXU__POOL12:
26907            decode_opc_mxu__pool12(env, ctx);
26908            break;
26909        case OPC_MXU__POOL13:
26910            decode_opc_mxu__pool13(env, ctx);
26911            break;
26912        case OPC_MXU__POOL14:
26913            decode_opc_mxu__pool14(env, ctx);
26914            break;
26915        case OPC_MXU_Q8ACCE:
26916            /* TODO: Implement emulation of Q8ACCE instruction. */
26917            MIPS_INVAL("OPC_MXU_Q8ACCE");
26918            generate_exception_end(ctx, EXCP_RI);
26919            break;
26920        case OPC_MXU_S8LDD:
26921            gen_mxu_s8ldd(ctx);
26922            break;
26923        case OPC_MXU_S8STD:
26924            /* TODO: Implement emulation of S8STD instruction. */
26925            MIPS_INVAL("OPC_MXU_S8STD");
26926            generate_exception_end(ctx, EXCP_RI);
26927            break;
26928        case OPC_MXU_S8LDI:
26929            /* TODO: Implement emulation of S8LDI instruction. */
26930            MIPS_INVAL("OPC_MXU_S8LDI");
26931            generate_exception_end(ctx, EXCP_RI);
26932            break;
26933        case OPC_MXU_S8SDI:
26934            /* TODO: Implement emulation of S8SDI instruction. */
26935            MIPS_INVAL("OPC_MXU_S8SDI");
26936            generate_exception_end(ctx, EXCP_RI);
26937            break;
26938        case OPC_MXU__POOL15:
26939            decode_opc_mxu__pool15(env, ctx);
26940            break;
26941        case OPC_MXU__POOL16:
26942            decode_opc_mxu__pool16(env, ctx);
26943            break;
26944        case OPC_MXU__POOL17:
26945            decode_opc_mxu__pool17(env, ctx);
26946            break;
26947        case OPC_MXU_S16LDD:
26948            /* TODO: Implement emulation of S16LDD instruction. */
26949            MIPS_INVAL("OPC_MXU_S16LDD");
26950            generate_exception_end(ctx, EXCP_RI);
26951            break;
26952        case OPC_MXU_S16STD:
26953            /* TODO: Implement emulation of S16STD instruction. */
26954            MIPS_INVAL("OPC_MXU_S16STD");
26955            generate_exception_end(ctx, EXCP_RI);
26956            break;
26957        case OPC_MXU_S16LDI:
26958            /* TODO: Implement emulation of S16LDI instruction. */
26959            MIPS_INVAL("OPC_MXU_S16LDI");
26960            generate_exception_end(ctx, EXCP_RI);
26961            break;
26962        case OPC_MXU_S16SDI:
26963            /* TODO: Implement emulation of S16SDI instruction. */
26964            MIPS_INVAL("OPC_MXU_S16SDI");
26965            generate_exception_end(ctx, EXCP_RI);
26966            break;
26967        case OPC_MXU_D32SLL:
26968            /* TODO: Implement emulation of D32SLL instruction. */
26969            MIPS_INVAL("OPC_MXU_D32SLL");
26970            generate_exception_end(ctx, EXCP_RI);
26971            break;
26972        case OPC_MXU_D32SLR:
26973            /* TODO: Implement emulation of D32SLR instruction. */
26974            MIPS_INVAL("OPC_MXU_D32SLR");
26975            generate_exception_end(ctx, EXCP_RI);
26976            break;
26977        case OPC_MXU_D32SARL:
26978            /* TODO: Implement emulation of D32SARL instruction. */
26979            MIPS_INVAL("OPC_MXU_D32SARL");
26980            generate_exception_end(ctx, EXCP_RI);
26981            break;
26982        case OPC_MXU_D32SAR:
26983            /* TODO: Implement emulation of D32SAR instruction. */
26984            MIPS_INVAL("OPC_MXU_D32SAR");
26985            generate_exception_end(ctx, EXCP_RI);
26986            break;
26987        case OPC_MXU_Q16SLL:
26988            /* TODO: Implement emulation of Q16SLL instruction. */
26989            MIPS_INVAL("OPC_MXU_Q16SLL");
26990            generate_exception_end(ctx, EXCP_RI);
26991            break;
26992        case OPC_MXU_Q16SLR:
26993            /* TODO: Implement emulation of Q16SLR instruction. */
26994            MIPS_INVAL("OPC_MXU_Q16SLR");
26995            generate_exception_end(ctx, EXCP_RI);
26996            break;
26997        case OPC_MXU__POOL18:
26998            decode_opc_mxu__pool18(env, ctx);
26999            break;
27000        case OPC_MXU_Q16SAR:
27001            /* TODO: Implement emulation of Q16SAR instruction. */
27002            MIPS_INVAL("OPC_MXU_Q16SAR");
27003            generate_exception_end(ctx, EXCP_RI);
27004            break;
27005        case OPC_MXU__POOL19:
27006            decode_opc_mxu__pool19(env, ctx);
27007            break;
27008        case OPC_MXU__POOL20:
27009            decode_opc_mxu__pool20(env, ctx);
27010            break;
27011        case OPC_MXU__POOL21:
27012            decode_opc_mxu__pool21(env, ctx);
27013            break;
27014        case OPC_MXU_Q16SCOP:
27015            /* TODO: Implement emulation of Q16SCOP instruction. */
27016            MIPS_INVAL("OPC_MXU_Q16SCOP");
27017            generate_exception_end(ctx, EXCP_RI);
27018            break;
27019        case OPC_MXU_Q8MADL:
27020            /* TODO: Implement emulation of Q8MADL instruction. */
27021            MIPS_INVAL("OPC_MXU_Q8MADL");
27022            generate_exception_end(ctx, EXCP_RI);
27023            break;
27024        case OPC_MXU_S32SFL:
27025            /* TODO: Implement emulation of S32SFL instruction. */
27026            MIPS_INVAL("OPC_MXU_S32SFL");
27027            generate_exception_end(ctx, EXCP_RI);
27028            break;
27029        case OPC_MXU_Q8SAD:
27030            /* TODO: Implement emulation of Q8SAD instruction. */
27031            MIPS_INVAL("OPC_MXU_Q8SAD");
27032            generate_exception_end(ctx, EXCP_RI);
27033            break;
27034        default:
27035            MIPS_INVAL("decode_opc_mxu");
27036            generate_exception_end(ctx, EXCP_RI);
27037        }
27038
27039        gen_set_label(l_exit);
27040        tcg_temp_free(t_mxu_cr);
27041    }
27042}
27043
27044#endif /* !defined(TARGET_MIPS64) */
27045
27046
27047static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
27048{
27049    int rs, rt, rd;
27050    uint32_t op1;
27051
27052    check_insn_opc_removed(ctx, ISA_MIPS32R6);
27053
27054    rs = (ctx->opcode >> 21) & 0x1f;
27055    rt = (ctx->opcode >> 16) & 0x1f;
27056    rd = (ctx->opcode >> 11) & 0x1f;
27057
27058    op1 = MASK_SPECIAL2(ctx->opcode);
27059    switch (op1) {
27060    case OPC_MADD: /* Multiply and add/sub */
27061    case OPC_MADDU:
27062    case OPC_MSUB:
27063    case OPC_MSUBU:
27064        check_insn(ctx, ISA_MIPS32);
27065        gen_muldiv(ctx, op1, rd & 3, rs, rt);
27066        break;
27067    case OPC_MUL:
27068        gen_arith(ctx, op1, rd, rs, rt);
27069        break;
27070    case OPC_DIV_G_2F:
27071    case OPC_DIVU_G_2F:
27072    case OPC_MULT_G_2F:
27073    case OPC_MULTU_G_2F:
27074    case OPC_MOD_G_2F:
27075    case OPC_MODU_G_2F:
27076        check_insn(ctx, INSN_LOONGSON2F);
27077        gen_loongson_integer(ctx, op1, rd, rs, rt);
27078        break;
27079    case OPC_CLO:
27080    case OPC_CLZ:
27081        check_insn(ctx, ISA_MIPS32);
27082        gen_cl(ctx, op1, rd, rs);
27083        break;
27084    case OPC_SDBBP:
27085        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
27086            gen_helper_do_semihosting(cpu_env);
27087        } else {
27088            /*
27089             * XXX: not clear which exception should be raised
27090             *      when in debug mode...
27091             */
27092            check_insn(ctx, ISA_MIPS32);
27093            generate_exception_end(ctx, EXCP_DBp);
27094        }
27095        break;
27096#if defined(TARGET_MIPS64)
27097    case OPC_DCLO:
27098    case OPC_DCLZ:
27099        check_insn(ctx, ISA_MIPS64);
27100        check_mips_64(ctx);
27101        gen_cl(ctx, op1, rd, rs);
27102        break;
27103    case OPC_DMULT_G_2F:
27104    case OPC_DMULTU_G_2F:
27105    case OPC_DDIV_G_2F:
27106    case OPC_DDIVU_G_2F:
27107    case OPC_DMOD_G_2F:
27108    case OPC_DMODU_G_2F:
27109        check_insn(ctx, INSN_LOONGSON2F);
27110        gen_loongson_integer(ctx, op1, rd, rs, rt);
27111        break;
27112#endif
27113    default:            /* Invalid */
27114        MIPS_INVAL("special2_legacy");
27115        generate_exception_end(ctx, EXCP_RI);
27116        break;
27117    }
27118}
27119
27120static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
27121{
27122    int rs, rt, rd, sa;
27123    uint32_t op1, op2;
27124    int16_t imm;
27125
27126    rs = (ctx->opcode >> 21) & 0x1f;
27127    rt = (ctx->opcode >> 16) & 0x1f;
27128    rd = (ctx->opcode >> 11) & 0x1f;
27129    sa = (ctx->opcode >> 6) & 0x1f;
27130    imm = (int16_t)ctx->opcode >> 7;
27131
27132    op1 = MASK_SPECIAL3(ctx->opcode);
27133    switch (op1) {
27134    case R6_OPC_PREF:
27135        if (rt >= 24) {
27136            /* hint codes 24-31 are reserved and signal RI */
27137            generate_exception_end(ctx, EXCP_RI);
27138        }
27139        /* Treat as NOP. */
27140        break;
27141    case R6_OPC_CACHE:
27142        check_cp0_enabled(ctx);
27143        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27144            gen_cache_operation(ctx, rt, rs, imm);
27145        }
27146        break;
27147    case R6_OPC_SC:
27148        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
27149        break;
27150    case R6_OPC_LL:
27151        gen_ld(ctx, op1, rt, rs, imm);
27152        break;
27153    case OPC_BSHFL:
27154        {
27155            if (rd == 0) {
27156                /* Treat as NOP. */
27157                break;
27158            }
27159            op2 = MASK_BSHFL(ctx->opcode);
27160            switch (op2) {
27161            case OPC_ALIGN:
27162            case OPC_ALIGN_1:
27163            case OPC_ALIGN_2:
27164            case OPC_ALIGN_3:
27165                gen_align(ctx, 32, rd, rs, rt, sa & 3);
27166                break;
27167            case OPC_BITSWAP:
27168                gen_bitswap(ctx, op2, rd, rt);
27169                break;
27170            }
27171        }
27172        break;
27173#if defined(TARGET_MIPS64)
27174    case R6_OPC_SCD:
27175        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
27176        break;
27177    case R6_OPC_LLD:
27178        gen_ld(ctx, op1, rt, rs, imm);
27179        break;
27180    case OPC_DBSHFL:
27181        check_mips_64(ctx);
27182        {
27183            if (rd == 0) {
27184                /* Treat as NOP. */
27185                break;
27186            }
27187            op2 = MASK_DBSHFL(ctx->opcode);
27188            switch (op2) {
27189            case OPC_DALIGN:
27190            case OPC_DALIGN_1:
27191            case OPC_DALIGN_2:
27192            case OPC_DALIGN_3:
27193            case OPC_DALIGN_4:
27194            case OPC_DALIGN_5:
27195            case OPC_DALIGN_6:
27196            case OPC_DALIGN_7:
27197                gen_align(ctx, 64, rd, rs, rt, sa & 7);
27198                break;
27199            case OPC_DBITSWAP:
27200                gen_bitswap(ctx, op2, rd, rt);
27201                break;
27202            }
27203
27204        }
27205        break;
27206#endif
27207    default:            /* Invalid */
27208        MIPS_INVAL("special3_r6");
27209        generate_exception_end(ctx, EXCP_RI);
27210        break;
27211    }
27212}
27213
27214static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
27215{
27216    int rs, rt, rd;
27217    uint32_t op1, op2;
27218
27219    rs = (ctx->opcode >> 21) & 0x1f;
27220    rt = (ctx->opcode >> 16) & 0x1f;
27221    rd = (ctx->opcode >> 11) & 0x1f;
27222
27223    op1 = MASK_SPECIAL3(ctx->opcode);
27224    switch (op1) {
27225    case OPC_DIV_G_2E:
27226    case OPC_DIVU_G_2E:
27227    case OPC_MOD_G_2E:
27228    case OPC_MODU_G_2E:
27229    case OPC_MULT_G_2E:
27230    case OPC_MULTU_G_2E:
27231        /*
27232         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27233         * the same mask and op1.
27234         */
27235        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
27236            op2 = MASK_ADDUH_QB(ctx->opcode);
27237            switch (op2) {
27238            case OPC_ADDUH_QB:
27239            case OPC_ADDUH_R_QB:
27240            case OPC_ADDQH_PH:
27241            case OPC_ADDQH_R_PH:
27242            case OPC_ADDQH_W:
27243            case OPC_ADDQH_R_W:
27244            case OPC_SUBUH_QB:
27245            case OPC_SUBUH_R_QB:
27246            case OPC_SUBQH_PH:
27247            case OPC_SUBQH_R_PH:
27248            case OPC_SUBQH_W:
27249            case OPC_SUBQH_R_W:
27250                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27251                break;
27252            case OPC_MUL_PH:
27253            case OPC_MUL_S_PH:
27254            case OPC_MULQ_S_W:
27255            case OPC_MULQ_RS_W:
27256                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27257                break;
27258            default:
27259                MIPS_INVAL("MASK ADDUH.QB");
27260                generate_exception_end(ctx, EXCP_RI);
27261                break;
27262            }
27263        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
27264            gen_loongson_integer(ctx, op1, rd, rs, rt);
27265        } else {
27266            generate_exception_end(ctx, EXCP_RI);
27267        }
27268        break;
27269    case OPC_LX_DSP:
27270        op2 = MASK_LX(ctx->opcode);
27271        switch (op2) {
27272#if defined(TARGET_MIPS64)
27273        case OPC_LDX:
27274#endif
27275        case OPC_LBUX:
27276        case OPC_LHX:
27277        case OPC_LWX:
27278            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
27279            break;
27280        default:            /* Invalid */
27281            MIPS_INVAL("MASK LX");
27282            generate_exception_end(ctx, EXCP_RI);
27283            break;
27284        }
27285        break;
27286    case OPC_ABSQ_S_PH_DSP:
27287        op2 = MASK_ABSQ_S_PH(ctx->opcode);
27288        switch (op2) {
27289        case OPC_ABSQ_S_QB:
27290        case OPC_ABSQ_S_PH:
27291        case OPC_ABSQ_S_W:
27292        case OPC_PRECEQ_W_PHL:
27293        case OPC_PRECEQ_W_PHR:
27294        case OPC_PRECEQU_PH_QBL:
27295        case OPC_PRECEQU_PH_QBR:
27296        case OPC_PRECEQU_PH_QBLA:
27297        case OPC_PRECEQU_PH_QBRA:
27298        case OPC_PRECEU_PH_QBL:
27299        case OPC_PRECEU_PH_QBR:
27300        case OPC_PRECEU_PH_QBLA:
27301        case OPC_PRECEU_PH_QBRA:
27302            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27303            break;
27304        case OPC_BITREV:
27305        case OPC_REPL_QB:
27306        case OPC_REPLV_QB:
27307        case OPC_REPL_PH:
27308        case OPC_REPLV_PH:
27309            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27310            break;
27311        default:
27312            MIPS_INVAL("MASK ABSQ_S.PH");
27313            generate_exception_end(ctx, EXCP_RI);
27314            break;
27315        }
27316        break;
27317    case OPC_ADDU_QB_DSP:
27318        op2 = MASK_ADDU_QB(ctx->opcode);
27319        switch (op2) {
27320        case OPC_ADDQ_PH:
27321        case OPC_ADDQ_S_PH:
27322        case OPC_ADDQ_S_W:
27323        case OPC_ADDU_QB:
27324        case OPC_ADDU_S_QB:
27325        case OPC_ADDU_PH:
27326        case OPC_ADDU_S_PH:
27327        case OPC_SUBQ_PH:
27328        case OPC_SUBQ_S_PH:
27329        case OPC_SUBQ_S_W:
27330        case OPC_SUBU_QB:
27331        case OPC_SUBU_S_QB:
27332        case OPC_SUBU_PH:
27333        case OPC_SUBU_S_PH:
27334        case OPC_ADDSC:
27335        case OPC_ADDWC:
27336        case OPC_MODSUB:
27337        case OPC_RADDU_W_QB:
27338            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27339            break;
27340        case OPC_MULEU_S_PH_QBL:
27341        case OPC_MULEU_S_PH_QBR:
27342        case OPC_MULQ_RS_PH:
27343        case OPC_MULEQ_S_W_PHL:
27344        case OPC_MULEQ_S_W_PHR:
27345        case OPC_MULQ_S_PH:
27346            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27347            break;
27348        default:            /* Invalid */
27349            MIPS_INVAL("MASK ADDU.QB");
27350            generate_exception_end(ctx, EXCP_RI);
27351            break;
27352
27353        }
27354        break;
27355    case OPC_CMPU_EQ_QB_DSP:
27356        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27357        switch (op2) {
27358        case OPC_PRECR_SRA_PH_W:
27359        case OPC_PRECR_SRA_R_PH_W:
27360            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27361            break;
27362        case OPC_PRECR_QB_PH:
27363        case OPC_PRECRQ_QB_PH:
27364        case OPC_PRECRQ_PH_W:
27365        case OPC_PRECRQ_RS_PH_W:
27366        case OPC_PRECRQU_S_QB_PH:
27367            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27368            break;
27369        case OPC_CMPU_EQ_QB:
27370        case OPC_CMPU_LT_QB:
27371        case OPC_CMPU_LE_QB:
27372        case OPC_CMP_EQ_PH:
27373        case OPC_CMP_LT_PH:
27374        case OPC_CMP_LE_PH:
27375            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27376            break;
27377        case OPC_CMPGU_EQ_QB:
27378        case OPC_CMPGU_LT_QB:
27379        case OPC_CMPGU_LE_QB:
27380        case OPC_CMPGDU_EQ_QB:
27381        case OPC_CMPGDU_LT_QB:
27382        case OPC_CMPGDU_LE_QB:
27383        case OPC_PICK_QB:
27384        case OPC_PICK_PH:
27385        case OPC_PACKRL_PH:
27386            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27387            break;
27388        default:            /* Invalid */
27389            MIPS_INVAL("MASK CMPU.EQ.QB");
27390            generate_exception_end(ctx, EXCP_RI);
27391            break;
27392        }
27393        break;
27394    case OPC_SHLL_QB_DSP:
27395        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27396        break;
27397    case OPC_DPA_W_PH_DSP:
27398        op2 = MASK_DPA_W_PH(ctx->opcode);
27399        switch (op2) {
27400        case OPC_DPAU_H_QBL:
27401        case OPC_DPAU_H_QBR:
27402        case OPC_DPSU_H_QBL:
27403        case OPC_DPSU_H_QBR:
27404        case OPC_DPA_W_PH:
27405        case OPC_DPAX_W_PH:
27406        case OPC_DPAQ_S_W_PH:
27407        case OPC_DPAQX_S_W_PH:
27408        case OPC_DPAQX_SA_W_PH:
27409        case OPC_DPS_W_PH:
27410        case OPC_DPSX_W_PH:
27411        case OPC_DPSQ_S_W_PH:
27412        case OPC_DPSQX_S_W_PH:
27413        case OPC_DPSQX_SA_W_PH:
27414        case OPC_MULSAQ_S_W_PH:
27415        case OPC_DPAQ_SA_L_W:
27416        case OPC_DPSQ_SA_L_W:
27417        case OPC_MAQ_S_W_PHL:
27418        case OPC_MAQ_S_W_PHR:
27419        case OPC_MAQ_SA_W_PHL:
27420        case OPC_MAQ_SA_W_PHR:
27421        case OPC_MULSA_W_PH:
27422            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27423            break;
27424        default:            /* Invalid */
27425            MIPS_INVAL("MASK DPAW.PH");
27426            generate_exception_end(ctx, EXCP_RI);
27427            break;
27428        }
27429        break;
27430    case OPC_INSV_DSP:
27431        op2 = MASK_INSV(ctx->opcode);
27432        switch (op2) {
27433        case OPC_INSV:
27434            check_dsp(ctx);
27435            {
27436                TCGv t0, t1;
27437
27438                if (rt == 0) {
27439                    break;
27440                }
27441
27442                t0 = tcg_temp_new();
27443                t1 = tcg_temp_new();
27444
27445                gen_load_gpr(t0, rt);
27446                gen_load_gpr(t1, rs);
27447
27448                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27449
27450                tcg_temp_free(t0);
27451                tcg_temp_free(t1);
27452                break;
27453            }
27454        default:            /* Invalid */
27455            MIPS_INVAL("MASK INSV");
27456            generate_exception_end(ctx, EXCP_RI);
27457            break;
27458        }
27459        break;
27460    case OPC_APPEND_DSP:
27461        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27462        break;
27463    case OPC_EXTR_W_DSP:
27464        op2 = MASK_EXTR_W(ctx->opcode);
27465        switch (op2) {
27466        case OPC_EXTR_W:
27467        case OPC_EXTR_R_W:
27468        case OPC_EXTR_RS_W:
27469        case OPC_EXTR_S_H:
27470        case OPC_EXTRV_S_H:
27471        case OPC_EXTRV_W:
27472        case OPC_EXTRV_R_W:
27473        case OPC_EXTRV_RS_W:
27474        case OPC_EXTP:
27475        case OPC_EXTPV:
27476        case OPC_EXTPDP:
27477        case OPC_EXTPDPV:
27478            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27479            break;
27480        case OPC_RDDSP:
27481            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27482            break;
27483        case OPC_SHILO:
27484        case OPC_SHILOV:
27485        case OPC_MTHLIP:
27486        case OPC_WRDSP:
27487            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27488            break;
27489        default:            /* Invalid */
27490            MIPS_INVAL("MASK EXTR.W");
27491            generate_exception_end(ctx, EXCP_RI);
27492            break;
27493        }
27494        break;
27495#if defined(TARGET_MIPS64)
27496    case OPC_DDIV_G_2E:
27497    case OPC_DDIVU_G_2E:
27498    case OPC_DMULT_G_2E:
27499    case OPC_DMULTU_G_2E:
27500    case OPC_DMOD_G_2E:
27501    case OPC_DMODU_G_2E:
27502        check_insn(ctx, INSN_LOONGSON2E);
27503        gen_loongson_integer(ctx, op1, rd, rs, rt);
27504        break;
27505    case OPC_ABSQ_S_QH_DSP:
27506        op2 = MASK_ABSQ_S_QH(ctx->opcode);
27507        switch (op2) {
27508        case OPC_PRECEQ_L_PWL:
27509        case OPC_PRECEQ_L_PWR:
27510        case OPC_PRECEQ_PW_QHL:
27511        case OPC_PRECEQ_PW_QHR:
27512        case OPC_PRECEQ_PW_QHLA:
27513        case OPC_PRECEQ_PW_QHRA:
27514        case OPC_PRECEQU_QH_OBL:
27515        case OPC_PRECEQU_QH_OBR:
27516        case OPC_PRECEQU_QH_OBLA:
27517        case OPC_PRECEQU_QH_OBRA:
27518        case OPC_PRECEU_QH_OBL:
27519        case OPC_PRECEU_QH_OBR:
27520        case OPC_PRECEU_QH_OBLA:
27521        case OPC_PRECEU_QH_OBRA:
27522        case OPC_ABSQ_S_OB:
27523        case OPC_ABSQ_S_PW:
27524        case OPC_ABSQ_S_QH:
27525            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27526            break;
27527        case OPC_REPL_OB:
27528        case OPC_REPL_PW:
27529        case OPC_REPL_QH:
27530        case OPC_REPLV_OB:
27531        case OPC_REPLV_PW:
27532        case OPC_REPLV_QH:
27533            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27534            break;
27535        default:            /* Invalid */
27536            MIPS_INVAL("MASK ABSQ_S.QH");
27537            generate_exception_end(ctx, EXCP_RI);
27538            break;
27539        }
27540        break;
27541    case OPC_ADDU_OB_DSP:
27542        op2 = MASK_ADDU_OB(ctx->opcode);
27543        switch (op2) {
27544        case OPC_RADDU_L_OB:
27545        case OPC_SUBQ_PW:
27546        case OPC_SUBQ_S_PW:
27547        case OPC_SUBQ_QH:
27548        case OPC_SUBQ_S_QH:
27549        case OPC_SUBU_OB:
27550        case OPC_SUBU_S_OB:
27551        case OPC_SUBU_QH:
27552        case OPC_SUBU_S_QH:
27553        case OPC_SUBUH_OB:
27554        case OPC_SUBUH_R_OB:
27555        case OPC_ADDQ_PW:
27556        case OPC_ADDQ_S_PW:
27557        case OPC_ADDQ_QH:
27558        case OPC_ADDQ_S_QH:
27559        case OPC_ADDU_OB:
27560        case OPC_ADDU_S_OB:
27561        case OPC_ADDU_QH:
27562        case OPC_ADDU_S_QH:
27563        case OPC_ADDUH_OB:
27564        case OPC_ADDUH_R_OB:
27565            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27566            break;
27567        case OPC_MULEQ_S_PW_QHL:
27568        case OPC_MULEQ_S_PW_QHR:
27569        case OPC_MULEU_S_QH_OBL:
27570        case OPC_MULEU_S_QH_OBR:
27571        case OPC_MULQ_RS_QH:
27572            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27573            break;
27574        default:            /* Invalid */
27575            MIPS_INVAL("MASK ADDU.OB");
27576            generate_exception_end(ctx, EXCP_RI);
27577            break;
27578        }
27579        break;
27580    case OPC_CMPU_EQ_OB_DSP:
27581        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27582        switch (op2) {
27583        case OPC_PRECR_SRA_QH_PW:
27584        case OPC_PRECR_SRA_R_QH_PW:
27585            /* Return value is rt. */
27586            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27587            break;
27588        case OPC_PRECR_OB_QH:
27589        case OPC_PRECRQ_OB_QH:
27590        case OPC_PRECRQ_PW_L:
27591        case OPC_PRECRQ_QH_PW:
27592        case OPC_PRECRQ_RS_QH_PW:
27593        case OPC_PRECRQU_S_OB_QH:
27594            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27595            break;
27596        case OPC_CMPU_EQ_OB:
27597        case OPC_CMPU_LT_OB:
27598        case OPC_CMPU_LE_OB:
27599        case OPC_CMP_EQ_QH:
27600        case OPC_CMP_LT_QH:
27601        case OPC_CMP_LE_QH:
27602        case OPC_CMP_EQ_PW:
27603        case OPC_CMP_LT_PW:
27604        case OPC_CMP_LE_PW:
27605            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27606            break;
27607        case OPC_CMPGDU_EQ_OB:
27608        case OPC_CMPGDU_LT_OB:
27609        case OPC_CMPGDU_LE_OB:
27610        case OPC_CMPGU_EQ_OB:
27611        case OPC_CMPGU_LT_OB:
27612        case OPC_CMPGU_LE_OB:
27613        case OPC_PACKRL_PW:
27614        case OPC_PICK_OB:
27615        case OPC_PICK_PW:
27616        case OPC_PICK_QH:
27617            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27618            break;
27619        default:            /* Invalid */
27620            MIPS_INVAL("MASK CMPU_EQ.OB");
27621            generate_exception_end(ctx, EXCP_RI);
27622            break;
27623        }
27624        break;
27625    case OPC_DAPPEND_DSP:
27626        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27627        break;
27628    case OPC_DEXTR_W_DSP:
27629        op2 = MASK_DEXTR_W(ctx->opcode);
27630        switch (op2) {
27631        case OPC_DEXTP:
27632        case OPC_DEXTPDP:
27633        case OPC_DEXTPDPV:
27634        case OPC_DEXTPV:
27635        case OPC_DEXTR_L:
27636        case OPC_DEXTR_R_L:
27637        case OPC_DEXTR_RS_L:
27638        case OPC_DEXTR_W:
27639        case OPC_DEXTR_R_W:
27640        case OPC_DEXTR_RS_W:
27641        case OPC_DEXTR_S_H:
27642        case OPC_DEXTRV_L:
27643        case OPC_DEXTRV_R_L:
27644        case OPC_DEXTRV_RS_L:
27645        case OPC_DEXTRV_S_H:
27646        case OPC_DEXTRV_W:
27647        case OPC_DEXTRV_R_W:
27648        case OPC_DEXTRV_RS_W:
27649            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27650            break;
27651        case OPC_DMTHLIP:
27652        case OPC_DSHILO:
27653        case OPC_DSHILOV:
27654            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27655            break;
27656        default:            /* Invalid */
27657            MIPS_INVAL("MASK EXTR.W");
27658            generate_exception_end(ctx, EXCP_RI);
27659            break;
27660        }
27661        break;
27662    case OPC_DPAQ_W_QH_DSP:
27663        op2 = MASK_DPAQ_W_QH(ctx->opcode);
27664        switch (op2) {
27665        case OPC_DPAU_H_OBL:
27666        case OPC_DPAU_H_OBR:
27667        case OPC_DPSU_H_OBL:
27668        case OPC_DPSU_H_OBR:
27669        case OPC_DPA_W_QH:
27670        case OPC_DPAQ_S_W_QH:
27671        case OPC_DPS_W_QH:
27672        case OPC_DPSQ_S_W_QH:
27673        case OPC_MULSAQ_S_W_QH:
27674        case OPC_DPAQ_SA_L_PW:
27675        case OPC_DPSQ_SA_L_PW:
27676        case OPC_MULSAQ_S_L_PW:
27677            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27678            break;
27679        case OPC_MAQ_S_W_QHLL:
27680        case OPC_MAQ_S_W_QHLR:
27681        case OPC_MAQ_S_W_QHRL:
27682        case OPC_MAQ_S_W_QHRR:
27683        case OPC_MAQ_SA_W_QHLL:
27684        case OPC_MAQ_SA_W_QHLR:
27685        case OPC_MAQ_SA_W_QHRL:
27686        case OPC_MAQ_SA_W_QHRR:
27687        case OPC_MAQ_S_L_PWL:
27688        case OPC_MAQ_S_L_PWR:
27689        case OPC_DMADD:
27690        case OPC_DMADDU:
27691        case OPC_DMSUB:
27692        case OPC_DMSUBU:
27693            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27694            break;
27695        default:            /* Invalid */
27696            MIPS_INVAL("MASK DPAQ.W.QH");
27697            generate_exception_end(ctx, EXCP_RI);
27698            break;
27699        }
27700        break;
27701    case OPC_DINSV_DSP:
27702        op2 = MASK_INSV(ctx->opcode);
27703        switch (op2) {
27704        case OPC_DINSV:
27705        {
27706            TCGv t0, t1;
27707
27708            if (rt == 0) {
27709                break;
27710            }
27711            check_dsp(ctx);
27712
27713            t0 = tcg_temp_new();
27714            t1 = tcg_temp_new();
27715
27716            gen_load_gpr(t0, rt);
27717            gen_load_gpr(t1, rs);
27718
27719            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27720
27721            tcg_temp_free(t0);
27722            tcg_temp_free(t1);
27723            break;
27724        }
27725        default:            /* Invalid */
27726            MIPS_INVAL("MASK DINSV");
27727            generate_exception_end(ctx, EXCP_RI);
27728            break;
27729        }
27730        break;
27731    case OPC_SHLL_OB_DSP:
27732        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27733        break;
27734#endif
27735    default:            /* Invalid */
27736        MIPS_INVAL("special3_legacy");
27737        generate_exception_end(ctx, EXCP_RI);
27738        break;
27739    }
27740}
27741
27742
27743#if defined(TARGET_MIPS64)
27744
27745static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27746{
27747    uint32_t opc = MASK_MMI0(ctx->opcode);
27748
27749    switch (opc) {
27750    case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27751    case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27752    case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27753    case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27754    case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27755    case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27756    case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27757    case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27758    case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27759    case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27760    case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27761    case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27762    case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27763    case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27764    case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27765    case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27766    case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27767    case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27768    case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27769    case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27770    case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27771    case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27772    case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27773    case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27774    case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27775        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27776        break;
27777    default:
27778        MIPS_INVAL("TX79 MMI class MMI0");
27779        generate_exception_end(ctx, EXCP_RI);
27780        break;
27781    }
27782}
27783
27784static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27785{
27786    uint32_t opc = MASK_MMI1(ctx->opcode);
27787
27788    switch (opc) {
27789    case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27790    case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27791    case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27792    case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27793    case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27794    case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27795    case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27796    case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27797    case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27798    case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27799    case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27800    case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27801    case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27802    case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27803    case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27804    case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27805    case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27806    case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27807        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27808        break;
27809    default:
27810        MIPS_INVAL("TX79 MMI class MMI1");
27811        generate_exception_end(ctx, EXCP_RI);
27812        break;
27813    }
27814}
27815
27816static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27817{
27818    uint32_t opc = MASK_MMI2(ctx->opcode);
27819
27820    switch (opc) {
27821    case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27822    case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27823    case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27824    case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27825    case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27826    case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27827    case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27828    case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27829    case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27830    case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27831    case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27832    case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27833    case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27834    case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27835    case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27836    case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27837    case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27838    case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27839    case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27840    case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27841    case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27842        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27843        break;
27844    case MMI_OPC_2_PCPYLD:
27845        gen_mmi_pcpyld(ctx);
27846        break;
27847    default:
27848        MIPS_INVAL("TX79 MMI class MMI2");
27849        generate_exception_end(ctx, EXCP_RI);
27850        break;
27851    }
27852}
27853
27854static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27855{
27856    uint32_t opc = MASK_MMI3(ctx->opcode);
27857
27858    switch (opc) {
27859    case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27860    case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27861    case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27862    case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27863    case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27864    case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27865    case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27866    case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27867    case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27868    case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27869    case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27870        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27871        break;
27872    case MMI_OPC_3_PCPYH:
27873        gen_mmi_pcpyh(ctx);
27874        break;
27875    case MMI_OPC_3_PCPYUD:
27876        gen_mmi_pcpyud(ctx);
27877        break;
27878    default:
27879        MIPS_INVAL("TX79 MMI class MMI3");
27880        generate_exception_end(ctx, EXCP_RI);
27881        break;
27882    }
27883}
27884
27885static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27886{
27887    uint32_t opc = MASK_MMI(ctx->opcode);
27888    int rs = extract32(ctx->opcode, 21, 5);
27889    int rt = extract32(ctx->opcode, 16, 5);
27890    int rd = extract32(ctx->opcode, 11, 5);
27891
27892    switch (opc) {
27893    case MMI_OPC_CLASS_MMI0:
27894        decode_mmi0(env, ctx);
27895        break;
27896    case MMI_OPC_CLASS_MMI1:
27897        decode_mmi1(env, ctx);
27898        break;
27899    case MMI_OPC_CLASS_MMI2:
27900        decode_mmi2(env, ctx);
27901        break;
27902    case MMI_OPC_CLASS_MMI3:
27903        decode_mmi3(env, ctx);
27904        break;
27905    case MMI_OPC_MULT1:
27906    case MMI_OPC_MULTU1:
27907    case MMI_OPC_MADD:
27908    case MMI_OPC_MADDU:
27909    case MMI_OPC_MADD1:
27910    case MMI_OPC_MADDU1:
27911        gen_mul_txx9(ctx, opc, rd, rs, rt);
27912        break;
27913    case MMI_OPC_DIV1:
27914    case MMI_OPC_DIVU1:
27915        gen_div1_tx79(ctx, opc, rs, rt);
27916        break;
27917    case MMI_OPC_MTLO1:
27918    case MMI_OPC_MTHI1:
27919        gen_HILO1_tx79(ctx, opc, rs);
27920        break;
27921    case MMI_OPC_MFLO1:
27922    case MMI_OPC_MFHI1:
27923        gen_HILO1_tx79(ctx, opc, rd);
27924        break;
27925    case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
27926    case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
27927    case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
27928    case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
27929    case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
27930    case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
27931    case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
27932    case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
27933    case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
27934        generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
27935        break;
27936    default:
27937        MIPS_INVAL("TX79 MMI class");
27938        generate_exception_end(ctx, EXCP_RI);
27939        break;
27940    }
27941}
27942
27943static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27944{
27945    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
27946}
27947
27948static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27949{
27950    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
27951}
27952
27953/*
27954 * The TX79-specific instruction Store Quadword
27955 *
27956 * +--------+-------+-------+------------------------+
27957 * | 011111 |  base |   rt  |           offset       | SQ
27958 * +--------+-------+-------+------------------------+
27959 *      6       5       5                 16
27960 *
27961 * has the same opcode as the Read Hardware Register instruction
27962 *
27963 * +--------+-------+-------+-------+-------+--------+
27964 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
27965 * +--------+-------+-------+-------+-------+--------+
27966 *      6       5       5       5       5        6
27967 *
27968 * that is required, trapped and emulated by the Linux kernel. However, all
27969 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27970 * offset is odd. Therefore all valid SQ instructions can execute normally.
27971 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27972 * between SQ and RDHWR, as the Linux kernel does.
27973 */
27974static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27975{
27976    int base = extract32(ctx->opcode, 21, 5);
27977    int rt = extract32(ctx->opcode, 16, 5);
27978    int offset = extract32(ctx->opcode, 0, 16);
27979
27980#ifdef CONFIG_USER_ONLY
27981    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27982    uint32_t op2 = extract32(ctx->opcode, 6, 5);
27983
27984    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27985        int rd = extract32(ctx->opcode, 11, 5);
27986
27987        gen_rdhwr(ctx, rt, rd, 0);
27988        return;
27989    }
27990#endif
27991
27992    gen_mmi_sq(ctx, base, rt, offset);
27993}
27994
27995#endif
27996
27997static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27998{
27999    int rs, rt, rd, sa;
28000    uint32_t op1, op2;
28001    int16_t imm;
28002
28003    rs = (ctx->opcode >> 21) & 0x1f;
28004    rt = (ctx->opcode >> 16) & 0x1f;
28005    rd = (ctx->opcode >> 11) & 0x1f;
28006    sa = (ctx->opcode >> 6) & 0x1f;
28007    imm = sextract32(ctx->opcode, 7, 9);
28008
28009    op1 = MASK_SPECIAL3(ctx->opcode);
28010
28011    /*
28012     * EVA loads and stores overlap Loongson 2E instructions decoded by
28013     * decode_opc_special3_legacy(), so be careful to allow their decoding when
28014     * EVA is absent.
28015     */
28016    if (ctx->eva) {
28017        switch (op1) {
28018        case OPC_LWLE:
28019        case OPC_LWRE:
28020            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28021            /* fall through */
28022        case OPC_LBUE:
28023        case OPC_LHUE:
28024        case OPC_LBE:
28025        case OPC_LHE:
28026        case OPC_LLE:
28027        case OPC_LWE:
28028            check_cp0_enabled(ctx);
28029            gen_ld(ctx, op1, rt, rs, imm);
28030            return;
28031        case OPC_SWLE:
28032        case OPC_SWRE:
28033            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28034            /* fall through */
28035        case OPC_SBE:
28036        case OPC_SHE:
28037        case OPC_SWE:
28038            check_cp0_enabled(ctx);
28039            gen_st(ctx, op1, rt, rs, imm);
28040            return;
28041        case OPC_SCE:
28042            check_cp0_enabled(ctx);
28043            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
28044            return;
28045        case OPC_CACHEE:
28046            check_cp0_enabled(ctx);
28047            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28048                gen_cache_operation(ctx, rt, rs, imm);
28049            }
28050            /* Treat as NOP. */
28051            return;
28052        case OPC_PREFE:
28053            check_cp0_enabled(ctx);
28054            /* Treat as NOP. */
28055            return;
28056        }
28057    }
28058
28059    switch (op1) {
28060    case OPC_EXT:
28061    case OPC_INS:
28062        check_insn(ctx, ISA_MIPS32R2);
28063        gen_bitops(ctx, op1, rt, rs, sa, rd);
28064        break;
28065    case OPC_BSHFL:
28066        op2 = MASK_BSHFL(ctx->opcode);
28067        switch (op2) {
28068        case OPC_ALIGN:
28069        case OPC_ALIGN_1:
28070        case OPC_ALIGN_2:
28071        case OPC_ALIGN_3:
28072        case OPC_BITSWAP:
28073            check_insn(ctx, ISA_MIPS32R6);
28074            decode_opc_special3_r6(env, ctx);
28075            break;
28076        default:
28077            check_insn(ctx, ISA_MIPS32R2);
28078            gen_bshfl(ctx, op2, rt, rd);
28079            break;
28080        }
28081        break;
28082#if defined(TARGET_MIPS64)
28083    case OPC_DEXTM:
28084    case OPC_DEXTU:
28085    case OPC_DEXT:
28086    case OPC_DINSM:
28087    case OPC_DINSU:
28088    case OPC_DINS:
28089        check_insn(ctx, ISA_MIPS64R2);
28090        check_mips_64(ctx);
28091        gen_bitops(ctx, op1, rt, rs, sa, rd);
28092        break;
28093    case OPC_DBSHFL:
28094        op2 = MASK_DBSHFL(ctx->opcode);
28095        switch (op2) {
28096        case OPC_DALIGN:
28097        case OPC_DALIGN_1:
28098        case OPC_DALIGN_2:
28099        case OPC_DALIGN_3:
28100        case OPC_DALIGN_4:
28101        case OPC_DALIGN_5:
28102        case OPC_DALIGN_6:
28103        case OPC_DALIGN_7:
28104        case OPC_DBITSWAP:
28105            check_insn(ctx, ISA_MIPS32R6);
28106            decode_opc_special3_r6(env, ctx);
28107            break;
28108        default:
28109            check_insn(ctx, ISA_MIPS64R2);
28110            check_mips_64(ctx);
28111            op2 = MASK_DBSHFL(ctx->opcode);
28112            gen_bshfl(ctx, op2, rt, rd);
28113            break;
28114        }
28115        break;
28116#endif
28117    case OPC_RDHWR:
28118        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
28119        break;
28120    case OPC_FORK:
28121        check_mt(ctx);
28122        {
28123            TCGv t0 = tcg_temp_new();
28124            TCGv t1 = tcg_temp_new();
28125
28126            gen_load_gpr(t0, rt);
28127            gen_load_gpr(t1, rs);
28128            gen_helper_fork(t0, t1);
28129            tcg_temp_free(t0);
28130            tcg_temp_free(t1);
28131        }
28132        break;
28133    case OPC_YIELD:
28134        check_mt(ctx);
28135        {
28136            TCGv t0 = tcg_temp_new();
28137
28138            gen_load_gpr(t0, rs);
28139            gen_helper_yield(t0, cpu_env, t0);
28140            gen_store_gpr(t0, rd);
28141            tcg_temp_free(t0);
28142        }
28143        break;
28144    default:
28145        if (ctx->insn_flags & ISA_MIPS32R6) {
28146            decode_opc_special3_r6(env, ctx);
28147        } else {
28148            decode_opc_special3_legacy(env, ctx);
28149        }
28150    }
28151}
28152
28153/* MIPS SIMD Architecture (MSA)  */
28154static inline int check_msa_access(DisasContext *ctx)
28155{
28156    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
28157                 !(ctx->hflags & MIPS_HFLAG_F64))) {
28158        generate_exception_end(ctx, EXCP_RI);
28159        return 0;
28160    }
28161
28162    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
28163        if (ctx->insn_flags & ASE_MSA) {
28164            generate_exception_end(ctx, EXCP_MSADIS);
28165            return 0;
28166        } else {
28167            generate_exception_end(ctx, EXCP_RI);
28168            return 0;
28169        }
28170    }
28171    return 1;
28172}
28173
28174static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
28175{
28176    /* generates tcg ops to check if any element is 0 */
28177    /* Note this function only works with MSA_WRLEN = 128 */
28178    uint64_t eval_zero_or_big = 0;
28179    uint64_t eval_big = 0;
28180    TCGv_i64 t0 = tcg_temp_new_i64();
28181    TCGv_i64 t1 = tcg_temp_new_i64();
28182    switch (df) {
28183    case DF_BYTE:
28184        eval_zero_or_big = 0x0101010101010101ULL;
28185        eval_big = 0x8080808080808080ULL;
28186        break;
28187    case DF_HALF:
28188        eval_zero_or_big = 0x0001000100010001ULL;
28189        eval_big = 0x8000800080008000ULL;
28190        break;
28191    case DF_WORD:
28192        eval_zero_or_big = 0x0000000100000001ULL;
28193        eval_big = 0x8000000080000000ULL;
28194        break;
28195    case DF_DOUBLE:
28196        eval_zero_or_big = 0x0000000000000001ULL;
28197        eval_big = 0x8000000000000000ULL;
28198        break;
28199    }
28200    tcg_gen_subi_i64(t0, msa_wr_d[wt << 1], eval_zero_or_big);
28201    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt << 1]);
28202    tcg_gen_andi_i64(t0, t0, eval_big);
28203    tcg_gen_subi_i64(t1, msa_wr_d[(wt << 1) + 1], eval_zero_or_big);
28204    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt << 1) + 1]);
28205    tcg_gen_andi_i64(t1, t1, eval_big);
28206    tcg_gen_or_i64(t0, t0, t1);
28207    /* if all bits are zero then all elements are not zero */
28208    /* if some bit is non-zero then some element is zero */
28209    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
28210    tcg_gen_trunc_i64_tl(tresult, t0);
28211    tcg_temp_free_i64(t0);
28212    tcg_temp_free_i64(t1);
28213}
28214
28215static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
28216{
28217    uint8_t df = (ctx->opcode >> 21) & 0x3;
28218    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28219    int64_t s16 = (int16_t)ctx->opcode;
28220
28221    check_msa_access(ctx);
28222
28223    if (ctx->hflags & MIPS_HFLAG_BMASK) {
28224        generate_exception_end(ctx, EXCP_RI);
28225        return;
28226    }
28227    switch (op1) {
28228    case OPC_BZ_V:
28229    case OPC_BNZ_V:
28230        {
28231            TCGv_i64 t0 = tcg_temp_new_i64();
28232            tcg_gen_or_i64(t0, msa_wr_d[wt << 1], msa_wr_d[(wt << 1) + 1]);
28233            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
28234                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
28235            tcg_gen_trunc_i64_tl(bcond, t0);
28236            tcg_temp_free_i64(t0);
28237        }
28238        break;
28239    case OPC_BZ_B:
28240    case OPC_BZ_H:
28241    case OPC_BZ_W:
28242    case OPC_BZ_D:
28243        gen_check_zero_element(bcond, df, wt);
28244        break;
28245    case OPC_BNZ_B:
28246    case OPC_BNZ_H:
28247    case OPC_BNZ_W:
28248    case OPC_BNZ_D:
28249        gen_check_zero_element(bcond, df, wt);
28250        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
28251        break;
28252    }
28253
28254    ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
28255
28256    ctx->hflags |= MIPS_HFLAG_BC;
28257    ctx->hflags |= MIPS_HFLAG_BDS32;
28258}
28259
28260static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
28261{
28262#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28263    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
28264    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28265    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28266
28267    TCGv_i32 twd = tcg_const_i32(wd);
28268    TCGv_i32 tws = tcg_const_i32(ws);
28269    TCGv_i32 ti8 = tcg_const_i32(i8);
28270
28271    switch (MASK_MSA_I8(ctx->opcode)) {
28272    case OPC_ANDI_B:
28273        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
28274        break;
28275    case OPC_ORI_B:
28276        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
28277        break;
28278    case OPC_NORI_B:
28279        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
28280        break;
28281    case OPC_XORI_B:
28282        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
28283        break;
28284    case OPC_BMNZI_B:
28285        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
28286        break;
28287    case OPC_BMZI_B:
28288        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
28289        break;
28290    case OPC_BSELI_B:
28291        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
28292        break;
28293    case OPC_SHF_B:
28294    case OPC_SHF_H:
28295    case OPC_SHF_W:
28296        {
28297            uint8_t df = (ctx->opcode >> 24) & 0x3;
28298            if (df == DF_DOUBLE) {
28299                generate_exception_end(ctx, EXCP_RI);
28300            } else {
28301                TCGv_i32 tdf = tcg_const_i32(df);
28302                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
28303                tcg_temp_free_i32(tdf);
28304            }
28305        }
28306        break;
28307    default:
28308        MIPS_INVAL("MSA instruction");
28309        generate_exception_end(ctx, EXCP_RI);
28310        break;
28311    }
28312
28313    tcg_temp_free_i32(twd);
28314    tcg_temp_free_i32(tws);
28315    tcg_temp_free_i32(ti8);
28316}
28317
28318static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28319{
28320#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28321    uint8_t df = (ctx->opcode >> 21) & 0x3;
28322    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28323    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28324    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28325    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28326
28327    TCGv_i32 tdf = tcg_const_i32(df);
28328    TCGv_i32 twd = tcg_const_i32(wd);
28329    TCGv_i32 tws = tcg_const_i32(ws);
28330    TCGv_i32 timm = tcg_temp_new_i32();
28331    tcg_gen_movi_i32(timm, u5);
28332
28333    switch (MASK_MSA_I5(ctx->opcode)) {
28334    case OPC_ADDVI_df:
28335        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28336        break;
28337    case OPC_SUBVI_df:
28338        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28339        break;
28340    case OPC_MAXI_S_df:
28341        tcg_gen_movi_i32(timm, s5);
28342        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28343        break;
28344    case OPC_MAXI_U_df:
28345        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28346        break;
28347    case OPC_MINI_S_df:
28348        tcg_gen_movi_i32(timm, s5);
28349        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28350        break;
28351    case OPC_MINI_U_df:
28352        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28353        break;
28354    case OPC_CEQI_df:
28355        tcg_gen_movi_i32(timm, s5);
28356        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28357        break;
28358    case OPC_CLTI_S_df:
28359        tcg_gen_movi_i32(timm, s5);
28360        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28361        break;
28362    case OPC_CLTI_U_df:
28363        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28364        break;
28365    case OPC_CLEI_S_df:
28366        tcg_gen_movi_i32(timm, s5);
28367        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28368        break;
28369    case OPC_CLEI_U_df:
28370        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28371        break;
28372    case OPC_LDI_df:
28373        {
28374            int32_t s10 = sextract32(ctx->opcode, 11, 10);
28375            tcg_gen_movi_i32(timm, s10);
28376            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28377        }
28378        break;
28379    default:
28380        MIPS_INVAL("MSA instruction");
28381        generate_exception_end(ctx, EXCP_RI);
28382        break;
28383    }
28384
28385    tcg_temp_free_i32(tdf);
28386    tcg_temp_free_i32(twd);
28387    tcg_temp_free_i32(tws);
28388    tcg_temp_free_i32(timm);
28389}
28390
28391static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28392{
28393#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28394    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28395    uint32_t df = 0, m = 0;
28396    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28397    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28398
28399    TCGv_i32 tdf;
28400    TCGv_i32 tm;
28401    TCGv_i32 twd;
28402    TCGv_i32 tws;
28403
28404    if ((dfm & 0x40) == 0x00) {
28405        m = dfm & 0x3f;
28406        df = DF_DOUBLE;
28407    } else if ((dfm & 0x60) == 0x40) {
28408        m = dfm & 0x1f;
28409        df = DF_WORD;
28410    } else if ((dfm & 0x70) == 0x60) {
28411        m = dfm & 0x0f;
28412        df = DF_HALF;
28413    } else if ((dfm & 0x78) == 0x70) {
28414        m = dfm & 0x7;
28415        df = DF_BYTE;
28416    } else {
28417        generate_exception_end(ctx, EXCP_RI);
28418        return;
28419    }
28420
28421    tdf = tcg_const_i32(df);
28422    tm  = tcg_const_i32(m);
28423    twd = tcg_const_i32(wd);
28424    tws = tcg_const_i32(ws);
28425
28426    switch (MASK_MSA_BIT(ctx->opcode)) {
28427    case OPC_SLLI_df:
28428        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28429        break;
28430    case OPC_SRAI_df:
28431        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28432        break;
28433    case OPC_SRLI_df:
28434        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28435        break;
28436    case OPC_BCLRI_df:
28437        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28438        break;
28439    case OPC_BSETI_df:
28440        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28441        break;
28442    case OPC_BNEGI_df:
28443        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28444        break;
28445    case OPC_BINSLI_df:
28446        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28447        break;
28448    case OPC_BINSRI_df:
28449        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28450        break;
28451    case OPC_SAT_S_df:
28452        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28453        break;
28454    case OPC_SAT_U_df:
28455        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28456        break;
28457    case OPC_SRARI_df:
28458        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28459        break;
28460    case OPC_SRLRI_df:
28461        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
28462        break;
28463    default:
28464        MIPS_INVAL("MSA instruction");
28465        generate_exception_end(ctx, EXCP_RI);
28466        break;
28467    }
28468
28469    tcg_temp_free_i32(tdf);
28470    tcg_temp_free_i32(tm);
28471    tcg_temp_free_i32(twd);
28472    tcg_temp_free_i32(tws);
28473}
28474
28475static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28476{
28477#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28478    uint8_t df = (ctx->opcode >> 21) & 0x3;
28479    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28480    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28481    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28482
28483    TCGv_i32 tdf = tcg_const_i32(df);
28484    TCGv_i32 twd = tcg_const_i32(wd);
28485    TCGv_i32 tws = tcg_const_i32(ws);
28486    TCGv_i32 twt = tcg_const_i32(wt);
28487
28488    switch (MASK_MSA_3R(ctx->opcode)) {
28489    case OPC_BINSL_df:
28490        switch (df) {
28491        case DF_BYTE:
28492            gen_helper_msa_binsl_b(cpu_env, twd, tws, twt);
28493            break;
28494        case DF_HALF:
28495            gen_helper_msa_binsl_h(cpu_env, twd, tws, twt);
28496            break;
28497        case DF_WORD:
28498            gen_helper_msa_binsl_w(cpu_env, twd, tws, twt);
28499            break;
28500        case DF_DOUBLE:
28501            gen_helper_msa_binsl_d(cpu_env, twd, tws, twt);
28502            break;
28503        }
28504        break;
28505    case OPC_BINSR_df:
28506        switch (df) {
28507        case DF_BYTE:
28508            gen_helper_msa_binsr_b(cpu_env, twd, tws, twt);
28509            break;
28510        case DF_HALF:
28511            gen_helper_msa_binsr_h(cpu_env, twd, tws, twt);
28512            break;
28513        case DF_WORD:
28514            gen_helper_msa_binsr_w(cpu_env, twd, tws, twt);
28515            break;
28516        case DF_DOUBLE:
28517            gen_helper_msa_binsr_d(cpu_env, twd, tws, twt);
28518            break;
28519        }
28520        break;
28521    case OPC_BCLR_df:
28522        switch (df) {
28523        case DF_BYTE:
28524            gen_helper_msa_bclr_b(cpu_env, twd, tws, twt);
28525            break;
28526        case DF_HALF:
28527            gen_helper_msa_bclr_h(cpu_env, twd, tws, twt);
28528            break;
28529        case DF_WORD:
28530            gen_helper_msa_bclr_w(cpu_env, twd, tws, twt);
28531            break;
28532        case DF_DOUBLE:
28533            gen_helper_msa_bclr_d(cpu_env, twd, tws, twt);
28534            break;
28535        }
28536        break;
28537    case OPC_BNEG_df:
28538        switch (df) {
28539        case DF_BYTE:
28540            gen_helper_msa_bneg_b(cpu_env, twd, tws, twt);
28541            break;
28542        case DF_HALF:
28543            gen_helper_msa_bneg_h(cpu_env, twd, tws, twt);
28544            break;
28545        case DF_WORD:
28546            gen_helper_msa_bneg_w(cpu_env, twd, tws, twt);
28547            break;
28548        case DF_DOUBLE:
28549            gen_helper_msa_bneg_d(cpu_env, twd, tws, twt);
28550            break;
28551        }
28552        break;
28553    case OPC_BSET_df:
28554        switch (df) {
28555        case DF_BYTE:
28556            gen_helper_msa_bset_b(cpu_env, twd, tws, twt);
28557            break;
28558        case DF_HALF:
28559            gen_helper_msa_bset_h(cpu_env, twd, tws, twt);
28560            break;
28561        case DF_WORD:
28562            gen_helper_msa_bset_w(cpu_env, twd, tws, twt);
28563            break;
28564        case DF_DOUBLE:
28565            gen_helper_msa_bset_d(cpu_env, twd, tws, twt);
28566            break;
28567        }
28568        break;
28569    case OPC_ADD_A_df:
28570        switch (df) {
28571        case DF_BYTE:
28572            gen_helper_msa_add_a_b(cpu_env, twd, tws, twt);
28573            break;
28574        case DF_HALF:
28575            gen_helper_msa_add_a_h(cpu_env, twd, tws, twt);
28576            break;
28577        case DF_WORD:
28578            gen_helper_msa_add_a_w(cpu_env, twd, tws, twt);
28579            break;
28580        case DF_DOUBLE:
28581            gen_helper_msa_add_a_d(cpu_env, twd, tws, twt);
28582            break;
28583        }
28584        break;
28585    case OPC_ADDS_A_df:
28586        switch (df) {
28587        case DF_BYTE:
28588            gen_helper_msa_adds_a_b(cpu_env, twd, tws, twt);
28589            break;
28590        case DF_HALF:
28591            gen_helper_msa_adds_a_h(cpu_env, twd, tws, twt);
28592            break;
28593        case DF_WORD:
28594            gen_helper_msa_adds_a_w(cpu_env, twd, tws, twt);
28595            break;
28596        case DF_DOUBLE:
28597            gen_helper_msa_adds_a_d(cpu_env, twd, tws, twt);
28598            break;
28599        }
28600        break;
28601    case OPC_ADDS_S_df:
28602        switch (df) {
28603        case DF_BYTE:
28604            gen_helper_msa_adds_s_b(cpu_env, twd, tws, twt);
28605            break;
28606        case DF_HALF:
28607            gen_helper_msa_adds_s_h(cpu_env, twd, tws, twt);
28608            break;
28609        case DF_WORD:
28610            gen_helper_msa_adds_s_w(cpu_env, twd, tws, twt);
28611            break;
28612        case DF_DOUBLE:
28613            gen_helper_msa_adds_s_d(cpu_env, twd, tws, twt);
28614            break;
28615        }
28616        break;
28617    case OPC_ADDS_U_df:
28618        switch (df) {
28619        case DF_BYTE:
28620            gen_helper_msa_adds_u_b(cpu_env, twd, tws, twt);
28621            break;
28622        case DF_HALF:
28623            gen_helper_msa_adds_u_h(cpu_env, twd, tws, twt);
28624            break;
28625        case DF_WORD:
28626            gen_helper_msa_adds_u_w(cpu_env, twd, tws, twt);
28627            break;
28628        case DF_DOUBLE:
28629            gen_helper_msa_adds_u_d(cpu_env, twd, tws, twt);
28630            break;
28631        }
28632        break;
28633    case OPC_ADDV_df:
28634        switch (df) {
28635        case DF_BYTE:
28636            gen_helper_msa_addv_b(cpu_env, twd, tws, twt);
28637            break;
28638        case DF_HALF:
28639            gen_helper_msa_addv_h(cpu_env, twd, tws, twt);
28640            break;
28641        case DF_WORD:
28642            gen_helper_msa_addv_w(cpu_env, twd, tws, twt);
28643            break;
28644        case DF_DOUBLE:
28645            gen_helper_msa_addv_d(cpu_env, twd, tws, twt);
28646            break;
28647        }
28648        break;
28649    case OPC_AVE_S_df:
28650        switch (df) {
28651        case DF_BYTE:
28652            gen_helper_msa_ave_s_b(cpu_env, twd, tws, twt);
28653            break;
28654        case DF_HALF:
28655            gen_helper_msa_ave_s_h(cpu_env, twd, tws, twt);
28656            break;
28657        case DF_WORD:
28658            gen_helper_msa_ave_s_w(cpu_env, twd, tws, twt);
28659            break;
28660        case DF_DOUBLE:
28661            gen_helper_msa_ave_s_d(cpu_env, twd, tws, twt);
28662            break;
28663        }
28664        break;
28665    case OPC_AVE_U_df:
28666        switch (df) {
28667        case DF_BYTE:
28668            gen_helper_msa_ave_u_b(cpu_env, twd, tws, twt);
28669            break;
28670        case DF_HALF:
28671            gen_helper_msa_ave_u_h(cpu_env, twd, tws, twt);
28672            break;
28673        case DF_WORD:
28674            gen_helper_msa_ave_u_w(cpu_env, twd, tws, twt);
28675            break;
28676        case DF_DOUBLE:
28677            gen_helper_msa_ave_u_d(cpu_env, twd, tws, twt);
28678            break;
28679        }
28680        break;
28681    case OPC_AVER_S_df:
28682        switch (df) {
28683        case DF_BYTE:
28684            gen_helper_msa_aver_s_b(cpu_env, twd, tws, twt);
28685            break;
28686        case DF_HALF:
28687            gen_helper_msa_aver_s_h(cpu_env, twd, tws, twt);
28688            break;
28689        case DF_WORD:
28690            gen_helper_msa_aver_s_w(cpu_env, twd, tws, twt);
28691            break;
28692        case DF_DOUBLE:
28693            gen_helper_msa_aver_s_d(cpu_env, twd, tws, twt);
28694            break;
28695        }
28696        break;
28697    case OPC_AVER_U_df:
28698        switch (df) {
28699        case DF_BYTE:
28700            gen_helper_msa_aver_u_b(cpu_env, twd, tws, twt);
28701            break;
28702        case DF_HALF:
28703            gen_helper_msa_aver_u_h(cpu_env, twd, tws, twt);
28704            break;
28705        case DF_WORD:
28706            gen_helper_msa_aver_u_w(cpu_env, twd, tws, twt);
28707            break;
28708        case DF_DOUBLE:
28709            gen_helper_msa_aver_u_d(cpu_env, twd, tws, twt);
28710            break;
28711        }
28712        break;
28713    case OPC_CEQ_df:
28714        switch (df) {
28715        case DF_BYTE:
28716            gen_helper_msa_ceq_b(cpu_env, twd, tws, twt);
28717            break;
28718        case DF_HALF:
28719            gen_helper_msa_ceq_h(cpu_env, twd, tws, twt);
28720            break;
28721        case DF_WORD:
28722            gen_helper_msa_ceq_w(cpu_env, twd, tws, twt);
28723            break;
28724        case DF_DOUBLE:
28725            gen_helper_msa_ceq_d(cpu_env, twd, tws, twt);
28726            break;
28727        }
28728        break;
28729    case OPC_CLE_S_df:
28730        switch (df) {
28731        case DF_BYTE:
28732            gen_helper_msa_cle_s_b(cpu_env, twd, tws, twt);
28733            break;
28734        case DF_HALF:
28735            gen_helper_msa_cle_s_h(cpu_env, twd, tws, twt);
28736            break;
28737        case DF_WORD:
28738            gen_helper_msa_cle_s_w(cpu_env, twd, tws, twt);
28739            break;
28740        case DF_DOUBLE:
28741            gen_helper_msa_cle_s_d(cpu_env, twd, tws, twt);
28742            break;
28743        }
28744        break;
28745    case OPC_CLE_U_df:
28746        switch (df) {
28747        case DF_BYTE:
28748            gen_helper_msa_cle_u_b(cpu_env, twd, tws, twt);
28749            break;
28750        case DF_HALF:
28751            gen_helper_msa_cle_u_h(cpu_env, twd, tws, twt);
28752            break;
28753        case DF_WORD:
28754            gen_helper_msa_cle_u_w(cpu_env, twd, tws, twt);
28755            break;
28756        case DF_DOUBLE:
28757            gen_helper_msa_cle_u_d(cpu_env, twd, tws, twt);
28758            break;
28759        }
28760        break;
28761    case OPC_CLT_S_df:
28762        switch (df) {
28763        case DF_BYTE:
28764            gen_helper_msa_clt_s_b(cpu_env, twd, tws, twt);
28765            break;
28766        case DF_HALF:
28767            gen_helper_msa_clt_s_h(cpu_env, twd, tws, twt);
28768            break;
28769        case DF_WORD:
28770            gen_helper_msa_clt_s_w(cpu_env, twd, tws, twt);
28771            break;
28772        case DF_DOUBLE:
28773            gen_helper_msa_clt_s_d(cpu_env, twd, tws, twt);
28774            break;
28775        }
28776        break;
28777    case OPC_CLT_U_df:
28778        switch (df) {
28779        case DF_BYTE:
28780            gen_helper_msa_clt_u_b(cpu_env, twd, tws, twt);
28781            break;
28782        case DF_HALF:
28783            gen_helper_msa_clt_u_h(cpu_env, twd, tws, twt);
28784            break;
28785        case DF_WORD:
28786            gen_helper_msa_clt_u_w(cpu_env, twd, tws, twt);
28787            break;
28788        case DF_DOUBLE:
28789            gen_helper_msa_clt_u_d(cpu_env, twd, tws, twt);
28790            break;
28791        }
28792        break;
28793    case OPC_DIV_S_df:
28794        switch (df) {
28795        case DF_BYTE:
28796            gen_helper_msa_div_s_b(cpu_env, twd, tws, twt);
28797            break;
28798        case DF_HALF:
28799            gen_helper_msa_div_s_h(cpu_env, twd, tws, twt);
28800            break;
28801        case DF_WORD:
28802            gen_helper_msa_div_s_w(cpu_env, twd, tws, twt);
28803            break;
28804        case DF_DOUBLE:
28805            gen_helper_msa_div_s_d(cpu_env, twd, tws, twt);
28806            break;
28807        }
28808        break;
28809    case OPC_DIV_U_df:
28810        switch (df) {
28811        case DF_BYTE:
28812            gen_helper_msa_div_u_b(cpu_env, twd, tws, twt);
28813            break;
28814        case DF_HALF:
28815            gen_helper_msa_div_u_h(cpu_env, twd, tws, twt);
28816            break;
28817        case DF_WORD:
28818            gen_helper_msa_div_u_w(cpu_env, twd, tws, twt);
28819            break;
28820        case DF_DOUBLE:
28821            gen_helper_msa_div_u_d(cpu_env, twd, tws, twt);
28822            break;
28823        }
28824        break;
28825    case OPC_MAX_A_df:
28826        switch (df) {
28827        case DF_BYTE:
28828            gen_helper_msa_max_a_b(cpu_env, twd, tws, twt);
28829            break;
28830        case DF_HALF:
28831            gen_helper_msa_max_a_h(cpu_env, twd, tws, twt);
28832            break;
28833        case DF_WORD:
28834            gen_helper_msa_max_a_w(cpu_env, twd, tws, twt);
28835            break;
28836        case DF_DOUBLE:
28837            gen_helper_msa_max_a_d(cpu_env, twd, tws, twt);
28838            break;
28839        }
28840        break;
28841    case OPC_MAX_S_df:
28842        switch (df) {
28843        case DF_BYTE:
28844            gen_helper_msa_max_s_b(cpu_env, twd, tws, twt);
28845            break;
28846        case DF_HALF:
28847            gen_helper_msa_max_s_h(cpu_env, twd, tws, twt);
28848            break;
28849        case DF_WORD:
28850            gen_helper_msa_max_s_w(cpu_env, twd, tws, twt);
28851            break;
28852        case DF_DOUBLE:
28853            gen_helper_msa_max_s_d(cpu_env, twd, tws, twt);
28854            break;
28855        }
28856        break;
28857    case OPC_MAX_U_df:
28858        switch (df) {
28859        case DF_BYTE:
28860            gen_helper_msa_max_u_b(cpu_env, twd, tws, twt);
28861            break;
28862        case DF_HALF:
28863            gen_helper_msa_max_u_h(cpu_env, twd, tws, twt);
28864            break;
28865        case DF_WORD:
28866            gen_helper_msa_max_u_w(cpu_env, twd, tws, twt);
28867            break;
28868        case DF_DOUBLE:
28869            gen_helper_msa_max_u_d(cpu_env, twd, tws, twt);
28870            break;
28871        }
28872        break;
28873    case OPC_MIN_A_df:
28874        switch (df) {
28875        case DF_BYTE:
28876            gen_helper_msa_min_a_b(cpu_env, twd, tws, twt);
28877            break;
28878        case DF_HALF:
28879            gen_helper_msa_min_a_h(cpu_env, twd, tws, twt);
28880            break;
28881        case DF_WORD:
28882            gen_helper_msa_min_a_w(cpu_env, twd, tws, twt);
28883            break;
28884        case DF_DOUBLE:
28885            gen_helper_msa_min_a_d(cpu_env, twd, tws, twt);
28886            break;
28887        }
28888        break;
28889    case OPC_MIN_S_df:
28890        switch (df) {
28891        case DF_BYTE:
28892            gen_helper_msa_min_s_b(cpu_env, twd, tws, twt);
28893            break;
28894        case DF_HALF:
28895            gen_helper_msa_min_s_h(cpu_env, twd, tws, twt);
28896            break;
28897        case DF_WORD:
28898            gen_helper_msa_min_s_w(cpu_env, twd, tws, twt);
28899            break;
28900        case DF_DOUBLE:
28901            gen_helper_msa_min_s_d(cpu_env, twd, tws, twt);
28902            break;
28903        }
28904        break;
28905    case OPC_MIN_U_df:
28906        switch (df) {
28907        case DF_BYTE:
28908            gen_helper_msa_min_u_b(cpu_env, twd, tws, twt);
28909            break;
28910        case DF_HALF:
28911            gen_helper_msa_min_u_h(cpu_env, twd, tws, twt);
28912            break;
28913        case DF_WORD:
28914            gen_helper_msa_min_u_w(cpu_env, twd, tws, twt);
28915            break;
28916        case DF_DOUBLE:
28917            gen_helper_msa_min_u_d(cpu_env, twd, tws, twt);
28918            break;
28919        }
28920        break;
28921    case OPC_MOD_S_df:
28922        switch (df) {
28923        case DF_BYTE:
28924            gen_helper_msa_mod_s_b(cpu_env, twd, tws, twt);
28925            break;
28926        case DF_HALF:
28927            gen_helper_msa_mod_s_h(cpu_env, twd, tws, twt);
28928            break;
28929        case DF_WORD:
28930            gen_helper_msa_mod_s_w(cpu_env, twd, tws, twt);
28931            break;
28932        case DF_DOUBLE:
28933            gen_helper_msa_mod_s_d(cpu_env, twd, tws, twt);
28934            break;
28935        }
28936        break;
28937    case OPC_MOD_U_df:
28938        switch (df) {
28939        case DF_BYTE:
28940            gen_helper_msa_mod_u_b(cpu_env, twd, tws, twt);
28941            break;
28942        case DF_HALF:
28943            gen_helper_msa_mod_u_h(cpu_env, twd, tws, twt);
28944            break;
28945        case DF_WORD:
28946            gen_helper_msa_mod_u_w(cpu_env, twd, tws, twt);
28947            break;
28948        case DF_DOUBLE:
28949            gen_helper_msa_mod_u_d(cpu_env, twd, tws, twt);
28950            break;
28951        }
28952        break;
28953    case OPC_ASUB_S_df:
28954        switch (df) {
28955        case DF_BYTE:
28956            gen_helper_msa_asub_s_b(cpu_env, twd, tws, twt);
28957            break;
28958        case DF_HALF:
28959            gen_helper_msa_asub_s_h(cpu_env, twd, tws, twt);
28960            break;
28961        case DF_WORD:
28962            gen_helper_msa_asub_s_w(cpu_env, twd, tws, twt);
28963            break;
28964        case DF_DOUBLE:
28965            gen_helper_msa_asub_s_d(cpu_env, twd, tws, twt);
28966            break;
28967        }
28968        break;
28969    case OPC_ASUB_U_df:
28970        switch (df) {
28971        case DF_BYTE:
28972            gen_helper_msa_asub_u_b(cpu_env, twd, tws, twt);
28973            break;
28974        case DF_HALF:
28975            gen_helper_msa_asub_u_h(cpu_env, twd, tws, twt);
28976            break;
28977        case DF_WORD:
28978            gen_helper_msa_asub_u_w(cpu_env, twd, tws, twt);
28979            break;
28980        case DF_DOUBLE:
28981            gen_helper_msa_asub_u_d(cpu_env, twd, tws, twt);
28982            break;
28983        }
28984        break;
28985    case OPC_ILVEV_df:
28986        switch (df) {
28987        case DF_BYTE:
28988            gen_helper_msa_ilvev_b(cpu_env, twd, tws, twt);
28989            break;
28990        case DF_HALF:
28991            gen_helper_msa_ilvev_h(cpu_env, twd, tws, twt);
28992            break;
28993        case DF_WORD:
28994            gen_helper_msa_ilvev_w(cpu_env, twd, tws, twt);
28995            break;
28996        case DF_DOUBLE:
28997            gen_helper_msa_ilvev_d(cpu_env, twd, tws, twt);
28998            break;
28999        }
29000        break;
29001    case OPC_ILVOD_df:
29002        switch (df) {
29003        case DF_BYTE:
29004            gen_helper_msa_ilvod_b(cpu_env, twd, tws, twt);
29005            break;
29006        case DF_HALF:
29007            gen_helper_msa_ilvod_h(cpu_env, twd, tws, twt);
29008            break;
29009        case DF_WORD:
29010            gen_helper_msa_ilvod_w(cpu_env, twd, tws, twt);
29011            break;
29012        case DF_DOUBLE:
29013            gen_helper_msa_ilvod_d(cpu_env, twd, tws, twt);
29014            break;
29015        }
29016        break;
29017    case OPC_ILVL_df:
29018        switch (df) {
29019        case DF_BYTE:
29020            gen_helper_msa_ilvl_b(cpu_env, twd, tws, twt);
29021            break;
29022        case DF_HALF:
29023            gen_helper_msa_ilvl_h(cpu_env, twd, tws, twt);
29024            break;
29025        case DF_WORD:
29026            gen_helper_msa_ilvl_w(cpu_env, twd, tws, twt);
29027            break;
29028        case DF_DOUBLE:
29029            gen_helper_msa_ilvl_d(cpu_env, twd, tws, twt);
29030            break;
29031        }
29032        break;
29033    case OPC_ILVR_df:
29034        switch (df) {
29035        case DF_BYTE:
29036            gen_helper_msa_ilvr_b(cpu_env, twd, tws, twt);
29037            break;
29038        case DF_HALF:
29039            gen_helper_msa_ilvr_h(cpu_env, twd, tws, twt);
29040            break;
29041        case DF_WORD:
29042            gen_helper_msa_ilvr_w(cpu_env, twd, tws, twt);
29043            break;
29044        case DF_DOUBLE:
29045            gen_helper_msa_ilvr_d(cpu_env, twd, tws, twt);
29046            break;
29047        }
29048        break;
29049    case OPC_PCKEV_df:
29050        switch (df) {
29051        case DF_BYTE:
29052            gen_helper_msa_pckev_b(cpu_env, twd, tws, twt);
29053            break;
29054        case DF_HALF:
29055            gen_helper_msa_pckev_h(cpu_env, twd, tws, twt);
29056            break;
29057        case DF_WORD:
29058            gen_helper_msa_pckev_w(cpu_env, twd, tws, twt);
29059            break;
29060        case DF_DOUBLE:
29061            gen_helper_msa_pckev_d(cpu_env, twd, tws, twt);
29062            break;
29063        }
29064        break;
29065    case OPC_PCKOD_df:
29066        switch (df) {
29067        case DF_BYTE:
29068            gen_helper_msa_pckod_b(cpu_env, twd, tws, twt);
29069            break;
29070        case DF_HALF:
29071            gen_helper_msa_pckod_h(cpu_env, twd, tws, twt);
29072            break;
29073        case DF_WORD:
29074            gen_helper_msa_pckod_w(cpu_env, twd, tws, twt);
29075            break;
29076        case DF_DOUBLE:
29077            gen_helper_msa_pckod_d(cpu_env, twd, tws, twt);
29078            break;
29079        }
29080        break;
29081    case OPC_SLL_df:
29082        switch (df) {
29083        case DF_BYTE:
29084            gen_helper_msa_sll_b(cpu_env, twd, tws, twt);
29085            break;
29086        case DF_HALF:
29087            gen_helper_msa_sll_h(cpu_env, twd, tws, twt);
29088            break;
29089        case DF_WORD:
29090            gen_helper_msa_sll_w(cpu_env, twd, tws, twt);
29091            break;
29092        case DF_DOUBLE:
29093            gen_helper_msa_sll_d(cpu_env, twd, tws, twt);
29094            break;
29095        }
29096        break;
29097    case OPC_SRA_df:
29098        switch (df) {
29099        case DF_BYTE:
29100            gen_helper_msa_sra_b(cpu_env, twd, tws, twt);
29101            break;
29102        case DF_HALF:
29103            gen_helper_msa_sra_h(cpu_env, twd, tws, twt);
29104            break;
29105        case DF_WORD:
29106            gen_helper_msa_sra_w(cpu_env, twd, tws, twt);
29107            break;
29108        case DF_DOUBLE:
29109            gen_helper_msa_sra_d(cpu_env, twd, tws, twt);
29110            break;
29111        }
29112        break;
29113    case OPC_SRAR_df:
29114        switch (df) {
29115        case DF_BYTE:
29116            gen_helper_msa_srar_b(cpu_env, twd, tws, twt);
29117            break;
29118        case DF_HALF:
29119            gen_helper_msa_srar_h(cpu_env, twd, tws, twt);
29120            break;
29121        case DF_WORD:
29122            gen_helper_msa_srar_w(cpu_env, twd, tws, twt);
29123            break;
29124        case DF_DOUBLE:
29125            gen_helper_msa_srar_d(cpu_env, twd, tws, twt);
29126            break;
29127        }
29128        break;
29129    case OPC_SRL_df:
29130        switch (df) {
29131        case DF_BYTE:
29132            gen_helper_msa_srl_b(cpu_env, twd, tws, twt);
29133            break;
29134        case DF_HALF:
29135            gen_helper_msa_srl_h(cpu_env, twd, tws, twt);
29136            break;
29137        case DF_WORD:
29138            gen_helper_msa_srl_w(cpu_env, twd, tws, twt);
29139            break;
29140        case DF_DOUBLE:
29141            gen_helper_msa_srl_d(cpu_env, twd, tws, twt);
29142            break;
29143        }
29144        break;
29145    case OPC_SRLR_df:
29146        switch (df) {
29147        case DF_BYTE:
29148            gen_helper_msa_srlr_b(cpu_env, twd, tws, twt);
29149            break;
29150        case DF_HALF:
29151            gen_helper_msa_srlr_h(cpu_env, twd, tws, twt);
29152            break;
29153        case DF_WORD:
29154            gen_helper_msa_srlr_w(cpu_env, twd, tws, twt);
29155            break;
29156        case DF_DOUBLE:
29157            gen_helper_msa_srlr_d(cpu_env, twd, tws, twt);
29158            break;
29159        }
29160        break;
29161    case OPC_SUBS_S_df:
29162        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
29163        break;
29164    case OPC_MULV_df:
29165        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
29166        break;
29167    case OPC_SLD_df:
29168        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
29169        break;
29170    case OPC_VSHF_df:
29171        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
29172        break;
29173    case OPC_SUBV_df:
29174        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
29175        break;
29176    case OPC_SUBS_U_df:
29177        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
29178        break;
29179    case OPC_MADDV_df:
29180        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
29181        break;
29182    case OPC_SPLAT_df:
29183        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
29184        break;
29185    case OPC_SUBSUS_U_df:
29186        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
29187        break;
29188    case OPC_MSUBV_df:
29189        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
29190        break;
29191    case OPC_SUBSUU_S_df:
29192        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
29193        break;
29194
29195    case OPC_DOTP_S_df:
29196    case OPC_DOTP_U_df:
29197    case OPC_DPADD_S_df:
29198    case OPC_DPADD_U_df:
29199    case OPC_DPSUB_S_df:
29200    case OPC_HADD_S_df:
29201    case OPC_DPSUB_U_df:
29202    case OPC_HADD_U_df:
29203    case OPC_HSUB_S_df:
29204    case OPC_HSUB_U_df:
29205        if (df == DF_BYTE) {
29206            generate_exception_end(ctx, EXCP_RI);
29207            break;
29208        }
29209        switch (MASK_MSA_3R(ctx->opcode)) {
29210        case OPC_HADD_S_df:
29211            switch (df) {
29212            case DF_HALF:
29213                gen_helper_msa_hadd_s_h(cpu_env, twd, tws, twt);
29214                break;
29215            case DF_WORD:
29216                gen_helper_msa_hadd_s_w(cpu_env, twd, tws, twt);
29217                break;
29218            case DF_DOUBLE:
29219                gen_helper_msa_hadd_s_d(cpu_env, twd, tws, twt);
29220                break;
29221            }
29222            break;
29223        case OPC_HADD_U_df:
29224            switch (df) {
29225            case DF_HALF:
29226                gen_helper_msa_hadd_u_h(cpu_env, twd, tws, twt);
29227                break;
29228            case DF_WORD:
29229                gen_helper_msa_hadd_u_w(cpu_env, twd, tws, twt);
29230                break;
29231            case DF_DOUBLE:
29232                gen_helper_msa_hadd_u_d(cpu_env, twd, tws, twt);
29233                break;
29234            }
29235            break;
29236        case OPC_HSUB_S_df:
29237            switch (df) {
29238            case DF_HALF:
29239                gen_helper_msa_hsub_s_h(cpu_env, twd, tws, twt);
29240                break;
29241            case DF_WORD:
29242                gen_helper_msa_hsub_s_w(cpu_env, twd, tws, twt);
29243                break;
29244            case DF_DOUBLE:
29245                gen_helper_msa_hsub_s_d(cpu_env, twd, tws, twt);
29246                break;
29247            }
29248            break;
29249        case OPC_HSUB_U_df:
29250            switch (df) {
29251            case DF_HALF:
29252                gen_helper_msa_hsub_u_h(cpu_env, twd, tws, twt);
29253                break;
29254            case DF_WORD:
29255                gen_helper_msa_hsub_u_w(cpu_env, twd, tws, twt);
29256                break;
29257            case DF_DOUBLE:
29258                gen_helper_msa_hsub_u_d(cpu_env, twd, tws, twt);
29259                break;
29260            }
29261            break;
29262        case OPC_DOTP_S_df:
29263            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
29264            break;
29265        case OPC_DOTP_U_df:
29266            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
29267            break;
29268        case OPC_DPADD_S_df:
29269            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
29270            break;
29271        case OPC_DPADD_U_df:
29272            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
29273            break;
29274        case OPC_DPSUB_S_df:
29275            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
29276            break;
29277        case OPC_DPSUB_U_df:
29278            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
29279            break;
29280        }
29281        break;
29282    default:
29283        MIPS_INVAL("MSA instruction");
29284        generate_exception_end(ctx, EXCP_RI);
29285        break;
29286    }
29287    tcg_temp_free_i32(twd);
29288    tcg_temp_free_i32(tws);
29289    tcg_temp_free_i32(twt);
29290    tcg_temp_free_i32(tdf);
29291}
29292
29293static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
29294{
29295#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29296    uint8_t source = (ctx->opcode >> 11) & 0x1f;
29297    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
29298    TCGv telm = tcg_temp_new();
29299    TCGv_i32 tsr = tcg_const_i32(source);
29300    TCGv_i32 tdt = tcg_const_i32(dest);
29301
29302    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
29303    case OPC_CTCMSA:
29304        gen_load_gpr(telm, source);
29305        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
29306        break;
29307    case OPC_CFCMSA:
29308        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
29309        gen_store_gpr(telm, dest);
29310        break;
29311    case OPC_MOVE_V:
29312        gen_helper_msa_move_v(cpu_env, tdt, tsr);
29313        break;
29314    default:
29315        MIPS_INVAL("MSA instruction");
29316        generate_exception_end(ctx, EXCP_RI);
29317        break;
29318    }
29319
29320    tcg_temp_free(telm);
29321    tcg_temp_free_i32(tdt);
29322    tcg_temp_free_i32(tsr);
29323}
29324
29325static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
29326        uint32_t n)
29327{
29328#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29329    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29330    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29331
29332    TCGv_i32 tws = tcg_const_i32(ws);
29333    TCGv_i32 twd = tcg_const_i32(wd);
29334    TCGv_i32 tn  = tcg_const_i32(n);
29335    TCGv_i32 tdf = tcg_const_i32(df);
29336
29337    switch (MASK_MSA_ELM(ctx->opcode)) {
29338    case OPC_SLDI_df:
29339        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
29340        break;
29341    case OPC_SPLATI_df:
29342        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
29343        break;
29344    case OPC_INSVE_df:
29345        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
29346        break;
29347    case OPC_COPY_S_df:
29348    case OPC_COPY_U_df:
29349    case OPC_INSERT_df:
29350#if !defined(TARGET_MIPS64)
29351        /* Double format valid only for MIPS64 */
29352        if (df == DF_DOUBLE) {
29353            generate_exception_end(ctx, EXCP_RI);
29354            break;
29355        }
29356        if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
29357              (df == DF_WORD)) {
29358            generate_exception_end(ctx, EXCP_RI);
29359            break;
29360        }
29361#endif
29362        switch (MASK_MSA_ELM(ctx->opcode)) {
29363        case OPC_COPY_S_df:
29364            if (likely(wd != 0)) {
29365                switch (df) {
29366                case DF_BYTE:
29367                    gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
29368                    break;
29369                case DF_HALF:
29370                    gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
29371                    break;
29372                case DF_WORD:
29373                    gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
29374                    break;
29375#if defined(TARGET_MIPS64)
29376                case DF_DOUBLE:
29377                    gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
29378                    break;
29379#endif
29380                default:
29381                    assert(0);
29382                }
29383            }
29384            break;
29385        case OPC_COPY_U_df:
29386            if (likely(wd != 0)) {
29387                switch (df) {
29388                case DF_BYTE:
29389                    gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
29390                    break;
29391                case DF_HALF:
29392                    gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
29393                    break;
29394#if defined(TARGET_MIPS64)
29395                case DF_WORD:
29396                    gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
29397                    break;
29398#endif
29399                default:
29400                    assert(0);
29401                }
29402            }
29403            break;
29404        case OPC_INSERT_df:
29405            switch (df) {
29406            case DF_BYTE:
29407                gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
29408                break;
29409            case DF_HALF:
29410                gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
29411                break;
29412            case DF_WORD:
29413                gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
29414                break;
29415#if defined(TARGET_MIPS64)
29416            case DF_DOUBLE:
29417                gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
29418                break;
29419#endif
29420            default:
29421                assert(0);
29422            }
29423            break;
29424        }
29425        break;
29426    default:
29427        MIPS_INVAL("MSA instruction");
29428        generate_exception_end(ctx, EXCP_RI);
29429    }
29430    tcg_temp_free_i32(twd);
29431    tcg_temp_free_i32(tws);
29432    tcg_temp_free_i32(tn);
29433    tcg_temp_free_i32(tdf);
29434}
29435
29436static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
29437{
29438    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
29439    uint32_t df = 0, n = 0;
29440
29441    if ((dfn & 0x30) == 0x00) {
29442        n = dfn & 0x0f;
29443        df = DF_BYTE;
29444    } else if ((dfn & 0x38) == 0x20) {
29445        n = dfn & 0x07;
29446        df = DF_HALF;
29447    } else if ((dfn & 0x3c) == 0x30) {
29448        n = dfn & 0x03;
29449        df = DF_WORD;
29450    } else if ((dfn & 0x3e) == 0x38) {
29451        n = dfn & 0x01;
29452        df = DF_DOUBLE;
29453    } else if (dfn == 0x3E) {
29454        /* CTCMSA, CFCMSA, MOVE.V */
29455        gen_msa_elm_3e(env, ctx);
29456        return;
29457    } else {
29458        generate_exception_end(ctx, EXCP_RI);
29459        return;
29460    }
29461
29462    gen_msa_elm_df(env, ctx, df, n);
29463}
29464
29465static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
29466{
29467#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29468    uint8_t df = (ctx->opcode >> 21) & 0x1;
29469    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29470    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29471    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29472
29473    TCGv_i32 twd = tcg_const_i32(wd);
29474    TCGv_i32 tws = tcg_const_i32(ws);
29475    TCGv_i32 twt = tcg_const_i32(wt);
29476    TCGv_i32 tdf = tcg_temp_new_i32();
29477
29478    /* adjust df value for floating-point instruction */
29479    tcg_gen_movi_i32(tdf, df + 2);
29480
29481    switch (MASK_MSA_3RF(ctx->opcode)) {
29482    case OPC_FCAF_df:
29483        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
29484        break;
29485    case OPC_FADD_df:
29486        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
29487        break;
29488    case OPC_FCUN_df:
29489        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
29490        break;
29491    case OPC_FSUB_df:
29492        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
29493        break;
29494    case OPC_FCOR_df:
29495        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
29496        break;
29497    case OPC_FCEQ_df:
29498        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
29499        break;
29500    case OPC_FMUL_df:
29501        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
29502        break;
29503    case OPC_FCUNE_df:
29504        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
29505        break;
29506    case OPC_FCUEQ_df:
29507        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
29508        break;
29509    case OPC_FDIV_df:
29510        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
29511        break;
29512    case OPC_FCNE_df:
29513        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
29514        break;
29515    case OPC_FCLT_df:
29516        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
29517        break;
29518    case OPC_FMADD_df:
29519        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
29520        break;
29521    case OPC_MUL_Q_df:
29522        tcg_gen_movi_i32(tdf, df + 1);
29523        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
29524        break;
29525    case OPC_FCULT_df:
29526        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
29527        break;
29528    case OPC_FMSUB_df:
29529        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
29530        break;
29531    case OPC_MADD_Q_df:
29532        tcg_gen_movi_i32(tdf, df + 1);
29533        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
29534        break;
29535    case OPC_FCLE_df:
29536        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
29537        break;
29538    case OPC_MSUB_Q_df:
29539        tcg_gen_movi_i32(tdf, df + 1);
29540        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
29541        break;
29542    case OPC_FCULE_df:
29543        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
29544        break;
29545    case OPC_FEXP2_df:
29546        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
29547        break;
29548    case OPC_FSAF_df:
29549        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
29550        break;
29551    case OPC_FEXDO_df:
29552        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
29553        break;
29554    case OPC_FSUN_df:
29555        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
29556        break;
29557    case OPC_FSOR_df:
29558        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
29559        break;
29560    case OPC_FSEQ_df:
29561        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
29562        break;
29563    case OPC_FTQ_df:
29564        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
29565        break;
29566    case OPC_FSUNE_df:
29567        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
29568        break;
29569    case OPC_FSUEQ_df:
29570        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
29571        break;
29572    case OPC_FSNE_df:
29573        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
29574        break;
29575    case OPC_FSLT_df:
29576        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
29577        break;
29578    case OPC_FMIN_df:
29579        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
29580        break;
29581    case OPC_MULR_Q_df:
29582        tcg_gen_movi_i32(tdf, df + 1);
29583        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
29584        break;
29585    case OPC_FSULT_df:
29586        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
29587        break;
29588    case OPC_FMIN_A_df:
29589        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
29590        break;
29591    case OPC_MADDR_Q_df:
29592        tcg_gen_movi_i32(tdf, df + 1);
29593        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
29594        break;
29595    case OPC_FSLE_df:
29596        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
29597        break;
29598    case OPC_FMAX_df:
29599        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
29600        break;
29601    case OPC_MSUBR_Q_df:
29602        tcg_gen_movi_i32(tdf, df + 1);
29603        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
29604        break;
29605    case OPC_FSULE_df:
29606        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
29607        break;
29608    case OPC_FMAX_A_df:
29609        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
29610        break;
29611    default:
29612        MIPS_INVAL("MSA instruction");
29613        generate_exception_end(ctx, EXCP_RI);
29614        break;
29615    }
29616
29617    tcg_temp_free_i32(twd);
29618    tcg_temp_free_i32(tws);
29619    tcg_temp_free_i32(twt);
29620    tcg_temp_free_i32(tdf);
29621}
29622
29623static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
29624{
29625#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29626                            (op & (0x7 << 18)))
29627    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29628    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29629    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29630    uint8_t df = (ctx->opcode >> 16) & 0x3;
29631    TCGv_i32 twd = tcg_const_i32(wd);
29632    TCGv_i32 tws = tcg_const_i32(ws);
29633    TCGv_i32 twt = tcg_const_i32(wt);
29634    TCGv_i32 tdf = tcg_const_i32(df);
29635
29636    switch (MASK_MSA_2R(ctx->opcode)) {
29637    case OPC_FILL_df:
29638#if !defined(TARGET_MIPS64)
29639        /* Double format valid only for MIPS64 */
29640        if (df == DF_DOUBLE) {
29641            generate_exception_end(ctx, EXCP_RI);
29642            break;
29643        }
29644#endif
29645        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
29646        break;
29647    case OPC_NLOC_df:
29648        switch (df) {
29649        case DF_BYTE:
29650            gen_helper_msa_nloc_b(cpu_env, twd, tws);
29651            break;
29652        case DF_HALF:
29653            gen_helper_msa_nloc_h(cpu_env, twd, tws);
29654            break;
29655        case DF_WORD:
29656            gen_helper_msa_nloc_w(cpu_env, twd, tws);
29657            break;
29658        case DF_DOUBLE:
29659            gen_helper_msa_nloc_d(cpu_env, twd, tws);
29660            break;
29661        }
29662        break;
29663    case OPC_NLZC_df:
29664        switch (df) {
29665        case DF_BYTE:
29666            gen_helper_msa_nlzc_b(cpu_env, twd, tws);
29667            break;
29668        case DF_HALF:
29669            gen_helper_msa_nlzc_h(cpu_env, twd, tws);
29670            break;
29671        case DF_WORD:
29672            gen_helper_msa_nlzc_w(cpu_env, twd, tws);
29673            break;
29674        case DF_DOUBLE:
29675            gen_helper_msa_nlzc_d(cpu_env, twd, tws);
29676            break;
29677        }
29678        break;
29679    case OPC_PCNT_df:
29680        switch (df) {
29681        case DF_BYTE:
29682            gen_helper_msa_pcnt_b(cpu_env, twd, tws);
29683            break;
29684        case DF_HALF:
29685            gen_helper_msa_pcnt_h(cpu_env, twd, tws);
29686            break;
29687        case DF_WORD:
29688            gen_helper_msa_pcnt_w(cpu_env, twd, tws);
29689            break;
29690        case DF_DOUBLE:
29691            gen_helper_msa_pcnt_d(cpu_env, twd, tws);
29692            break;
29693        }
29694        break;
29695    default:
29696        MIPS_INVAL("MSA instruction");
29697        generate_exception_end(ctx, EXCP_RI);
29698        break;
29699    }
29700
29701    tcg_temp_free_i32(twd);
29702    tcg_temp_free_i32(tws);
29703    tcg_temp_free_i32(twt);
29704    tcg_temp_free_i32(tdf);
29705}
29706
29707static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
29708{
29709#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29710                            (op & (0xf << 17)))
29711    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29712    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29713    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29714    uint8_t df = (ctx->opcode >> 16) & 0x1;
29715    TCGv_i32 twd = tcg_const_i32(wd);
29716    TCGv_i32 tws = tcg_const_i32(ws);
29717    TCGv_i32 twt = tcg_const_i32(wt);
29718    /* adjust df value for floating-point instruction */
29719    TCGv_i32 tdf = tcg_const_i32(df + 2);
29720
29721    switch (MASK_MSA_2RF(ctx->opcode)) {
29722    case OPC_FCLASS_df:
29723        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
29724        break;
29725    case OPC_FTRUNC_S_df:
29726        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
29727        break;
29728    case OPC_FTRUNC_U_df:
29729        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
29730        break;
29731    case OPC_FSQRT_df:
29732        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
29733        break;
29734    case OPC_FRSQRT_df:
29735        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
29736        break;
29737    case OPC_FRCP_df:
29738        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
29739        break;
29740    case OPC_FRINT_df:
29741        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
29742        break;
29743    case OPC_FLOG2_df:
29744        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
29745        break;
29746    case OPC_FEXUPL_df:
29747        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
29748        break;
29749    case OPC_FEXUPR_df:
29750        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
29751        break;
29752    case OPC_FFQL_df:
29753        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
29754        break;
29755    case OPC_FFQR_df:
29756        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
29757        break;
29758    case OPC_FTINT_S_df:
29759        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
29760        break;
29761    case OPC_FTINT_U_df:
29762        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
29763        break;
29764    case OPC_FFINT_S_df:
29765        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
29766        break;
29767    case OPC_FFINT_U_df:
29768        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
29769        break;
29770    }
29771
29772    tcg_temp_free_i32(twd);
29773    tcg_temp_free_i32(tws);
29774    tcg_temp_free_i32(twt);
29775    tcg_temp_free_i32(tdf);
29776}
29777
29778static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
29779{
29780#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29781    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
29782    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
29783    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29784    TCGv_i32 twd = tcg_const_i32(wd);
29785    TCGv_i32 tws = tcg_const_i32(ws);
29786    TCGv_i32 twt = tcg_const_i32(wt);
29787
29788    switch (MASK_MSA_VEC(ctx->opcode)) {
29789    case OPC_AND_V:
29790        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
29791        break;
29792    case OPC_OR_V:
29793        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
29794        break;
29795    case OPC_NOR_V:
29796        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
29797        break;
29798    case OPC_XOR_V:
29799        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
29800        break;
29801    case OPC_BMNZ_V:
29802        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
29803        break;
29804    case OPC_BMZ_V:
29805        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
29806        break;
29807    case OPC_BSEL_V:
29808        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
29809        break;
29810    default:
29811        MIPS_INVAL("MSA instruction");
29812        generate_exception_end(ctx, EXCP_RI);
29813        break;
29814    }
29815
29816    tcg_temp_free_i32(twd);
29817    tcg_temp_free_i32(tws);
29818    tcg_temp_free_i32(twt);
29819}
29820
29821static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
29822{
29823    switch (MASK_MSA_VEC(ctx->opcode)) {
29824    case OPC_AND_V:
29825    case OPC_OR_V:
29826    case OPC_NOR_V:
29827    case OPC_XOR_V:
29828    case OPC_BMNZ_V:
29829    case OPC_BMZ_V:
29830    case OPC_BSEL_V:
29831        gen_msa_vec_v(env, ctx);
29832        break;
29833    case OPC_MSA_2R:
29834        gen_msa_2r(env, ctx);
29835        break;
29836    case OPC_MSA_2RF:
29837        gen_msa_2rf(env, ctx);
29838        break;
29839    default:
29840        MIPS_INVAL("MSA instruction");
29841        generate_exception_end(ctx, EXCP_RI);
29842        break;
29843    }
29844}
29845
29846static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
29847{
29848    uint32_t opcode = ctx->opcode;
29849    check_insn(ctx, ASE_MSA);
29850    check_msa_access(ctx);
29851
29852    switch (MASK_MSA_MINOR(opcode)) {
29853    case OPC_MSA_I8_00:
29854    case OPC_MSA_I8_01:
29855    case OPC_MSA_I8_02:
29856        gen_msa_i8(env, ctx);
29857        break;
29858    case OPC_MSA_I5_06:
29859    case OPC_MSA_I5_07:
29860        gen_msa_i5(env, ctx);
29861        break;
29862    case OPC_MSA_BIT_09:
29863    case OPC_MSA_BIT_0A:
29864        gen_msa_bit(env, ctx);
29865        break;
29866    case OPC_MSA_3R_0D:
29867    case OPC_MSA_3R_0E:
29868    case OPC_MSA_3R_0F:
29869    case OPC_MSA_3R_10:
29870    case OPC_MSA_3R_11:
29871    case OPC_MSA_3R_12:
29872    case OPC_MSA_3R_13:
29873    case OPC_MSA_3R_14:
29874    case OPC_MSA_3R_15:
29875        gen_msa_3r(env, ctx);
29876        break;
29877    case OPC_MSA_ELM:
29878        gen_msa_elm(env, ctx);
29879        break;
29880    case OPC_MSA_3RF_1A:
29881    case OPC_MSA_3RF_1B:
29882    case OPC_MSA_3RF_1C:
29883        gen_msa_3rf(env, ctx);
29884        break;
29885    case OPC_MSA_VEC:
29886        gen_msa_vec(env, ctx);
29887        break;
29888    case OPC_LD_B:
29889    case OPC_LD_H:
29890    case OPC_LD_W:
29891    case OPC_LD_D:
29892    case OPC_ST_B:
29893    case OPC_ST_H:
29894    case OPC_ST_W:
29895    case OPC_ST_D:
29896        {
29897            int32_t s10 = sextract32(ctx->opcode, 16, 10);
29898            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
29899            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
29900            uint8_t df = (ctx->opcode >> 0) & 0x3;
29901
29902            TCGv_i32 twd = tcg_const_i32(wd);
29903            TCGv taddr = tcg_temp_new();
29904            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
29905
29906            switch (MASK_MSA_MINOR(opcode)) {
29907            case OPC_LD_B:
29908                gen_helper_msa_ld_b(cpu_env, twd, taddr);
29909                break;
29910            case OPC_LD_H:
29911                gen_helper_msa_ld_h(cpu_env, twd, taddr);
29912                break;
29913            case OPC_LD_W:
29914                gen_helper_msa_ld_w(cpu_env, twd, taddr);
29915                break;
29916            case OPC_LD_D:
29917                gen_helper_msa_ld_d(cpu_env, twd, taddr);
29918                break;
29919            case OPC_ST_B:
29920                gen_helper_msa_st_b(cpu_env, twd, taddr);
29921                break;
29922            case OPC_ST_H:
29923                gen_helper_msa_st_h(cpu_env, twd, taddr);
29924                break;
29925            case OPC_ST_W:
29926                gen_helper_msa_st_w(cpu_env, twd, taddr);
29927                break;
29928            case OPC_ST_D:
29929                gen_helper_msa_st_d(cpu_env, twd, taddr);
29930                break;
29931            }
29932
29933            tcg_temp_free_i32(twd);
29934            tcg_temp_free(taddr);
29935        }
29936        break;
29937    default:
29938        MIPS_INVAL("MSA instruction");
29939        generate_exception_end(ctx, EXCP_RI);
29940        break;
29941    }
29942
29943}
29944
29945static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
29946{
29947    int32_t offset;
29948    int rs, rt, rd, sa;
29949    uint32_t op, op1;
29950    int16_t imm;
29951
29952    /* make sure instructions are on a word boundary */
29953    if (ctx->base.pc_next & 0x3) {
29954        env->CP0_BadVAddr = ctx->base.pc_next;
29955        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
29956        return;
29957    }
29958
29959    /* Handle blikely not taken case */
29960    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
29961        TCGLabel *l1 = gen_new_label();
29962
29963        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
29964        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
29965        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
29966        gen_set_label(l1);
29967    }
29968
29969    op = MASK_OP_MAJOR(ctx->opcode);
29970    rs = (ctx->opcode >> 21) & 0x1f;
29971    rt = (ctx->opcode >> 16) & 0x1f;
29972    rd = (ctx->opcode >> 11) & 0x1f;
29973    sa = (ctx->opcode >> 6) & 0x1f;
29974    imm = (int16_t)ctx->opcode;
29975    switch (op) {
29976    case OPC_SPECIAL:
29977        decode_opc_special(env, ctx);
29978        break;
29979    case OPC_SPECIAL2:
29980#if defined(TARGET_MIPS64)
29981        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
29982            decode_mmi(env, ctx);
29983#else
29984        if (ctx->insn_flags & ASE_MXU) {
29985            decode_opc_mxu(env, ctx);
29986#endif
29987        } else {
29988            decode_opc_special2_legacy(env, ctx);
29989        }
29990        break;
29991    case OPC_SPECIAL3:
29992#if defined(TARGET_MIPS64)
29993        if (ctx->insn_flags & INSN_R5900) {
29994            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
29995        } else {
29996            decode_opc_special3(env, ctx);
29997        }
29998#else
29999        decode_opc_special3(env, ctx);
30000#endif
30001        break;
30002    case OPC_REGIMM:
30003        op1 = MASK_REGIMM(ctx->opcode);
30004        switch (op1) {
30005        case OPC_BLTZL: /* REGIMM branches */
30006        case OPC_BGEZL:
30007        case OPC_BLTZALL:
30008        case OPC_BGEZALL:
30009            check_insn(ctx, ISA_MIPS2);
30010            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30011            /* Fallthrough */
30012        case OPC_BLTZ:
30013        case OPC_BGEZ:
30014            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
30015            break;
30016        case OPC_BLTZAL:
30017        case OPC_BGEZAL:
30018            if (ctx->insn_flags & ISA_MIPS32R6) {
30019                if (rs == 0) {
30020                    /* OPC_NAL, OPC_BAL */
30021                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
30022                } else {
30023                    generate_exception_end(ctx, EXCP_RI);
30024                }
30025            } else {
30026                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
30027            }
30028            break;
30029        case OPC_TGEI: /* REGIMM traps */
30030        case OPC_TGEIU:
30031        case OPC_TLTI:
30032        case OPC_TLTIU:
30033        case OPC_TEQI:
30034
30035        case OPC_TNEI:
30036            check_insn(ctx, ISA_MIPS2);
30037            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30038            gen_trap(ctx, op1, rs, -1, imm);
30039            break;
30040        case OPC_SIGRIE:
30041            check_insn(ctx, ISA_MIPS32R6);
30042            generate_exception_end(ctx, EXCP_RI);
30043            break;
30044        case OPC_SYNCI:
30045            check_insn(ctx, ISA_MIPS32R2);
30046            /*
30047             * Break the TB to be able to sync copied instructions
30048             * immediately.
30049             */
30050            ctx->base.is_jmp = DISAS_STOP;
30051            break;
30052        case OPC_BPOSGE32:    /* MIPS DSP branch */
30053#if defined(TARGET_MIPS64)
30054        case OPC_BPOSGE64:
30055#endif
30056            check_dsp(ctx);
30057            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
30058            break;
30059#if defined(TARGET_MIPS64)
30060        case OPC_DAHI:
30061            check_insn(ctx, ISA_MIPS32R6);
30062            check_mips_64(ctx);
30063            if (rs != 0) {
30064                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
30065            }
30066            break;
30067        case OPC_DATI:
30068            check_insn(ctx, ISA_MIPS32R6);
30069            check_mips_64(ctx);
30070            if (rs != 0) {
30071                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
30072            }
30073            break;
30074#endif
30075        default:            /* Invalid */
30076            MIPS_INVAL("regimm");
30077            generate_exception_end(ctx, EXCP_RI);
30078            break;
30079        }
30080        break;
30081    case OPC_CP0:
30082        check_cp0_enabled(ctx);
30083        op1 = MASK_CP0(ctx->opcode);
30084        switch (op1) {
30085        case OPC_MFC0:
30086        case OPC_MTC0:
30087        case OPC_MFTR:
30088        case OPC_MTTR:
30089        case OPC_MFHC0:
30090        case OPC_MTHC0:
30091#if defined(TARGET_MIPS64)
30092        case OPC_DMFC0:
30093        case OPC_DMTC0:
30094#endif
30095#ifndef CONFIG_USER_ONLY
30096            gen_cp0(env, ctx, op1, rt, rd);
30097#endif /* !CONFIG_USER_ONLY */
30098            break;
30099        case OPC_C0:
30100        case OPC_C0_1:
30101        case OPC_C0_2:
30102        case OPC_C0_3:
30103        case OPC_C0_4:
30104        case OPC_C0_5:
30105        case OPC_C0_6:
30106        case OPC_C0_7:
30107        case OPC_C0_8:
30108        case OPC_C0_9:
30109        case OPC_C0_A:
30110        case OPC_C0_B:
30111        case OPC_C0_C:
30112        case OPC_C0_D:
30113        case OPC_C0_E:
30114        case OPC_C0_F:
30115#ifndef CONFIG_USER_ONLY
30116            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
30117#endif /* !CONFIG_USER_ONLY */
30118            break;
30119        case OPC_MFMC0:
30120#ifndef CONFIG_USER_ONLY
30121            {
30122                uint32_t op2;
30123                TCGv t0 = tcg_temp_new();
30124
30125                op2 = MASK_MFMC0(ctx->opcode);
30126                switch (op2) {
30127                case OPC_DMT:
30128                    check_cp0_mt(ctx);
30129                    gen_helper_dmt(t0);
30130                    gen_store_gpr(t0, rt);
30131                    break;
30132                case OPC_EMT:
30133                    check_cp0_mt(ctx);
30134                    gen_helper_emt(t0);
30135                    gen_store_gpr(t0, rt);
30136                    break;
30137                case OPC_DVPE:
30138                    check_cp0_mt(ctx);
30139                    gen_helper_dvpe(t0, cpu_env);
30140                    gen_store_gpr(t0, rt);
30141                    break;
30142                case OPC_EVPE:
30143                    check_cp0_mt(ctx);
30144                    gen_helper_evpe(t0, cpu_env);
30145                    gen_store_gpr(t0, rt);
30146                    break;
30147                case OPC_DVP:
30148                    check_insn(ctx, ISA_MIPS32R6);
30149                    if (ctx->vp) {
30150                        gen_helper_dvp(t0, cpu_env);
30151                        gen_store_gpr(t0, rt);
30152                    }
30153                    break;
30154                case OPC_EVP:
30155                    check_insn(ctx, ISA_MIPS32R6);
30156                    if (ctx->vp) {
30157                        gen_helper_evp(t0, cpu_env);
30158                        gen_store_gpr(t0, rt);
30159                    }
30160                    break;
30161                case OPC_DI:
30162                    check_insn(ctx, ISA_MIPS32R2);
30163                    save_cpu_state(ctx, 1);
30164                    gen_helper_di(t0, cpu_env);
30165                    gen_store_gpr(t0, rt);
30166                    /*
30167                     * Stop translation as we may have switched
30168                     * the execution mode.
30169                     */
30170                    ctx->base.is_jmp = DISAS_STOP;
30171                    break;
30172                case OPC_EI:
30173                    check_insn(ctx, ISA_MIPS32R2);
30174                    save_cpu_state(ctx, 1);
30175                    gen_helper_ei(t0, cpu_env);
30176                    gen_store_gpr(t0, rt);
30177                    /*
30178                     * DISAS_STOP isn't sufficient, we need to ensure we break
30179                     * out of translated code to check for pending interrupts.
30180                     */
30181                    gen_save_pc(ctx->base.pc_next + 4);
30182                    ctx->base.is_jmp = DISAS_EXIT;
30183                    break;
30184                default:            /* Invalid */
30185                    MIPS_INVAL("mfmc0");
30186                    generate_exception_end(ctx, EXCP_RI);
30187                    break;
30188                }
30189                tcg_temp_free(t0);
30190            }
30191#endif /* !CONFIG_USER_ONLY */
30192            break;
30193        case OPC_RDPGPR:
30194            check_insn(ctx, ISA_MIPS32R2);
30195            gen_load_srsgpr(rt, rd);
30196            break;
30197        case OPC_WRPGPR:
30198            check_insn(ctx, ISA_MIPS32R2);
30199            gen_store_srsgpr(rt, rd);
30200            break;
30201        default:
30202            MIPS_INVAL("cp0");
30203            generate_exception_end(ctx, EXCP_RI);
30204            break;
30205        }
30206        break;
30207    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30208        if (ctx->insn_flags & ISA_MIPS32R6) {
30209            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30210            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30211        } else {
30212            /* OPC_ADDI */
30213            /* Arithmetic with immediate opcode */
30214            gen_arith_imm(ctx, op, rt, rs, imm);
30215        }
30216        break;
30217    case OPC_ADDIU:
30218         gen_arith_imm(ctx, op, rt, rs, imm);
30219         break;
30220    case OPC_SLTI: /* Set on less than with immediate opcode */
30221    case OPC_SLTIU:
30222         gen_slt_imm(ctx, op, rt, rs, imm);
30223         break;
30224    case OPC_ANDI: /* Arithmetic with immediate opcode */
30225    case OPC_LUI: /* OPC_AUI */
30226    case OPC_ORI:
30227    case OPC_XORI:
30228         gen_logic_imm(ctx, op, rt, rs, imm);
30229         break;
30230    case OPC_J: /* Jump */
30231    case OPC_JAL:
30232         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
30233         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
30234         break;
30235    /* Branch */
30236    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30237        if (ctx->insn_flags & ISA_MIPS32R6) {
30238            if (rt == 0) {
30239                generate_exception_end(ctx, EXCP_RI);
30240                break;
30241            }
30242            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30243            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30244        } else {
30245            /* OPC_BLEZL */
30246            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30247        }
30248        break;
30249    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30250        if (ctx->insn_flags & ISA_MIPS32R6) {
30251            if (rt == 0) {
30252                generate_exception_end(ctx, EXCP_RI);
30253                break;
30254            }
30255            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30256            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30257        } else {
30258            /* OPC_BGTZL */
30259            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30260        }
30261        break;
30262    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30263        if (rt == 0) {
30264            /* OPC_BLEZ */
30265            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30266        } else {
30267            check_insn(ctx, ISA_MIPS32R6);
30268            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30269            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30270        }
30271        break;
30272    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30273        if (rt == 0) {
30274            /* OPC_BGTZ */
30275            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30276        } else {
30277            check_insn(ctx, ISA_MIPS32R6);
30278            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30279            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30280        }
30281        break;
30282    case OPC_BEQL:
30283    case OPC_BNEL:
30284        check_insn(ctx, ISA_MIPS2);
30285         check_insn_opc_removed(ctx, ISA_MIPS32R6);
30286        /* Fallthrough */
30287    case OPC_BEQ:
30288    case OPC_BNE:
30289         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
30290         break;
30291    case OPC_LL: /* Load and stores */
30292        check_insn(ctx, ISA_MIPS2);
30293        if (ctx->insn_flags & INSN_R5900) {
30294            check_insn_opc_user_only(ctx, INSN_R5900);
30295        }
30296        /* Fallthrough */
30297    case OPC_LWL:
30298    case OPC_LWR:
30299        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30300         /* Fallthrough */
30301    case OPC_LB:
30302    case OPC_LH:
30303    case OPC_LW:
30304    case OPC_LWPC:
30305    case OPC_LBU:
30306    case OPC_LHU:
30307         gen_ld(ctx, op, rt, rs, imm);
30308         break;
30309    case OPC_SWL:
30310    case OPC_SWR:
30311        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30312        /* fall through */
30313    case OPC_SB:
30314    case OPC_SH:
30315    case OPC_SW:
30316         gen_st(ctx, op, rt, rs, imm);
30317         break;
30318    case OPC_SC:
30319        check_insn(ctx, ISA_MIPS2);
30320         check_insn_opc_removed(ctx, ISA_MIPS32R6);
30321        if (ctx->insn_flags & INSN_R5900) {
30322            check_insn_opc_user_only(ctx, INSN_R5900);
30323        }
30324        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
30325        break;
30326    case OPC_CACHE:
30327        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30328        check_cp0_enabled(ctx);
30329        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
30330        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
30331            gen_cache_operation(ctx, rt, rs, imm);
30332        }
30333        /* Treat as NOP. */
30334        break;
30335    case OPC_PREF:
30336        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30337        if (ctx->insn_flags & INSN_R5900) {
30338            /* Treat as NOP. */
30339        } else {
30340            check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
30341            /* Treat as NOP. */
30342        }
30343        break;
30344
30345    /* Floating point (COP1). */
30346    case OPC_LWC1:
30347    case OPC_LDC1:
30348    case OPC_SWC1:
30349    case OPC_SDC1:
30350        gen_cop1_ldst(ctx, op, rt, rs, imm);
30351        break;
30352
30353    case OPC_CP1:
30354        op1 = MASK_CP1(ctx->opcode);
30355
30356        switch (op1) {
30357        case OPC_MFHC1:
30358        case OPC_MTHC1:
30359            check_cp1_enabled(ctx);
30360            check_insn(ctx, ISA_MIPS32R2);
30361            /* fall through */
30362        case OPC_MFC1:
30363        case OPC_CFC1:
30364        case OPC_MTC1:
30365        case OPC_CTC1:
30366            check_cp1_enabled(ctx);
30367            gen_cp1(ctx, op1, rt, rd);
30368            break;
30369#if defined(TARGET_MIPS64)
30370        case OPC_DMFC1:
30371        case OPC_DMTC1:
30372            check_cp1_enabled(ctx);
30373            check_insn(ctx, ISA_MIPS3);
30374            check_mips_64(ctx);
30375            gen_cp1(ctx, op1, rt, rd);
30376            break;
30377#endif
30378        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
30379            check_cp1_enabled(ctx);
30380            if (ctx->insn_flags & ISA_MIPS32R6) {
30381                /* OPC_BC1EQZ */
30382                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
30383                                       rt, imm << 2, 4);
30384            } else {
30385                /* OPC_BC1ANY2 */
30386                check_cop1x(ctx);
30387                check_insn(ctx, ASE_MIPS3D);
30388                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
30389                                    (rt >> 2) & 0x7, imm << 2);
30390            }
30391            break;
30392        case OPC_BC1NEZ:
30393            check_cp1_enabled(ctx);
30394            check_insn(ctx, ISA_MIPS32R6);
30395            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
30396                                   rt, imm << 2, 4);
30397            break;
30398        case OPC_BC1ANY4:
30399            check_cp1_enabled(ctx);
30400            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30401            check_cop1x(ctx);
30402            check_insn(ctx, ASE_MIPS3D);
30403            /* fall through */
30404        case OPC_BC1:
30405            check_cp1_enabled(ctx);
30406            check_insn_opc_removed(ctx, ISA_MIPS32R6);
30407            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
30408                                (rt >> 2) & 0x7, imm << 2);
30409            break;
30410        case OPC_PS_FMT:
30411            check_ps(ctx);
30412            /* fall through */
30413        case OPC_S_FMT:
30414        case OPC_D_FMT:
30415            check_cp1_enabled(ctx);
30416            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
30417                       (imm >> 8) & 0x7);
30418            break;
30419        case OPC_W_FMT:
30420        case OPC_L_FMT:
30421        {
30422            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
30423            check_cp1_enabled(ctx);
30424            if (ctx->insn_flags & ISA_MIPS32R6) {
30425                switch (r6_op) {
30426                case R6_OPC_CMP_AF_S:
30427                case R6_OPC_CMP_UN_S:
30428                case R6_OPC_CMP_EQ_S:
30429                case R6_OPC_CMP_UEQ_S:
30430                case R6_OPC_CMP_LT_S:
30431                case R6_OPC_CMP_ULT_S:
30432                case R6_OPC_CMP_LE_S:
30433                case R6_OPC_CMP_ULE_S:
30434                case R6_OPC_CMP_SAF_S:
30435                case R6_OPC_CMP_SUN_S:
30436                case R6_OPC_CMP_SEQ_S:
30437                case R6_OPC_CMP_SEUQ_S:
30438                case R6_OPC_CMP_SLT_S:
30439                case R6_OPC_CMP_SULT_S:
30440                case R6_OPC_CMP_SLE_S:
30441                case R6_OPC_CMP_SULE_S:
30442                case R6_OPC_CMP_OR_S:
30443                case R6_OPC_CMP_UNE_S:
30444                case R6_OPC_CMP_NE_S:
30445                case R6_OPC_CMP_SOR_S:
30446                case R6_OPC_CMP_SUNE_S:
30447                case R6_OPC_CMP_SNE_S:
30448                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
30449                    break;
30450                case R6_OPC_CMP_AF_D:
30451                case R6_OPC_CMP_UN_D:
30452                case R6_OPC_CMP_EQ_D:
30453                case R6_OPC_CMP_UEQ_D:
30454                case R6_OPC_CMP_LT_D:
30455                case R6_OPC_CMP_ULT_D:
30456                case R6_OPC_CMP_LE_D:
30457                case R6_OPC_CMP_ULE_D:
30458                case R6_OPC_CMP_SAF_D:
30459                case R6_OPC_CMP_SUN_D:
30460                case R6_OPC_CMP_SEQ_D:
30461                case R6_OPC_CMP_SEUQ_D:
30462                case R6_OPC_CMP_SLT_D:
30463                case R6_OPC_CMP_SULT_D:
30464                case R6_OPC_CMP_SLE_D:
30465                case R6_OPC_CMP_SULE_D:
30466                case R6_OPC_CMP_OR_D:
30467                case R6_OPC_CMP_UNE_D:
30468                case R6_OPC_CMP_NE_D:
30469                case R6_OPC_CMP_SOR_D:
30470                case R6_OPC_CMP_SUNE_D:
30471                case R6_OPC_CMP_SNE_D:
30472                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
30473                    break;
30474                default:
30475                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
30476                               rt, rd, sa, (imm >> 8) & 0x7);
30477
30478                    break;
30479                }
30480            } else {
30481                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
30482                           (imm >> 8) & 0x7);
30483            }
30484            break;
30485        }
30486        case OPC_BZ_V:
30487        case OPC_BNZ_V:
30488        case OPC_BZ_B:
30489        case OPC_BZ_H:
30490        case OPC_BZ_W:
30491        case OPC_BZ_D:
30492        case OPC_BNZ_B:
30493        case OPC_BNZ_H:
30494        case OPC_BNZ_W:
30495        case OPC_BNZ_D:
30496            check_insn(ctx, ASE_MSA);
30497            gen_msa_branch(env, ctx, op1);
30498            break;
30499        default:
30500            MIPS_INVAL("cp1");
30501            generate_exception_end(ctx, EXCP_RI);
30502            break;
30503        }
30504        break;
30505
30506    /* Compact branches [R6] and COP2 [non-R6] */
30507    case OPC_BC: /* OPC_LWC2 */
30508    case OPC_BALC: /* OPC_SWC2 */
30509        if (ctx->insn_flags & ISA_MIPS32R6) {
30510            /* OPC_BC, OPC_BALC */
30511            gen_compute_compact_branch(ctx, op, 0, 0,
30512                                       sextract32(ctx->opcode << 2, 0, 28));
30513        } else {
30514            /* OPC_LWC2, OPC_SWC2 */
30515            /* COP2: Not implemented. */
30516            generate_exception_err(ctx, EXCP_CpU, 2);
30517        }
30518        break;
30519    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
30520    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
30521        if (ctx->insn_flags & ISA_MIPS32R6) {
30522            if (rs != 0) {
30523                /* OPC_BEQZC, OPC_BNEZC */
30524                gen_compute_compact_branch(ctx, op, rs, 0,
30525                                           sextract32(ctx->opcode << 2, 0, 23));
30526            } else {
30527                /* OPC_JIC, OPC_JIALC */
30528                gen_compute_compact_branch(ctx, op, 0, rt, imm);
30529            }
30530        } else {
30531            /* OPC_LWC2, OPC_SWC2 */
30532            /* COP2: Not implemented. */
30533            generate_exception_err(ctx, EXCP_CpU, 2);
30534        }
30535        break;
30536    case OPC_CP2:
30537        check_insn(ctx, INSN_LOONGSON2F);
30538        /* Note that these instructions use different fields.  */
30539        gen_loongson_multimedia(ctx, sa, rd, rt);
30540        break;
30541
30542    case OPC_CP3:
30543        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30544        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
30545            check_cp1_enabled(ctx);
30546            op1 = MASK_CP3(ctx->opcode);
30547            switch (op1) {
30548            case OPC_LUXC1:
30549            case OPC_SUXC1:
30550                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
30551                /* Fallthrough */
30552            case OPC_LWXC1:
30553            case OPC_LDXC1:
30554            case OPC_SWXC1:
30555            case OPC_SDXC1:
30556                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
30557                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
30558                break;
30559            case OPC_PREFX:
30560                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
30561                /* Treat as NOP. */
30562                break;
30563            case OPC_ALNV_PS:
30564                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
30565                /* Fallthrough */
30566            case OPC_MADD_S:
30567            case OPC_MADD_D:
30568            case OPC_MADD_PS:
30569            case OPC_MSUB_S:
30570            case OPC_MSUB_D:
30571            case OPC_MSUB_PS:
30572            case OPC_NMADD_S:
30573            case OPC_NMADD_D:
30574            case OPC_NMADD_PS:
30575            case OPC_NMSUB_S:
30576            case OPC_NMSUB_D:
30577            case OPC_NMSUB_PS:
30578                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
30579                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
30580                break;
30581            default:
30582                MIPS_INVAL("cp3");
30583                generate_exception_end(ctx, EXCP_RI);
30584                break;
30585            }
30586        } else {
30587            generate_exception_err(ctx, EXCP_CpU, 1);
30588        }
30589        break;
30590
30591#if defined(TARGET_MIPS64)
30592    /* MIPS64 opcodes */
30593    case OPC_LLD:
30594        if (ctx->insn_flags & INSN_R5900) {
30595            check_insn_opc_user_only(ctx, INSN_R5900);
30596        }
30597        /* fall through */
30598    case OPC_LDL:
30599    case OPC_LDR:
30600        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30601        /* fall through */
30602    case OPC_LWU:
30603    case OPC_LD:
30604        check_insn(ctx, ISA_MIPS3);
30605        check_mips_64(ctx);
30606        gen_ld(ctx, op, rt, rs, imm);
30607        break;
30608    case OPC_SDL:
30609    case OPC_SDR:
30610        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30611        /* fall through */
30612    case OPC_SD:
30613        check_insn(ctx, ISA_MIPS3);
30614        check_mips_64(ctx);
30615        gen_st(ctx, op, rt, rs, imm);
30616        break;
30617    case OPC_SCD:
30618        check_insn_opc_removed(ctx, ISA_MIPS32R6);
30619        check_insn(ctx, ISA_MIPS3);
30620        if (ctx->insn_flags & INSN_R5900) {
30621            check_insn_opc_user_only(ctx, INSN_R5900);
30622        }
30623        check_mips_64(ctx);
30624        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
30625        break;
30626    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
30627        if (ctx->insn_flags & ISA_MIPS32R6) {
30628            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
30629            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30630        } else {
30631            /* OPC_DADDI */
30632            check_insn(ctx, ISA_MIPS3);
30633            check_mips_64(ctx);
30634            gen_arith_imm(ctx, op, rt, rs, imm);
30635        }
30636        break;
30637    case OPC_DADDIU:
30638        check_insn(ctx, ISA_MIPS3);
30639        check_mips_64(ctx);
30640        gen_arith_imm(ctx, op, rt, rs, imm);
30641        break;
30642#else
30643    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
30644        if (ctx->insn_flags & ISA_MIPS32R6) {
30645            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
30646        } else {
30647            MIPS_INVAL("major opcode");
30648            generate_exception_end(ctx, EXCP_RI);
30649        }
30650        break;
30651#endif
30652    case OPC_DAUI: /* OPC_JALX */
30653        if (ctx->insn_flags & ISA_MIPS32R6) {
30654#if defined(TARGET_MIPS64)
30655            /* OPC_DAUI */
30656            check_mips_64(ctx);
30657            if (rs == 0) {
30658                generate_exception(ctx, EXCP_RI);
30659            } else if (rt != 0) {
30660                TCGv t0 = tcg_temp_new();
30661                gen_load_gpr(t0, rs);
30662                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
30663                tcg_temp_free(t0);
30664            }
30665#else
30666            generate_exception_end(ctx, EXCP_RI);
30667            MIPS_INVAL("major opcode");
30668#endif
30669        } else {
30670            /* OPC_JALX */
30671            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
30672            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
30673            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
30674        }
30675        break;
30676    case OPC_MSA: /* OPC_MDMX */
30677        if (ctx->insn_flags & INSN_R5900) {
30678#if defined(TARGET_MIPS64)
30679            gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
30680#endif
30681        } else {
30682            /* MDMX: Not implemented. */
30683            gen_msa(env, ctx);
30684        }
30685        break;
30686    case OPC_PCREL:
30687        check_insn(ctx, ISA_MIPS32R6);
30688        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
30689        break;
30690    default:            /* Invalid */
30691        MIPS_INVAL("major opcode");
30692        generate_exception_end(ctx, EXCP_RI);
30693        break;
30694    }
30695}
30696
30697static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
30698{
30699    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30700    CPUMIPSState *env = cs->env_ptr;
30701
30702    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
30703    ctx->saved_pc = -1;
30704    ctx->insn_flags = env->insn_flags;
30705    ctx->CP0_Config1 = env->CP0_Config1;
30706    ctx->CP0_Config2 = env->CP0_Config2;
30707    ctx->CP0_Config3 = env->CP0_Config3;
30708    ctx->CP0_Config5 = env->CP0_Config5;
30709    ctx->btarget = 0;
30710    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
30711    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
30712    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
30713    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
30714    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
30715    ctx->PAMask = env->PAMask;
30716    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
30717    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
30718    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
30719    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
30720    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
30721    /* Restore delay slot state from the tb context.  */
30722    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
30723    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
30724    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
30725             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
30726    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
30727    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
30728    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
30729    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
30730    restore_cpu_state(env, ctx);
30731#ifdef CONFIG_USER_ONLY
30732        ctx->mem_idx = MIPS_HFLAG_UM;
30733#else
30734        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
30735#endif
30736    ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
30737                                  MO_UNALN : MO_ALIGN;
30738
30739    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
30740              ctx->hflags);
30741}
30742
30743static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
30744{
30745}
30746
30747static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
30748{
30749    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30750
30751    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
30752                       ctx->btarget);
30753}
30754
30755static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
30756                                     const CPUBreakpoint *bp)
30757{
30758    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30759
30760    save_cpu_state(ctx, 1);
30761    ctx->base.is_jmp = DISAS_NORETURN;
30762    gen_helper_raise_exception_debug(cpu_env);
30763    /*
30764     * The address covered by the breakpoint must be included in
30765     * [tb->pc, tb->pc + tb->size) in order to for it to be
30766     * properly cleared -- thus we increment the PC here so that
30767     * the logic setting tb->size below does the right thing.
30768     */
30769    ctx->base.pc_next += 4;
30770    return true;
30771}
30772
30773static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
30774{
30775    CPUMIPSState *env = cs->env_ptr;
30776    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30777    int insn_bytes;
30778    int is_slot;
30779
30780    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
30781    if (ctx->insn_flags & ISA_NANOMIPS32) {
30782        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30783        insn_bytes = decode_nanomips_opc(env, ctx);
30784    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
30785        ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
30786        insn_bytes = 4;
30787        decode_opc(env, ctx);
30788    } else if (ctx->insn_flags & ASE_MICROMIPS) {
30789        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30790        insn_bytes = decode_micromips_opc(env, ctx);
30791    } else if (ctx->insn_flags & ASE_MIPS16) {
30792        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
30793        insn_bytes = decode_mips16_opc(env, ctx);
30794    } else {
30795        generate_exception_end(ctx, EXCP_RI);
30796        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
30797        return;
30798    }
30799
30800    if (ctx->hflags & MIPS_HFLAG_BMASK) {
30801        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
30802                             MIPS_HFLAG_FBNSLOT))) {
30803            /*
30804             * Force to generate branch as there is neither delay nor
30805             * forbidden slot.
30806             */
30807            is_slot = 1;
30808        }
30809        if ((ctx->hflags & MIPS_HFLAG_M16) &&
30810            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
30811            /*
30812             * Force to generate branch as microMIPS R6 doesn't restrict
30813             * branches in the forbidden slot.
30814             */
30815            is_slot = 1;
30816        }
30817    }
30818    if (is_slot) {
30819        gen_branch(ctx, insn_bytes);
30820    }
30821    ctx->base.pc_next += insn_bytes;
30822
30823    if (ctx->base.is_jmp != DISAS_NEXT) {
30824        return;
30825    }
30826    /*
30827     * Execute a branch and its delay slot as a single instruction.
30828     * This is what GDB expects and is consistent with what the
30829     * hardware does (e.g. if a delay slot instruction faults, the
30830     * reported PC is the PC of the branch).
30831     */
30832    if (ctx->base.singlestep_enabled &&
30833        (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
30834        ctx->base.is_jmp = DISAS_TOO_MANY;
30835    }
30836    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
30837        ctx->base.is_jmp = DISAS_TOO_MANY;
30838    }
30839}
30840
30841static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
30842{
30843    DisasContext *ctx = container_of(dcbase, DisasContext, base);
30844
30845    if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
30846        save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
30847        gen_helper_raise_exception_debug(cpu_env);
30848    } else {
30849        switch (ctx->base.is_jmp) {
30850        case DISAS_STOP:
30851            gen_save_pc(ctx->base.pc_next);
30852            tcg_gen_lookup_and_goto_ptr();
30853            break;
30854        case DISAS_NEXT:
30855        case DISAS_TOO_MANY:
30856            save_cpu_state(ctx, 0);
30857            gen_goto_tb(ctx, 0, ctx->base.pc_next);
30858            break;
30859        case DISAS_EXIT:
30860            tcg_gen_exit_tb(NULL, 0);
30861            break;
30862        case DISAS_NORETURN:
30863            break;
30864        default:
30865            g_assert_not_reached();
30866        }
30867    }
30868}
30869
30870static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
30871{
30872    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
30873    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
30874}
30875
30876static const TranslatorOps mips_tr_ops = {
30877    .init_disas_context = mips_tr_init_disas_context,
30878    .tb_start           = mips_tr_tb_start,
30879    .insn_start         = mips_tr_insn_start,
30880    .breakpoint_check   = mips_tr_breakpoint_check,
30881    .translate_insn     = mips_tr_translate_insn,
30882    .tb_stop            = mips_tr_tb_stop,
30883    .disas_log          = mips_tr_disas_log,
30884};
30885
30886void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
30887{
30888    DisasContext ctx;
30889
30890    translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
30891}
30892
30893static void fpu_dump_state(CPUMIPSState *env, FILE * f, int flags)
30894{
30895    int i;
30896    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
30897
30898#define printfpr(fp)                                                    \
30899    do {                                                                \
30900        if (is_fpu64)                                                   \
30901            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
30902                         " fd:%13g fs:%13g psu: %13g\n",                \
30903                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,               \
30904                         (double)(fp)->fd,                              \
30905                         (double)(fp)->fs[FP_ENDIAN_IDX],               \
30906                         (double)(fp)->fs[!FP_ENDIAN_IDX]);             \
30907        else {                                                          \
30908            fpr_t tmp;                                                  \
30909            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
30910            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
30911            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
30912                         " fd:%13g fs:%13g psu:%13g\n",                 \
30913                         tmp.w[FP_ENDIAN_IDX], tmp.d,                   \
30914                         (double)tmp.fd,                                \
30915                         (double)tmp.fs[FP_ENDIAN_IDX],                 \
30916                         (double)tmp.fs[!FP_ENDIAN_IDX]);               \
30917        }                                                               \
30918    } while (0)
30919
30920
30921    qemu_fprintf(f,
30922                 "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
30923                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
30924                 get_float_exception_flags(&env->active_fpu.fp_status));
30925    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
30926        qemu_fprintf(f, "%3s: ", fregnames[i]);
30927        printfpr(&env->active_fpu.fpr[i]);
30928    }
30929
30930#undef printfpr
30931}
30932
30933void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
30934{
30935    MIPSCPU *cpu = MIPS_CPU(cs);
30936    CPUMIPSState *env = &cpu->env;
30937    int i;
30938
30939    qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
30940                 " LO=0x" TARGET_FMT_lx " ds %04x "
30941                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
30942                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
30943                 env->hflags, env->btarget, env->bcond);
30944    for (i = 0; i < 32; i++) {
30945        if ((i & 3) == 0) {
30946            qemu_fprintf(f, "GPR%02d:", i);
30947        }
30948        qemu_fprintf(f, " %s " TARGET_FMT_lx,
30949                     regnames[i], env->active_tc.gpr[i]);
30950        if ((i & 3) == 3) {
30951            qemu_fprintf(f, "\n");
30952        }
30953    }
30954
30955    qemu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x"
30956                 TARGET_FMT_lx "\n",
30957                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
30958    qemu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
30959                 PRIx64 "\n",
30960                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
30961    qemu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
30962                 env->CP0_Config2, env->CP0_Config3);
30963    qemu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
30964                 env->CP0_Config4, env->CP0_Config5);
30965    if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
30966        fpu_dump_state(env, f, flags);
30967    }
30968}
30969
30970void mips_tcg_init(void)
30971{
30972    int i;
30973
30974    cpu_gpr[0] = NULL;
30975    for (i = 1; i < 32; i++)
30976        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
30977                                        offsetof(CPUMIPSState,
30978                                                 active_tc.gpr[i]),
30979                                        regnames[i]);
30980
30981    for (i = 0; i < 32; i++) {
30982        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
30983        msa_wr_d[i * 2] =
30984                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
30985        /*
30986         * The scalar floating-point unit (FPU) registers are mapped on
30987         * the MSA vector registers.
30988         */
30989        fpu_f64[i] = msa_wr_d[i * 2];
30990        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
30991        msa_wr_d[i * 2 + 1] =
30992                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
30993    }
30994
30995    cpu_PC = tcg_global_mem_new(cpu_env,
30996                                offsetof(CPUMIPSState, active_tc.PC), "PC");
30997    for (i = 0; i < MIPS_DSP_ACC; i++) {
30998        cpu_HI[i] = tcg_global_mem_new(cpu_env,
30999                                       offsetof(CPUMIPSState, active_tc.HI[i]),
31000                                       regnames_HI[i]);
31001        cpu_LO[i] = tcg_global_mem_new(cpu_env,
31002                                       offsetof(CPUMIPSState, active_tc.LO[i]),
31003                                       regnames_LO[i]);
31004    }
31005    cpu_dspctrl = tcg_global_mem_new(cpu_env,
31006                                     offsetof(CPUMIPSState,
31007                                              active_tc.DSPControl),
31008                                     "DSPControl");
31009    bcond = tcg_global_mem_new(cpu_env,
31010                               offsetof(CPUMIPSState, bcond), "bcond");
31011    btarget = tcg_global_mem_new(cpu_env,
31012                                 offsetof(CPUMIPSState, btarget), "btarget");
31013    hflags = tcg_global_mem_new_i32(cpu_env,
31014                                    offsetof(CPUMIPSState, hflags), "hflags");
31015
31016    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
31017                                      offsetof(CPUMIPSState, active_fpu.fcr0),
31018                                      "fcr0");
31019    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
31020                                       offsetof(CPUMIPSState, active_fpu.fcr31),
31021                                       "fcr31");
31022    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
31023                                    "lladdr");
31024    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
31025                                   "llval");
31026
31027#if defined(TARGET_MIPS64)
31028    cpu_mmr[0] = NULL;
31029    for (i = 1; i < 32; i++) {
31030        cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
31031                                            offsetof(CPUMIPSState,
31032                                                     active_tc.mmr[i]),
31033                                            regnames[i]);
31034    }
31035#endif
31036
31037#if !defined(TARGET_MIPS64)
31038    for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
31039        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
31040                                        offsetof(CPUMIPSState,
31041                                                 active_tc.mxu_gpr[i]),
31042                                        mxuregnames[i]);
31043    }
31044
31045    mxu_CR = tcg_global_mem_new(cpu_env,
31046                                offsetof(CPUMIPSState, active_tc.mxu_cr),
31047                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
31048#endif
31049}
31050
31051#include "translate_init.inc.c"
31052
31053void cpu_mips_realize_env(CPUMIPSState *env)
31054{
31055    env->exception_base = (int32_t)0xBFC00000;
31056
31057#ifndef CONFIG_USER_ONLY
31058    mmu_init(env, env->cpu_model);
31059#endif
31060    fpu_init(env, env->cpu_model);
31061    mvp_init(env, env->cpu_model);
31062}
31063
31064bool cpu_supports_cps_smp(const char *cpu_type)
31065{
31066    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
31067    return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
31068}
31069
31070bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
31071{
31072    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
31073    return (mcc->cpu_def->insn_flags & isa) != 0;
31074}
31075
31076void cpu_set_exception_base(int vp_index, target_ulong address)
31077{
31078    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
31079    vp->env.exception_base = address;
31080}
31081
31082void cpu_state_reset(CPUMIPSState *env)
31083{
31084    CPUState *cs = env_cpu(env);
31085
31086    /* Reset registers to their default values */
31087    env->CP0_PRid = env->cpu_model->CP0_PRid;
31088    env->CP0_Config0 = env->cpu_model->CP0_Config0;
31089#ifdef TARGET_WORDS_BIGENDIAN
31090    env->CP0_Config0 |= (1 << CP0C0_BE);
31091#endif
31092    env->CP0_Config1 = env->cpu_model->CP0_Config1;
31093    env->CP0_Config2 = env->cpu_model->CP0_Config2;
31094    env->CP0_Config3 = env->cpu_model->CP0_Config3;
31095    env->CP0_Config4 = env->cpu_model->CP0_Config4;
31096    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
31097    env->CP0_Config5 = env->cpu_model->CP0_Config5;
31098    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
31099    env->CP0_Config6 = env->cpu_model->CP0_Config6;
31100    env->CP0_Config7 = env->cpu_model->CP0_Config7;
31101    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
31102                                 << env->cpu_model->CP0_LLAddr_shift;
31103    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
31104    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
31105    env->CCRes = env->cpu_model->CCRes;
31106    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
31107    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
31108    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
31109    env->current_tc = 0;
31110    env->SEGBITS = env->cpu_model->SEGBITS;
31111    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
31112#if defined(TARGET_MIPS64)
31113    if (env->cpu_model->insn_flags & ISA_MIPS3) {
31114        env->SEGMask |= 3ULL << 62;
31115    }
31116#endif
31117    env->PABITS = env->cpu_model->PABITS;
31118    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
31119    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
31120    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
31121    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
31122    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
31123    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
31124    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
31125    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
31126    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
31127    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
31128    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
31129    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
31130    env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
31131    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
31132    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
31133    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
31134    env->msair = env->cpu_model->MSAIR;
31135    env->insn_flags = env->cpu_model->insn_flags;
31136
31137#if defined(CONFIG_USER_ONLY)
31138    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
31139# ifdef TARGET_MIPS64
31140    /* Enable 64-bit register mode.  */
31141    env->CP0_Status |= (1 << CP0St_PX);
31142# endif
31143# ifdef TARGET_ABI_MIPSN64
31144    /* Enable 64-bit address mode.  */
31145    env->CP0_Status |= (1 << CP0St_UX);
31146# endif
31147    /*
31148     * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
31149     * hardware registers.
31150     */
31151    env->CP0_HWREna |= 0x0000000F;
31152    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
31153        env->CP0_Status |= (1 << CP0St_CU1);
31154    }
31155    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
31156        env->CP0_Status |= (1 << CP0St_MX);
31157    }
31158# if defined(TARGET_MIPS64)
31159    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
31160    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
31161        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
31162        env->CP0_Status |= (1 << CP0St_FR);
31163    }
31164# endif
31165#else
31166    if (env->hflags & MIPS_HFLAG_BMASK) {
31167        /*
31168         * If the exception was raised from a delay slot,
31169         * come back to the jump.
31170         */
31171        env->CP0_ErrorEPC = (env->active_tc.PC
31172                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
31173    } else {
31174        env->CP0_ErrorEPC = env->active_tc.PC;
31175    }
31176    env->active_tc.PC = env->exception_base;
31177    env->CP0_Random = env->tlb->nb_tlb - 1;
31178    env->tlb->tlb_in_use = env->tlb->nb_tlb;
31179    env->CP0_Wired = 0;
31180    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
31181    env->CP0_EBase = (cs->cpu_index & 0x3FF);
31182    if (mips_um_ksegs_enabled()) {
31183        env->CP0_EBase |= 0x40000000;
31184    } else {
31185        env->CP0_EBase |= (int32_t)0x80000000;
31186    }
31187    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
31188        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
31189    }
31190    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
31191                                 0x3ff : 0xff;
31192    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
31193    /*
31194     * Vectored interrupts not implemented, timer on int 7,
31195     * no performance counters.
31196     */
31197    env->CP0_IntCtl = 0xe0000000;
31198    {
31199        int i;
31200
31201        for (i = 0; i < 7; i++) {
31202            env->CP0_WatchLo[i] = 0;
31203            env->CP0_WatchHi[i] = 0x80000000;
31204        }
31205        env->CP0_WatchLo[7] = 0;
31206        env->CP0_WatchHi[7] = 0;
31207    }
31208    /* Count register increments in debug mode, EJTAG version 1 */
31209    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
31210
31211    cpu_mips_store_count(env, 1);
31212
31213    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
31214        int i;
31215
31216        /* Only TC0 on VPE 0 starts as active.  */
31217        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
31218            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
31219            env->tcs[i].CP0_TCHalt = 1;
31220        }
31221        env->active_tc.CP0_TCHalt = 1;
31222        cs->halted = 1;
31223
31224        if (cs->cpu_index == 0) {
31225            /* VPE0 starts up enabled.  */
31226            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
31227            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
31228
31229            /* TC0 starts up unhalted.  */
31230            cs->halted = 0;
31231            env->active_tc.CP0_TCHalt = 0;
31232            env->tcs[0].CP0_TCHalt = 0;
31233            /* With thread 0 active.  */
31234            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
31235            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
31236        }
31237    }
31238
31239    /*
31240     * Configure default legacy segmentation control. We use this regardless of
31241     * whether segmentation control is presented to the guest.
31242     */
31243    /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
31244    env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
31245    /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
31246    env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
31247    /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
31248    env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
31249                         (2 << CP0SC_C);
31250    /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
31251    env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
31252                         (3 << CP0SC_C)) << 16;
31253    /* USeg (seg4 0x40000000..0x7FFFFFFF) */
31254    env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
31255                         (1 << CP0SC_EU) | (2 << CP0SC_C);
31256    /* USeg (seg5 0x00000000..0x3FFFFFFF) */
31257    env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
31258                         (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
31259    /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
31260    env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
31261#endif
31262    if ((env->insn_flags & ISA_MIPS32R6) &&
31263        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
31264        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
31265        env->CP0_Status |= (1 << CP0St_FR);
31266    }
31267
31268    if (env->insn_flags & ISA_MIPS32R6) {
31269        /* PTW  =  1 */
31270        env->CP0_PWSize = 0x40;
31271        /* GDI  = 12 */
31272        /* UDI  = 12 */
31273        /* MDI  = 12 */
31274        /* PRI  = 12 */
31275        /* PTEI =  2 */
31276        env->CP0_PWField = 0x0C30C302;
31277    } else {
31278        /* GDI  =  0 */
31279        /* UDI  =  0 */
31280        /* MDI  =  0 */
31281        /* PRI  =  0 */
31282        /* PTEI =  2 */
31283        env->CP0_PWField = 0x02;
31284    }
31285
31286    if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
31287        /*  microMIPS on reset when Config3.ISA is 3 */
31288        env->hflags |= MIPS_HFLAG_M16;
31289    }
31290
31291    /* MSA */
31292    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
31293        msa_reset(env);
31294    }
31295
31296    compute_hflags(env);
31297    restore_fp_status(env);
31298    restore_pamask(env);
31299    cs->exception_index = EXCP_NONE;
31300
31301    if (semihosting_get_argc()) {
31302        /* UHI interface can be used to obtain argc and argv */
31303        env->active_tc.gpr[4] = -1;
31304    }
31305}
31306
31307void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
31308                          target_ulong *data)
31309{
31310    env->active_tc.PC = data[0];
31311    env->hflags &= ~MIPS_HFLAG_BMASK;
31312    env->hflags |= data[1];
31313    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
31314    case MIPS_HFLAG_BR:
31315        break;
31316    case MIPS_HFLAG_BC:
31317    case MIPS_HFLAG_BL:
31318    case MIPS_HFLAG_B:
31319        env->btarget = data[2];
31320        break;
31321    }
31322}
31323