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 "exec/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
  42#define MIPS_DEBUG_DISAS 0
  43
  44/* MIPS major opcodes */
  45#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  46
  47enum {
  48    /* indirect opcode tables */
  49    OPC_SPECIAL  = (0x00 << 26),
  50    OPC_REGIMM   = (0x01 << 26),
  51    OPC_CP0      = (0x10 << 26),
  52    OPC_CP1      = (0x11 << 26),
  53    OPC_CP2      = (0x12 << 26),
  54    OPC_CP3      = (0x13 << 26),
  55    OPC_SPECIAL2 = (0x1C << 26),
  56    OPC_SPECIAL3 = (0x1F << 26),
  57    /* arithmetic with immediate */
  58    OPC_ADDI     = (0x08 << 26),
  59    OPC_ADDIU    = (0x09 << 26),
  60    OPC_SLTI     = (0x0A << 26),
  61    OPC_SLTIU    = (0x0B << 26),
  62    /* logic with immediate */
  63    OPC_ANDI     = (0x0C << 26),
  64    OPC_ORI      = (0x0D << 26),
  65    OPC_XORI     = (0x0E << 26),
  66    OPC_LUI      = (0x0F << 26),
  67    /* arithmetic with immediate */
  68    OPC_DADDI    = (0x18 << 26),
  69    OPC_DADDIU   = (0x19 << 26),
  70    /* Jump and branches */
  71    OPC_J        = (0x02 << 26),
  72    OPC_JAL      = (0x03 << 26),
  73    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  74    OPC_BEQL     = (0x14 << 26),
  75    OPC_BNE      = (0x05 << 26),
  76    OPC_BNEL     = (0x15 << 26),
  77    OPC_BLEZ     = (0x06 << 26),
  78    OPC_BLEZL    = (0x16 << 26),
  79    OPC_BGTZ     = (0x07 << 26),
  80    OPC_BGTZL    = (0x17 << 26),
  81    OPC_JALX     = (0x1D << 26),
  82    OPC_DAUI     = (0x1D << 26),
  83    /* Load and stores */
  84    OPC_LDL      = (0x1A << 26),
  85    OPC_LDR      = (0x1B << 26),
  86    OPC_LB       = (0x20 << 26),
  87    OPC_LH       = (0x21 << 26),
  88    OPC_LWL      = (0x22 << 26),
  89    OPC_LW       = (0x23 << 26),
  90    OPC_LWPC     = OPC_LW | 0x5,
  91    OPC_LBU      = (0x24 << 26),
  92    OPC_LHU      = (0x25 << 26),
  93    OPC_LWR      = (0x26 << 26),
  94    OPC_LWU      = (0x27 << 26),
  95    OPC_SB       = (0x28 << 26),
  96    OPC_SH       = (0x29 << 26),
  97    OPC_SWL      = (0x2A << 26),
  98    OPC_SW       = (0x2B << 26),
  99    OPC_SDL      = (0x2C << 26),
 100    OPC_SDR      = (0x2D << 26),
 101    OPC_SWR      = (0x2E << 26),
 102    OPC_LL       = (0x30 << 26),
 103    OPC_LLD      = (0x34 << 26),
 104    OPC_LD       = (0x37 << 26),
 105    OPC_LDPC     = OPC_LD | 0x5,
 106    OPC_SC       = (0x38 << 26),
 107    OPC_SCD      = (0x3C << 26),
 108    OPC_SD       = (0x3F << 26),
 109    /* Floating point load/store */
 110    OPC_LWC1     = (0x31 << 26),
 111    OPC_LWC2     = (0x32 << 26),
 112    OPC_LDC1     = (0x35 << 26),
 113    OPC_LDC2     = (0x36 << 26),
 114    OPC_SWC1     = (0x39 << 26),
 115    OPC_SWC2     = (0x3A << 26),
 116    OPC_SDC1     = (0x3D << 26),
 117    OPC_SDC2     = (0x3E << 26),
 118    /* Compact Branches */
 119    OPC_BLEZALC  = (0x06 << 26),
 120    OPC_BGEZALC  = (0x06 << 26),
 121    OPC_BGEUC    = (0x06 << 26),
 122    OPC_BGTZALC  = (0x07 << 26),
 123    OPC_BLTZALC  = (0x07 << 26),
 124    OPC_BLTUC    = (0x07 << 26),
 125    OPC_BOVC     = (0x08 << 26),
 126    OPC_BEQZALC  = (0x08 << 26),
 127    OPC_BEQC     = (0x08 << 26),
 128    OPC_BLEZC    = (0x16 << 26),
 129    OPC_BGEZC    = (0x16 << 26),
 130    OPC_BGEC     = (0x16 << 26),
 131    OPC_BGTZC    = (0x17 << 26),
 132    OPC_BLTZC    = (0x17 << 26),
 133    OPC_BLTC     = (0x17 << 26),
 134    OPC_BNVC     = (0x18 << 26),
 135    OPC_BNEZALC  = (0x18 << 26),
 136    OPC_BNEC     = (0x18 << 26),
 137    OPC_BC       = (0x32 << 26),
 138    OPC_BEQZC    = (0x36 << 26),
 139    OPC_JIC      = (0x36 << 26),
 140    OPC_BALC     = (0x3A << 26),
 141    OPC_BNEZC    = (0x3E << 26),
 142    OPC_JIALC    = (0x3E << 26),
 143    /* MDMX ASE specific */
 144    OPC_MDMX     = (0x1E << 26),
 145    /* MSA ASE, same as MDMX */
 146    OPC_MSA      = OPC_MDMX,
 147    /* Cache and prefetch */
 148    OPC_CACHE    = (0x2F << 26),
 149    OPC_PREF     = (0x33 << 26),
 150    /* PC-relative address computation / loads */
 151    OPC_PCREL    = (0x3B << 26),
 152};
 153
 154/* PC-relative address computation / loads  */
 155#define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 156#define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 157enum {
 158    /* Instructions determined by bits 19 and 20 */
 159    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 160    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 161    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 162
 163    /* Instructions determined by bits 16 ... 20 */
 164    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 165    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 166
 167    /* Other */
 168    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 169};
 170
 171/* MIPS special opcodes */
 172#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 173
 174enum {
 175    /* Shifts */
 176    OPC_SLL      = 0x00 | OPC_SPECIAL,
 177    /* NOP is SLL r0, r0, 0   */
 178    /* SSNOP is SLL r0, r0, 1 */
 179    /* EHB is SLL r0, r0, 3 */
 180    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 181    OPC_ROTR     = OPC_SRL | (1 << 21),
 182    OPC_SRA      = 0x03 | OPC_SPECIAL,
 183    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 184    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 185    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 186    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 187    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 188    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 189    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 190    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 191    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 192    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 193    OPC_DROTR    = OPC_DSRL | (1 << 21),
 194    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 195    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 196    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 197    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 198    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 199    /* Multiplication / division */
 200    OPC_MULT     = 0x18 | OPC_SPECIAL,
 201    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 202    OPC_DIV      = 0x1A | OPC_SPECIAL,
 203    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 204    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 205    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 206    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 207    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 208
 209    /* 2 registers arithmetic / logic */
 210    OPC_ADD      = 0x20 | OPC_SPECIAL,
 211    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 212    OPC_SUB      = 0x22 | OPC_SPECIAL,
 213    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 214    OPC_AND      = 0x24 | OPC_SPECIAL,
 215    OPC_OR       = 0x25 | OPC_SPECIAL,
 216    OPC_XOR      = 0x26 | OPC_SPECIAL,
 217    OPC_NOR      = 0x27 | OPC_SPECIAL,
 218    OPC_SLT      = 0x2A | OPC_SPECIAL,
 219    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 220    OPC_DADD     = 0x2C | OPC_SPECIAL,
 221    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 222    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 223    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 224    /* Jumps */
 225    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 226    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 227    /* Traps */
 228    OPC_TGE      = 0x30 | OPC_SPECIAL,
 229    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 230    OPC_TLT      = 0x32 | OPC_SPECIAL,
 231    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 232    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 233    OPC_TNE      = 0x36 | OPC_SPECIAL,
 234    /* HI / LO registers load & stores */
 235    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 236    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 237    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 238    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 239    /* Conditional moves */
 240    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 241    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 242
 243    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 244    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 245
 246    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 247
 248    /* Special */
 249    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 250    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 251    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 252    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 253    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 254
 255    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 256    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 257    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 258    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 259};
 260
 261/* R6 Multiply and Divide instructions have the same Opcode
 262   and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
 263#define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
 264
 265enum {
 266    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 267    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 268    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 269    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 270    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 271    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 272    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 273    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 274
 275    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 276    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 277    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 278    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 279    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 280    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 281    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 282    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 283
 284    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 285    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 286    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 287    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 288    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 289
 290    OPC_LSA  = 0x05 | OPC_SPECIAL,
 291    OPC_DLSA = 0x15 | OPC_SPECIAL,
 292};
 293
 294/* Multiplication variants of the vr54xx. */
 295#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 296
 297enum {
 298    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 299    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 300    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 301    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 302    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 303    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 304    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 305    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 306    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 307    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 308    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 309    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 310    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 311    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 312};
 313
 314/* REGIMM (rt field) opcodes */
 315#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 316
 317enum {
 318    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 319    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 320    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 321    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 322    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 323    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 324    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 325    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 326    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 327    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 328    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 329    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 330    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 331    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 332    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 333    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 334
 335    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 336    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 337};
 338
 339/* Special2 opcodes */
 340#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 341
 342enum {
 343    /* Multiply & xxx operations */
 344    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 345    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 346    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 347    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 348    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 349    /* Loongson 2F */
 350    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 351    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 352    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 353    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 354    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 355    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 356    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 357    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 358    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 359    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 360    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 361    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 362    /* Misc */
 363    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 364    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 365    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 366    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 367    /* Special */
 368    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 369};
 370
 371/* Special3 opcodes */
 372#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 373
 374enum {
 375    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 376    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 377    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 378    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 379    OPC_INS      = 0x04 | OPC_SPECIAL3,
 380    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 381    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 382    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 383    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 384    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 385    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 386    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 387    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 388
 389    /* Loongson 2E */
 390    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 391    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 392    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 393    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 394    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 395    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 396    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 397    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 398    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 399    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 400    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 401    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 402
 403    /* MIPS DSP Load */
 404    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 405    /* MIPS DSP Arithmetic */
 406    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 407    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 408    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 409    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 410    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 411    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 412    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 413    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 414    /* MIPS DSP GPR-Based Shift Sub-class */
 415    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 416    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 417    /* MIPS DSP Multiply Sub-class insns */
 418    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 419    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 420    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 421    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 422    /* DSP Bit/Manipulation Sub-class */
 423    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 424    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 425    /* MIPS DSP Append Sub-class */
 426    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 427    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 428    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 429    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 430    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 431
 432    /* EVA */
 433    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 434    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 435    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 436    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 437    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 438    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 439    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 440    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 441    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 442    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 443    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 444    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 445    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 446    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 447    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 448    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 449
 450    /* R6 */
 451    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 452    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 453    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 454    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 455    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 456    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 457};
 458
 459/* BSHFL opcodes */
 460#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 461
 462enum {
 463    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 464    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 465    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 466    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 467    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 468    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 469    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 470    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 471};
 472
 473/* DBSHFL opcodes */
 474#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 475
 476enum {
 477    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 478    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 479    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 480    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 481    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 482    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 483    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 484    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 485    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 486    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 487    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 488};
 489
 490/* MIPS DSP REGIMM opcodes */
 491enum {
 492    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 493    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 494};
 495
 496#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 497/* MIPS DSP Load */
 498enum {
 499    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 500    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 501    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 502    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 503};
 504
 505#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 506enum {
 507    /* MIPS DSP Arithmetic Sub-class */
 508    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 509    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 510    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 511    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 512    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 513    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 514    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 515    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 516    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 517    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 518    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 519    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 520    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 521    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 522    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 523    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 524    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 525    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 526    /* MIPS DSP Multiply Sub-class insns */
 527    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 528    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 529    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 530    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 531    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 532    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 533};
 534
 535#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 536#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 537enum {
 538    /* MIPS DSP Arithmetic Sub-class */
 539    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 540    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 541    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 542    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 543    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 544    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 545    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 546    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 547    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 548    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 549    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 550    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 551    /* MIPS DSP Multiply Sub-class insns */
 552    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 553    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 554    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 555    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 556};
 557
 558#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 559enum {
 560    /* MIPS DSP Arithmetic Sub-class */
 561    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 562    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 563    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 564    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 565    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 566    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 567    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 568    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 569    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 570    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 571    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 572    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 573    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 574    /* DSP Bit/Manipulation Sub-class */
 575    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 576    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 577    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 578    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 579    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 580};
 581
 582#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 583enum {
 584    /* MIPS DSP Arithmetic Sub-class */
 585    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 586    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 587    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 588    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 589    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 590    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 591    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 592    /* DSP Compare-Pick Sub-class */
 593    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 594    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 595    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 596    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 597    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 598    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 599    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 600    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 601    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 602    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 603    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 604    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 605    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 606    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 607    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 608};
 609
 610#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 611enum {
 612    /* MIPS DSP GPR-Based Shift Sub-class */
 613    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 614    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 615    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 616    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 617    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 618    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 619    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 620    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 621    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 622    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 623    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 624    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 625    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 626    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 627    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 628    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 629    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 630    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 631    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 632    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 633    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 634    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 635};
 636
 637#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 638enum {
 639    /* MIPS DSP Multiply Sub-class insns */
 640    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 641    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 642    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 643    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 644    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 645    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 646    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 647    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 648    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 649    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 650    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 651    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 652    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 653    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 654    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 655    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 656    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 657    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 658    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 659    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 660    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 661    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 662};
 663
 664#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 665enum {
 666    /* DSP Bit/Manipulation Sub-class */
 667    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 668};
 669
 670#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 671enum {
 672    /* MIPS DSP Append Sub-class */
 673    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 674    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 675    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 676};
 677
 678#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 679enum {
 680    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 681    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 682    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 683    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 684    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 685    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 686    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 687    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 688    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 689    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 690    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 691    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 692    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 693    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 694    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 695    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 696    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 697    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 698};
 699
 700#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 701enum {
 702    /* MIPS DSP Arithmetic Sub-class */
 703    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 704    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 705    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 706    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 707    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 708    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 709    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 710    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 711    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 712    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 713    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 714    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 715    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 716    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 717    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 718    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 719    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 720    /* DSP Bit/Manipulation Sub-class */
 721    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 722    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 723    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 724    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 725    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 726    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 727};
 728
 729#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 730enum {
 731    /* MIPS DSP Multiply Sub-class insns */
 732    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 733    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 734    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 735    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 736    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 737    /* MIPS DSP Arithmetic Sub-class */
 738    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 739    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 740    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 741    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 742    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 743    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 744    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 745    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 746    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 747    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 748    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 749    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 750    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 751    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 752    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 753    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 754    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 755    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 756    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 757    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 758    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 759};
 760
 761#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 762enum {
 763    /* DSP Compare-Pick Sub-class */
 764    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 765    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 766    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 767    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 768    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 769    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 770    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 771    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 772    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 773    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 774    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 775    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 776    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 777    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 778    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 779    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 780    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 781    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 782    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 783    /* MIPS DSP Arithmetic Sub-class */
 784    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 785    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 786    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 787    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 788    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 789    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 790    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 792};
 793
 794#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 795enum {
 796    /* DSP Append Sub-class */
 797    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 798    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 799    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 800    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 801};
 802
 803#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 804enum {
 805    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 806    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 807    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 808    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 809    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 810    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 811    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 812    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 813    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 814    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 815    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 816    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 817    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 818    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 819    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 820    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 821    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 822    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 823    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 824    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 825    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 826    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 827};
 828
 829#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 830enum {
 831    /* DSP Bit/Manipulation Sub-class */
 832    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 833};
 834
 835#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 836enum {
 837    /* MIPS DSP Multiply Sub-class insns */
 838    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 839    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 840    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 841    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 842    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 843    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 844    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 845    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 846    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 847    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 848    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 849    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 850    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 851    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 852    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 853    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 854    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 855    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 856    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 857    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 858    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 859    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 860    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 861    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 862    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 863    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 864};
 865
 866#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 867enum {
 868    /* MIPS DSP GPR-Based Shift Sub-class */
 869    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 870    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 871    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 872    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 873    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 874    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 875    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 876    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 877    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 878    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 879    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 880    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 881    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 882    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 883    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 884    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 885    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 886    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 887    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 888    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 889    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 890    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 891    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 892    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 893    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 894    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 895};
 896
 897/* Coprocessor 0 (rs field) */
 898#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 899
 900enum {
 901    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 902    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 903    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 904    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 905    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 906    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 907    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 908    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 909    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 910    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 911    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 912    OPC_C0       = (0x10 << 21) | OPC_CP0,
 913    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 914    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 915    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 916    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 917    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 918    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 919    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 920    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 921    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 922    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 923    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 924    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 925    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 926    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 927    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 928};
 929
 930/* MFMC0 opcodes */
 931#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 932
 933enum {
 934    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 935    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 936    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 937    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 938    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 939    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 940    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 941    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 942};
 943
 944/* Coprocessor 0 (with rs == C0) */
 945#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 946
 947enum {
 948    OPC_TLBR     = 0x01 | OPC_C0,
 949    OPC_TLBWI    = 0x02 | OPC_C0,
 950    OPC_TLBINV   = 0x03 | OPC_C0,
 951    OPC_TLBINVF  = 0x04 | OPC_C0,
 952    OPC_TLBWR    = 0x06 | OPC_C0,
 953    OPC_TLBP     = 0x08 | OPC_C0,
 954    OPC_RFE      = 0x10 | OPC_C0,
 955    OPC_ERET     = 0x18 | OPC_C0,
 956    OPC_DERET    = 0x1F | OPC_C0,
 957    OPC_WAIT     = 0x20 | OPC_C0,
 958};
 959
 960/* Coprocessor 1 (rs field) */
 961#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 962
 963/* Values for the fmt field in FP instructions */
 964enum {
 965    /* 0 - 15 are reserved */
 966    FMT_S = 16,          /* single fp */
 967    FMT_D = 17,          /* double fp */
 968    FMT_E = 18,          /* extended fp */
 969    FMT_Q = 19,          /* quad fp */
 970    FMT_W = 20,          /* 32-bit fixed */
 971    FMT_L = 21,          /* 64-bit fixed */
 972    FMT_PS = 22,         /* paired single fp */
 973    /* 23 - 31 are reserved */
 974};
 975
 976enum {
 977    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 978    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 979    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 980    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 981    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 982    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 983    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 984    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 985    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 986    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 987    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 988    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 989    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 990    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 991    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 992    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 993    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 994    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 995    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 996    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 997    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
 998    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
 999    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1000    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1001    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1002    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1003    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1004    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1005    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1006    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1007};
1008
1009#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1010#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1011
1012enum {
1013    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1014    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1015    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1016    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1017};
1018
1019enum {
1020    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1021    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1022};
1023
1024enum {
1025    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1026    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1027};
1028
1029#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1030
1031enum {
1032    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1033    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1034    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1035    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1036    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1037    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1038    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1039    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1040    OPC_BC2     = (0x08 << 21) | OPC_CP2,
1041    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1042    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1043};
1044
1045#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1046
1047enum {
1048    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1049    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1051    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1052    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1053    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1055    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1056
1057    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1058    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1060    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1061    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1062    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1064    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1065
1066    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1067    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1071    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1072    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1073    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1074
1075    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1080    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1081    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1082    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1083
1084    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1085    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1086    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1087    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1088    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1089    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1090
1091    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1097
1098    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1099    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1100    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1101    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1102    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1103    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1104
1105    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1106    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1107    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1108    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1109    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1111
1112    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1114    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1115    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1118
1119    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1121    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1122    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1125
1126    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1127    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1129    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1130    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1132
1133    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1134    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1136    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1138    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1139};
1140
1141
1142#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1143
1144enum {
1145    OPC_LWXC1   = 0x00 | OPC_CP3,
1146    OPC_LDXC1   = 0x01 | OPC_CP3,
1147    OPC_LUXC1   = 0x05 | OPC_CP3,
1148    OPC_SWXC1   = 0x08 | OPC_CP3,
1149    OPC_SDXC1   = 0x09 | OPC_CP3,
1150    OPC_SUXC1   = 0x0D | OPC_CP3,
1151    OPC_PREFX   = 0x0F | OPC_CP3,
1152    OPC_ALNV_PS = 0x1E | OPC_CP3,
1153    OPC_MADD_S  = 0x20 | OPC_CP3,
1154    OPC_MADD_D  = 0x21 | OPC_CP3,
1155    OPC_MADD_PS = 0x26 | OPC_CP3,
1156    OPC_MSUB_S  = 0x28 | OPC_CP3,
1157    OPC_MSUB_D  = 0x29 | OPC_CP3,
1158    OPC_MSUB_PS = 0x2E | OPC_CP3,
1159    OPC_NMADD_S = 0x30 | OPC_CP3,
1160    OPC_NMADD_D = 0x31 | OPC_CP3,
1161    OPC_NMADD_PS= 0x36 | OPC_CP3,
1162    OPC_NMSUB_S = 0x38 | OPC_CP3,
1163    OPC_NMSUB_D = 0x39 | OPC_CP3,
1164    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1165};
1166
1167/* MSA Opcodes */
1168#define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1169enum {
1170    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1171    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1172    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1173    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1174    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1175    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1176    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1177    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1178    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1179    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1180    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1181    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1182    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1183    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1184    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1185    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1186    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1187    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1188    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1189    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1190    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1191
1192    /* MI10 instruction */
1193    OPC_LD_B    = (0x20) | OPC_MSA,
1194    OPC_LD_H    = (0x21) | OPC_MSA,
1195    OPC_LD_W    = (0x22) | OPC_MSA,
1196    OPC_LD_D    = (0x23) | OPC_MSA,
1197    OPC_ST_B    = (0x24) | OPC_MSA,
1198    OPC_ST_H    = (0x25) | OPC_MSA,
1199    OPC_ST_W    = (0x26) | OPC_MSA,
1200    OPC_ST_D    = (0x27) | OPC_MSA,
1201};
1202
1203enum {
1204    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1206    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1207    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1208    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1209    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1210    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1211    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1212    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1213    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1214    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1215    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1216    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1217
1218    /* I8 instruction */
1219    OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1220    OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221    OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1222    OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1223    OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1224    OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1225    OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1226    OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227    OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1228    OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1229
1230    /* VEC/2R/2RF instruction */
1231    OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1232    OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1233    OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1234    OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1235    OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1236    OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1237    OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1238
1239    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1240    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1241
1242    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243    OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244    OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245    OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246    OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1247
1248    /* 2RF instruction df(bit 16) = _w, _d */
1249    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1250    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1253    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1254    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1255    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1256    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1257    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1258    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1259    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1260    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1261    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1262    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1263    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1264    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1265
1266    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1268    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1269    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1270    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1271    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1272    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1273    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1274    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1275    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1276    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1277    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1278    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1279    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1280    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1281    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1282    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1283    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1284    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1285    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1286    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1287    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1288    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1290    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1291    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1292    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1293    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1294    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1295    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1296    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1297    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1299    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1300    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1301    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1302    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1303    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1304    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1305    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1306    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1307    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1308    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1309    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1310    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1311    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1312    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1313    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1314    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1315    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1316    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1317    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1318    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1319    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1320    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1321    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1322    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1323    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1324    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1325    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1326    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1327    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1328    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1329    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1330
1331    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341
1342    /* 3RF instruction _df(bit 21) = _w, _d */
1343    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1344    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1345    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1346    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1347    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1348    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1349    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1350    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1351    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1352    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1353    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1354    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1355    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1356    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1357    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1358    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1359    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1360    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1361    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1362    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1363    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1364    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1365    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1366    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1367    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1368    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1369    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1370    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1371    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1372    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1373    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1374    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1375    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1376    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1377    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1378    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1379    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1380    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1381    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1382    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1383    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1384
1385    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1387    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1388    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1389    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1390    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1391    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1392    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1393    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1394    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1395    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1396    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1397    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1398};
1399
1400
1401/*
1402 *
1403 *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1404 *       ============================================
1405 *
1406 *
1407 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1408 * instructions set. It is designed to fit the needs of signal, graphical and
1409 * video processing applications. MXU instruction set is used in Xburst family
1410 * of microprocessors by Ingenic.
1411 *
1412 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1413 * the control register.
1414 *
1415 *
1416 *     The notation used in MXU assembler mnemonics
1417 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1418 *
1419 *  Register operands:
1420 *
1421 *   XRa, XRb, XRc, XRd - MXU registers
1422 *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1423 *
1424 *  Non-register operands:
1425 *
1426 *   aptn1 - 1-bit accumulate add/subtract pattern
1427 *   aptn2 - 2-bit accumulate add/subtract pattern
1428 *   eptn2 - 2-bit execute add/subtract pattern
1429 *   optn2 - 2-bit operand pattern
1430 *   optn3 - 3-bit operand pattern
1431 *   sft4  - 4-bit shift amount
1432 *   strd2 - 2-bit stride amount
1433 *
1434 *  Prefixes:
1435 *
1436 *   Level of parallelism:                Operand size:
1437 *    S - single operation at a time       32 - word
1438 *    D - two operations in parallel       16 - half word
1439 *    Q - four operations in parallel       8 - byte
1440 *
1441 *  Operations:
1442 *
1443 *   ADD   - Add or subtract
1444 *   ADDC  - Add with carry-in
1445 *   ACC   - Accumulate
1446 *   ASUM  - Sum together then accumulate (add or subtract)
1447 *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1448 *   AVG   - Average between 2 operands
1449 *   ABD   - Absolute difference
1450 *   ALN   - Align data
1451 *   AND   - Logical bitwise 'and' operation
1452 *   CPS   - Copy sign
1453 *   EXTR  - Extract bits
1454 *   I2M   - Move from GPR register to MXU register
1455 *   LDD   - Load data from memory to XRF
1456 *   LDI   - Load data from memory to XRF (and increase the address base)
1457 *   LUI   - Load unsigned immediate
1458 *   MUL   - Multiply
1459 *   MULU  - Unsigned multiply
1460 *   MADD  - 64-bit operand add 32x32 product
1461 *   MSUB  - 64-bit operand subtract 32x32 product
1462 *   MAC   - Multiply and accumulate (add or subtract)
1463 *   MAD   - Multiply and add or subtract
1464 *   MAX   - Maximum between 2 operands
1465 *   MIN   - Minimum between 2 operands
1466 *   M2I   - Move from MXU register to GPR register
1467 *   MOVZ  - Move if zero
1468 *   MOVN  - Move if non-zero
1469 *   NOR   - Logical bitwise 'nor' operation
1470 *   OR    - Logical bitwise 'or' operation
1471 *   STD   - Store data from XRF to memory
1472 *   SDI   - Store data from XRF to memory (and increase the address base)
1473 *   SLT   - Set of less than comparison
1474 *   SAD   - Sum of absolute differences
1475 *   SLL   - Logical shift left
1476 *   SLR   - Logical shift right
1477 *   SAR   - Arithmetic shift right
1478 *   SAT   - Saturation
1479 *   SFL   - Shuffle
1480 *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1481 *   XOR   - Logical bitwise 'exclusive or' operation
1482 *
1483 *  Suffixes:
1484 *
1485 *   E - Expand results
1486 *   F - Fixed point multiplication
1487 *   L - Low part result
1488 *   R - Doing rounding
1489 *   V - Variable instead of immediate
1490 *   W - Combine above L and V
1491 *
1492 *
1493 *     The list of MXU instructions grouped by functionality
1494 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1495 *
1496 * Load/Store instructions           Multiplication instructions
1497 * -----------------------           ---------------------------
1498 *
1499 *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1500 *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1501 *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1502 *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1503 *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1504 *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1505 *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1506 *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1507 *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1508 *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1509 *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1510 *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1511 *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1512 *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1513 *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1514 *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1515 *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1516 *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1517 *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1518 *  S16SDI XRa, Rb, s10, eptn2
1519 *  S8LDD XRa, Rb, s8, eptn3
1520 *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1521 *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1522 *  S8SDI XRa, Rb, s8, eptn3
1523 *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1524 *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1525 *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1526 *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1527 *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1528 *                                    S32CPS XRa, XRb, XRc
1529 *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1530 * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1531 * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1532 *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1533 *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1534 *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1535 *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1536 *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1537 *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1538 *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1539 *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1540 *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1541 *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1542 *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1543 *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1544 *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1545 *  Q8SLT XRa, XRb, XRc
1546 *  Q8SLTU XRa, XRb, XRc
1547 *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1548 *  Q8MOVN XRa, XRb, XRc             ------------------
1549 *
1550 *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1551 * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1552 * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1553 *                                    D32SARL XRa, XRb, XRc, sft4
1554 *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1555 *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1556 *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1557 *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1558 *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1559 *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1560 * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1561 * -------------------------          Q16SLLV XRa, XRb, Rb
1562 *                                    Q16SLRV XRa, XRb, Rb
1563 *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1564 *  S32ALN XRa, XRb, XRc, Rb
1565 *  S32ALNI XRa, XRb, XRc, s3
1566 *  S32LUI XRa, s8, optn3            Move instructions
1567 *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1568 *  S32EXTRV XRa, XRb, Rs, Rt
1569 *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1570 *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1571 *
1572 *
1573 *     The opcode organization of MXU instructions
1574 *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1575 *
1576 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1577 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1578 * other bits up to the instruction level is as follows:
1579 *
1580 *              bits
1581 *             05..00
1582 *
1583 *          ┌─ 000000 ─ OPC_MXU_S32MADD
1584 *          ├─ 000001 ─ OPC_MXU_S32MADDU
1585 *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
1586 *          │
1587 *          │                               20..18
1588 *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1589 *          │                            ├─ 001 ─ OPC_MXU_S32MIN
1590 *          │                            ├─ 010 ─ OPC_MXU_D16MAX
1591 *          │                            ├─ 011 ─ OPC_MXU_D16MIN
1592 *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
1593 *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
1594 *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
1595 *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
1596 *          ├─ 000100 ─ OPC_MXU_S32MSUB
1597 *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
1598 *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1599 *          │                            ├─ 001 ─ OPC_MXU_D16SLT
1600 *          │                            ├─ 010 ─ OPC_MXU_D16AVG
1601 *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
1602 *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
1603 *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
1604 *          │                            └─ 111 ─ OPC_MXU_Q8ADD
1605 *          │
1606 *          │                               20..18
1607 *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1608 *          │                            ├─ 010 ─ OPC_MXU_D16CPS
1609 *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
1610 *          │                            └─ 110 ─ OPC_MXU_Q16SAT
1611 *          ├─ 001000 ─ OPC_MXU_D16MUL
1612 *          │                               25..24
1613 *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1614 *          │                            └─ 01 ─ OPC_MXU_D16MULE
1615 *          ├─ 001010 ─ OPC_MXU_D16MAC
1616 *          ├─ 001011 ─ OPC_MXU_D16MACF
1617 *          ├─ 001100 ─ OPC_MXU_D16MADL
1618 *          ├─ 001101 ─ OPC_MXU_S16MAD
1619 *          ├─ 001110 ─ OPC_MXU_Q16ADD
1620 *          ├─ 001111 ─ OPC_MXU_D16MACE     23
1621 *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
1622 *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1623 *          │
1624 *          │                               23
1625 *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1626 *          │                            └─ 1 ─ OPC_MXU_S32STDR
1627 *          │
1628 *          │                               13..10
1629 *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1630 *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
1631 *          │
1632 *          │                               13..10
1633 *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1634 *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
1635 *          │
1636 *          │                               23
1637 *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1638 *          │                            └─ 1 ─ OPC_MXU_S32LDIR
1639 *          │
1640 *          │                               23
1641 *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1642 *          │                            └─ 1 ─ OPC_MXU_S32SDIR
1643 *          │
1644 *          │                               13..10
1645 *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1646 *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
1647 *          │
1648 *          │                               13..10
1649 *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1650 *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
1651 *          ├─ 011000 ─ OPC_MXU_D32ADD
1652 *          │                               23..22
1653 *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1654 * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
1655 *          │                            └─ 10 ─ OPC_MXU_D32ASUM
1656 *          ├─ 011010 ─ <not assigned>
1657 *          │                               23..22
1658 *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1659 *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
1660 *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
1661 *          │
1662 *          │                               23..22
1663 *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1664 *          │                            ├─ 01 ─ OPC_MXU_D8SUM
1665 *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
1666 *          ├─ 011110 ─ <not assigned>
1667 *          ├─ 011111 ─ <not assigned>
1668 *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
1669 *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
1670 *          ├─ 100010 ─ OPC_MXU_S8LDD
1671 *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
1672 *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
1673 *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
1674 *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
1675 *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1676 *          │
1677 *          │                               20..18
1678 *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1679 *          │                            ├─ 001 ─ OPC_MXU_S32ALN
1680 *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
1681 *          │                            ├─ 011 ─ OPC_MXU_S32LUI
1682 *          │                            ├─ 100 ─ OPC_MXU_S32NOR
1683 *          │                            ├─ 101 ─ OPC_MXU_S32AND
1684 *          │                            ├─ 110 ─ OPC_MXU_S32OR
1685 *          │                            └─ 111 ─ OPC_MXU_S32XOR
1686 *          │
1687 *          │                               7..5
1688 *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1689 *          │                            ├─ 001 ─ OPC_MXU_LXH
1690 *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
1691 *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
1692 *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
1693 *          ├─ 101100 ─ OPC_MXU_S16LDI
1694 *          ├─ 101101 ─ OPC_MXU_S16SDI
1695 *          ├─ 101110 ─ OPC_MXU_S32M2I
1696 *          ├─ 101111 ─ OPC_MXU_S32I2M
1697 *          ├─ 110000 ─ OPC_MXU_D32SLL
1698 *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
1699 *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
1700 *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
1701 *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
1702 *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
1703 *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
1704 *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1705 *          │
1706 *          ├─ 110111 ─ OPC_MXU_Q16SAR
1707 *          │                               23..22
1708 *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1709 *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
1710 *          │
1711 *          │                               20..18
1712 *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1713 *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
1714 *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
1715 *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
1716 *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
1717 *          │                            └─ 101 ─ OPC_MXU_S32MOVN
1718 *          │
1719 *          │                               23..22
1720 *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1721 *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
1722 *          ├─ 111011 ─ OPC_MXU_Q16SCOP
1723 *          ├─ 111100 ─ OPC_MXU_Q8MADL
1724 *          ├─ 111101 ─ OPC_MXU_S32SFL
1725 *          ├─ 111110 ─ OPC_MXU_Q8SAD
1726 *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
1727 *
1728 *
1729 * Compiled after:
1730 *
1731 *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1732 *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1733 */
1734
1735enum {
1736    OPC_MXU_S32MADD  = 0x00,
1737    OPC_MXU_S32MADDU = 0x01,
1738    OPC__MXU_MUL     = 0x02,
1739    OPC_MXU__POOL00  = 0x03,
1740    OPC_MXU_S32MSUB  = 0x04,
1741    OPC_MXU_S32MSUBU = 0x05,
1742    OPC_MXU__POOL01  = 0x06,
1743    OPC_MXU__POOL02  = 0x07,
1744    OPC_MXU_D16MUL   = 0x08,
1745    OPC_MXU__POOL03  = 0x09,
1746    OPC_MXU_D16MAC   = 0x0A,
1747    OPC_MXU_D16MACF  = 0x0B,
1748    OPC_MXU_D16MADL  = 0x0C,
1749    OPC_MXU_S16MAD   = 0x0D,
1750    OPC_MXU_Q16ADD   = 0x0E,
1751    OPC_MXU_D16MACE  = 0x0F,
1752    OPC_MXU__POOL04  = 0x10,
1753    OPC_MXU__POOL05  = 0x11,
1754    OPC_MXU__POOL06  = 0x12,
1755    OPC_MXU__POOL07  = 0x13,
1756    OPC_MXU__POOL08  = 0x14,
1757    OPC_MXU__POOL09  = 0x15,
1758    OPC_MXU__POOL10  = 0x16,
1759    OPC_MXU__POOL11  = 0x17,
1760    OPC_MXU_D32ADD   = 0x18,
1761    OPC_MXU__POOL12  = 0x19,
1762    /* not assigned 0x1A */
1763    OPC_MXU__POOL13  = 0x1B,
1764    OPC_MXU__POOL14  = 0x1C,
1765    OPC_MXU_Q8ACCE   = 0x1D,
1766    /* not assigned 0x1E */
1767    /* not assigned 0x1F */
1768    /* not assigned 0x20 */
1769    /* not assigned 0x21 */
1770    OPC_MXU_S8LDD    = 0x22,
1771    OPC_MXU_S8STD    = 0x23,
1772    OPC_MXU_S8LDI    = 0x24,
1773    OPC_MXU_S8SDI    = 0x25,
1774    OPC_MXU__POOL15  = 0x26,
1775    OPC_MXU__POOL16  = 0x27,
1776    OPC_MXU__POOL17  = 0x28,
1777    /* not assigned 0x29 */
1778    OPC_MXU_S16LDD   = 0x2A,
1779    OPC_MXU_S16STD   = 0x2B,
1780    OPC_MXU_S16LDI   = 0x2C,
1781    OPC_MXU_S16SDI   = 0x2D,
1782    OPC_MXU_S32M2I   = 0x2E,
1783    OPC_MXU_S32I2M   = 0x2F,
1784    OPC_MXU_D32SLL   = 0x30,
1785    OPC_MXU_D32SLR   = 0x31,
1786    OPC_MXU_D32SARL  = 0x32,
1787    OPC_MXU_D32SAR   = 0x33,
1788    OPC_MXU_Q16SLL   = 0x34,
1789    OPC_MXU_Q16SLR   = 0x35,
1790    OPC_MXU__POOL18  = 0x36,
1791    OPC_MXU_Q16SAR   = 0x37,
1792    OPC_MXU__POOL19  = 0x38,
1793    OPC_MXU__POOL20  = 0x39,
1794    OPC_MXU__POOL21  = 0x3A,
1795    OPC_MXU_Q16SCOP  = 0x3B,
1796    OPC_MXU_Q8MADL   = 0x3C,
1797    OPC_MXU_S32SFL   = 0x3D,
1798    OPC_MXU_Q8SAD    = 0x3E,
1799    /* not assigned 0x3F */
1800};
1801
1802
1803/*
1804 * MXU pool 00
1805 */
1806enum {
1807    OPC_MXU_S32MAX   = 0x00,
1808    OPC_MXU_S32MIN   = 0x01,
1809    OPC_MXU_D16MAX   = 0x02,
1810    OPC_MXU_D16MIN   = 0x03,
1811    OPC_MXU_Q8MAX    = 0x04,
1812    OPC_MXU_Q8MIN    = 0x05,
1813    OPC_MXU_Q8SLT    = 0x06,
1814    OPC_MXU_Q8SLTU   = 0x07,
1815};
1816
1817/*
1818 * MXU pool 01
1819 */
1820enum {
1821    OPC_MXU_S32SLT   = 0x00,
1822    OPC_MXU_D16SLT   = 0x01,
1823    OPC_MXU_D16AVG   = 0x02,
1824    OPC_MXU_D16AVGR  = 0x03,
1825    OPC_MXU_Q8AVG    = 0x04,
1826    OPC_MXU_Q8AVGR   = 0x05,
1827    OPC_MXU_Q8ADD    = 0x07,
1828};
1829
1830/*
1831 * MXU pool 02
1832 */
1833enum {
1834    OPC_MXU_S32CPS   = 0x00,
1835    OPC_MXU_D16CPS   = 0x02,
1836    OPC_MXU_Q8ABD    = 0x04,
1837    OPC_MXU_Q16SAT   = 0x06,
1838};
1839
1840/*
1841 * MXU pool 03
1842 */
1843enum {
1844    OPC_MXU_D16MULF  = 0x00,
1845    OPC_MXU_D16MULE  = 0x01,
1846};
1847
1848/*
1849 * MXU pool 04
1850 */
1851enum {
1852    OPC_MXU_S32LDD   = 0x00,
1853    OPC_MXU_S32LDDR  = 0x01,
1854};
1855
1856/*
1857 * MXU pool 05
1858 */
1859enum {
1860    OPC_MXU_S32STD   = 0x00,
1861    OPC_MXU_S32STDR  = 0x01,
1862};
1863
1864/*
1865 * MXU pool 06
1866 */
1867enum {
1868    OPC_MXU_S32LDDV  = 0x00,
1869    OPC_MXU_S32LDDVR = 0x01,
1870};
1871
1872/*
1873 * MXU pool 07
1874 */
1875enum {
1876    OPC_MXU_S32STDV  = 0x00,
1877    OPC_MXU_S32STDVR = 0x01,
1878};
1879
1880/*
1881 * MXU pool 08
1882 */
1883enum {
1884    OPC_MXU_S32LDI   = 0x00,
1885    OPC_MXU_S32LDIR  = 0x01,
1886};
1887
1888/*
1889 * MXU pool 09
1890 */
1891enum {
1892    OPC_MXU_S32SDI   = 0x00,
1893    OPC_MXU_S32SDIR  = 0x01,
1894};
1895
1896/*
1897 * MXU pool 10
1898 */
1899enum {
1900    OPC_MXU_S32LDIV  = 0x00,
1901    OPC_MXU_S32LDIVR = 0x01,
1902};
1903
1904/*
1905 * MXU pool 11
1906 */
1907enum {
1908    OPC_MXU_S32SDIV  = 0x00,
1909    OPC_MXU_S32SDIVR = 0x01,
1910};
1911
1912/*
1913 * MXU pool 12
1914 */
1915enum {
1916    OPC_MXU_D32ACC   = 0x00,
1917    OPC_MXU_D32ACCM  = 0x01,
1918    OPC_MXU_D32ASUM  = 0x02,
1919};
1920
1921/*
1922 * MXU pool 13
1923 */
1924enum {
1925    OPC_MXU_Q16ACC   = 0x00,
1926    OPC_MXU_Q16ACCM  = 0x01,
1927    OPC_MXU_Q16ASUM  = 0x02,
1928};
1929
1930/*
1931 * MXU pool 14
1932 */
1933enum {
1934    OPC_MXU_Q8ADDE   = 0x00,
1935    OPC_MXU_D8SUM    = 0x01,
1936    OPC_MXU_D8SUMC   = 0x02,
1937};
1938
1939/*
1940 * MXU pool 15
1941 */
1942enum {
1943    OPC_MXU_S32MUL   = 0x00,
1944    OPC_MXU_S32MULU  = 0x01,
1945    OPC_MXU_S32EXTR  = 0x02,
1946    OPC_MXU_S32EXTRV = 0x03,
1947};
1948
1949/*
1950 * MXU pool 16
1951 */
1952enum {
1953    OPC_MXU_D32SARW  = 0x00,
1954    OPC_MXU_S32ALN   = 0x01,
1955    OPC_MXU_S32ALNI  = 0x02,
1956    OPC_MXU_S32LUI   = 0x03,
1957    OPC_MXU_S32NOR   = 0x04,
1958    OPC_MXU_S32AND   = 0x05,
1959    OPC_MXU_S32OR    = 0x06,
1960    OPC_MXU_S32XOR   = 0x07,
1961};
1962
1963/*
1964 * MXU pool 17
1965 */
1966enum {
1967    OPC_MXU_LXB      = 0x00,
1968    OPC_MXU_LXH      = 0x01,
1969    OPC_MXU_LXW      = 0x03,
1970    OPC_MXU_LXBU     = 0x04,
1971    OPC_MXU_LXHU     = 0x05,
1972};
1973
1974/*
1975 * MXU pool 18
1976 */
1977enum {
1978    OPC_MXU_D32SLLV  = 0x00,
1979    OPC_MXU_D32SLRV  = 0x01,
1980    OPC_MXU_D32SARV  = 0x03,
1981    OPC_MXU_Q16SLLV  = 0x04,
1982    OPC_MXU_Q16SLRV  = 0x05,
1983    OPC_MXU_Q16SARV  = 0x07,
1984};
1985
1986/*
1987 * MXU pool 19
1988 */
1989enum {
1990    OPC_MXU_Q8MUL    = 0x00,
1991    OPC_MXU_Q8MULSU  = 0x01,
1992};
1993
1994/*
1995 * MXU pool 20
1996 */
1997enum {
1998    OPC_MXU_Q8MOVZ   = 0x00,
1999    OPC_MXU_Q8MOVN   = 0x01,
2000    OPC_MXU_D16MOVZ  = 0x02,
2001    OPC_MXU_D16MOVN  = 0x03,
2002    OPC_MXU_S32MOVZ  = 0x04,
2003    OPC_MXU_S32MOVN  = 0x05,
2004};
2005
2006/*
2007 * MXU pool 21
2008 */
2009enum {
2010    OPC_MXU_Q8MAC    = 0x00,
2011    OPC_MXU_Q8MACSU  = 0x01,
2012};
2013
2014/*
2015 *     Overview of the TX79-specific instruction set
2016 *     =============================================
2017 *
2018 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2019 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2020 * instructions and certain multimedia instructions (MMIs). These MMIs
2021 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2022 * or sixteen 8-bit paths.
2023 *
2024 * Reference:
2025 *
2026 * The Toshiba TX System RISC TX79 Core Architecture manual,
2027 * https://wiki.qemu.org/File:C790.pdf
2028 *
2029 *     Three-Operand Multiply and Multiply-Add (4 instructions)
2030 *     --------------------------------------------------------
2031 * MADD    [rd,] rs, rt      Multiply/Add
2032 * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
2033 * MULT    [rd,] rs, rt      Multiply (3-operand)
2034 * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2035 *
2036 *     Multiply Instructions for Pipeline 1 (10 instructions)
2037 *     ------------------------------------------------------
2038 * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2039 * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2040 * DIV1    rs, rt            Divide Pipeline 1
2041 * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2042 * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2043 * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2044 * MFHI1   rd                Move From HI1 Register
2045 * MFLO1   rd                Move From LO1 Register
2046 * MTHI1   rs                Move To HI1 Register
2047 * MTLO1   rs                Move To LO1 Register
2048 *
2049 *     Arithmetic (19 instructions)
2050 *     ----------------------------
2051 * PADDB   rd, rs, rt        Parallel Add Byte
2052 * PSUBB   rd, rs, rt        Parallel Subtract Byte
2053 * PADDH   rd, rs, rt        Parallel Add Halfword
2054 * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2055 * PADDW   rd, rs, rt        Parallel Add Word
2056 * PSUBW   rd, rs, rt        Parallel Subtract Word
2057 * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2058 * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2059 * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2060 * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2061 * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2062 * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2063 * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2064 * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2065 * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2066 * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2067 * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2068 * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2069 * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2070 *
2071 *     Min/Max (4 instructions)
2072 *     ------------------------
2073 * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2074 * PMINH   rd, rs, rt        Parallel Minimum Halfword
2075 * PMAXW   rd, rs, rt        Parallel Maximum Word
2076 * PMINW   rd, rs, rt        Parallel Minimum Word
2077 *
2078 *     Absolute (2 instructions)
2079 *     -------------------------
2080 * PABSH   rd, rt            Parallel Absolute Halfword
2081 * PABSW   rd, rt            Parallel Absolute Word
2082 *
2083 *     Logical (4 instructions)
2084 *     ------------------------
2085 * PAND    rd, rs, rt        Parallel AND
2086 * POR     rd, rs, rt        Parallel OR
2087 * PXOR    rd, rs, rt        Parallel XOR
2088 * PNOR    rd, rs, rt        Parallel NOR
2089 *
2090 *     Shift (9 instructions)
2091 *     ----------------------
2092 * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2093 * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2094 * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2095 * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2096 * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2097 * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2098 * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2099 * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2100 * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2101 *
2102 *     Compare (6 instructions)
2103 *     ------------------------
2104 * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2105 * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2106 * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2107 * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2108 * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2109 * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2110 *
2111 *     LZC (1 instruction)
2112 *     -------------------
2113 * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2114 *
2115 *     Quadword Load and Store (2 instructions)
2116 *     ----------------------------------------
2117 * LQ      rt, offset(base)  Load Quadword
2118 * SQ      rt, offset(base)  Store Quadword
2119 *
2120 *     Multiply and Divide (19 instructions)
2121 *     -------------------------------------
2122 * PMULTW  rd, rs, rt        Parallel Multiply Word
2123 * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2124 * PDIVW   rs, rt            Parallel Divide Word
2125 * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2126 * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2127 * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2128 * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2129 * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2130 * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2131 * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2132 * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2133 * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2134 * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2135 * PMFHI   rd                Parallel Move From HI Register
2136 * PMFLO   rd                Parallel Move From LO Register
2137 * PMTHI   rs                Parallel Move To HI Register
2138 * PMTLO   rs                Parallel Move To LO Register
2139 * PMFHL   rd                Parallel Move From HI/LO Register
2140 * PMTHL   rs                Parallel Move To HI/LO Register
2141 *
2142 *     Pack/Extend (11 instructions)
2143 *     -----------------------------
2144 * PPAC5   rd, rt            Parallel Pack to 5 bits
2145 * PPACB   rd, rs, rt        Parallel Pack to Byte
2146 * PPACH   rd, rs, rt        Parallel Pack to Halfword
2147 * PPACW   rd, rs, rt        Parallel Pack to Word
2148 * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2149 * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2150 * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2151 * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2152 * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2153 * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2154 * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2155 *
2156 *     Others (16 instructions)
2157 *     ------------------------
2158 * PCPYH   rd, rt            Parallel Copy Halfword
2159 * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2160 * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2161 * PREVH   rd, rt            Parallel Reverse Halfword
2162 * PINTH   rd, rs, rt        Parallel Interleave Halfword
2163 * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2164 * PEXEH   rd, rt            Parallel Exchange Even Halfword
2165 * PEXCH   rd, rt            Parallel Exchange Center Halfword
2166 * PEXEW   rd, rt            Parallel Exchange Even Word
2167 * PEXCW   rd, rt            Parallel Exchange Center Word
2168 * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2169 * MFSA    rd                Move from Shift Amount Register
2170 * MTSA    rs                Move to Shift Amount Register
2171 * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2172 * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2173 * PROT3W  rd, rt            Parallel Rotate 3 Words
2174 *
2175 *     MMI (MultiMedia Instruction) encodings
2176 *     ======================================
2177 *
2178 * MMI instructions encoding table keys:
2179 *
2180 *     *   This code is reserved for future use. An attempt to execute it
2181 *         causes a Reserved Instruction exception.
2182 *     %   This code indicates an instruction class. The instruction word
2183 *         must be further decoded by examining additional tables that show
2184 *         the values for other instruction fields.
2185 *     #   This code is reserved for the unsupported instructions DMULT,
2186 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2187 *         to execute it causes a Reserved Instruction exception.
2188 *
2189 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2190 *
2191 *  31    26                                        0
2192 * +--------+----------------------------------------+
2193 * | opcode |                                        |
2194 * +--------+----------------------------------------+
2195 *
2196 *   opcode  bits 28..26
2197 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2198 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2199 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2200 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2201 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2202 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2203 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2204 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2205 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2206 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2207 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2208 */
2209
2210enum {
2211    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2212    MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2213    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2214};
2215
2216/*
2217 * MMI instructions with opcode field = MMI:
2218 *
2219 *  31    26                                 5      0
2220 * +--------+-------------------------------+--------+
2221 * |   MMI  |                               |function|
2222 * +--------+-------------------------------+--------+
2223 *
2224 * function  bits 2..0
2225 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2226 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2227 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2228 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2229 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2230 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2231 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2232 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2233 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2234 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2235 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2236 */
2237
2238#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2239enum {
2240    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2241    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2242    MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2243    MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2244    MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2245    MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2246    MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2247    MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2248    MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2249    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2250    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2251    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2252    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2253    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2254    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2255    MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2256    MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2257    MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2258    MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2259    MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2260    MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2261    MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2262    MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2263    MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2264    MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2265};
2266
2267/*
2268 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2269 *
2270 *  31    26                        10     6 5      0
2271 * +--------+----------------------+--------+--------+
2272 * |   MMI  |                      |function|  MMI0  |
2273 * +--------+----------------------+--------+--------+
2274 *
2275 * function  bits 7..6
2276 *     bits |   0   |   1   |   2   |   3
2277 *    10..8 |   00  |   01  |   10  |   11
2278 *   -------+-------+-------+-------+-------
2279 *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2280 *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2281 *    2 010 | PADDB | PSUBB | PCGTB |   *
2282 *    3 011 |   *   |   *   |   *   |   *
2283 *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2284 *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2285 *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2286 *    7 111 |   *   |   *   | PEXT5 | PPAC5
2287 */
2288
2289#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2290enum {
2291    MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2292    MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2293    MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2294    MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2295    MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2296    MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2297    MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2298    MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2299    MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2300    MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2301    MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2302    MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2303    MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2304    MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2305    MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2306    MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2307    MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2308    MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2309    MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2310    MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2311    MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2312    MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2313    MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2314    MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2315    MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2316};
2317
2318/*
2319 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2320 *
2321 *  31    26                        10     6 5      0
2322 * +--------+----------------------+--------+--------+
2323 * |   MMI  |                      |function|  MMI1  |
2324 * +--------+----------------------+--------+--------+
2325 *
2326 * function  bits 7..6
2327 *     bits |   0   |   1   |   2   |   3
2328 *    10..8 |   00  |   01  |   10  |   11
2329 *   -------+-------+-------+-------+-------
2330 *    0 000 |   *   | PABSW | PCEQW | PMINW
2331 *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2332 *    2 010 |   *   |   *   | PCEQB |   *
2333 *    3 011 |   *   |   *   |   *   |   *
2334 *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2335 *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2336 *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2337 *    7 111 |   *   |   *   |   *   |   *
2338 */
2339
2340#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2341enum {
2342    MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2343    MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2344    MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2345    MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2346    MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2347    MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2348    MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2349    MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2350    MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2351    MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2352    MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2353    MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2354    MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2355    MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2356    MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2357    MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2358    MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2359    MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2360};
2361
2362/*
2363 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2364 *
2365 *  31    26                        10     6 5      0
2366 * +--------+----------------------+--------+--------+
2367 * |   MMI  |                      |function|  MMI2  |
2368 * +--------+----------------------+--------+--------+
2369 *
2370 * function  bits 7..6
2371 *     bits |   0   |   1   |   2   |   3
2372 *    10..8 |   00  |   01  |   10  |   11
2373 *   -------+-------+-------+-------+-------
2374 *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2375 *    1 001 | PMSUBW|   *   |   *   |   *
2376 *    2 010 | PMFHI | PMFLO | PINTH |   *
2377 *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2378 *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2379 *    5 101 | PMSUBH| PHMSBH|   *   |   *
2380 *    6 110 |   *   |   *   | PEXEH | PREVH
2381 *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2382 */
2383
2384#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2385enum {
2386    MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2387    MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2388    MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2389    MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2390    MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2391    MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2392    MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2393    MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2394    MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2395    MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2396    MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2397    MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2398    MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2399    MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2400    MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2401    MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2402    MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2403    MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2404    MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2405    MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2406    MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2407    MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2408};
2409
2410/*
2411 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2412 *
2413 *  31    26                        10     6 5      0
2414 * +--------+----------------------+--------+--------+
2415 * |   MMI  |                      |function|  MMI3  |
2416 * +--------+----------------------+--------+--------+
2417 *
2418 * function  bits 7..6
2419 *     bits |   0   |   1   |   2   |   3
2420 *    10..8 |   00  |   01  |   10  |   11
2421 *   -------+-------+-------+-------+-------
2422 *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2423 *    1 001 |   *   |   *   |   *   |   *
2424 *    2 010 | PMTHI | PMTLO | PINTEH|   *
2425 *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2426 *    4 100 |   *   |   *   |  POR  |  PNOR
2427 *    5 101 |   *   |   *   |   *   |   *
2428 *    6 110 |   *   |   *   | PEXCH | PCPYH
2429 *    7 111 |   *   |   *   | PEXCW |   *
2430 */
2431
2432#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2433enum {
2434    MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2435    MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2436    MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2437    MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2438    MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2439    MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2440    MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2441    MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2442    MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2443    MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2444    MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2445    MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2446    MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2447};
2448
2449/* global register indices */
2450static TCGv cpu_gpr[32], cpu_PC;
2451static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2452static TCGv cpu_dspctrl, btarget, bcond;
2453static TCGv cpu_lladdr, cpu_llval;
2454static TCGv_i32 hflags;
2455static TCGv_i32 fpu_fcr0, fpu_fcr31;
2456static TCGv_i64 fpu_f64[32];
2457static TCGv_i64 msa_wr_d[64];
2458
2459#if defined(TARGET_MIPS64)
2460/* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2461static TCGv_i64 cpu_mmr[32];
2462#endif
2463
2464#if !defined(TARGET_MIPS64)
2465/* MXU registers */
2466static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2467static TCGv mxu_CR;
2468#endif
2469
2470#include "exec/gen-icount.h"
2471
2472#define gen_helper_0e0i(name, arg) do {                           \
2473    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2474    gen_helper_##name(cpu_env, helper_tmp);                       \
2475    tcg_temp_free_i32(helper_tmp);                                \
2476    } while(0)
2477
2478#define gen_helper_0e1i(name, arg1, arg2) do {                    \
2479    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2480    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2481    tcg_temp_free_i32(helper_tmp);                                \
2482    } while(0)
2483
2484#define gen_helper_1e0i(name, ret, arg1) do {                     \
2485    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2486    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2487    tcg_temp_free_i32(helper_tmp);                                \
2488    } while(0)
2489
2490#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2491    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2492    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2493    tcg_temp_free_i32(helper_tmp);                                \
2494    } while(0)
2495
2496#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2497    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2498    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2499    tcg_temp_free_i32(helper_tmp);                                \
2500    } while(0)
2501
2502#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2503    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2504    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2505    tcg_temp_free_i32(helper_tmp);                                \
2506    } while(0)
2507
2508#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2509    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2510    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2511    tcg_temp_free_i32(helper_tmp);                                \
2512    } while(0)
2513
2514typedef struct DisasContext {
2515    DisasContextBase base;
2516    target_ulong saved_pc;
2517    target_ulong page_start;
2518    uint32_t opcode;
2519    uint64_t insn_flags;
2520    int32_t CP0_Config1;
2521    int32_t CP0_Config2;
2522    int32_t CP0_Config3;
2523    int32_t CP0_Config5;
2524    /* Routine used to access memory */
2525    int mem_idx;
2526    TCGMemOp default_tcg_memop_mask;
2527    uint32_t hflags, saved_hflags;
2528    target_ulong btarget;
2529    bool ulri;
2530    int kscrexist;
2531    bool rxi;
2532    int ie;
2533    bool bi;
2534    bool bp;
2535    uint64_t PAMask;
2536    bool mvh;
2537    bool eva;
2538    bool sc;
2539    int CP0_LLAddr_shift;
2540    bool ps;
2541    bool vp;
2542    bool cmgcr;
2543    bool mrp;
2544    bool nan2008;
2545    bool abs2008;
2546    bool saar;
2547} DisasContext;
2548
2549#define DISAS_STOP       DISAS_TARGET_0
2550#define DISAS_EXIT       DISAS_TARGET_1
2551
2552static const char * const regnames[] = {
2553    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2554    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2555    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2556    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2557};
2558
2559static const char * const regnames_HI[] = {
2560    "HI0", "HI1", "HI2", "HI3",
2561};
2562
2563static const char * const regnames_LO[] = {
2564    "LO0", "LO1", "LO2", "LO3",
2565};
2566
2567static const char * const fregnames[] = {
2568    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2569    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2570    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2571    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2572};
2573
2574static const char * const msaregnames[] = {
2575    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2576    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2577    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2578    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2579    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2580    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2581    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2582    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2583    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2584    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2585    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2586    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2587    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2588    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2589    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2590    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2591};
2592
2593#if !defined(TARGET_MIPS64)
2594static const char * const mxuregnames[] = {
2595    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2596    "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2597};
2598#endif
2599
2600#define LOG_DISAS(...)                                                        \
2601    do {                                                                      \
2602        if (MIPS_DEBUG_DISAS) {                                               \
2603            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2604        }                                                                     \
2605    } while (0)
2606
2607#define MIPS_INVAL(op)                                                        \
2608    do {                                                                      \
2609        if (MIPS_DEBUG_DISAS) {                                               \
2610            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2611                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2612                          ctx->base.pc_next, ctx->opcode, op,                 \
2613                          ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2614                          ((ctx->opcode >> 16) & 0x1F));                      \
2615        }                                                                     \
2616    } while (0)
2617
2618/* General purpose registers moves. */
2619static inline void gen_load_gpr (TCGv t, int reg)
2620{
2621    if (reg == 0)
2622        tcg_gen_movi_tl(t, 0);
2623    else
2624        tcg_gen_mov_tl(t, cpu_gpr[reg]);
2625}
2626
2627static inline void gen_store_gpr (TCGv t, int reg)
2628{
2629    if (reg != 0)
2630        tcg_gen_mov_tl(cpu_gpr[reg], t);
2631}
2632
2633/* Moves to/from shadow registers. */
2634static inline void gen_load_srsgpr (int from, int to)
2635{
2636    TCGv t0 = tcg_temp_new();
2637
2638    if (from == 0)
2639        tcg_gen_movi_tl(t0, 0);
2640    else {
2641        TCGv_i32 t2 = tcg_temp_new_i32();
2642        TCGv_ptr addr = tcg_temp_new_ptr();
2643
2644        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2645        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2646        tcg_gen_andi_i32(t2, t2, 0xf);
2647        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2648        tcg_gen_ext_i32_ptr(addr, t2);
2649        tcg_gen_add_ptr(addr, cpu_env, addr);
2650
2651        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2652        tcg_temp_free_ptr(addr);
2653        tcg_temp_free_i32(t2);
2654    }
2655    gen_store_gpr(t0, to);
2656    tcg_temp_free(t0);
2657}
2658
2659static inline void gen_store_srsgpr (int from, int to)
2660{
2661    if (to != 0) {
2662        TCGv t0 = tcg_temp_new();
2663        TCGv_i32 t2 = tcg_temp_new_i32();
2664        TCGv_ptr addr = tcg_temp_new_ptr();
2665
2666        gen_load_gpr(t0, from);
2667        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2668        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2669        tcg_gen_andi_i32(t2, t2, 0xf);
2670        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2671        tcg_gen_ext_i32_ptr(addr, t2);
2672        tcg_gen_add_ptr(addr, cpu_env, addr);
2673
2674        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2675        tcg_temp_free_ptr(addr);
2676        tcg_temp_free_i32(t2);
2677        tcg_temp_free(t0);
2678    }
2679}
2680
2681#if !defined(TARGET_MIPS64)
2682/* MXU General purpose registers moves. */
2683static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2684{
2685    if (reg == 0) {
2686        tcg_gen_movi_tl(t, 0);
2687    } else if (reg <= 15) {
2688        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2689    }
2690}
2691
2692static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2693{
2694    if (reg > 0 && reg <= 15) {
2695        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2696    }
2697}
2698
2699/* MXU control register moves. */
2700static inline void gen_load_mxu_cr(TCGv t)
2701{
2702    tcg_gen_mov_tl(t, mxu_CR);
2703}
2704
2705static inline void gen_store_mxu_cr(TCGv t)
2706{
2707    /* TODO: Add handling of RW rules for MXU_CR. */
2708    tcg_gen_mov_tl(mxu_CR, t);
2709}
2710#endif
2711
2712
2713/* Tests */
2714static inline void gen_save_pc(target_ulong pc)
2715{
2716    tcg_gen_movi_tl(cpu_PC, pc);
2717}
2718
2719static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2720{
2721    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2722    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2723        gen_save_pc(ctx->base.pc_next);
2724        ctx->saved_pc = ctx->base.pc_next;
2725    }
2726    if (ctx->hflags != ctx->saved_hflags) {
2727        tcg_gen_movi_i32(hflags, ctx->hflags);
2728        ctx->saved_hflags = ctx->hflags;
2729        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2730        case MIPS_HFLAG_BR:
2731            break;
2732        case MIPS_HFLAG_BC:
2733        case MIPS_HFLAG_BL:
2734        case MIPS_HFLAG_B:
2735            tcg_gen_movi_tl(btarget, ctx->btarget);
2736            break;
2737        }
2738    }
2739}
2740
2741static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2742{
2743    ctx->saved_hflags = ctx->hflags;
2744    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2745    case MIPS_HFLAG_BR:
2746        break;
2747    case MIPS_HFLAG_BC:
2748    case MIPS_HFLAG_BL:
2749    case MIPS_HFLAG_B:
2750        ctx->btarget = env->btarget;
2751        break;
2752    }
2753}
2754
2755static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2756{
2757    TCGv_i32 texcp = tcg_const_i32(excp);
2758    TCGv_i32 terr = tcg_const_i32(err);
2759    save_cpu_state(ctx, 1);
2760    gen_helper_raise_exception_err(cpu_env, texcp, terr);
2761    tcg_temp_free_i32(terr);
2762    tcg_temp_free_i32(texcp);
2763    ctx->base.is_jmp = DISAS_NORETURN;
2764}
2765
2766static inline void generate_exception(DisasContext *ctx, int excp)
2767{
2768    gen_helper_0e0i(raise_exception, excp);
2769}
2770
2771static inline void generate_exception_end(DisasContext *ctx, int excp)
2772{
2773    generate_exception_err(ctx, excp, 0);
2774}
2775
2776/* Floating point register moves. */
2777static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2778{
2779    if (ctx->hflags & MIPS_HFLAG_FRE) {
2780        generate_exception(ctx, EXCP_RI);
2781    }
2782    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2783}
2784
2785static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2786{
2787    TCGv_i64 t64;
2788    if (ctx->hflags & MIPS_HFLAG_FRE) {
2789        generate_exception(ctx, EXCP_RI);
2790    }
2791    t64 = tcg_temp_new_i64();
2792    tcg_gen_extu_i32_i64(t64, t);
2793    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2794    tcg_temp_free_i64(t64);
2795}
2796
2797static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2798{
2799    if (ctx->hflags & MIPS_HFLAG_F64) {
2800        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2801    } else {
2802        gen_load_fpr32(ctx, t, reg | 1);
2803    }
2804}
2805
2806static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2807{
2808    if (ctx->hflags & MIPS_HFLAG_F64) {
2809        TCGv_i64 t64 = tcg_temp_new_i64();
2810        tcg_gen_extu_i32_i64(t64, t);
2811        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2812        tcg_temp_free_i64(t64);
2813    } else {
2814        gen_store_fpr32(ctx, t, reg | 1);
2815    }
2816}
2817
2818static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2819{
2820    if (ctx->hflags & MIPS_HFLAG_F64) {
2821        tcg_gen_mov_i64(t, fpu_f64[reg]);
2822    } else {
2823        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2824    }
2825}
2826
2827static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2828{
2829    if (ctx->hflags & MIPS_HFLAG_F64) {
2830        tcg_gen_mov_i64(fpu_f64[reg], t);
2831    } else {
2832        TCGv_i64 t0;
2833        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2834        t0 = tcg_temp_new_i64();
2835        tcg_gen_shri_i64(t0, t, 32);
2836        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2837        tcg_temp_free_i64(t0);
2838    }
2839}
2840
2841static inline int get_fp_bit (int cc)
2842{
2843    if (cc)
2844        return 24 + cc;
2845    else
2846        return 23;
2847}
2848
2849/* Addresses computation */
2850static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2851{
2852    tcg_gen_add_tl(ret, arg0, arg1);
2853
2854#if defined(TARGET_MIPS64)
2855    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2856        tcg_gen_ext32s_i64(ret, ret);
2857    }
2858#endif
2859}
2860
2861static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2862                                    target_long ofs)
2863{
2864    tcg_gen_addi_tl(ret, base, ofs);
2865
2866#if defined(TARGET_MIPS64)
2867    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2868        tcg_gen_ext32s_i64(ret, ret);
2869    }
2870#endif
2871}
2872
2873/* Addresses computation (translation time) */
2874static target_long addr_add(DisasContext *ctx, target_long base,
2875                            target_long offset)
2876{
2877    target_long sum = base + offset;
2878
2879#if defined(TARGET_MIPS64)
2880    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2881        sum = (int32_t)sum;
2882    }
2883#endif
2884    return sum;
2885}
2886
2887/* Sign-extract the low 32-bits to a target_long.  */
2888static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2889{
2890#if defined(TARGET_MIPS64)
2891    tcg_gen_ext32s_i64(ret, arg);
2892#else
2893    tcg_gen_extrl_i64_i32(ret, arg);
2894#endif
2895}
2896
2897/* Sign-extract the high 32-bits to a target_long.  */
2898static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2899{
2900#if defined(TARGET_MIPS64)
2901    tcg_gen_sari_i64(ret, arg, 32);
2902#else
2903    tcg_gen_extrh_i64_i32(ret, arg);
2904#endif
2905}
2906
2907static inline void check_cp0_enabled(DisasContext *ctx)
2908{
2909    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2910        generate_exception_err(ctx, EXCP_CpU, 0);
2911}
2912
2913static inline void check_cp1_enabled(DisasContext *ctx)
2914{
2915    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2916        generate_exception_err(ctx, EXCP_CpU, 1);
2917}
2918
2919/* Verify that the processor is running with COP1X instructions enabled.
2920   This is associated with the nabla symbol in the MIPS32 and MIPS64
2921   opcode tables.  */
2922
2923static inline void check_cop1x(DisasContext *ctx)
2924{
2925    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2926        generate_exception_end(ctx, EXCP_RI);
2927}
2928
2929/* Verify that the processor is running with 64-bit floating-point
2930   operations enabled.  */
2931
2932static inline void check_cp1_64bitmode(DisasContext *ctx)
2933{
2934    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2935        generate_exception_end(ctx, EXCP_RI);
2936}
2937
2938/*
2939 * Verify if floating point register is valid; an operation is not defined
2940 * if bit 0 of any register specification is set and the FR bit in the
2941 * Status register equals zero, since the register numbers specify an
2942 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2943 * in the Status register equals one, both even and odd register numbers
2944 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2945 *
2946 * Multiple 64 bit wide registers can be checked by calling
2947 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2948 */
2949static inline void check_cp1_registers(DisasContext *ctx, int regs)
2950{
2951    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2952        generate_exception_end(ctx, EXCP_RI);
2953}
2954
2955/* Verify that the processor is running with DSP instructions enabled.
2956   This is enabled by CP0 Status register MX(24) bit.
2957 */
2958
2959static inline void check_dsp(DisasContext *ctx)
2960{
2961    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2962        if (ctx->insn_flags & ASE_DSP) {
2963            generate_exception_end(ctx, EXCP_DSPDIS);
2964        } else {
2965            generate_exception_end(ctx, EXCP_RI);
2966        }
2967    }
2968}
2969
2970static inline void check_dsp_r2(DisasContext *ctx)
2971{
2972    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2973        if (ctx->insn_flags & ASE_DSP) {
2974            generate_exception_end(ctx, EXCP_DSPDIS);
2975        } else {
2976            generate_exception_end(ctx, EXCP_RI);
2977        }
2978    }
2979}
2980
2981static inline void check_dsp_r3(DisasContext *ctx)
2982{
2983    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2984        if (ctx->insn_flags & ASE_DSP) {
2985            generate_exception_end(ctx, EXCP_DSPDIS);
2986        } else {
2987            generate_exception_end(ctx, EXCP_RI);
2988        }
2989    }
2990}
2991
2992/* This code generates a "reserved instruction" exception if the
2993   CPU does not support the instruction set corresponding to flags. */
2994static inline void check_insn(DisasContext *ctx, uint64_t flags)
2995{
2996    if (unlikely(!(ctx->insn_flags & flags))) {
2997        generate_exception_end(ctx, EXCP_RI);
2998    }
2999}
3000
3001/* This code generates a "reserved instruction" exception if the
3002   CPU has corresponding flag set which indicates that the instruction
3003   has been removed. */
3004static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3005{
3006    if (unlikely(ctx->insn_flags & flags)) {
3007        generate_exception_end(ctx, EXCP_RI);
3008    }
3009}
3010
3011/*
3012 * The Linux kernel traps certain reserved instruction exceptions to
3013 * emulate the corresponding instructions. QEMU is the kernel in user
3014 * mode, so those traps are emulated by accepting the instructions.
3015 *
3016 * A reserved instruction exception is generated for flagged CPUs if
3017 * QEMU runs in system mode.
3018 */
3019static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3020{
3021#ifndef CONFIG_USER_ONLY
3022    check_insn_opc_removed(ctx, flags);
3023#endif
3024}
3025
3026/* This code generates a "reserved instruction" exception if the
3027   CPU does not support 64-bit paired-single (PS) floating point data type */
3028static inline void check_ps(DisasContext *ctx)
3029{
3030    if (unlikely(!ctx->ps)) {
3031        generate_exception(ctx, EXCP_RI);
3032    }
3033    check_cp1_64bitmode(ctx);
3034}
3035
3036#ifdef TARGET_MIPS64
3037/* This code generates a "reserved instruction" exception if 64-bit
3038   instructions are not enabled. */
3039static inline void check_mips_64(DisasContext *ctx)
3040{
3041    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3042        generate_exception_end(ctx, EXCP_RI);
3043}
3044#endif
3045
3046#ifndef CONFIG_USER_ONLY
3047static inline void check_mvh(DisasContext *ctx)
3048{
3049    if (unlikely(!ctx->mvh)) {
3050        generate_exception(ctx, EXCP_RI);
3051    }
3052}
3053#endif
3054
3055/*
3056 * This code generates a "reserved instruction" exception if the
3057 * Config5 XNP bit is set.
3058 */
3059static inline void check_xnp(DisasContext *ctx)
3060{
3061    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3062        generate_exception_end(ctx, EXCP_RI);
3063    }
3064}
3065
3066#ifndef CONFIG_USER_ONLY
3067/*
3068 * This code generates a "reserved instruction" exception if the
3069 * Config3 PW bit is NOT set.
3070 */
3071static inline void check_pw(DisasContext *ctx)
3072{
3073    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3074        generate_exception_end(ctx, EXCP_RI);
3075    }
3076}
3077#endif
3078
3079/*
3080 * This code generates a "reserved instruction" exception if the
3081 * Config3 MT bit is NOT set.
3082 */
3083static inline void check_mt(DisasContext *ctx)
3084{
3085    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3086        generate_exception_end(ctx, EXCP_RI);
3087    }
3088}
3089
3090#ifndef CONFIG_USER_ONLY
3091/*
3092 * This code generates a "coprocessor unusable" exception if CP0 is not
3093 * available, and, if that is not the case, generates a "reserved instruction"
3094 * exception if the Config5 MT bit is NOT set. This is needed for availability
3095 * control of some of MT ASE instructions.
3096 */
3097static inline void check_cp0_mt(DisasContext *ctx)
3098{
3099    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3100        generate_exception_err(ctx, EXCP_CpU, 0);
3101    } else {
3102        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3103            generate_exception_err(ctx, EXCP_RI, 0);
3104        }
3105    }
3106}
3107#endif
3108
3109/*
3110 * This code generates a "reserved instruction" exception if the
3111 * Config5 NMS bit is set.
3112 */
3113static inline void check_nms(DisasContext *ctx)
3114{
3115    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3116        generate_exception_end(ctx, EXCP_RI);
3117    }
3118}
3119
3120/*
3121 * This code generates a "reserved instruction" exception if the
3122 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3123 * Config2 TL, and Config5 L2C are unset.
3124 */
3125static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3126{
3127    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3128        !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3129        !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3130        !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3131        !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3132        !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3133    {
3134        generate_exception_end(ctx, EXCP_RI);
3135    }
3136}
3137
3138/*
3139 * This code generates a "reserved instruction" exception if the
3140 * Config5 EVA bit is NOT set.
3141 */
3142static inline void check_eva(DisasContext *ctx)
3143{
3144    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3145        generate_exception_end(ctx, EXCP_RI);
3146    }
3147}
3148
3149
3150/* Define small wrappers for gen_load_fpr* so that we have a uniform
3151   calling interface for 32 and 64-bit FPRs.  No sense in changing
3152   all callers for gen_load_fpr32 when we need the CTX parameter for
3153   this one use.  */
3154#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3155#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3156#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3157static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3158                                               int ft, int fs, int cc)        \
3159{                                                                             \
3160    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3161    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3162    switch (ifmt) {                                                           \
3163    case FMT_PS:                                                              \
3164        check_ps(ctx);                                                        \
3165        break;                                                                \
3166    case FMT_D:                                                               \
3167        if (abs) {                                                            \
3168            check_cop1x(ctx);                                                 \
3169        }                                                                     \
3170        check_cp1_registers(ctx, fs | ft);                                    \
3171        break;                                                                \
3172    case FMT_S:                                                               \
3173        if (abs) {                                                            \
3174            check_cop1x(ctx);                                                 \
3175        }                                                                     \
3176        break;                                                                \
3177    }                                                                         \
3178    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3179    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3180    switch (n) {                                                              \
3181    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
3182    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
3183    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
3184    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
3185    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
3186    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
3187    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
3188    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
3189    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
3190    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3191    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
3192    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
3193    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
3194    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
3195    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
3196    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
3197    default: abort();                                                         \
3198    }                                                                         \
3199    tcg_temp_free_i##bits (fp0);                                              \
3200    tcg_temp_free_i##bits (fp1);                                              \
3201}
3202
3203FOP_CONDS(, 0, d, FMT_D, 64)
3204FOP_CONDS(abs, 1, d, FMT_D, 64)
3205FOP_CONDS(, 0, s, FMT_S, 32)
3206FOP_CONDS(abs, 1, s, FMT_S, 32)
3207FOP_CONDS(, 0, ps, FMT_PS, 64)
3208FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3209#undef FOP_CONDS
3210
3211#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3212static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3213                                      int ft, int fs, int fd)           \
3214{                                                                       \
3215    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3216    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3217    if (ifmt == FMT_D) {                                                \
3218        check_cp1_registers(ctx, fs | ft | fd);                         \
3219    }                                                                   \
3220    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3221    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3222    switch (n) {                                                        \
3223    case  0:                                                            \
3224        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3225        break;                                                          \
3226    case  1:                                                            \
3227        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3228        break;                                                          \
3229    case  2:                                                            \
3230        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3231        break;                                                          \
3232    case  3:                                                            \
3233        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3234        break;                                                          \
3235    case  4:                                                            \
3236        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3237        break;                                                          \
3238    case  5:                                                            \
3239        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3240        break;                                                          \
3241    case  6:                                                            \
3242        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3243        break;                                                          \
3244    case  7:                                                            \
3245        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3246        break;                                                          \
3247    case  8:                                                            \
3248        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3249        break;                                                          \
3250    case  9:                                                            \
3251        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3252        break;                                                          \
3253    case 10:                                                            \
3254        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3255        break;                                                          \
3256    case 11:                                                            \
3257        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3258        break;                                                          \
3259    case 12:                                                            \
3260        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3261        break;                                                          \
3262    case 13:                                                            \
3263        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3264        break;                                                          \
3265    case 14:                                                            \
3266        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3267        break;                                                          \
3268    case 15:                                                            \
3269        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3270        break;                                                          \
3271    case 17:                                                            \
3272        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3273        break;                                                          \
3274    case 18:                                                            \
3275        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3276        break;                                                          \
3277    case 19:                                                            \
3278        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3279        break;                                                          \
3280    case 25:                                                            \
3281        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3282        break;                                                          \
3283    case 26:                                                            \
3284        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3285        break;                                                          \
3286    case 27:                                                            \
3287        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3288        break;                                                          \
3289    default:                                                            \
3290        abort();                                                        \
3291    }                                                                   \
3292    STORE;                                                              \
3293    tcg_temp_free_i ## bits (fp0);                                      \
3294    tcg_temp_free_i ## bits (fp1);                                      \
3295}
3296
3297FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3298FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3299#undef FOP_CONDNS
3300#undef gen_ldcmp_fpr32
3301#undef gen_ldcmp_fpr64
3302
3303/* load/store instructions. */
3304#ifdef CONFIG_USER_ONLY
3305#define OP_LD_ATOMIC(insn,fname)                                           \
3306static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3307                                DisasContext *ctx)                         \
3308{                                                                          \
3309    TCGv t0 = tcg_temp_new();                                              \
3310    tcg_gen_mov_tl(t0, arg1);                                              \
3311    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3312    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3313    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3314    tcg_temp_free(t0);                                                     \
3315}
3316#else
3317#define OP_LD_ATOMIC(insn,fname)                                           \
3318static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3319                                DisasContext *ctx)                         \
3320{                                                                          \
3321    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3322}
3323#endif
3324OP_LD_ATOMIC(ll,ld32s);
3325#if defined(TARGET_MIPS64)
3326OP_LD_ATOMIC(lld,ld64);
3327#endif
3328#undef OP_LD_ATOMIC
3329
3330static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3331                                  int base, int offset)
3332{
3333    if (base == 0) {
3334        tcg_gen_movi_tl(addr, offset);
3335    } else if (offset == 0) {
3336        gen_load_gpr(addr, base);
3337    } else {
3338        tcg_gen_movi_tl(addr, offset);
3339        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3340    }
3341}
3342
3343static target_ulong pc_relative_pc (DisasContext *ctx)
3344{
3345    target_ulong pc = ctx->base.pc_next;
3346
3347    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3348        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3349
3350        pc -= branch_bytes;
3351    }
3352
3353    pc &= ~(target_ulong)3;
3354    return pc;
3355}
3356
3357/* Load */
3358static void gen_ld(DisasContext *ctx, uint32_t opc,
3359                   int rt, int base, int offset)
3360{
3361    TCGv t0, t1, t2;
3362    int mem_idx = ctx->mem_idx;
3363
3364    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3365        /* Loongson CPU uses a load to zero register for prefetch.
3366           We emulate it as a NOP. On other CPU we must perform the
3367           actual memory access. */
3368        return;
3369    }
3370
3371    t0 = tcg_temp_new();
3372    gen_base_offset_addr(ctx, t0, base, offset);
3373
3374    switch (opc) {
3375#if defined(TARGET_MIPS64)
3376    case OPC_LWU:
3377        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3378                           ctx->default_tcg_memop_mask);
3379        gen_store_gpr(t0, rt);
3380        break;
3381    case OPC_LD:
3382        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3383                           ctx->default_tcg_memop_mask);
3384        gen_store_gpr(t0, rt);
3385        break;
3386    case OPC_LLD:
3387    case R6_OPC_LLD:
3388        op_ld_lld(t0, t0, mem_idx, ctx);
3389        gen_store_gpr(t0, rt);
3390        break;
3391    case OPC_LDL:
3392        t1 = tcg_temp_new();
3393        /* Do a byte access to possibly trigger a page
3394           fault with the unaligned address.  */
3395        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3396        tcg_gen_andi_tl(t1, t0, 7);
3397#ifndef TARGET_WORDS_BIGENDIAN
3398        tcg_gen_xori_tl(t1, t1, 7);
3399#endif
3400        tcg_gen_shli_tl(t1, t1, 3);
3401        tcg_gen_andi_tl(t0, t0, ~7);
3402        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3403        tcg_gen_shl_tl(t0, t0, t1);
3404        t2 = tcg_const_tl(-1);
3405        tcg_gen_shl_tl(t2, t2, t1);
3406        gen_load_gpr(t1, rt);
3407        tcg_gen_andc_tl(t1, t1, t2);
3408        tcg_temp_free(t2);
3409        tcg_gen_or_tl(t0, t0, t1);
3410        tcg_temp_free(t1);
3411        gen_store_gpr(t0, rt);
3412        break;
3413    case OPC_LDR:
3414        t1 = tcg_temp_new();
3415        /* Do a byte access to possibly trigger a page
3416           fault with the unaligned address.  */
3417        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3418        tcg_gen_andi_tl(t1, t0, 7);
3419#ifdef TARGET_WORDS_BIGENDIAN
3420        tcg_gen_xori_tl(t1, t1, 7);
3421#endif
3422        tcg_gen_shli_tl(t1, t1, 3);
3423        tcg_gen_andi_tl(t0, t0, ~7);
3424        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3425        tcg_gen_shr_tl(t0, t0, t1);
3426        tcg_gen_xori_tl(t1, t1, 63);
3427        t2 = tcg_const_tl(0xfffffffffffffffeull);
3428        tcg_gen_shl_tl(t2, t2, t1);
3429        gen_load_gpr(t1, rt);
3430        tcg_gen_and_tl(t1, t1, t2);
3431        tcg_temp_free(t2);
3432        tcg_gen_or_tl(t0, t0, t1);
3433        tcg_temp_free(t1);
3434        gen_store_gpr(t0, rt);
3435        break;
3436    case OPC_LDPC:
3437        t1 = tcg_const_tl(pc_relative_pc(ctx));
3438        gen_op_addr_add(ctx, t0, t0, t1);
3439        tcg_temp_free(t1);
3440        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3441        gen_store_gpr(t0, rt);
3442        break;
3443#endif
3444    case OPC_LWPC:
3445        t1 = tcg_const_tl(pc_relative_pc(ctx));
3446        gen_op_addr_add(ctx, t0, t0, t1);
3447        tcg_temp_free(t1);
3448        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3449        gen_store_gpr(t0, rt);
3450        break;
3451    case OPC_LWE:
3452        mem_idx = MIPS_HFLAG_UM;
3453        /* fall through */
3454    case OPC_LW:
3455        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3456                           ctx->default_tcg_memop_mask);
3457        gen_store_gpr(t0, rt);
3458        break;
3459    case OPC_LHE:
3460        mem_idx = MIPS_HFLAG_UM;
3461        /* fall through */
3462    case OPC_LH:
3463        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3464                           ctx->default_tcg_memop_mask);
3465        gen_store_gpr(t0, rt);
3466        break;
3467    case OPC_LHUE:
3468        mem_idx = MIPS_HFLAG_UM;
3469        /* fall through */
3470    case OPC_LHU:
3471        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3472                           ctx->default_tcg_memop_mask);
3473        gen_store_gpr(t0, rt);
3474        break;
3475    case OPC_LBE:
3476        mem_idx = MIPS_HFLAG_UM;
3477        /* fall through */
3478    case OPC_LB:
3479        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3480        gen_store_gpr(t0, rt);
3481        break;
3482    case OPC_LBUE:
3483        mem_idx = MIPS_HFLAG_UM;
3484        /* fall through */
3485    case OPC_LBU:
3486        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3487        gen_store_gpr(t0, rt);
3488        break;
3489    case OPC_LWLE:
3490        mem_idx = MIPS_HFLAG_UM;
3491        /* fall through */
3492    case OPC_LWL:
3493        t1 = tcg_temp_new();
3494        /* Do a byte access to possibly trigger a page
3495           fault with the unaligned address.  */
3496        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3497        tcg_gen_andi_tl(t1, t0, 3);
3498#ifndef TARGET_WORDS_BIGENDIAN
3499        tcg_gen_xori_tl(t1, t1, 3);
3500#endif
3501        tcg_gen_shli_tl(t1, t1, 3);
3502        tcg_gen_andi_tl(t0, t0, ~3);
3503        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3504        tcg_gen_shl_tl(t0, t0, t1);
3505        t2 = tcg_const_tl(-1);
3506        tcg_gen_shl_tl(t2, t2, t1);
3507        gen_load_gpr(t1, rt);
3508        tcg_gen_andc_tl(t1, t1, t2);
3509        tcg_temp_free(t2);
3510        tcg_gen_or_tl(t0, t0, t1);
3511        tcg_temp_free(t1);
3512        tcg_gen_ext32s_tl(t0, t0);
3513        gen_store_gpr(t0, rt);
3514        break;
3515    case OPC_LWRE:
3516        mem_idx = MIPS_HFLAG_UM;
3517        /* fall through */
3518    case OPC_LWR:
3519        t1 = tcg_temp_new();
3520        /* Do a byte access to possibly trigger a page
3521           fault with the unaligned address.  */
3522        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3523        tcg_gen_andi_tl(t1, t0, 3);
3524#ifdef TARGET_WORDS_BIGENDIAN
3525        tcg_gen_xori_tl(t1, t1, 3);
3526#endif
3527        tcg_gen_shli_tl(t1, t1, 3);
3528        tcg_gen_andi_tl(t0, t0, ~3);
3529        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3530        tcg_gen_shr_tl(t0, t0, t1);
3531        tcg_gen_xori_tl(t1, t1, 31);
3532        t2 = tcg_const_tl(0xfffffffeull);
3533        tcg_gen_shl_tl(t2, t2, t1);
3534        gen_load_gpr(t1, rt);
3535        tcg_gen_and_tl(t1, t1, t2);
3536        tcg_temp_free(t2);
3537        tcg_gen_or_tl(t0, t0, t1);
3538        tcg_temp_free(t1);
3539        tcg_gen_ext32s_tl(t0, t0);
3540        gen_store_gpr(t0, rt);
3541        break;
3542    case OPC_LLE:
3543        mem_idx = MIPS_HFLAG_UM;
3544        /* fall through */
3545    case OPC_LL:
3546    case R6_OPC_LL:
3547        op_ld_ll(t0, t0, mem_idx, ctx);
3548        gen_store_gpr(t0, rt);
3549        break;
3550    }
3551    tcg_temp_free(t0);
3552}
3553
3554static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3555                    uint32_t reg1, uint32_t reg2)
3556{
3557    TCGv taddr = tcg_temp_new();
3558    TCGv_i64 tval = tcg_temp_new_i64();
3559    TCGv tmp1 = tcg_temp_new();
3560    TCGv tmp2 = tcg_temp_new();
3561
3562    gen_base_offset_addr(ctx, taddr, base, offset);
3563    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3564#ifdef TARGET_WORDS_BIGENDIAN
3565    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3566#else
3567    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3568#endif
3569    gen_store_gpr(tmp1, reg1);
3570    tcg_temp_free(tmp1);
3571    gen_store_gpr(tmp2, reg2);
3572    tcg_temp_free(tmp2);
3573    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3574    tcg_temp_free_i64(tval);
3575    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3576    tcg_temp_free(taddr);
3577}
3578
3579/* Store */
3580static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3581                    int base, int offset)
3582{
3583    TCGv t0 = tcg_temp_new();
3584    TCGv t1 = tcg_temp_new();
3585    int mem_idx = ctx->mem_idx;
3586
3587    gen_base_offset_addr(ctx, t0, base, offset);
3588    gen_load_gpr(t1, rt);
3589    switch (opc) {
3590#if defined(TARGET_MIPS64)
3591    case OPC_SD:
3592        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3593                           ctx->default_tcg_memop_mask);
3594        break;
3595    case OPC_SDL:
3596        gen_helper_0e2i(sdl, t1, t0, mem_idx);
3597        break;
3598    case OPC_SDR:
3599        gen_helper_0e2i(sdr, t1, t0, mem_idx);
3600        break;
3601#endif
3602    case OPC_SWE:
3603        mem_idx = MIPS_HFLAG_UM;
3604        /* fall through */
3605    case OPC_SW:
3606        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3607                           ctx->default_tcg_memop_mask);
3608        break;
3609    case OPC_SHE:
3610        mem_idx = MIPS_HFLAG_UM;
3611        /* fall through */
3612    case OPC_SH:
3613        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3614                           ctx->default_tcg_memop_mask);
3615        break;
3616    case OPC_SBE:
3617        mem_idx = MIPS_HFLAG_UM;
3618        /* fall through */
3619    case OPC_SB:
3620        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3621        break;
3622    case OPC_SWLE:
3623        mem_idx = MIPS_HFLAG_UM;
3624        /* fall through */
3625    case OPC_SWL:
3626        gen_helper_0e2i(swl, t1, t0, mem_idx);
3627        break;
3628    case OPC_SWRE:
3629        mem_idx = MIPS_HFLAG_UM;
3630        /* fall through */
3631    case OPC_SWR:
3632        gen_helper_0e2i(swr, t1, t0, mem_idx);
3633        break;
3634    }
3635    tcg_temp_free(t0);
3636    tcg_temp_free(t1);
3637}
3638
3639
3640/* Store conditional */
3641static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3642                        TCGMemOp tcg_mo, bool eva)
3643{
3644    TCGv addr, t0, val;
3645    TCGLabel *l1 = gen_new_label();
3646    TCGLabel *done = gen_new_label();
3647
3648    t0 = tcg_temp_new();
3649    addr = tcg_temp_new();
3650    /* compare the address against that of the preceeding LL */
3651    gen_base_offset_addr(ctx, addr, base, offset);
3652    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3653    tcg_temp_free(addr);
3654    tcg_gen_movi_tl(t0, 0);
3655    gen_store_gpr(t0, rt);
3656    tcg_gen_br(done);
3657
3658    gen_set_label(l1);
3659    /* generate cmpxchg */
3660    val = tcg_temp_new();
3661    gen_load_gpr(val, rt);
3662    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3663                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3664    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3665    gen_store_gpr(t0, rt);
3666    tcg_temp_free(val);
3667
3668    gen_set_label(done);
3669    tcg_temp_free(t0);
3670}
3671
3672
3673static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3674                    uint32_t reg1, uint32_t reg2, bool eva)
3675{
3676    TCGv taddr = tcg_temp_local_new();
3677    TCGv lladdr = tcg_temp_local_new();
3678    TCGv_i64 tval = tcg_temp_new_i64();
3679    TCGv_i64 llval = tcg_temp_new_i64();
3680    TCGv_i64 val = tcg_temp_new_i64();
3681    TCGv tmp1 = tcg_temp_new();
3682    TCGv tmp2 = tcg_temp_new();
3683    TCGLabel *lab_fail = gen_new_label();
3684    TCGLabel *lab_done = gen_new_label();
3685
3686    gen_base_offset_addr(ctx, taddr, base, offset);
3687
3688    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3689    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3690
3691    gen_load_gpr(tmp1, reg1);
3692    gen_load_gpr(tmp2, reg2);
3693
3694#ifdef TARGET_WORDS_BIGENDIAN
3695    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3696#else
3697    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3698#endif
3699
3700    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3701    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3702                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3703    if (reg1 != 0) {
3704        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3705    }
3706    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3707
3708    gen_set_label(lab_fail);
3709
3710    if (reg1 != 0) {
3711        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3712    }
3713    gen_set_label(lab_done);
3714    tcg_gen_movi_tl(lladdr, -1);
3715    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3716}
3717
3718/* Load and store */
3719static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3720                          TCGv t0)
3721{
3722    /* Don't do NOP if destination is zero: we must perform the actual
3723       memory access. */
3724    switch (opc) {
3725    case OPC_LWC1:
3726        {
3727            TCGv_i32 fp0 = tcg_temp_new_i32();
3728            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3729                                ctx->default_tcg_memop_mask);
3730            gen_store_fpr32(ctx, fp0, ft);
3731            tcg_temp_free_i32(fp0);
3732        }
3733        break;
3734    case OPC_SWC1:
3735        {
3736            TCGv_i32 fp0 = tcg_temp_new_i32();
3737            gen_load_fpr32(ctx, fp0, ft);
3738            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3739                                ctx->default_tcg_memop_mask);
3740            tcg_temp_free_i32(fp0);
3741        }
3742        break;
3743    case OPC_LDC1:
3744        {
3745            TCGv_i64 fp0 = tcg_temp_new_i64();
3746            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3747                                ctx->default_tcg_memop_mask);
3748            gen_store_fpr64(ctx, fp0, ft);
3749            tcg_temp_free_i64(fp0);
3750        }
3751        break;
3752    case OPC_SDC1:
3753        {
3754            TCGv_i64 fp0 = tcg_temp_new_i64();
3755            gen_load_fpr64(ctx, fp0, ft);
3756            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3757                                ctx->default_tcg_memop_mask);
3758            tcg_temp_free_i64(fp0);
3759        }
3760        break;
3761    default:
3762        MIPS_INVAL("flt_ldst");
3763        generate_exception_end(ctx, EXCP_RI);
3764        break;
3765    }
3766}
3767
3768static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3769                          int rs, int16_t imm)
3770{
3771    TCGv t0 = tcg_temp_new();
3772
3773    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3774        check_cp1_enabled(ctx);
3775        switch (op) {
3776        case OPC_LDC1:
3777        case OPC_SDC1:
3778            check_insn(ctx, ISA_MIPS2);
3779            /* Fallthrough */
3780        default:
3781            gen_base_offset_addr(ctx, t0, rs, imm);
3782            gen_flt_ldst(ctx, op, rt, t0);
3783        }
3784    } else {
3785        generate_exception_err(ctx, EXCP_CpU, 1);
3786    }
3787    tcg_temp_free(t0);
3788}
3789
3790/* Arithmetic with immediate operand */
3791static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3792                          int rt, int rs, int imm)
3793{
3794    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3795
3796    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3797        /* If no destination, treat it as a NOP.
3798           For addi, we must generate the overflow exception when needed. */
3799        return;
3800    }
3801    switch (opc) {
3802    case OPC_ADDI:
3803        {
3804            TCGv t0 = tcg_temp_local_new();
3805            TCGv t1 = tcg_temp_new();
3806            TCGv t2 = tcg_temp_new();
3807            TCGLabel *l1 = gen_new_label();
3808
3809            gen_load_gpr(t1, rs);
3810            tcg_gen_addi_tl(t0, t1, uimm);
3811            tcg_gen_ext32s_tl(t0, t0);
3812
3813            tcg_gen_xori_tl(t1, t1, ~uimm);
3814            tcg_gen_xori_tl(t2, t0, uimm);
3815            tcg_gen_and_tl(t1, t1, t2);
3816            tcg_temp_free(t2);
3817            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3818            tcg_temp_free(t1);
3819            /* operands of same sign, result different sign */
3820            generate_exception(ctx, EXCP_OVERFLOW);
3821            gen_set_label(l1);
3822            tcg_gen_ext32s_tl(t0, t0);
3823            gen_store_gpr(t0, rt);
3824            tcg_temp_free(t0);
3825        }
3826        break;
3827    case OPC_ADDIU:
3828        if (rs != 0) {
3829            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3830            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3831        } else {
3832            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3833        }
3834        break;
3835#if defined(TARGET_MIPS64)
3836    case OPC_DADDI:
3837        {
3838            TCGv t0 = tcg_temp_local_new();
3839            TCGv t1 = tcg_temp_new();
3840            TCGv t2 = tcg_temp_new();
3841            TCGLabel *l1 = gen_new_label();
3842
3843            gen_load_gpr(t1, rs);
3844            tcg_gen_addi_tl(t0, t1, uimm);
3845
3846            tcg_gen_xori_tl(t1, t1, ~uimm);
3847            tcg_gen_xori_tl(t2, t0, uimm);
3848            tcg_gen_and_tl(t1, t1, t2);
3849            tcg_temp_free(t2);
3850            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3851            tcg_temp_free(t1);
3852            /* operands of same sign, result different sign */
3853            generate_exception(ctx, EXCP_OVERFLOW);
3854            gen_set_label(l1);
3855            gen_store_gpr(t0, rt);
3856            tcg_temp_free(t0);
3857        }
3858        break;
3859    case OPC_DADDIU:
3860        if (rs != 0) {
3861            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3862        } else {
3863            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3864        }
3865        break;
3866#endif
3867    }
3868}
3869
3870/* Logic with immediate operand */
3871static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3872                          int rt, int rs, int16_t imm)
3873{
3874    target_ulong uimm;
3875
3876    if (rt == 0) {
3877        /* If no destination, treat it as a NOP. */
3878        return;
3879    }
3880    uimm = (uint16_t)imm;
3881    switch (opc) {
3882    case OPC_ANDI:
3883        if (likely(rs != 0))
3884            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3885        else
3886            tcg_gen_movi_tl(cpu_gpr[rt], 0);
3887        break;
3888    case OPC_ORI:
3889        if (rs != 0)
3890            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3891        else
3892            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3893        break;
3894    case OPC_XORI:
3895        if (likely(rs != 0))
3896            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3897        else
3898            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3899        break;
3900    case OPC_LUI:
3901        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3902            /* OPC_AUI */
3903            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3904            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3905        } else {
3906            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3907        }
3908        break;
3909
3910    default:
3911        break;
3912    }
3913}
3914
3915/* Set on less than with immediate operand */
3916static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3917                        int rt, int rs, int16_t imm)
3918{
3919    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3920    TCGv t0;
3921
3922    if (rt == 0) {
3923        /* If no destination, treat it as a NOP. */
3924        return;
3925    }
3926    t0 = tcg_temp_new();
3927    gen_load_gpr(t0, rs);
3928    switch (opc) {
3929    case OPC_SLTI:
3930        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3931        break;
3932    case OPC_SLTIU:
3933        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3934        break;
3935    }
3936    tcg_temp_free(t0);
3937}
3938
3939/* Shifts with immediate operand */
3940static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3941                          int rt, int rs, int16_t imm)
3942{
3943    target_ulong uimm = ((uint16_t)imm) & 0x1f;
3944    TCGv t0;
3945
3946    if (rt == 0) {
3947        /* If no destination, treat it as a NOP. */
3948        return;
3949    }
3950
3951    t0 = tcg_temp_new();
3952    gen_load_gpr(t0, rs);
3953    switch (opc) {
3954    case OPC_SLL:
3955        tcg_gen_shli_tl(t0, t0, uimm);
3956        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3957        break;
3958    case OPC_SRA:
3959        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3960        break;
3961    case OPC_SRL:
3962        if (uimm != 0) {
3963            tcg_gen_ext32u_tl(t0, t0);
3964            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3965        } else {
3966            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3967        }
3968        break;
3969    case OPC_ROTR:
3970        if (uimm != 0) {
3971            TCGv_i32 t1 = tcg_temp_new_i32();
3972
3973            tcg_gen_trunc_tl_i32(t1, t0);
3974            tcg_gen_rotri_i32(t1, t1, uimm);
3975            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3976            tcg_temp_free_i32(t1);
3977        } else {
3978            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3979        }
3980        break;
3981#if defined(TARGET_MIPS64)
3982    case OPC_DSLL:
3983        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3984        break;
3985    case OPC_DSRA:
3986        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3987        break;
3988    case OPC_DSRL:
3989        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3990        break;
3991    case OPC_DROTR:
3992        if (uimm != 0) {
3993            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3994        } else {
3995            tcg_gen_mov_tl(cpu_gpr[rt], t0);
3996        }
3997        break;
3998    case OPC_DSLL32:
3999        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4000        break;
4001    case OPC_DSRA32:
4002        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4003        break;
4004    case OPC_DSRL32:
4005        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4006        break;
4007    case OPC_DROTR32:
4008        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4009        break;
4010#endif
4011    }
4012    tcg_temp_free(t0);
4013}
4014
4015/* Arithmetic */
4016static void gen_arith(DisasContext *ctx, uint32_t opc,
4017                      int rd, int rs, int rt)
4018{
4019    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4020       && opc != OPC_DADD && opc != OPC_DSUB) {
4021        /* If no destination, treat it as a NOP.
4022           For add & sub, we must generate the overflow exception when needed. */
4023        return;
4024    }
4025
4026    switch (opc) {
4027    case OPC_ADD:
4028        {
4029            TCGv t0 = tcg_temp_local_new();
4030            TCGv t1 = tcg_temp_new();
4031            TCGv t2 = tcg_temp_new();
4032            TCGLabel *l1 = gen_new_label();
4033
4034            gen_load_gpr(t1, rs);
4035            gen_load_gpr(t2, rt);
4036            tcg_gen_add_tl(t0, t1, t2);
4037            tcg_gen_ext32s_tl(t0, t0);
4038            tcg_gen_xor_tl(t1, t1, t2);
4039            tcg_gen_xor_tl(t2, t0, t2);
4040            tcg_gen_andc_tl(t1, t2, t1);
4041            tcg_temp_free(t2);
4042            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4043            tcg_temp_free(t1);
4044            /* operands of same sign, result different sign */
4045            generate_exception(ctx, EXCP_OVERFLOW);
4046            gen_set_label(l1);
4047            gen_store_gpr(t0, rd);
4048            tcg_temp_free(t0);
4049        }
4050        break;
4051    case OPC_ADDU:
4052        if (rs != 0 && rt != 0) {
4053            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4054            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4055        } else if (rs == 0 && rt != 0) {
4056            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4057        } else if (rs != 0 && rt == 0) {
4058            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4059        } else {
4060            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4061        }
4062        break;
4063    case OPC_SUB:
4064        {
4065            TCGv t0 = tcg_temp_local_new();
4066            TCGv t1 = tcg_temp_new();
4067            TCGv t2 = tcg_temp_new();
4068            TCGLabel *l1 = gen_new_label();
4069
4070            gen_load_gpr(t1, rs);
4071            gen_load_gpr(t2, rt);
4072            tcg_gen_sub_tl(t0, t1, t2);
4073            tcg_gen_ext32s_tl(t0, t0);
4074            tcg_gen_xor_tl(t2, t1, t2);
4075            tcg_gen_xor_tl(t1, t0, t1);
4076            tcg_gen_and_tl(t1, t1, t2);
4077            tcg_temp_free(t2);
4078            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4079            tcg_temp_free(t1);
4080            /* operands of different sign, first operand and result different sign */
4081            generate_exception(ctx, EXCP_OVERFLOW);
4082            gen_set_label(l1);
4083            gen_store_gpr(t0, rd);
4084            tcg_temp_free(t0);
4085        }
4086        break;
4087    case OPC_SUBU:
4088        if (rs != 0 && rt != 0) {
4089            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4090            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4091        } else if (rs == 0 && rt != 0) {
4092            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4093            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4094        } else if (rs != 0 && rt == 0) {
4095            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4096        } else {
4097            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4098        }
4099        break;
4100#if defined(TARGET_MIPS64)
4101    case OPC_DADD:
4102        {
4103            TCGv t0 = tcg_temp_local_new();
4104            TCGv t1 = tcg_temp_new();
4105            TCGv t2 = tcg_temp_new();
4106            TCGLabel *l1 = gen_new_label();
4107
4108            gen_load_gpr(t1, rs);
4109            gen_load_gpr(t2, rt);
4110            tcg_gen_add_tl(t0, t1, t2);
4111            tcg_gen_xor_tl(t1, t1, t2);
4112            tcg_gen_xor_tl(t2, t0, t2);
4113            tcg_gen_andc_tl(t1, t2, t1);
4114            tcg_temp_free(t2);
4115            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4116            tcg_temp_free(t1);
4117            /* operands of same sign, result different sign */
4118            generate_exception(ctx, EXCP_OVERFLOW);
4119            gen_set_label(l1);
4120            gen_store_gpr(t0, rd);
4121            tcg_temp_free(t0);
4122        }
4123        break;
4124    case OPC_DADDU:
4125        if (rs != 0 && rt != 0) {
4126            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4127        } else if (rs == 0 && rt != 0) {
4128            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4129        } else if (rs != 0 && rt == 0) {
4130            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4131        } else {
4132            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4133        }
4134        break;
4135    case OPC_DSUB:
4136        {
4137            TCGv t0 = tcg_temp_local_new();
4138            TCGv t1 = tcg_temp_new();
4139            TCGv t2 = tcg_temp_new();
4140            TCGLabel *l1 = gen_new_label();
4141
4142            gen_load_gpr(t1, rs);
4143            gen_load_gpr(t2, rt);
4144            tcg_gen_sub_tl(t0, t1, t2);
4145            tcg_gen_xor_tl(t2, t1, t2);
4146            tcg_gen_xor_tl(t1, t0, t1);
4147            tcg_gen_and_tl(t1, t1, t2);
4148            tcg_temp_free(t2);
4149            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4150            tcg_temp_free(t1);
4151            /* operands of different sign, first operand and result different sign */
4152            generate_exception(ctx, EXCP_OVERFLOW);
4153            gen_set_label(l1);
4154            gen_store_gpr(t0, rd);
4155            tcg_temp_free(t0);
4156        }
4157        break;
4158    case OPC_DSUBU:
4159        if (rs != 0 && rt != 0) {
4160            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4161        } else if (rs == 0 && rt != 0) {
4162            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4163        } else if (rs != 0 && rt == 0) {
4164            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4165        } else {
4166            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4167        }
4168        break;
4169#endif
4170    case OPC_MUL:
4171        if (likely(rs != 0 && rt != 0)) {
4172            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4173            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4174        } else {
4175            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4176        }
4177        break;
4178    }
4179}
4180
4181/* Conditional move */
4182static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4183                          int rd, int rs, int rt)
4184{
4185    TCGv t0, t1, t2;
4186
4187    if (rd == 0) {
4188        /* If no destination, treat it as a NOP. */
4189        return;
4190    }
4191
4192    t0 = tcg_temp_new();
4193    gen_load_gpr(t0, rt);
4194    t1 = tcg_const_tl(0);
4195    t2 = tcg_temp_new();
4196    gen_load_gpr(t2, rs);
4197    switch (opc) {
4198    case OPC_MOVN:
4199        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4200        break;
4201    case OPC_MOVZ:
4202        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4203        break;
4204    case OPC_SELNEZ:
4205        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4206        break;
4207    case OPC_SELEQZ:
4208        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4209        break;
4210    }
4211    tcg_temp_free(t2);
4212    tcg_temp_free(t1);
4213    tcg_temp_free(t0);
4214}
4215
4216/* Logic */
4217static void gen_logic(DisasContext *ctx, uint32_t opc,
4218                      int rd, int rs, int rt)
4219{
4220    if (rd == 0) {
4221        /* If no destination, treat it as a NOP. */
4222        return;
4223    }
4224
4225    switch (opc) {
4226    case OPC_AND:
4227        if (likely(rs != 0 && rt != 0)) {
4228            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4229        } else {
4230            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4231        }
4232        break;
4233    case OPC_NOR:
4234        if (rs != 0 && rt != 0) {
4235            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4236        } else if (rs == 0 && rt != 0) {
4237            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4238        } else if (rs != 0 && rt == 0) {
4239            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4240        } else {
4241            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4242        }
4243        break;
4244    case OPC_OR:
4245        if (likely(rs != 0 && rt != 0)) {
4246            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4247        } else if (rs == 0 && rt != 0) {
4248            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4249        } else if (rs != 0 && rt == 0) {
4250            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4251        } else {
4252            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4253        }
4254        break;
4255    case OPC_XOR:
4256        if (likely(rs != 0 && rt != 0)) {
4257            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4258        } else if (rs == 0 && rt != 0) {
4259            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4260        } else if (rs != 0 && rt == 0) {
4261            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4262        } else {
4263            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4264        }
4265        break;
4266    }
4267}
4268
4269/* Set on lower than */
4270static void gen_slt(DisasContext *ctx, uint32_t opc,
4271                    int rd, int rs, int rt)
4272{
4273    TCGv t0, t1;
4274
4275    if (rd == 0) {
4276        /* If no destination, treat it as a NOP. */
4277        return;
4278    }
4279
4280    t0 = tcg_temp_new();
4281    t1 = tcg_temp_new();
4282    gen_load_gpr(t0, rs);
4283    gen_load_gpr(t1, rt);
4284    switch (opc) {
4285    case OPC_SLT:
4286        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4287        break;
4288    case OPC_SLTU:
4289        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4290        break;
4291    }
4292    tcg_temp_free(t0);
4293    tcg_temp_free(t1);
4294}
4295
4296/* Shifts */
4297static void gen_shift(DisasContext *ctx, uint32_t opc,
4298                      int rd, int rs, int rt)
4299{
4300    TCGv t0, t1;
4301
4302    if (rd == 0) {
4303        /* If no destination, treat it as a NOP.
4304           For add & sub, we must generate the overflow exception when needed. */
4305        return;
4306    }
4307
4308    t0 = tcg_temp_new();
4309    t1 = tcg_temp_new();
4310    gen_load_gpr(t0, rs);
4311    gen_load_gpr(t1, rt);
4312    switch (opc) {
4313    case OPC_SLLV:
4314        tcg_gen_andi_tl(t0, t0, 0x1f);
4315        tcg_gen_shl_tl(t0, t1, t0);
4316        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4317        break;
4318    case OPC_SRAV:
4319        tcg_gen_andi_tl(t0, t0, 0x1f);
4320        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4321        break;
4322    case OPC_SRLV:
4323        tcg_gen_ext32u_tl(t1, t1);
4324        tcg_gen_andi_tl(t0, t0, 0x1f);
4325        tcg_gen_shr_tl(t0, t1, t0);
4326        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4327        break;
4328    case OPC_ROTRV:
4329        {
4330            TCGv_i32 t2 = tcg_temp_new_i32();
4331            TCGv_i32 t3 = tcg_temp_new_i32();
4332
4333            tcg_gen_trunc_tl_i32(t2, t0);
4334            tcg_gen_trunc_tl_i32(t3, t1);
4335            tcg_gen_andi_i32(t2, t2, 0x1f);
4336            tcg_gen_rotr_i32(t2, t3, t2);
4337            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4338            tcg_temp_free_i32(t2);
4339            tcg_temp_free_i32(t3);
4340        }
4341        break;
4342#if defined(TARGET_MIPS64)
4343    case OPC_DSLLV:
4344        tcg_gen_andi_tl(t0, t0, 0x3f);
4345        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4346        break;
4347    case OPC_DSRAV:
4348        tcg_gen_andi_tl(t0, t0, 0x3f);
4349        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4350        break;
4351    case OPC_DSRLV:
4352        tcg_gen_andi_tl(t0, t0, 0x3f);
4353        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4354        break;
4355    case OPC_DROTRV:
4356        tcg_gen_andi_tl(t0, t0, 0x3f);
4357        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4358        break;
4359#endif
4360    }
4361    tcg_temp_free(t0);
4362    tcg_temp_free(t1);
4363}
4364
4365#if defined(TARGET_MIPS64)
4366/* Copy GPR to and from TX79 HI1/LO1 register. */
4367static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4368{
4369    if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4370        /* Treat as NOP. */
4371        return;
4372    }
4373
4374    switch (opc) {
4375    case MMI_OPC_MFHI1:
4376        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4377        break;
4378    case MMI_OPC_MFLO1:
4379        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4380        break;
4381    case MMI_OPC_MTHI1:
4382        if (reg != 0) {
4383            tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4384        } else {
4385            tcg_gen_movi_tl(cpu_HI[1], 0);
4386        }
4387        break;
4388    case MMI_OPC_MTLO1:
4389        if (reg != 0) {
4390            tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4391        } else {
4392            tcg_gen_movi_tl(cpu_LO[1], 0);
4393        }
4394        break;
4395    default:
4396        MIPS_INVAL("mfthilo1 TX79");
4397        generate_exception_end(ctx, EXCP_RI);
4398        break;
4399    }
4400}
4401#endif
4402
4403/* Arithmetic on HI/LO registers */
4404static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4405{
4406    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4407        /* Treat as NOP. */
4408        return;
4409    }
4410
4411    if (acc != 0) {
4412        check_dsp(ctx);
4413    }
4414
4415    switch (opc) {
4416    case OPC_MFHI:
4417#if defined(TARGET_MIPS64)
4418        if (acc != 0) {
4419            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4420        } else
4421#endif
4422        {
4423            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4424        }
4425        break;
4426    case OPC_MFLO:
4427#if defined(TARGET_MIPS64)
4428        if (acc != 0) {
4429            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4430        } else
4431#endif
4432        {
4433            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4434        }
4435        break;
4436    case OPC_MTHI:
4437        if (reg != 0) {
4438#if defined(TARGET_MIPS64)
4439            if (acc != 0) {
4440                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4441            } else
4442#endif
4443            {
4444                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4445            }
4446        } else {
4447            tcg_gen_movi_tl(cpu_HI[acc], 0);
4448        }
4449        break;
4450    case OPC_MTLO:
4451        if (reg != 0) {
4452#if defined(TARGET_MIPS64)
4453            if (acc != 0) {
4454                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4455            } else
4456#endif
4457            {
4458                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4459            }
4460        } else {
4461            tcg_gen_movi_tl(cpu_LO[acc], 0);
4462        }
4463        break;
4464    }
4465}
4466
4467static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4468                             TCGMemOp memop)
4469{
4470    TCGv t0 = tcg_const_tl(addr);
4471    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4472    gen_store_gpr(t0, reg);
4473    tcg_temp_free(t0);
4474}
4475
4476static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4477                             int rs)
4478{
4479    target_long offset;
4480    target_long addr;
4481
4482    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4483    case OPC_ADDIUPC:
4484        if (rs != 0) {
4485            offset = sextract32(ctx->opcode << 2, 0, 21);
4486            addr = addr_add(ctx, pc, offset);
4487            tcg_gen_movi_tl(cpu_gpr[rs], addr);
4488        }
4489        break;
4490    case R6_OPC_LWPC:
4491        offset = sextract32(ctx->opcode << 2, 0, 21);
4492        addr = addr_add(ctx, pc, offset);
4493        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4494        break;
4495#if defined(TARGET_MIPS64)
4496    case OPC_LWUPC:
4497        check_mips_64(ctx);
4498        offset = sextract32(ctx->opcode << 2, 0, 21);
4499        addr = addr_add(ctx, pc, offset);
4500        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4501        break;
4502#endif
4503    default:
4504        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4505        case OPC_AUIPC:
4506            if (rs != 0) {
4507                offset = sextract32(ctx->opcode, 0, 16) << 16;
4508                addr = addr_add(ctx, pc, offset);
4509                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4510            }
4511            break;
4512        case OPC_ALUIPC:
4513            if (rs != 0) {
4514                offset = sextract32(ctx->opcode, 0, 16) << 16;
4515                addr = ~0xFFFF & addr_add(ctx, pc, offset);
4516                tcg_gen_movi_tl(cpu_gpr[rs], addr);
4517            }
4518            break;
4519#if defined(TARGET_MIPS64)
4520        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4521        case R6_OPC_LDPC + (1 << 16):
4522        case R6_OPC_LDPC + (2 << 16):
4523        case R6_OPC_LDPC + (3 << 16):
4524            check_mips_64(ctx);
4525            offset = sextract32(ctx->opcode << 3, 0, 21);
4526            addr = addr_add(ctx, (pc & ~0x7), offset);
4527            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4528            break;
4529#endif
4530        default:
4531            MIPS_INVAL("OPC_PCREL");
4532            generate_exception_end(ctx, EXCP_RI);
4533            break;
4534        }
4535        break;
4536    }
4537}
4538
4539static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4540{
4541    TCGv t0, t1;
4542
4543    if (rd == 0) {
4544        /* Treat as NOP. */
4545        return;
4546    }
4547
4548    t0 = tcg_temp_new();
4549    t1 = tcg_temp_new();
4550
4551    gen_load_gpr(t0, rs);
4552    gen_load_gpr(t1, rt);
4553
4554    switch (opc) {
4555    case R6_OPC_DIV:
4556        {
4557            TCGv t2 = tcg_temp_new();
4558            TCGv t3 = tcg_temp_new();
4559            tcg_gen_ext32s_tl(t0, t0);
4560            tcg_gen_ext32s_tl(t1, t1);
4561            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4562            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4563            tcg_gen_and_tl(t2, t2, t3);
4564            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4565            tcg_gen_or_tl(t2, t2, t3);
4566            tcg_gen_movi_tl(t3, 0);
4567            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4568            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4569            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4570            tcg_temp_free(t3);
4571            tcg_temp_free(t2);
4572        }
4573        break;
4574    case R6_OPC_MOD:
4575        {
4576            TCGv t2 = tcg_temp_new();
4577            TCGv t3 = tcg_temp_new();
4578            tcg_gen_ext32s_tl(t0, t0);
4579            tcg_gen_ext32s_tl(t1, t1);
4580            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4581            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4582            tcg_gen_and_tl(t2, t2, t3);
4583            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4584            tcg_gen_or_tl(t2, t2, t3);
4585            tcg_gen_movi_tl(t3, 0);
4586            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4587            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4588            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4589            tcg_temp_free(t3);
4590            tcg_temp_free(t2);
4591        }
4592        break;
4593    case R6_OPC_DIVU:
4594        {
4595            TCGv t2 = tcg_const_tl(0);
4596            TCGv t3 = tcg_const_tl(1);
4597            tcg_gen_ext32u_tl(t0, t0);
4598            tcg_gen_ext32u_tl(t1, t1);
4599            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4600            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4601            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4602            tcg_temp_free(t3);
4603            tcg_temp_free(t2);
4604        }
4605        break;
4606    case R6_OPC_MODU:
4607        {
4608            TCGv t2 = tcg_const_tl(0);
4609            TCGv t3 = tcg_const_tl(1);
4610            tcg_gen_ext32u_tl(t0, t0);
4611            tcg_gen_ext32u_tl(t1, t1);
4612            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4613            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4614            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4615            tcg_temp_free(t3);
4616            tcg_temp_free(t2);
4617        }
4618        break;
4619    case R6_OPC_MUL:
4620        {
4621            TCGv_i32 t2 = tcg_temp_new_i32();
4622            TCGv_i32 t3 = tcg_temp_new_i32();
4623            tcg_gen_trunc_tl_i32(t2, t0);
4624            tcg_gen_trunc_tl_i32(t3, t1);
4625            tcg_gen_mul_i32(t2, t2, t3);
4626            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4627            tcg_temp_free_i32(t2);
4628            tcg_temp_free_i32(t3);
4629        }
4630        break;
4631    case R6_OPC_MUH:
4632        {
4633            TCGv_i32 t2 = tcg_temp_new_i32();
4634            TCGv_i32 t3 = tcg_temp_new_i32();
4635            tcg_gen_trunc_tl_i32(t2, t0);
4636            tcg_gen_trunc_tl_i32(t3, t1);
4637            tcg_gen_muls2_i32(t2, t3, t2, t3);
4638            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4639            tcg_temp_free_i32(t2);
4640            tcg_temp_free_i32(t3);
4641        }
4642        break;
4643    case R6_OPC_MULU:
4644        {
4645            TCGv_i32 t2 = tcg_temp_new_i32();
4646            TCGv_i32 t3 = tcg_temp_new_i32();
4647            tcg_gen_trunc_tl_i32(t2, t0);
4648            tcg_gen_trunc_tl_i32(t3, t1);
4649            tcg_gen_mul_i32(t2, t2, t3);
4650            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4651            tcg_temp_free_i32(t2);
4652            tcg_temp_free_i32(t3);
4653        }
4654        break;
4655    case R6_OPC_MUHU:
4656        {
4657            TCGv_i32 t2 = tcg_temp_new_i32();
4658            TCGv_i32 t3 = tcg_temp_new_i32();
4659            tcg_gen_trunc_tl_i32(t2, t0);
4660            tcg_gen_trunc_tl_i32(t3, t1);
4661            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4662            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4663            tcg_temp_free_i32(t2);
4664            tcg_temp_free_i32(t3);
4665        }
4666        break;
4667#if defined(TARGET_MIPS64)
4668    case R6_OPC_DDIV:
4669        {
4670            TCGv t2 = tcg_temp_new();
4671            TCGv t3 = tcg_temp_new();
4672            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4673            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4674            tcg_gen_and_tl(t2, t2, t3);
4675            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4676            tcg_gen_or_tl(t2, t2, t3);
4677            tcg_gen_movi_tl(t3, 0);
4678            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4679            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4680            tcg_temp_free(t3);
4681            tcg_temp_free(t2);
4682        }
4683        break;
4684    case R6_OPC_DMOD:
4685        {
4686            TCGv t2 = tcg_temp_new();
4687            TCGv t3 = tcg_temp_new();
4688            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4689            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4690            tcg_gen_and_tl(t2, t2, t3);
4691            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4692            tcg_gen_or_tl(t2, t2, t3);
4693            tcg_gen_movi_tl(t3, 0);
4694            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4695            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4696            tcg_temp_free(t3);
4697            tcg_temp_free(t2);
4698        }
4699        break;
4700    case R6_OPC_DDIVU:
4701        {
4702            TCGv t2 = tcg_const_tl(0);
4703            TCGv t3 = tcg_const_tl(1);
4704            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4705            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4706            tcg_temp_free(t3);
4707            tcg_temp_free(t2);
4708        }
4709        break;
4710    case R6_OPC_DMODU:
4711        {
4712            TCGv t2 = tcg_const_tl(0);
4713            TCGv t3 = tcg_const_tl(1);
4714            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4715            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4716            tcg_temp_free(t3);
4717            tcg_temp_free(t2);
4718        }
4719        break;
4720    case R6_OPC_DMUL:
4721        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4722        break;
4723    case R6_OPC_DMUH:
4724        {
4725            TCGv t2 = tcg_temp_new();
4726            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4727            tcg_temp_free(t2);
4728        }
4729        break;
4730    case R6_OPC_DMULU:
4731        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4732        break;
4733    case R6_OPC_DMUHU:
4734        {
4735            TCGv t2 = tcg_temp_new();
4736            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4737            tcg_temp_free(t2);
4738        }
4739        break;
4740#endif
4741    default:
4742        MIPS_INVAL("r6 mul/div");
4743        generate_exception_end(ctx, EXCP_RI);
4744        goto out;
4745    }
4746 out:
4747    tcg_temp_free(t0);
4748    tcg_temp_free(t1);
4749}
4750
4751#if defined(TARGET_MIPS64)
4752static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4753{
4754    TCGv t0, t1;
4755
4756    t0 = tcg_temp_new();
4757    t1 = tcg_temp_new();
4758
4759    gen_load_gpr(t0, rs);
4760    gen_load_gpr(t1, rt);
4761
4762    switch (opc) {
4763    case MMI_OPC_DIV1:
4764        {
4765            TCGv t2 = tcg_temp_new();
4766            TCGv t3 = tcg_temp_new();
4767            tcg_gen_ext32s_tl(t0, t0);
4768            tcg_gen_ext32s_tl(t1, t1);
4769            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4770            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4771            tcg_gen_and_tl(t2, t2, t3);
4772            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4773            tcg_gen_or_tl(t2, t2, t3);
4774            tcg_gen_movi_tl(t3, 0);
4775            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4776            tcg_gen_div_tl(cpu_LO[1], t0, t1);
4777            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4778            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4779            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4780            tcg_temp_free(t3);
4781            tcg_temp_free(t2);
4782        }
4783        break;
4784    case MMI_OPC_DIVU1:
4785        {
4786            TCGv t2 = tcg_const_tl(0);
4787            TCGv t3 = tcg_const_tl(1);
4788            tcg_gen_ext32u_tl(t0, t0);
4789            tcg_gen_ext32u_tl(t1, t1);
4790            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4791            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4792            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4793            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4794            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4795            tcg_temp_free(t3);
4796            tcg_temp_free(t2);
4797        }
4798        break;
4799    default:
4800        MIPS_INVAL("div1 TX79");
4801        generate_exception_end(ctx, EXCP_RI);
4802        goto out;
4803    }
4804 out:
4805    tcg_temp_free(t0);
4806    tcg_temp_free(t1);
4807}
4808#endif
4809
4810static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4811                       int acc, int rs, int rt)
4812{
4813    TCGv t0, t1;
4814
4815    t0 = tcg_temp_new();
4816    t1 = tcg_temp_new();
4817
4818    gen_load_gpr(t0, rs);
4819    gen_load_gpr(t1, rt);
4820
4821    if (acc != 0) {
4822        check_dsp(ctx);
4823    }
4824
4825    switch (opc) {
4826    case OPC_DIV:
4827        {
4828            TCGv t2 = tcg_temp_new();
4829            TCGv t3 = tcg_temp_new();
4830            tcg_gen_ext32s_tl(t0, t0);
4831            tcg_gen_ext32s_tl(t1, t1);
4832            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4833            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4834            tcg_gen_and_tl(t2, t2, t3);
4835            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4836            tcg_gen_or_tl(t2, t2, t3);
4837            tcg_gen_movi_tl(t3, 0);
4838            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4839            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4840            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4841            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4842            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4843            tcg_temp_free(t3);
4844            tcg_temp_free(t2);
4845        }
4846        break;
4847    case OPC_DIVU:
4848        {
4849            TCGv t2 = tcg_const_tl(0);
4850            TCGv t3 = tcg_const_tl(1);
4851            tcg_gen_ext32u_tl(t0, t0);
4852            tcg_gen_ext32u_tl(t1, t1);
4853            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4854            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4855            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4856            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4857            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4858            tcg_temp_free(t3);
4859            tcg_temp_free(t2);
4860        }
4861        break;
4862    case OPC_MULT:
4863        {
4864            TCGv_i32 t2 = tcg_temp_new_i32();
4865            TCGv_i32 t3 = tcg_temp_new_i32();
4866            tcg_gen_trunc_tl_i32(t2, t0);
4867            tcg_gen_trunc_tl_i32(t3, t1);
4868            tcg_gen_muls2_i32(t2, t3, t2, t3);
4869            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4870            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4871            tcg_temp_free_i32(t2);
4872            tcg_temp_free_i32(t3);
4873        }
4874        break;
4875    case OPC_MULTU:
4876        {
4877            TCGv_i32 t2 = tcg_temp_new_i32();
4878            TCGv_i32 t3 = tcg_temp_new_i32();
4879            tcg_gen_trunc_tl_i32(t2, t0);
4880            tcg_gen_trunc_tl_i32(t3, t1);
4881            tcg_gen_mulu2_i32(t2, t3, t2, t3);
4882            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4883            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4884            tcg_temp_free_i32(t2);
4885            tcg_temp_free_i32(t3);
4886        }
4887        break;
4888#if defined(TARGET_MIPS64)
4889    case OPC_DDIV:
4890        {
4891            TCGv t2 = tcg_temp_new();
4892            TCGv t3 = tcg_temp_new();
4893            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4894            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4895            tcg_gen_and_tl(t2, t2, t3);
4896            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4897            tcg_gen_or_tl(t2, t2, t3);
4898            tcg_gen_movi_tl(t3, 0);
4899            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4900            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4901            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4902            tcg_temp_free(t3);
4903            tcg_temp_free(t2);
4904        }
4905        break;
4906    case OPC_DDIVU:
4907        {
4908            TCGv t2 = tcg_const_tl(0);
4909            TCGv t3 = tcg_const_tl(1);
4910            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4911            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4912            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4913            tcg_temp_free(t3);
4914            tcg_temp_free(t2);
4915        }
4916        break;
4917    case OPC_DMULT:
4918        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4919        break;
4920    case OPC_DMULTU:
4921        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4922        break;
4923#endif
4924    case OPC_MADD:
4925        {
4926            TCGv_i64 t2 = tcg_temp_new_i64();
4927            TCGv_i64 t3 = tcg_temp_new_i64();
4928
4929            tcg_gen_ext_tl_i64(t2, t0);
4930            tcg_gen_ext_tl_i64(t3, t1);
4931            tcg_gen_mul_i64(t2, t2, t3);
4932            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4933            tcg_gen_add_i64(t2, t2, t3);
4934            tcg_temp_free_i64(t3);
4935            gen_move_low32(cpu_LO[acc], t2);
4936            gen_move_high32(cpu_HI[acc], t2);
4937            tcg_temp_free_i64(t2);
4938        }
4939        break;
4940    case OPC_MADDU:
4941        {
4942            TCGv_i64 t2 = tcg_temp_new_i64();
4943            TCGv_i64 t3 = tcg_temp_new_i64();
4944
4945            tcg_gen_ext32u_tl(t0, t0);
4946            tcg_gen_ext32u_tl(t1, t1);
4947            tcg_gen_extu_tl_i64(t2, t0);
4948            tcg_gen_extu_tl_i64(t3, t1);
4949            tcg_gen_mul_i64(t2, t2, t3);
4950            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4951            tcg_gen_add_i64(t2, t2, t3);
4952            tcg_temp_free_i64(t3);
4953            gen_move_low32(cpu_LO[acc], t2);
4954            gen_move_high32(cpu_HI[acc], t2);
4955            tcg_temp_free_i64(t2);
4956        }
4957        break;
4958    case OPC_MSUB:
4959        {
4960            TCGv_i64 t2 = tcg_temp_new_i64();
4961            TCGv_i64 t3 = tcg_temp_new_i64();
4962
4963            tcg_gen_ext_tl_i64(t2, t0);
4964            tcg_gen_ext_tl_i64(t3, t1);
4965            tcg_gen_mul_i64(t2, t2, t3);
4966            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4967            tcg_gen_sub_i64(t2, t3, t2);
4968            tcg_temp_free_i64(t3);
4969            gen_move_low32(cpu_LO[acc], t2);
4970            gen_move_high32(cpu_HI[acc], t2);
4971            tcg_temp_free_i64(t2);
4972        }
4973        break;
4974    case OPC_MSUBU:
4975        {
4976            TCGv_i64 t2 = tcg_temp_new_i64();
4977            TCGv_i64 t3 = tcg_temp_new_i64();
4978
4979            tcg_gen_ext32u_tl(t0, t0);
4980            tcg_gen_ext32u_tl(t1, t1);
4981            tcg_gen_extu_tl_i64(t2, t0);
4982            tcg_gen_extu_tl_i64(t3, t1);
4983            tcg_gen_mul_i64(t2, t2, t3);
4984            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4985            tcg_gen_sub_i64(t2, t3, t2);
4986            tcg_temp_free_i64(t3);
4987            gen_move_low32(cpu_LO[acc], t2);
4988            gen_move_high32(cpu_HI[acc], t2);
4989            tcg_temp_free_i64(t2);
4990        }
4991        break;
4992    default:
4993        MIPS_INVAL("mul/div");
4994        generate_exception_end(ctx, EXCP_RI);
4995        goto out;
4996    }
4997 out:
4998    tcg_temp_free(t0);
4999    tcg_temp_free(t1);
5000}
5001
5002/*
5003 * These MULT[U] and MADD[U] instructions implemented in for example
5004 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5005 * architectures are special three-operand variants with the syntax
5006 *
5007 *     MULT[U][1] rd, rs, rt
5008 *
5009 * such that
5010 *
5011 *     (rd, LO, HI) <- rs * rt
5012 *
5013 * and
5014 *
5015 *     MADD[U][1] rd, rs, rt
5016 *
5017 * such that
5018 *
5019 *     (rd, LO, HI) <- (LO, HI) + rs * rt
5020 *
5021 * where the low-order 32-bits of the result is placed into both the
5022 * GPR rd and the special register LO. The high-order 32-bits of the
5023 * result is placed into the special register HI.
5024 *
5025 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5026 * which is the zero register that always reads as 0.
5027 */
5028static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5029                         int rd, int rs, int rt)
5030{
5031    TCGv t0 = tcg_temp_new();
5032    TCGv t1 = tcg_temp_new();
5033    int acc = 0;
5034
5035    gen_load_gpr(t0, rs);
5036    gen_load_gpr(t1, rt);
5037
5038    switch (opc) {
5039    case MMI_OPC_MULT1:
5040        acc = 1;
5041        /* Fall through */
5042    case OPC_MULT:
5043        {
5044            TCGv_i32 t2 = tcg_temp_new_i32();
5045            TCGv_i32 t3 = tcg_temp_new_i32();
5046            tcg_gen_trunc_tl_i32(t2, t0);
5047            tcg_gen_trunc_tl_i32(t3, t1);
5048            tcg_gen_muls2_i32(t2, t3, t2, t3);
5049            if (rd) {
5050                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5051            }
5052            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5053            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5054            tcg_temp_free_i32(t2);
5055            tcg_temp_free_i32(t3);
5056        }
5057        break;
5058    case MMI_OPC_MULTU1:
5059        acc = 1;
5060        /* Fall through */
5061    case OPC_MULTU:
5062        {
5063            TCGv_i32 t2 = tcg_temp_new_i32();
5064            TCGv_i32 t3 = tcg_temp_new_i32();
5065            tcg_gen_trunc_tl_i32(t2, t0);
5066            tcg_gen_trunc_tl_i32(t3, t1);
5067            tcg_gen_mulu2_i32(t2, t3, t2, t3);
5068            if (rd) {
5069                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5070            }
5071            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5072            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5073            tcg_temp_free_i32(t2);
5074            tcg_temp_free_i32(t3);
5075        }
5076        break;
5077    case MMI_OPC_MADD1:
5078        acc = 1;
5079        /* Fall through */
5080    case MMI_OPC_MADD:
5081        {
5082            TCGv_i64 t2 = tcg_temp_new_i64();
5083            TCGv_i64 t3 = tcg_temp_new_i64();
5084
5085            tcg_gen_ext_tl_i64(t2, t0);
5086            tcg_gen_ext_tl_i64(t3, t1);
5087            tcg_gen_mul_i64(t2, t2, t3);
5088            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5089            tcg_gen_add_i64(t2, t2, t3);
5090            tcg_temp_free_i64(t3);
5091            gen_move_low32(cpu_LO[acc], t2);
5092            gen_move_high32(cpu_HI[acc], t2);
5093            if (rd) {
5094                gen_move_low32(cpu_gpr[rd], t2);
5095            }
5096            tcg_temp_free_i64(t2);
5097        }
5098        break;
5099    case MMI_OPC_MADDU1:
5100        acc = 1;
5101        /* Fall through */
5102    case MMI_OPC_MADDU:
5103        {
5104            TCGv_i64 t2 = tcg_temp_new_i64();
5105            TCGv_i64 t3 = tcg_temp_new_i64();
5106
5107            tcg_gen_ext32u_tl(t0, t0);
5108            tcg_gen_ext32u_tl(t1, t1);
5109            tcg_gen_extu_tl_i64(t2, t0);
5110            tcg_gen_extu_tl_i64(t3, t1);
5111            tcg_gen_mul_i64(t2, t2, t3);
5112            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5113            tcg_gen_add_i64(t2, t2, t3);
5114            tcg_temp_free_i64(t3);
5115            gen_move_low32(cpu_LO[acc], t2);
5116            gen_move_high32(cpu_HI[acc], t2);
5117            if (rd) {
5118                gen_move_low32(cpu_gpr[rd], t2);
5119            }
5120            tcg_temp_free_i64(t2);
5121        }
5122        break;
5123    default:
5124        MIPS_INVAL("mul/madd TXx9");
5125        generate_exception_end(ctx, EXCP_RI);
5126        goto out;
5127    }
5128
5129 out:
5130    tcg_temp_free(t0);
5131    tcg_temp_free(t1);
5132}
5133
5134static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5135                            int rd, int rs, int rt)
5136{
5137    TCGv t0 = tcg_temp_new();
5138    TCGv t1 = tcg_temp_new();
5139
5140    gen_load_gpr(t0, rs);
5141    gen_load_gpr(t1, rt);
5142
5143    switch (opc) {
5144    case OPC_VR54XX_MULS:
5145        gen_helper_muls(t0, cpu_env, t0, t1);
5146        break;
5147    case OPC_VR54XX_MULSU:
5148        gen_helper_mulsu(t0, cpu_env, t0, t1);
5149        break;
5150    case OPC_VR54XX_MACC:
5151        gen_helper_macc(t0, cpu_env, t0, t1);
5152        break;
5153    case OPC_VR54XX_MACCU:
5154        gen_helper_maccu(t0, cpu_env, t0, t1);
5155        break;
5156    case OPC_VR54XX_MSAC:
5157        gen_helper_msac(t0, cpu_env, t0, t1);
5158        break;
5159    case OPC_VR54XX_MSACU:
5160        gen_helper_msacu(t0, cpu_env, t0, t1);
5161        break;
5162    case OPC_VR54XX_MULHI:
5163        gen_helper_mulhi(t0, cpu_env, t0, t1);
5164        break;
5165    case OPC_VR54XX_MULHIU:
5166        gen_helper_mulhiu(t0, cpu_env, t0, t1);
5167        break;
5168    case OPC_VR54XX_MULSHI:
5169        gen_helper_mulshi(t0, cpu_env, t0, t1);
5170        break;
5171    case OPC_VR54XX_MULSHIU:
5172        gen_helper_mulshiu(t0, cpu_env, t0, t1);
5173        break;
5174    case OPC_VR54XX_MACCHI:
5175        gen_helper_macchi(t0, cpu_env, t0, t1);
5176        break;
5177    case OPC_VR54XX_MACCHIU:
5178        gen_helper_macchiu(t0, cpu_env, t0, t1);
5179        break;
5180    case OPC_VR54XX_MSACHI:
5181        gen_helper_msachi(t0, cpu_env, t0, t1);
5182        break;
5183    case OPC_VR54XX_MSACHIU:
5184        gen_helper_msachiu(t0, cpu_env, t0, t1);
5185        break;
5186    default:
5187        MIPS_INVAL("mul vr54xx");
5188        generate_exception_end(ctx, EXCP_RI);
5189        goto out;
5190    }
5191    gen_store_gpr(t0, rd);
5192
5193 out:
5194    tcg_temp_free(t0);
5195    tcg_temp_free(t1);
5196}
5197
5198static void gen_cl (DisasContext *ctx, uint32_t opc,
5199                    int rd, int rs)
5200{
5201    TCGv t0;
5202
5203    if (rd == 0) {
5204        /* Treat as NOP. */
5205        return;
5206    }
5207    t0 = cpu_gpr[rd];
5208    gen_load_gpr(t0, rs);
5209
5210    switch (opc) {
5211    case OPC_CLO:
5212    case R6_OPC_CLO:
5213#if defined(TARGET_MIPS64)
5214    case OPC_DCLO:
5215    case R6_OPC_DCLO:
5216#endif
5217        tcg_gen_not_tl(t0, t0);
5218        break;
5219    }
5220
5221    switch (opc) {
5222    case OPC_CLO:
5223    case R6_OPC_CLO:
5224    case OPC_CLZ:
5225    case R6_OPC_CLZ:
5226        tcg_gen_ext32u_tl(t0, t0);
5227        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5228        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5229        break;
5230#if defined(TARGET_MIPS64)
5231    case OPC_DCLO:
5232    case R6_OPC_DCLO:
5233    case OPC_DCLZ:
5234    case R6_OPC_DCLZ:
5235        tcg_gen_clzi_i64(t0, t0, 64);
5236        break;
5237#endif
5238    }
5239}
5240
5241/* Godson integer instructions */
5242static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5243                                 int rd, int rs, int rt)
5244{
5245    TCGv t0, t1;
5246
5247    if (rd == 0) {
5248        /* Treat as NOP. */
5249        return;
5250    }
5251
5252    switch (opc) {
5253    case OPC_MULT_G_2E:
5254    case OPC_MULT_G_2F:
5255    case OPC_MULTU_G_2E:
5256    case OPC_MULTU_G_2F:
5257#if defined(TARGET_MIPS64)
5258    case OPC_DMULT_G_2E:
5259    case OPC_DMULT_G_2F:
5260    case OPC_DMULTU_G_2E:
5261    case OPC_DMULTU_G_2F:
5262#endif
5263        t0 = tcg_temp_new();
5264        t1 = tcg_temp_new();
5265        break;
5266    default:
5267        t0 = tcg_temp_local_new();
5268        t1 = tcg_temp_local_new();
5269        break;
5270    }
5271
5272    gen_load_gpr(t0, rs);
5273    gen_load_gpr(t1, rt);
5274
5275    switch (opc) {
5276    case OPC_MULT_G_2E:
5277    case OPC_MULT_G_2F:
5278        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5279        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5280        break;
5281    case OPC_MULTU_G_2E:
5282    case OPC_MULTU_G_2F:
5283        tcg_gen_ext32u_tl(t0, t0);
5284        tcg_gen_ext32u_tl(t1, t1);
5285        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5286        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5287        break;
5288    case OPC_DIV_G_2E:
5289    case OPC_DIV_G_2F:
5290        {
5291            TCGLabel *l1 = gen_new_label();
5292            TCGLabel *l2 = gen_new_label();
5293            TCGLabel *l3 = gen_new_label();
5294            tcg_gen_ext32s_tl(t0, t0);
5295            tcg_gen_ext32s_tl(t1, t1);
5296            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5297            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5298            tcg_gen_br(l3);
5299            gen_set_label(l1);
5300            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5301            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5302            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5303            tcg_gen_br(l3);
5304            gen_set_label(l2);
5305            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5306            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5307            gen_set_label(l3);
5308        }
5309        break;
5310    case OPC_DIVU_G_2E:
5311    case OPC_DIVU_G_2F:
5312        {
5313            TCGLabel *l1 = gen_new_label();
5314            TCGLabel *l2 = gen_new_label();
5315            tcg_gen_ext32u_tl(t0, t0);
5316            tcg_gen_ext32u_tl(t1, t1);
5317            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5318            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5319            tcg_gen_br(l2);
5320            gen_set_label(l1);
5321            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5322            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5323            gen_set_label(l2);
5324        }
5325        break;
5326    case OPC_MOD_G_2E:
5327    case OPC_MOD_G_2F:
5328        {
5329            TCGLabel *l1 = gen_new_label();
5330            TCGLabel *l2 = gen_new_label();
5331            TCGLabel *l3 = gen_new_label();
5332            tcg_gen_ext32u_tl(t0, t0);
5333            tcg_gen_ext32u_tl(t1, t1);
5334            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5335            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5336            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5337            gen_set_label(l1);
5338            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5339            tcg_gen_br(l3);
5340            gen_set_label(l2);
5341            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5342            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5343            gen_set_label(l3);
5344        }
5345        break;
5346    case OPC_MODU_G_2E:
5347    case OPC_MODU_G_2F:
5348        {
5349            TCGLabel *l1 = gen_new_label();
5350            TCGLabel *l2 = gen_new_label();
5351            tcg_gen_ext32u_tl(t0, t0);
5352            tcg_gen_ext32u_tl(t1, t1);
5353            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5354            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5355            tcg_gen_br(l2);
5356            gen_set_label(l1);
5357            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5358            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5359            gen_set_label(l2);
5360        }
5361        break;
5362#if defined(TARGET_MIPS64)
5363    case OPC_DMULT_G_2E:
5364    case OPC_DMULT_G_2F:
5365        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5366        break;
5367    case OPC_DMULTU_G_2E:
5368    case OPC_DMULTU_G_2F:
5369        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5370        break;
5371    case OPC_DDIV_G_2E:
5372    case OPC_DDIV_G_2F:
5373        {
5374            TCGLabel *l1 = gen_new_label();
5375            TCGLabel *l2 = gen_new_label();
5376            TCGLabel *l3 = gen_new_label();
5377            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5378            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5379            tcg_gen_br(l3);
5380            gen_set_label(l1);
5381            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5382            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5383            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5384            tcg_gen_br(l3);
5385            gen_set_label(l2);
5386            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5387            gen_set_label(l3);
5388        }
5389        break;
5390    case OPC_DDIVU_G_2E:
5391    case OPC_DDIVU_G_2F:
5392        {
5393            TCGLabel *l1 = gen_new_label();
5394            TCGLabel *l2 = gen_new_label();
5395            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5396            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5397            tcg_gen_br(l2);
5398            gen_set_label(l1);
5399            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5400            gen_set_label(l2);
5401        }
5402        break;
5403    case OPC_DMOD_G_2E:
5404    case OPC_DMOD_G_2F:
5405        {
5406            TCGLabel *l1 = gen_new_label();
5407            TCGLabel *l2 = gen_new_label();
5408            TCGLabel *l3 = gen_new_label();
5409            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5410            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5411            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5412            gen_set_label(l1);
5413            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5414            tcg_gen_br(l3);
5415            gen_set_label(l2);
5416            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5417            gen_set_label(l3);
5418        }
5419        break;
5420    case OPC_DMODU_G_2E:
5421    case OPC_DMODU_G_2F:
5422        {
5423            TCGLabel *l1 = gen_new_label();
5424            TCGLabel *l2 = gen_new_label();
5425            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5426            tcg_gen_movi_tl(cpu_gpr[rd], 0);
5427            tcg_gen_br(l2);
5428            gen_set_label(l1);
5429            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5430            gen_set_label(l2);
5431        }
5432        break;
5433#endif
5434    }
5435
5436    tcg_temp_free(t0);
5437    tcg_temp_free(t1);
5438}
5439
5440/* Loongson multimedia instructions */
5441static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5442{
5443    uint32_t opc, shift_max;
5444    TCGv_i64 t0, t1;
5445
5446    opc = MASK_LMI(ctx->opcode);
5447    switch (opc) {
5448    case OPC_ADD_CP2:
5449    case OPC_SUB_CP2:
5450    case OPC_DADD_CP2:
5451    case OPC_DSUB_CP2:
5452        t0 = tcg_temp_local_new_i64();
5453        t1 = tcg_temp_local_new_i64();
5454        break;
5455    default:
5456        t0 = tcg_temp_new_i64();
5457        t1 = tcg_temp_new_i64();
5458        break;
5459    }
5460
5461    check_cp1_enabled(ctx);
5462    gen_load_fpr64(ctx, t0, rs);
5463    gen_load_fpr64(ctx, t1, rt);
5464
5465#define LMI_HELPER(UP, LO) \
5466    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5467#define LMI_HELPER_1(UP, LO) \
5468    case OPC_##UP: gen_helper_##LO(t0, t0); break
5469#define LMI_DIRECT(UP, LO, OP) \
5470    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5471
5472    switch (opc) {
5473    LMI_HELPER(PADDSH, paddsh);
5474    LMI_HELPER(PADDUSH, paddush);
5475    LMI_HELPER(PADDH, paddh);
5476    LMI_HELPER(PADDW, paddw);
5477    LMI_HELPER(PADDSB, paddsb);
5478    LMI_HELPER(PADDUSB, paddusb);
5479    LMI_HELPER(PADDB, paddb);
5480
5481    LMI_HELPER(PSUBSH, psubsh);
5482    LMI_HELPER(PSUBUSH, psubush);
5483    LMI_HELPER(PSUBH, psubh);
5484    LMI_HELPER(PSUBW, psubw);
5485    LMI_HELPER(PSUBSB, psubsb);
5486    LMI_HELPER(PSUBUSB, psubusb);
5487    LMI_HELPER(PSUBB, psubb);
5488
5489    LMI_HELPER(PSHUFH, pshufh);
5490    LMI_HELPER(PACKSSWH, packsswh);
5491    LMI_HELPER(PACKSSHB, packsshb);
5492    LMI_HELPER(PACKUSHB, packushb);
5493
5494    LMI_HELPER(PUNPCKLHW, punpcklhw);
5495    LMI_HELPER(PUNPCKHHW, punpckhhw);
5496    LMI_HELPER(PUNPCKLBH, punpcklbh);
5497    LMI_HELPER(PUNPCKHBH, punpckhbh);
5498    LMI_HELPER(PUNPCKLWD, punpcklwd);
5499    LMI_HELPER(PUNPCKHWD, punpckhwd);
5500
5501    LMI_HELPER(PAVGH, pavgh);
5502    LMI_HELPER(PAVGB, pavgb);
5503    LMI_HELPER(PMAXSH, pmaxsh);
5504    LMI_HELPER(PMINSH, pminsh);
5505    LMI_HELPER(PMAXUB, pmaxub);
5506    LMI_HELPER(PMINUB, pminub);
5507
5508    LMI_HELPER(PCMPEQW, pcmpeqw);
5509    LMI_HELPER(PCMPGTW, pcmpgtw);
5510    LMI_HELPER(PCMPEQH, pcmpeqh);
5511    LMI_HELPER(PCMPGTH, pcmpgth);
5512    LMI_HELPER(PCMPEQB, pcmpeqb);
5513    LMI_HELPER(PCMPGTB, pcmpgtb);
5514
5515    LMI_HELPER(PSLLW, psllw);
5516    LMI_HELPER(PSLLH, psllh);
5517    LMI_HELPER(PSRLW, psrlw);
5518    LMI_HELPER(PSRLH, psrlh);
5519    LMI_HELPER(PSRAW, psraw);
5520    LMI_HELPER(PSRAH, psrah);
5521
5522    LMI_HELPER(PMULLH, pmullh);
5523    LMI_HELPER(PMULHH, pmulhh);
5524    LMI_HELPER(PMULHUH, pmulhuh);
5525    LMI_HELPER(PMADDHW, pmaddhw);
5526
5527    LMI_HELPER(PASUBUB, pasubub);
5528    LMI_HELPER_1(BIADD, biadd);
5529    LMI_HELPER_1(PMOVMSKB, pmovmskb);
5530
5531    LMI_DIRECT(PADDD, paddd, add);
5532    LMI_DIRECT(PSUBD, psubd, sub);
5533    LMI_DIRECT(XOR_CP2, xor, xor);
5534    LMI_DIRECT(NOR_CP2, nor, nor);
5535    LMI_DIRECT(AND_CP2, and, and);
5536    LMI_DIRECT(OR_CP2, or, or);
5537
5538    case OPC_PANDN:
5539        tcg_gen_andc_i64(t0, t1, t0);
5540        break;
5541
5542    case OPC_PINSRH_0:
5543        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5544        break;
5545    case OPC_PINSRH_1:
5546        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5547        break;
5548    case OPC_PINSRH_2:
5549        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5550        break;
5551    case OPC_PINSRH_3:
5552        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5553        break;
5554
5555    case OPC_PEXTRH:
5556        tcg_gen_andi_i64(t1, t1, 3);
5557        tcg_gen_shli_i64(t1, t1, 4);
5558        tcg_gen_shr_i64(t0, t0, t1);
5559        tcg_gen_ext16u_i64(t0, t0);
5560        break;
5561
5562    case OPC_ADDU_CP2:
5563        tcg_gen_add_i64(t0, t0, t1);
5564        tcg_gen_ext32s_i64(t0, t0);
5565        break;
5566    case OPC_SUBU_CP2:
5567        tcg_gen_sub_i64(t0, t0, t1);
5568        tcg_gen_ext32s_i64(t0, t0);
5569        break;
5570
5571    case OPC_SLL_CP2:
5572        shift_max = 32;
5573        goto do_shift;
5574    case OPC_SRL_CP2:
5575        shift_max = 32;
5576        goto do_shift;
5577    case OPC_SRA_CP2:
5578        shift_max = 32;
5579        goto do_shift;
5580    case OPC_DSLL_CP2:
5581        shift_max = 64;
5582        goto do_shift;
5583    case OPC_DSRL_CP2:
5584        shift_max = 64;
5585        goto do_shift;
5586    case OPC_DSRA_CP2:
5587        shift_max = 64;
5588        goto do_shift;
5589    do_shift:
5590        /* Make sure shift count isn't TCG undefined behaviour.  */
5591        tcg_gen_andi_i64(t1, t1, shift_max - 1);
5592
5593        switch (opc) {
5594        case OPC_SLL_CP2:
5595        case OPC_DSLL_CP2:
5596            tcg_gen_shl_i64(t0, t0, t1);
5597            break;
5598        case OPC_SRA_CP2:
5599        case OPC_DSRA_CP2:
5600            /* Since SRA is UndefinedResult without sign-extended inputs,
5601               we can treat SRA and DSRA the same.  */
5602            tcg_gen_sar_i64(t0, t0, t1);
5603            break;
5604        case OPC_SRL_CP2:
5605            /* We want to shift in zeros for SRL; zero-extend first.  */
5606            tcg_gen_ext32u_i64(t0, t0);
5607            /* FALLTHRU */
5608        case OPC_DSRL_CP2:
5609            tcg_gen_shr_i64(t0, t0, t1);
5610            break;
5611        }
5612
5613        if (shift_max == 32) {
5614            tcg_gen_ext32s_i64(t0, t0);
5615        }
5616
5617        /* Shifts larger than MAX produce zero.  */
5618        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5619        tcg_gen_neg_i64(t1, t1);
5620        tcg_gen_and_i64(t0, t0, t1);
5621        break;
5622
5623    case OPC_ADD_CP2:
5624    case OPC_DADD_CP2:
5625        {
5626            TCGv_i64 t2 = tcg_temp_new_i64();
5627            TCGLabel *lab = gen_new_label();
5628
5629            tcg_gen_mov_i64(t2, t0);
5630            tcg_gen_add_i64(t0, t1, t2);
5631            if (opc == OPC_ADD_CP2) {
5632                tcg_gen_ext32s_i64(t0, t0);
5633            }
5634            tcg_gen_xor_i64(t1, t1, t2);
5635            tcg_gen_xor_i64(t2, t2, t0);
5636            tcg_gen_andc_i64(t1, t2, t1);
5637            tcg_temp_free_i64(t2);
5638            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5639            generate_exception(ctx, EXCP_OVERFLOW);
5640            gen_set_label(lab);
5641            break;
5642        }
5643
5644    case OPC_SUB_CP2:
5645    case OPC_DSUB_CP2:
5646        {
5647            TCGv_i64 t2 = tcg_temp_new_i64();
5648            TCGLabel *lab = gen_new_label();
5649
5650            tcg_gen_mov_i64(t2, t0);
5651            tcg_gen_sub_i64(t0, t1, t2);
5652            if (opc == OPC_SUB_CP2) {
5653                tcg_gen_ext32s_i64(t0, t0);
5654            }
5655            tcg_gen_xor_i64(t1, t1, t2);
5656            tcg_gen_xor_i64(t2, t2, t0);
5657            tcg_gen_and_i64(t1, t1, t2);
5658            tcg_temp_free_i64(t2);
5659            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5660            generate_exception(ctx, EXCP_OVERFLOW);
5661            gen_set_label(lab);
5662            break;
5663        }
5664
5665    case OPC_PMULUW:
5666        tcg_gen_ext32u_i64(t0, t0);
5667        tcg_gen_ext32u_i64(t1, t1);
5668        tcg_gen_mul_i64(t0, t0, t1);
5669        break;
5670
5671    case OPC_SEQU_CP2:
5672    case OPC_SEQ_CP2:
5673    case OPC_SLTU_CP2:
5674    case OPC_SLT_CP2:
5675    case OPC_SLEU_CP2:
5676    case OPC_SLE_CP2:
5677        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
5678           FD field is the CC field?  */
5679    default:
5680        MIPS_INVAL("loongson_cp2");
5681        generate_exception_end(ctx, EXCP_RI);
5682        return;
5683    }
5684
5685#undef LMI_HELPER
5686#undef LMI_DIRECT
5687
5688    gen_store_fpr64(ctx, t0, rd);
5689
5690    tcg_temp_free_i64(t0);
5691    tcg_temp_free_i64(t1);
5692}
5693
5694/* Traps */
5695static void gen_trap (DisasContext *ctx, uint32_t opc,
5696                      int rs, int rt, int16_t imm)
5697{
5698    int cond;
5699    TCGv t0 = tcg_temp_new();
5700    TCGv t1 = tcg_temp_new();
5701
5702    cond = 0;
5703    /* Load needed operands */
5704    switch (opc) {
5705    case OPC_TEQ:
5706    case OPC_TGE:
5707    case OPC_TGEU:
5708    case OPC_TLT:
5709    case OPC_TLTU:
5710    case OPC_TNE:
5711        /* Compare two registers */
5712        if (rs != rt) {
5713            gen_load_gpr(t0, rs);
5714            gen_load_gpr(t1, rt);
5715            cond = 1;
5716        }
5717        break;
5718    case OPC_TEQI:
5719    case OPC_TGEI:
5720    case OPC_TGEIU:
5721    case OPC_TLTI:
5722    case OPC_TLTIU:
5723    case OPC_TNEI:
5724        /* Compare register to immediate */
5725        if (rs != 0 || imm != 0) {
5726            gen_load_gpr(t0, rs);
5727            tcg_gen_movi_tl(t1, (int32_t)imm);
5728            cond = 1;
5729        }
5730        break;
5731    }
5732    if (cond == 0) {
5733        switch (opc) {
5734        case OPC_TEQ:   /* rs == rs */
5735        case OPC_TEQI:  /* r0 == 0  */
5736        case OPC_TGE:   /* rs >= rs */
5737        case OPC_TGEI:  /* r0 >= 0  */
5738        case OPC_TGEU:  /* rs >= rs unsigned */
5739        case OPC_TGEIU: /* r0 >= 0  unsigned */
5740            /* Always trap */
5741            generate_exception_end(ctx, EXCP_TRAP);
5742            break;
5743        case OPC_TLT:   /* rs < rs           */
5744        case OPC_TLTI:  /* r0 < 0            */
5745        case OPC_TLTU:  /* rs < rs unsigned  */
5746        case OPC_TLTIU: /* r0 < 0  unsigned  */
5747        case OPC_TNE:   /* rs != rs          */
5748        case OPC_TNEI:  /* r0 != 0           */
5749            /* Never trap: treat as NOP. */
5750            break;
5751        }
5752    } else {
5753        TCGLabel *l1 = gen_new_label();
5754
5755        switch (opc) {
5756        case OPC_TEQ:
5757        case OPC_TEQI:
5758            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5759            break;
5760        case OPC_TGE:
5761        case OPC_TGEI:
5762            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5763            break;
5764        case OPC_TGEU:
5765        case OPC_TGEIU:
5766            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5767            break;
5768        case OPC_TLT:
5769        case OPC_TLTI:
5770            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5771            break;
5772        case OPC_TLTU:
5773        case OPC_TLTIU:
5774            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5775            break;
5776        case OPC_TNE:
5777        case OPC_TNEI:
5778            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5779            break;
5780        }
5781        generate_exception(ctx, EXCP_TRAP);
5782        gen_set_label(l1);
5783    }
5784    tcg_temp_free(t0);
5785    tcg_temp_free(t1);
5786}
5787
5788static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5789{
5790    if (unlikely(ctx->base.singlestep_enabled)) {
5791        return false;
5792    }
5793
5794#ifndef CONFIG_USER_ONLY
5795    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5796#else
5797    return true;
5798#endif
5799}
5800
5801static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5802{
5803    if (use_goto_tb(ctx, dest)) {
5804        tcg_gen_goto_tb(n);
5805        gen_save_pc(dest);
5806        tcg_gen_exit_tb(ctx->base.tb, n);
5807    } else {
5808        gen_save_pc(dest);
5809        if (ctx->base.singlestep_enabled) {
5810            save_cpu_state(ctx, 0);
5811            gen_helper_raise_exception_debug(cpu_env);
5812        }
5813        tcg_gen_lookup_and_goto_ptr();
5814    }
5815}
5816
5817/* Branches (before delay slot) */
5818static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5819                                int insn_bytes,
5820                                int rs, int rt, int32_t offset,
5821                                int delayslot_size)
5822{
5823    target_ulong btgt = -1;
5824    int blink = 0;
5825    int bcond_compute = 0;
5826    TCGv t0 = tcg_temp_new();
5827    TCGv t1 = tcg_temp_new();
5828
5829    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5830#ifdef MIPS_DEBUG_DISAS
5831        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5832                  TARGET_FMT_lx "\n", ctx->base.pc_next);
5833#endif
5834        generate_exception_end(ctx, EXCP_RI);
5835        goto out;
5836    }
5837
5838    /* Load needed operands */
5839    switch (opc) {
5840    case OPC_BEQ:
5841    case OPC_BEQL:
5842    case OPC_BNE:
5843    case OPC_BNEL:
5844        /* Compare two registers */
5845        if (rs != rt) {
5846            gen_load_gpr(t0, rs);
5847            gen_load_gpr(t1, rt);
5848            bcond_compute = 1;
5849        }
5850        btgt = ctx->base.pc_next + insn_bytes + offset;
5851        break;
5852    case OPC_BGEZ:
5853    case OPC_BGEZAL:
5854    case OPC_BGEZALL:
5855    case OPC_BGEZL:
5856    case OPC_BGTZ:
5857    case OPC_BGTZL:
5858    case OPC_BLEZ:
5859    case OPC_BLEZL:
5860    case OPC_BLTZ:
5861    case OPC_BLTZAL:
5862    case OPC_BLTZALL:
5863    case OPC_BLTZL:
5864        /* Compare to zero */
5865        if (rs != 0) {
5866            gen_load_gpr(t0, rs);
5867            bcond_compute = 1;
5868        }
5869        btgt = ctx->base.pc_next + insn_bytes + offset;
5870        break;
5871    case OPC_BPOSGE32:
5872#if defined(TARGET_MIPS64)
5873    case OPC_BPOSGE64:
5874        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5875#else
5876        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5877#endif
5878        bcond_compute = 1;
5879        btgt = ctx->base.pc_next + insn_bytes + offset;
5880        break;
5881    case OPC_J:
5882    case OPC_JAL:
5883    case OPC_JALX:
5884        /* Jump to immediate */
5885        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5886            (uint32_t)offset;
5887        break;
5888    case OPC_JR:
5889    case OPC_JALR:
5890        /* Jump to register */
5891        if (offset != 0 && offset != 16) {
5892            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5893               others are reserved. */
5894            MIPS_INVAL("jump hint");
5895            generate_exception_end(ctx, EXCP_RI);
5896            goto out;
5897        }
5898        gen_load_gpr(btarget, rs);
5899        break;
5900    default:
5901        MIPS_INVAL("branch/jump");
5902        generate_exception_end(ctx, EXCP_RI);
5903        goto out;
5904    }
5905    if (bcond_compute == 0) {
5906        /* No condition to be computed */
5907        switch (opc) {
5908        case OPC_BEQ:     /* rx == rx        */
5909        case OPC_BEQL:    /* rx == rx likely */
5910        case OPC_BGEZ:    /* 0 >= 0          */
5911        case OPC_BGEZL:   /* 0 >= 0 likely   */
5912        case OPC_BLEZ:    /* 0 <= 0          */
5913        case OPC_BLEZL:   /* 0 <= 0 likely   */
5914            /* Always take */
5915            ctx->hflags |= MIPS_HFLAG_B;
5916            break;
5917        case OPC_BGEZAL:  /* 0 >= 0          */
5918        case OPC_BGEZALL: /* 0 >= 0 likely   */
5919            /* Always take and link */
5920            blink = 31;
5921            ctx->hflags |= MIPS_HFLAG_B;
5922            break;
5923        case OPC_BNE:     /* rx != rx        */
5924        case OPC_BGTZ:    /* 0 > 0           */
5925        case OPC_BLTZ:    /* 0 < 0           */
5926            /* Treat as NOP. */
5927            goto out;
5928        case OPC_BLTZAL:  /* 0 < 0           */
5929            /* Handle as an unconditional branch to get correct delay
5930               slot checking.  */
5931            blink = 31;
5932            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5933            ctx->hflags |= MIPS_HFLAG_B;
5934            break;
5935        case OPC_BLTZALL: /* 0 < 0 likely */
5936            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5937            /* Skip the instruction in the delay slot */
5938            ctx->base.pc_next += 4;
5939            goto out;
5940        case OPC_BNEL:    /* rx != rx likely */
5941        case OPC_BGTZL:   /* 0 > 0 likely */
5942        case OPC_BLTZL:   /* 0 < 0 likely */
5943            /* Skip the instruction in the delay slot */
5944            ctx->base.pc_next += 4;
5945            goto out;
5946        case OPC_J:
5947            ctx->hflags |= MIPS_HFLAG_B;
5948            break;
5949        case OPC_JALX:
5950            ctx->hflags |= MIPS_HFLAG_BX;
5951            /* Fallthrough */
5952        case OPC_JAL:
5953            blink = 31;
5954            ctx->hflags |= MIPS_HFLAG_B;
5955            break;
5956        case OPC_JR:
5957            ctx->hflags |= MIPS_HFLAG_BR;
5958            break;
5959        case OPC_JALR:
5960            blink = rt;
5961            ctx->hflags |= MIPS_HFLAG_BR;
5962            break;
5963        default:
5964            MIPS_INVAL("branch/jump");
5965            generate_exception_end(ctx, EXCP_RI);
5966            goto out;
5967        }
5968    } else {
5969        switch (opc) {
5970        case OPC_BEQ:
5971            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5972            goto not_likely;
5973        case OPC_BEQL:
5974            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5975            goto likely;
5976        case OPC_BNE:
5977            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5978            goto not_likely;
5979        case OPC_BNEL:
5980            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5981            goto likely;
5982        case OPC_BGEZ:
5983            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5984            goto not_likely;
5985        case OPC_BGEZL:
5986            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5987            goto likely;
5988        case OPC_BGEZAL:
5989            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5990            blink = 31;
5991            goto not_likely;
5992        case OPC_BGEZALL:
5993            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5994            blink = 31;
5995            goto likely;
5996        case OPC_BGTZ:
5997            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5998            goto not_likely;
5999        case OPC_BGTZL:
6000            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6001            goto likely;
6002        case OPC_BLEZ:
6003            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6004            goto not_likely;
6005        case OPC_BLEZL:
6006            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6007            goto likely;
6008        case OPC_BLTZ:
6009            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6010            goto not_likely;
6011        case OPC_BLTZL:
6012            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6013            goto likely;
6014        case OPC_BPOSGE32:
6015            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6016            goto not_likely;
6017#if defined(TARGET_MIPS64)
6018        case OPC_BPOSGE64:
6019            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6020            goto not_likely;
6021#endif
6022        case OPC_BLTZAL:
6023            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6024            blink = 31;
6025        not_likely:
6026            ctx->hflags |= MIPS_HFLAG_BC;
6027            break;
6028        case OPC_BLTZALL:
6029            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6030            blink = 31;
6031        likely:
6032            ctx->hflags |= MIPS_HFLAG_BL;
6033            break;
6034        default:
6035            MIPS_INVAL("conditional branch/jump");
6036            generate_exception_end(ctx, EXCP_RI);
6037            goto out;
6038        }
6039    }
6040
6041    ctx->btarget = btgt;
6042
6043    switch (delayslot_size) {
6044    case 2:
6045        ctx->hflags |= MIPS_HFLAG_BDS16;
6046        break;
6047    case 4:
6048        ctx->hflags |= MIPS_HFLAG_BDS32;
6049        break;
6050    }
6051
6052    if (blink > 0) {
6053        int post_delay = insn_bytes + delayslot_size;
6054        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6055
6056        tcg_gen_movi_tl(cpu_gpr[blink],
6057                        ctx->base.pc_next + post_delay + lowbit);
6058    }
6059
6060 out:
6061    if (insn_bytes == 2)
6062        ctx->hflags |= MIPS_HFLAG_B16;
6063    tcg_temp_free(t0);
6064    tcg_temp_free(t1);
6065}
6066
6067
6068/* nanoMIPS Branches */
6069static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6070                                int insn_bytes,
6071                                int rs, int rt, int32_t offset)
6072{
6073    target_ulong btgt = -1;
6074    int bcond_compute = 0;
6075    TCGv t0 = tcg_temp_new();
6076    TCGv t1 = tcg_temp_new();
6077
6078    /* Load needed operands */
6079    switch (opc) {
6080    case OPC_BEQ:
6081    case OPC_BNE:
6082        /* Compare two registers */
6083        if (rs != rt) {
6084            gen_load_gpr(t0, rs);
6085            gen_load_gpr(t1, rt);
6086            bcond_compute = 1;
6087        }
6088        btgt = ctx->base.pc_next + insn_bytes + offset;
6089        break;
6090    case OPC_BGEZAL:
6091        /* Compare to zero */
6092        if (rs != 0) {
6093            gen_load_gpr(t0, rs);
6094            bcond_compute = 1;
6095        }
6096        btgt = ctx->base.pc_next + insn_bytes + offset;
6097        break;
6098    case OPC_BPOSGE32:
6099        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6100        bcond_compute = 1;
6101        btgt = ctx->base.pc_next + insn_bytes + offset;
6102        break;
6103    case OPC_JR:
6104    case OPC_JALR:
6105        /* Jump to register */
6106        if (offset != 0 && offset != 16) {
6107            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6108               others are reserved. */
6109            MIPS_INVAL("jump hint");
6110            generate_exception_end(ctx, EXCP_RI);
6111            goto out;
6112        }
6113        gen_load_gpr(btarget, rs);
6114        break;
6115    default:
6116        MIPS_INVAL("branch/jump");
6117        generate_exception_end(ctx, EXCP_RI);
6118        goto out;
6119    }
6120    if (bcond_compute == 0) {
6121        /* No condition to be computed */
6122        switch (opc) {
6123        case OPC_BEQ:     /* rx == rx        */
6124            /* Always take */
6125            ctx->hflags |= MIPS_HFLAG_B;
6126            break;
6127        case OPC_BGEZAL:  /* 0 >= 0          */
6128            /* Always take and link */
6129            tcg_gen_movi_tl(cpu_gpr[31],
6130                            ctx->base.pc_next + insn_bytes);
6131            ctx->hflags |= MIPS_HFLAG_B;
6132            break;
6133        case OPC_BNE:     /* rx != rx        */
6134            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6135            /* Skip the instruction in the delay slot */
6136            ctx->base.pc_next += 4;
6137            goto out;
6138        case OPC_JR:
6139            ctx->hflags |= MIPS_HFLAG_BR;
6140            break;
6141        case OPC_JALR:
6142            if (rt > 0) {
6143                tcg_gen_movi_tl(cpu_gpr[rt],
6144                                ctx->base.pc_next + insn_bytes);
6145            }
6146            ctx->hflags |= MIPS_HFLAG_BR;
6147            break;
6148        default:
6149            MIPS_INVAL("branch/jump");
6150            generate_exception_end(ctx, EXCP_RI);
6151            goto out;
6152        }
6153    } else {
6154        switch (opc) {
6155        case OPC_BEQ:
6156            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6157            goto not_likely;
6158        case OPC_BNE:
6159            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6160            goto not_likely;
6161        case OPC_BGEZAL:
6162            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6163            tcg_gen_movi_tl(cpu_gpr[31],
6164                            ctx->base.pc_next + insn_bytes);
6165            goto not_likely;
6166        case OPC_BPOSGE32:
6167            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6168        not_likely:
6169            ctx->hflags |= MIPS_HFLAG_BC;
6170            break;
6171        default:
6172            MIPS_INVAL("conditional branch/jump");
6173            generate_exception_end(ctx, EXCP_RI);
6174            goto out;
6175        }
6176    }
6177
6178    ctx->btarget = btgt;
6179
6180 out:
6181    if (insn_bytes == 2) {
6182        ctx->hflags |= MIPS_HFLAG_B16;
6183    }
6184    tcg_temp_free(t0);
6185    tcg_temp_free(t1);
6186}
6187
6188
6189/* special3 bitfield operations */
6190static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6191                        int rs, int lsb, int msb)
6192{
6193    TCGv t0 = tcg_temp_new();
6194    TCGv t1 = tcg_temp_new();
6195
6196    gen_load_gpr(t1, rs);
6197    switch (opc) {
6198    case OPC_EXT:
6199        if (lsb + msb > 31) {
6200            goto fail;
6201        }
6202        if (msb != 31) {
6203            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6204        } else {
6205            /* The two checks together imply that lsb == 0,
6206               so this is a simple sign-extension.  */
6207            tcg_gen_ext32s_tl(t0, t1);
6208        }
6209        break;
6210#if defined(TARGET_MIPS64)
6211    case OPC_DEXTU:
6212        lsb += 32;
6213        goto do_dext;
6214    case OPC_DEXTM:
6215        msb += 32;
6216        goto do_dext;
6217    case OPC_DEXT:
6218    do_dext:
6219        if (lsb + msb > 63) {
6220            goto fail;
6221        }
6222        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6223        break;
6224#endif
6225    case OPC_INS:
6226        if (lsb > msb) {
6227            goto fail;
6228        }
6229        gen_load_gpr(t0, rt);
6230        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6231        tcg_gen_ext32s_tl(t0, t0);
6232        break;
6233#if defined(TARGET_MIPS64)
6234    case OPC_DINSU:
6235        lsb += 32;
6236        /* FALLTHRU */
6237    case OPC_DINSM:
6238        msb += 32;
6239        /* FALLTHRU */
6240    case OPC_DINS:
6241        if (lsb > msb) {
6242            goto fail;
6243        }
6244        gen_load_gpr(t0, rt);
6245        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6246        break;
6247#endif
6248    default:
6249fail:
6250        MIPS_INVAL("bitops");
6251        generate_exception_end(ctx, EXCP_RI);
6252        tcg_temp_free(t0);
6253        tcg_temp_free(t1);
6254        return;
6255    }
6256    gen_store_gpr(t0, rt);
6257    tcg_temp_free(t0);
6258    tcg_temp_free(t1);
6259}
6260
6261static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6262{
6263    TCGv t0;
6264
6265    if (rd == 0) {
6266        /* If no destination, treat it as a NOP. */
6267        return;
6268    }
6269
6270    t0 = tcg_temp_new();
6271    gen_load_gpr(t0, rt);
6272    switch (op2) {
6273    case OPC_WSBH:
6274        {
6275            TCGv t1 = tcg_temp_new();
6276            TCGv t2 = tcg_const_tl(0x00FF00FF);
6277
6278            tcg_gen_shri_tl(t1, t0, 8);
6279            tcg_gen_and_tl(t1, t1, t2);
6280            tcg_gen_and_tl(t0, t0, t2);
6281            tcg_gen_shli_tl(t0, t0, 8);
6282            tcg_gen_or_tl(t0, t0, t1);
6283            tcg_temp_free(t2);
6284            tcg_temp_free(t1);
6285            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6286        }
6287        break;
6288    case OPC_SEB:
6289        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6290        break;
6291    case OPC_SEH:
6292        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6293        break;
6294#if defined(TARGET_MIPS64)
6295    case OPC_DSBH:
6296        {
6297            TCGv t1 = tcg_temp_new();
6298            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6299
6300            tcg_gen_shri_tl(t1, t0, 8);
6301            tcg_gen_and_tl(t1, t1, t2);
6302            tcg_gen_and_tl(t0, t0, t2);
6303            tcg_gen_shli_tl(t0, t0, 8);
6304            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6305            tcg_temp_free(t2);
6306            tcg_temp_free(t1);
6307        }
6308        break;
6309    case OPC_DSHD:
6310        {
6311            TCGv t1 = tcg_temp_new();
6312            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6313
6314            tcg_gen_shri_tl(t1, t0, 16);
6315            tcg_gen_and_tl(t1, t1, t2);
6316            tcg_gen_and_tl(t0, t0, t2);
6317            tcg_gen_shli_tl(t0, t0, 16);
6318            tcg_gen_or_tl(t0, t0, t1);
6319            tcg_gen_shri_tl(t1, t0, 32);
6320            tcg_gen_shli_tl(t0, t0, 32);
6321            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6322            tcg_temp_free(t2);
6323            tcg_temp_free(t1);
6324        }
6325        break;
6326#endif
6327    default:
6328        MIPS_INVAL("bsfhl");
6329        generate_exception_end(ctx, EXCP_RI);
6330        tcg_temp_free(t0);
6331        return;
6332    }
6333    tcg_temp_free(t0);
6334}
6335
6336static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6337                    int imm2)
6338{
6339    TCGv t0;
6340    TCGv t1;
6341    if (rd == 0) {
6342        /* Treat as NOP. */
6343        return;
6344    }
6345    t0 = tcg_temp_new();
6346    t1 = tcg_temp_new();
6347    gen_load_gpr(t0, rs);
6348    gen_load_gpr(t1, rt);
6349    tcg_gen_shli_tl(t0, t0, imm2 + 1);
6350    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6351    if (opc == OPC_LSA) {
6352        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6353    }
6354
6355    tcg_temp_free(t1);
6356    tcg_temp_free(t0);
6357
6358    return;
6359}
6360
6361static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6362                           int rt, int bits)
6363{
6364    TCGv t0;
6365    if (rd == 0) {
6366        /* Treat as NOP. */
6367        return;
6368    }
6369    t0 = tcg_temp_new();
6370    if (bits == 0 || bits == wordsz) {
6371        if (bits == 0) {
6372            gen_load_gpr(t0, rt);
6373        } else {
6374            gen_load_gpr(t0, rs);
6375        }
6376        switch (wordsz) {
6377        case 32:
6378            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6379            break;
6380#if defined(TARGET_MIPS64)
6381        case 64:
6382            tcg_gen_mov_tl(cpu_gpr[rd], t0);
6383            break;
6384#endif
6385        }
6386    } else {
6387        TCGv t1 = tcg_temp_new();
6388        gen_load_gpr(t0, rt);
6389        gen_load_gpr(t1, rs);
6390        switch (wordsz) {
6391        case 32:
6392            {
6393                TCGv_i64 t2 = tcg_temp_new_i64();
6394                tcg_gen_concat_tl_i64(t2, t1, t0);
6395                tcg_gen_shri_i64(t2, t2, 32 - bits);
6396                gen_move_low32(cpu_gpr[rd], t2);
6397                tcg_temp_free_i64(t2);
6398            }
6399            break;
6400#if defined(TARGET_MIPS64)
6401        case 64:
6402            tcg_gen_shli_tl(t0, t0, bits);
6403            tcg_gen_shri_tl(t1, t1, 64 - bits);
6404            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6405            break;
6406#endif
6407        }
6408        tcg_temp_free(t1);
6409    }
6410
6411    tcg_temp_free(t0);
6412}
6413
6414static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6415                      int bp)
6416{
6417    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6418}
6419
6420static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6421                    int shift)
6422{
6423    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6424}
6425
6426static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6427{
6428    TCGv t0;
6429    if (rd == 0) {
6430        /* Treat as NOP. */
6431        return;
6432    }
6433    t0 = tcg_temp_new();
6434    gen_load_gpr(t0, rt);
6435    switch (opc) {
6436    case OPC_BITSWAP:
6437        gen_helper_bitswap(cpu_gpr[rd], t0);
6438        break;
6439#if defined(TARGET_MIPS64)
6440    case OPC_DBITSWAP:
6441        gen_helper_dbitswap(cpu_gpr[rd], t0);
6442        break;
6443#endif
6444    }
6445    tcg_temp_free(t0);
6446}
6447
6448#ifndef CONFIG_USER_ONLY
6449/* CP0 (MMU and control) */
6450static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6451{
6452    TCGv_i64 t0 = tcg_temp_new_i64();
6453    TCGv_i64 t1 = tcg_temp_new_i64();
6454
6455    tcg_gen_ext_tl_i64(t0, arg);
6456    tcg_gen_ld_i64(t1, cpu_env, off);
6457#if defined(TARGET_MIPS64)
6458    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6459#else
6460    tcg_gen_concat32_i64(t1, t1, t0);
6461#endif
6462    tcg_gen_st_i64(t1, cpu_env, off);
6463    tcg_temp_free_i64(t1);
6464    tcg_temp_free_i64(t0);
6465}
6466
6467static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6468{
6469    TCGv_i64 t0 = tcg_temp_new_i64();
6470    TCGv_i64 t1 = tcg_temp_new_i64();
6471
6472    tcg_gen_ext_tl_i64(t0, arg);
6473    tcg_gen_ld_i64(t1, cpu_env, off);
6474    tcg_gen_concat32_i64(t1, t1, t0);
6475    tcg_gen_st_i64(t1, cpu_env, off);
6476    tcg_temp_free_i64(t1);
6477    tcg_temp_free_i64(t0);
6478}
6479
6480static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6481{
6482    TCGv_i64 t0 = tcg_temp_new_i64();
6483
6484    tcg_gen_ld_i64(t0, cpu_env, off);
6485#if defined(TARGET_MIPS64)
6486    tcg_gen_shri_i64(t0, t0, 30);
6487#else
6488    tcg_gen_shri_i64(t0, t0, 32);
6489#endif
6490    gen_move_low32(arg, t0);
6491    tcg_temp_free_i64(t0);
6492}
6493
6494static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6495{
6496    TCGv_i64 t0 = tcg_temp_new_i64();
6497
6498    tcg_gen_ld_i64(t0, cpu_env, off);
6499    tcg_gen_shri_i64(t0, t0, 32 + shift);
6500    gen_move_low32(arg, t0);
6501    tcg_temp_free_i64(t0);
6502}
6503
6504static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6505{
6506    TCGv_i32 t0 = tcg_temp_new_i32();
6507
6508    tcg_gen_ld_i32(t0, cpu_env, off);
6509    tcg_gen_ext_i32_tl(arg, t0);
6510    tcg_temp_free_i32(t0);
6511}
6512
6513static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6514{
6515    tcg_gen_ld_tl(arg, cpu_env, off);
6516    tcg_gen_ext32s_tl(arg, arg);
6517}
6518
6519static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6520{
6521    TCGv_i32 t0 = tcg_temp_new_i32();
6522
6523    tcg_gen_trunc_tl_i32(t0, arg);
6524    tcg_gen_st_i32(t0, cpu_env, off);
6525    tcg_temp_free_i32(t0);
6526}
6527
6528#define CP0_CHECK(c)                            \
6529    do {                                        \
6530        if (!(c)) {                             \
6531            goto cp0_unimplemented;             \
6532        }                                       \
6533    } while (0)
6534
6535static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6536{
6537    const char *register_name = "invalid";
6538
6539    switch (reg) {
6540    case CP0_REGISTER_02:
6541        switch (sel) {
6542        case 0:
6543            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6544            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6545            register_name = "EntryLo0";
6546            break;
6547        default:
6548            goto cp0_unimplemented;
6549        }
6550        break;
6551    case CP0_REGISTER_03:
6552        switch (sel) {
6553        case 0:
6554            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6555            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6556            register_name = "EntryLo1";
6557            break;
6558        default:
6559            goto cp0_unimplemented;
6560        }
6561        break;
6562    case CP0_REGISTER_09:
6563        switch (sel) {
6564        case 7:
6565            CP0_CHECK(ctx->saar);
6566            gen_helper_mfhc0_saar(arg, cpu_env);
6567            register_name = "SAAR";
6568            break;
6569        default:
6570            goto cp0_unimplemented;
6571        }
6572        break;
6573    case CP0_REGISTER_17:
6574        switch (sel) {
6575        case 0:
6576            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6577                             ctx->CP0_LLAddr_shift);
6578            register_name = "LLAddr";
6579            break;
6580        case 1:
6581            CP0_CHECK(ctx->mrp);
6582            gen_helper_mfhc0_maar(arg, cpu_env);
6583            register_name = "MAAR";
6584            break;
6585        default:
6586            goto cp0_unimplemented;
6587        }
6588        break;
6589    case CP0_REGISTER_28:
6590        switch (sel) {
6591        case 0:
6592        case 2:
6593        case 4:
6594        case 6:
6595            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6596            register_name = "TagLo";
6597            break;
6598        default:
6599            goto cp0_unimplemented;
6600        }
6601        break;
6602    default:
6603        goto cp0_unimplemented;
6604    }
6605    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6606    return;
6607
6608cp0_unimplemented:
6609    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6610                  register_name, reg, sel);
6611    tcg_gen_movi_tl(arg, 0);
6612}
6613
6614static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6615{
6616    const char *register_name = "invalid";
6617    uint64_t mask = ctx->PAMask >> 36;
6618
6619    switch (reg) {
6620    case CP0_REGISTER_02:
6621        switch (sel) {
6622        case 0:
6623            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6624            tcg_gen_andi_tl(arg, arg, mask);
6625            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6626            register_name = "EntryLo0";
6627            break;
6628        default:
6629            goto cp0_unimplemented;
6630        }
6631        break;
6632    case CP0_REGISTER_03:
6633        switch (sel) {
6634        case 0:
6635            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6636            tcg_gen_andi_tl(arg, arg, mask);
6637            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6638            register_name = "EntryLo1";
6639            break;
6640        default:
6641            goto cp0_unimplemented;
6642        }
6643        break;
6644    case CP0_REGISTER_09:
6645        switch (sel) {
6646        case 7:
6647            CP0_CHECK(ctx->saar);
6648            gen_helper_mthc0_saar(cpu_env, arg);
6649            register_name = "SAAR";
6650            break;
6651        default:
6652            goto cp0_unimplemented;
6653        }
6654    case CP0_REGISTER_17:
6655        switch (sel) {
6656        case 0:
6657            /* LLAddr is read-only (the only exception is bit 0 if LLB is
6658               supported); the CP0_LLAddr_rw_bitmask does not seem to be
6659               relevant for modern MIPS cores supporting MTHC0, therefore
6660               treating MTHC0 to LLAddr as NOP. */
6661            register_name = "LLAddr";
6662            break;
6663        case 1:
6664            CP0_CHECK(ctx->mrp);
6665            gen_helper_mthc0_maar(cpu_env, arg);
6666            register_name = "MAAR";
6667            break;
6668        default:
6669            goto cp0_unimplemented;
6670        }
6671        break;
6672    case CP0_REGISTER_28:
6673        switch (sel) {
6674        case 0:
6675        case 2:
6676        case 4:
6677        case 6:
6678            tcg_gen_andi_tl(arg, arg, mask);
6679            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6680            register_name = "TagLo";
6681            break;
6682        default:
6683            goto cp0_unimplemented;
6684        }
6685        break;
6686    default:
6687        goto cp0_unimplemented;
6688    }
6689    trace_mips_translate_c0("mthc0", register_name, reg, sel);
6690
6691cp0_unimplemented:
6692    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6693                  register_name, reg, sel);
6694}
6695
6696static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6697{
6698    if (ctx->insn_flags & ISA_MIPS32R6) {
6699        tcg_gen_movi_tl(arg, 0);
6700    } else {
6701        tcg_gen_movi_tl(arg, ~0);
6702    }
6703}
6704
6705static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6706{
6707    const char *register_name = "invalid";
6708
6709    if (sel != 0)
6710        check_insn(ctx, ISA_MIPS32);
6711
6712    switch (reg) {
6713    case CP0_REGISTER_00:
6714        switch (sel) {
6715        case 0:
6716            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6717            register_name = "Index";
6718            break;
6719        case 1:
6720            CP0_CHECK(ctx->insn_flags & ASE_MT);
6721            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6722            register_name = "MVPControl";
6723            break;
6724        case 2:
6725            CP0_CHECK(ctx->insn_flags & ASE_MT);
6726            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6727            register_name = "MVPConf0";
6728            break;
6729        case 3:
6730            CP0_CHECK(ctx->insn_flags & ASE_MT);
6731            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6732            register_name = "MVPConf1";
6733            break;
6734        case 4:
6735            CP0_CHECK(ctx->vp);
6736            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6737            register_name = "VPControl";
6738            break;
6739        default:
6740            goto cp0_unimplemented;
6741        }
6742        break;
6743    case CP0_REGISTER_01:
6744        switch (sel) {
6745        case 0:
6746            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6747            gen_helper_mfc0_random(arg, cpu_env);
6748            register_name = "Random";
6749            break;
6750        case 1:
6751            CP0_CHECK(ctx->insn_flags & ASE_MT);
6752            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6753            register_name = "VPEControl";
6754            break;
6755        case 2:
6756            CP0_CHECK(ctx->insn_flags & ASE_MT);
6757            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6758            register_name = "VPEConf0";
6759            break;
6760        case 3:
6761            CP0_CHECK(ctx->insn_flags & ASE_MT);
6762            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6763            register_name = "VPEConf1";
6764            break;
6765        case 4:
6766            CP0_CHECK(ctx->insn_flags & ASE_MT);
6767            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6768            register_name = "YQMask";
6769            break;
6770        case 5:
6771            CP0_CHECK(ctx->insn_flags & ASE_MT);
6772            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6773            register_name = "VPESchedule";
6774            break;
6775        case 6:
6776            CP0_CHECK(ctx->insn_flags & ASE_MT);
6777            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6778            register_name = "VPEScheFBack";
6779            break;
6780        case 7:
6781            CP0_CHECK(ctx->insn_flags & ASE_MT);
6782            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6783            register_name = "VPEOpt";
6784            break;
6785        default:
6786            goto cp0_unimplemented;
6787        }
6788        break;
6789    case CP0_REGISTER_02:
6790        switch (sel) {
6791        case 0:
6792            {
6793                TCGv_i64 tmp = tcg_temp_new_i64();
6794                tcg_gen_ld_i64(tmp, cpu_env,
6795                               offsetof(CPUMIPSState, CP0_EntryLo0));
6796#if defined(TARGET_MIPS64)
6797                if (ctx->rxi) {
6798                    /* Move RI/XI fields to bits 31:30 */
6799                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6800                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6801                }
6802#endif
6803                gen_move_low32(arg, tmp);
6804                tcg_temp_free_i64(tmp);
6805            }
6806            register_name = "EntryLo0";
6807            break;
6808        case 1:
6809            CP0_CHECK(ctx->insn_flags & ASE_MT);
6810            gen_helper_mfc0_tcstatus(arg, cpu_env);
6811            register_name = "TCStatus";
6812            break;
6813        case 2:
6814            CP0_CHECK(ctx->insn_flags & ASE_MT);
6815            gen_helper_mfc0_tcbind(arg, cpu_env);
6816            register_name = "TCBind";
6817            break;
6818        case 3:
6819            CP0_CHECK(ctx->insn_flags & ASE_MT);
6820            gen_helper_mfc0_tcrestart(arg, cpu_env);
6821            register_name = "TCRestart";
6822            break;
6823        case 4:
6824            CP0_CHECK(ctx->insn_flags & ASE_MT);
6825            gen_helper_mfc0_tchalt(arg, cpu_env);
6826            register_name = "TCHalt";
6827            break;
6828        case 5:
6829            CP0_CHECK(ctx->insn_flags & ASE_MT);
6830            gen_helper_mfc0_tccontext(arg, cpu_env);
6831            register_name = "TCContext";
6832            break;
6833        case 6:
6834            CP0_CHECK(ctx->insn_flags & ASE_MT);
6835            gen_helper_mfc0_tcschedule(arg, cpu_env);
6836            register_name = "TCSchedule";
6837            break;
6838        case 7:
6839            CP0_CHECK(ctx->insn_flags & ASE_MT);
6840            gen_helper_mfc0_tcschefback(arg, cpu_env);
6841            register_name = "TCScheFBack";
6842            break;
6843        default:
6844            goto cp0_unimplemented;
6845        }
6846        break;
6847    case CP0_REGISTER_03:
6848        switch (sel) {
6849        case 0:
6850            {
6851                TCGv_i64 tmp = tcg_temp_new_i64();
6852                tcg_gen_ld_i64(tmp, cpu_env,
6853                               offsetof(CPUMIPSState, CP0_EntryLo1));
6854#if defined(TARGET_MIPS64)
6855                if (ctx->rxi) {
6856                    /* Move RI/XI fields to bits 31:30 */
6857                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6858                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6859                }
6860#endif
6861                gen_move_low32(arg, tmp);
6862                tcg_temp_free_i64(tmp);
6863            }
6864            register_name = "EntryLo1";
6865            break;
6866        case 1:
6867            CP0_CHECK(ctx->vp);
6868            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6869            register_name = "GlobalNumber";
6870            break;
6871        default:
6872            goto cp0_unimplemented;
6873        }
6874        break;
6875    case CP0_REGISTER_04:
6876        switch (sel) {
6877        case 0:
6878            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6879            tcg_gen_ext32s_tl(arg, arg);
6880            register_name = "Context";
6881            break;
6882        case 1:
6883//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6884            register_name = "ContextConfig";
6885            goto cp0_unimplemented;
6886        case 2:
6887            CP0_CHECK(ctx->ulri);
6888            tcg_gen_ld_tl(arg, cpu_env,
6889                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6890            tcg_gen_ext32s_tl(arg, arg);
6891            register_name = "UserLocal";
6892            break;
6893        default:
6894            goto cp0_unimplemented;
6895        }
6896        break;
6897    case CP0_REGISTER_05:
6898        switch (sel) {
6899        case 0:
6900            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6901            register_name = "PageMask";
6902            break;
6903        case 1:
6904            check_insn(ctx, ISA_MIPS32R2);
6905            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6906            register_name = "PageGrain";
6907            break;
6908        case 2:
6909            CP0_CHECK(ctx->sc);
6910            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6911            tcg_gen_ext32s_tl(arg, arg);
6912            register_name = "SegCtl0";
6913            break;
6914        case 3:
6915            CP0_CHECK(ctx->sc);
6916            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6917            tcg_gen_ext32s_tl(arg, arg);
6918            register_name = "SegCtl1";
6919            break;
6920        case 4:
6921            CP0_CHECK(ctx->sc);
6922            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6923            tcg_gen_ext32s_tl(arg, arg);
6924            register_name = "SegCtl2";
6925            break;
6926        case 5:
6927            check_pw(ctx);
6928            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6929            register_name = "PWBase";
6930            break;
6931        case 6:
6932            check_pw(ctx);
6933            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6934            register_name = "PWField";
6935            break;
6936        case 7:
6937            check_pw(ctx);
6938            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6939            register_name = "PWSize";
6940            break;
6941        default:
6942            goto cp0_unimplemented;
6943        }
6944        break;
6945    case CP0_REGISTER_06:
6946        switch (sel) {
6947        case 0:
6948            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6949            register_name = "Wired";
6950            break;
6951        case 1:
6952            check_insn(ctx, ISA_MIPS32R2);
6953            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6954            register_name = "SRSConf0";
6955            break;
6956        case 2:
6957            check_insn(ctx, ISA_MIPS32R2);
6958            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6959            register_name = "SRSConf1";
6960            break;
6961        case 3:
6962            check_insn(ctx, ISA_MIPS32R2);
6963            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6964            register_name = "SRSConf2";
6965            break;
6966        case 4:
6967            check_insn(ctx, ISA_MIPS32R2);
6968            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6969            register_name = "SRSConf3";
6970            break;
6971        case 5:
6972            check_insn(ctx, ISA_MIPS32R2);
6973            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6974            register_name = "SRSConf4";
6975            break;
6976        case 6:
6977            check_pw(ctx);
6978            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6979            register_name = "PWCtl";
6980            break;
6981        default:
6982            goto cp0_unimplemented;
6983        }
6984        break;
6985    case CP0_REGISTER_07:
6986        switch (sel) {
6987        case 0:
6988            check_insn(ctx, ISA_MIPS32R2);
6989            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6990            register_name = "HWREna";
6991            break;
6992        default:
6993            goto cp0_unimplemented;
6994        }
6995        break;
6996    case CP0_REGISTER_08:
6997        switch (sel) {
6998        case 0:
6999            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7000            tcg_gen_ext32s_tl(arg, arg);
7001            register_name = "BadVAddr";
7002            break;
7003        case 1:
7004            CP0_CHECK(ctx->bi);
7005            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7006            register_name = "BadInstr";
7007            break;
7008        case 2:
7009            CP0_CHECK(ctx->bp);
7010            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7011            register_name = "BadInstrP";
7012            break;
7013        case 3:
7014            CP0_CHECK(ctx->bi);
7015            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7016            tcg_gen_andi_tl(arg, arg, ~0xffff);
7017            register_name = "BadInstrX";
7018            break;
7019       default:
7020            goto cp0_unimplemented;
7021        }
7022        break;
7023    case CP0_REGISTER_09:
7024        switch (sel) {
7025        case 0:
7026            /* Mark as an IO operation because we read the time.  */
7027            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7028                gen_io_start();
7029            }
7030            gen_helper_mfc0_count(arg, cpu_env);
7031            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7032                gen_io_end();
7033            }
7034            /* Break the TB to be able to take timer interrupts immediately
7035               after reading count. DISAS_STOP isn't sufficient, we need to
7036               ensure we break completely out of translated code.  */
7037            gen_save_pc(ctx->base.pc_next + 4);
7038            ctx->base.is_jmp = DISAS_EXIT;
7039            register_name = "Count";
7040            break;
7041        case 6:
7042            CP0_CHECK(ctx->saar);
7043            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7044            register_name = "SAARI";
7045            break;
7046        case 7:
7047            CP0_CHECK(ctx->saar);
7048            gen_helper_mfc0_saar(arg, cpu_env);
7049            register_name = "SAAR";
7050            break;
7051        default:
7052            goto cp0_unimplemented;
7053        }
7054        break;
7055    case CP0_REGISTER_10:
7056        switch (sel) {
7057        case 0:
7058            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7059            tcg_gen_ext32s_tl(arg, arg);
7060            register_name = "EntryHi";
7061            break;
7062        default:
7063            goto cp0_unimplemented;
7064        }
7065        break;
7066    case CP0_REGISTER_11:
7067        switch (sel) {
7068        case 0:
7069            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7070            register_name = "Compare";
7071            break;
7072        /* 6,7 are implementation dependent */
7073        default:
7074            goto cp0_unimplemented;
7075        }
7076        break;
7077    case CP0_REGISTER_12:
7078        switch (sel) {
7079        case 0:
7080            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7081            register_name = "Status";
7082            break;
7083        case 1:
7084            check_insn(ctx, ISA_MIPS32R2);
7085            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7086            register_name = "IntCtl";
7087            break;
7088        case 2:
7089            check_insn(ctx, ISA_MIPS32R2);
7090            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7091            register_name = "SRSCtl";
7092            break;
7093        case 3:
7094            check_insn(ctx, ISA_MIPS32R2);
7095            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7096            register_name = "SRSMap";
7097            break;
7098        default:
7099            goto cp0_unimplemented;
7100       }
7101        break;
7102    case CP0_REGISTER_13:
7103        switch (sel) {
7104        case 0:
7105            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7106            register_name = "Cause";
7107            break;
7108        default:
7109            goto cp0_unimplemented;
7110       }
7111        break;
7112    case CP0_REGISTER_14:
7113        switch (sel) {
7114        case 0:
7115            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7116            tcg_gen_ext32s_tl(arg, arg);
7117            register_name = "EPC";
7118            break;
7119        default:
7120            goto cp0_unimplemented;
7121        }
7122        break;
7123    case CP0_REGISTER_15:
7124        switch (sel) {
7125        case 0:
7126            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7127            register_name = "PRid";
7128            break;
7129        case 1:
7130            check_insn(ctx, ISA_MIPS32R2);
7131            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7132            tcg_gen_ext32s_tl(arg, arg);
7133            register_name = "EBase";
7134            break;
7135        case 3:
7136            check_insn(ctx, ISA_MIPS32R2);
7137            CP0_CHECK(ctx->cmgcr);
7138            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7139            tcg_gen_ext32s_tl(arg, arg);
7140            register_name = "CMGCRBase";
7141            break;
7142        default:
7143            goto cp0_unimplemented;
7144       }
7145        break;
7146    case CP0_REGISTER_16:
7147        switch (sel) {
7148        case 0:
7149            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7150            register_name = "Config";
7151            break;
7152        case 1:
7153            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7154            register_name = "Config1";
7155            break;
7156        case 2:
7157            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7158            register_name = "Config2";
7159            break;
7160        case 3:
7161            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7162            register_name = "Config3";
7163            break;
7164        case 4:
7165            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7166            register_name = "Config4";
7167            break;
7168        case 5:
7169            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7170            register_name = "Config5";
7171            break;
7172        /* 6,7 are implementation dependent */
7173        case 6:
7174            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7175            register_name = "Config6";
7176            break;
7177        case 7:
7178            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7179            register_name = "Config7";
7180            break;
7181        default:
7182            goto cp0_unimplemented;
7183        }
7184        break;
7185    case CP0_REGISTER_17:
7186        switch (sel) {
7187        case 0:
7188            gen_helper_mfc0_lladdr(arg, cpu_env);
7189            register_name = "LLAddr";
7190            break;
7191        case 1:
7192            CP0_CHECK(ctx->mrp);
7193            gen_helper_mfc0_maar(arg, cpu_env);
7194            register_name = "MAAR";
7195            break;
7196        case 2:
7197            CP0_CHECK(ctx->mrp);
7198            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7199            register_name = "MAARI";
7200            break;
7201        default:
7202            goto cp0_unimplemented;
7203        }
7204        break;
7205    case CP0_REGISTER_18:
7206        switch (sel) {
7207        case 0:
7208        case 1:
7209        case 2:
7210        case 3:
7211        case 4:
7212        case 5:
7213        case 6:
7214        case 7:
7215            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7216            gen_helper_1e0i(mfc0_watchlo, arg, sel);
7217            register_name = "WatchLo";
7218            break;
7219        default:
7220            goto cp0_unimplemented;
7221        }
7222        break;
7223    case CP0_REGISTER_19:
7224        switch (sel) {
7225        case 0:
7226        case 1:
7227        case 2:
7228        case 3:
7229        case 4:
7230        case 5:
7231        case 6:
7232        case 7:
7233            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7234            gen_helper_1e0i(mfc0_watchhi, arg, sel);
7235            register_name = "WatchHi";
7236            break;
7237        default:
7238            goto cp0_unimplemented;
7239        }
7240        break;
7241    case CP0_REGISTER_20:
7242        switch (sel) {
7243        case 0:
7244#if defined(TARGET_MIPS64)
7245            check_insn(ctx, ISA_MIPS3);
7246            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7247            tcg_gen_ext32s_tl(arg, arg);
7248            register_name = "XContext";
7249            break;
7250#endif
7251        default:
7252            goto cp0_unimplemented;
7253        }
7254        break;
7255    case CP0_REGISTER_21:
7256       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7257        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7258        switch (sel) {
7259        case 0:
7260            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7261            register_name = "Framemask";
7262            break;
7263        default:
7264            goto cp0_unimplemented;
7265        }
7266        break;
7267    case CP0_REGISTER_22:
7268        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7269        register_name = "'Diagnostic"; /* implementation dependent */
7270        break;
7271    case CP0_REGISTER_23:
7272        switch (sel) {
7273        case 0:
7274            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7275            register_name = "Debug";
7276            break;
7277        case 1:
7278//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7279            register_name = "TraceControl";
7280            goto cp0_unimplemented;
7281        case 2:
7282//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7283            register_name = "TraceControl2";
7284            goto cp0_unimplemented;
7285        case 3:
7286//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7287            register_name = "UserTraceData";
7288            goto cp0_unimplemented;
7289        case 4:
7290//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7291            register_name = "TraceBPC";
7292            goto cp0_unimplemented;
7293        default:
7294            goto cp0_unimplemented;
7295        }
7296        break;
7297    case CP0_REGISTER_24:
7298        switch (sel) {
7299        case 0:
7300            /* EJTAG support */
7301            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7302            tcg_gen_ext32s_tl(arg, arg);
7303            register_name = "DEPC";
7304            break;
7305        default:
7306            goto cp0_unimplemented;
7307        }
7308        break;
7309    case CP0_REGISTER_25:
7310        switch (sel) {
7311        case 0:
7312            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7313            register_name = "Performance0";
7314            break;
7315        case 1:
7316//            gen_helper_mfc0_performance1(arg);
7317            register_name = "Performance1";
7318            goto cp0_unimplemented;
7319        case 2:
7320//            gen_helper_mfc0_performance2(arg);
7321            register_name = "Performance2";
7322            goto cp0_unimplemented;
7323        case 3:
7324//            gen_helper_mfc0_performance3(arg);
7325            register_name = "Performance3";
7326            goto cp0_unimplemented;
7327        case 4:
7328//            gen_helper_mfc0_performance4(arg);
7329            register_name = "Performance4";
7330            goto cp0_unimplemented;
7331        case 5:
7332//            gen_helper_mfc0_performance5(arg);
7333            register_name = "Performance5";
7334            goto cp0_unimplemented;
7335        case 6:
7336//            gen_helper_mfc0_performance6(arg);
7337            register_name = "Performance6";
7338            goto cp0_unimplemented;
7339        case 7:
7340//            gen_helper_mfc0_performance7(arg);
7341            register_name = "Performance7";
7342            goto cp0_unimplemented;
7343        default:
7344            goto cp0_unimplemented;
7345        }
7346        break;
7347    case CP0_REGISTER_26:
7348        switch (sel) {
7349        case 0:
7350            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7351            register_name = "ErrCtl";
7352            break;
7353        default:
7354            goto cp0_unimplemented;
7355        }
7356        break;
7357    case CP0_REGISTER_27:
7358        switch (sel) {
7359        case 0:
7360        case 1:
7361        case 2:
7362        case 3:
7363            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7364            register_name = "CacheErr";
7365            break;
7366        default:
7367            goto cp0_unimplemented;
7368        }
7369        break;
7370    case CP0_REGISTER_28:
7371        switch (sel) {
7372        case 0:
7373        case 2:
7374        case 4:
7375        case 6:
7376            {
7377                TCGv_i64 tmp = tcg_temp_new_i64();
7378                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7379                gen_move_low32(arg, tmp);
7380                tcg_temp_free_i64(tmp);
7381            }
7382            register_name = "TagLo";
7383            break;
7384        case 1:
7385        case 3:
7386        case 5:
7387        case 7:
7388            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7389            register_name = "DataLo";
7390            break;
7391        default:
7392            goto cp0_unimplemented;
7393        }
7394        break;
7395    case CP0_REGISTER_29:
7396        switch (sel) {
7397        case 0:
7398        case 2:
7399        case 4:
7400        case 6:
7401            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7402            register_name = "TagHi";
7403            break;
7404        case 1:
7405        case 3:
7406        case 5:
7407        case 7:
7408            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7409            register_name = "DataHi";
7410            break;
7411        default:
7412            goto cp0_unimplemented;
7413        }
7414        break;
7415    case CP0_REGISTER_30:
7416        switch (sel) {
7417        case 0:
7418            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7419            tcg_gen_ext32s_tl(arg, arg);
7420            register_name = "ErrorEPC";
7421            break;
7422        default:
7423            goto cp0_unimplemented;
7424        }
7425        break;
7426    case CP0_REGISTER_31:
7427        switch (sel) {
7428        case 0:
7429            /* EJTAG support */
7430            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7431            register_name = "DESAVE";
7432            break;
7433        case 2:
7434        case 3:
7435        case 4:
7436        case 5:
7437        case 6:
7438        case 7:
7439            CP0_CHECK(ctx->kscrexist & (1 << sel));
7440            tcg_gen_ld_tl(arg, cpu_env,
7441                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7442            tcg_gen_ext32s_tl(arg, arg);
7443            register_name = "KScratch";
7444            break;
7445        default:
7446            goto cp0_unimplemented;
7447        }
7448        break;
7449    default:
7450       goto cp0_unimplemented;
7451    }
7452    trace_mips_translate_c0("mfc0", register_name, reg, sel);
7453    return;
7454
7455cp0_unimplemented:
7456    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7457                  register_name, reg, sel);
7458    gen_mfc0_unimplemented(ctx, arg);
7459}
7460
7461static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7462{
7463    const char *register_name = "invalid";
7464
7465    if (sel != 0)
7466        check_insn(ctx, ISA_MIPS32);
7467
7468    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7469        gen_io_start();
7470    }
7471
7472    switch (reg) {
7473    case CP0_REGISTER_00:
7474        switch (sel) {
7475        case 0:
7476            gen_helper_mtc0_index(cpu_env, arg);
7477            register_name = "Index";
7478            break;
7479        case 1:
7480            CP0_CHECK(ctx->insn_flags & ASE_MT);
7481            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7482            register_name = "MVPControl";
7483            break;
7484        case 2:
7485            CP0_CHECK(ctx->insn_flags & ASE_MT);
7486            /* ignored */
7487            register_name = "MVPConf0";
7488            break;
7489        case 3:
7490            CP0_CHECK(ctx->insn_flags & ASE_MT);
7491            /* ignored */
7492            register_name = "MVPConf1";
7493            break;
7494        case 4:
7495            CP0_CHECK(ctx->vp);
7496            /* ignored */
7497            register_name = "VPControl";
7498            break;
7499        default:
7500            goto cp0_unimplemented;
7501        }
7502        break;
7503    case CP0_REGISTER_01:
7504        switch (sel) {
7505        case 0:
7506            /* ignored */
7507            register_name = "Random";
7508            break;
7509        case 1:
7510            CP0_CHECK(ctx->insn_flags & ASE_MT);
7511            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7512            register_name = "VPEControl";
7513            break;
7514        case 2:
7515            CP0_CHECK(ctx->insn_flags & ASE_MT);
7516            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7517            register_name = "VPEConf0";
7518            break;
7519        case 3:
7520            CP0_CHECK(ctx->insn_flags & ASE_MT);
7521            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7522            register_name = "VPEConf1";
7523            break;
7524        case 4:
7525            CP0_CHECK(ctx->insn_flags & ASE_MT);
7526            gen_helper_mtc0_yqmask(cpu_env, arg);
7527            register_name = "YQMask";
7528            break;
7529        case 5:
7530            CP0_CHECK(ctx->insn_flags & ASE_MT);
7531            tcg_gen_st_tl(arg, cpu_env,
7532                          offsetof(CPUMIPSState, CP0_VPESchedule));
7533            register_name = "VPESchedule";
7534            break;
7535        case 6:
7536            CP0_CHECK(ctx->insn_flags & ASE_MT);
7537            tcg_gen_st_tl(arg, cpu_env,
7538                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7539            register_name = "VPEScheFBack";
7540            break;
7541        case 7:
7542            CP0_CHECK(ctx->insn_flags & ASE_MT);
7543            gen_helper_mtc0_vpeopt(cpu_env, arg);
7544            register_name = "VPEOpt";
7545            break;
7546        default:
7547            goto cp0_unimplemented;
7548        }
7549        break;
7550    case CP0_REGISTER_02:
7551        switch (sel) {
7552        case 0:
7553            gen_helper_mtc0_entrylo0(cpu_env, arg);
7554            register_name = "EntryLo0";
7555            break;
7556        case 1:
7557            CP0_CHECK(ctx->insn_flags & ASE_MT);
7558            gen_helper_mtc0_tcstatus(cpu_env, arg);
7559            register_name = "TCStatus";
7560            break;
7561        case 2:
7562            CP0_CHECK(ctx->insn_flags & ASE_MT);
7563            gen_helper_mtc0_tcbind(cpu_env, arg);
7564            register_name = "TCBind";
7565            break;
7566        case 3:
7567            CP0_CHECK(ctx->insn_flags & ASE_MT);
7568            gen_helper_mtc0_tcrestart(cpu_env, arg);
7569            register_name = "TCRestart";
7570            break;
7571        case 4:
7572            CP0_CHECK(ctx->insn_flags & ASE_MT);
7573            gen_helper_mtc0_tchalt(cpu_env, arg);
7574            register_name = "TCHalt";
7575            break;
7576        case 5:
7577            CP0_CHECK(ctx->insn_flags & ASE_MT);
7578            gen_helper_mtc0_tccontext(cpu_env, arg);
7579            register_name = "TCContext";
7580            break;
7581        case 6:
7582            CP0_CHECK(ctx->insn_flags & ASE_MT);
7583            gen_helper_mtc0_tcschedule(cpu_env, arg);
7584            register_name = "TCSchedule";
7585            break;
7586        case 7:
7587            CP0_CHECK(ctx->insn_flags & ASE_MT);
7588            gen_helper_mtc0_tcschefback(cpu_env, arg);
7589            register_name = "TCScheFBack";
7590            break;
7591        default:
7592            goto cp0_unimplemented;
7593        }
7594        break;
7595    case CP0_REGISTER_03:
7596        switch (sel) {
7597        case 0:
7598            gen_helper_mtc0_entrylo1(cpu_env, arg);
7599            register_name = "EntryLo1";
7600            break;
7601        case 1:
7602            CP0_CHECK(ctx->vp);
7603            /* ignored */
7604            register_name = "GlobalNumber";
7605            break;
7606        default:
7607            goto cp0_unimplemented;
7608        }
7609        break;
7610    case CP0_REGISTER_04:
7611        switch (sel) {
7612        case 0:
7613            gen_helper_mtc0_context(cpu_env, arg);
7614            register_name = "Context";
7615            break;
7616        case 1:
7617//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7618            register_name = "ContextConfig";
7619            goto cp0_unimplemented;
7620        case 2:
7621            CP0_CHECK(ctx->ulri);
7622            tcg_gen_st_tl(arg, cpu_env,
7623                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7624            register_name = "UserLocal";
7625            break;
7626        default:
7627            goto cp0_unimplemented;
7628        }
7629        break;
7630    case CP0_REGISTER_05:
7631        switch (sel) {
7632        case 0:
7633            gen_helper_mtc0_pagemask(cpu_env, arg);
7634            register_name = "PageMask";
7635            break;
7636        case 1:
7637            check_insn(ctx, ISA_MIPS32R2);
7638            gen_helper_mtc0_pagegrain(cpu_env, arg);
7639            register_name = "PageGrain";
7640            ctx->base.is_jmp = DISAS_STOP;
7641            break;
7642        case 2:
7643            CP0_CHECK(ctx->sc);
7644            gen_helper_mtc0_segctl0(cpu_env, arg);
7645            register_name = "SegCtl0";
7646            break;
7647        case 3:
7648            CP0_CHECK(ctx->sc);
7649            gen_helper_mtc0_segctl1(cpu_env, arg);
7650            register_name = "SegCtl1";
7651            break;
7652        case 4:
7653            CP0_CHECK(ctx->sc);
7654            gen_helper_mtc0_segctl2(cpu_env, arg);
7655            register_name = "SegCtl2";
7656            break;
7657        case 5:
7658            check_pw(ctx);
7659            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7660            register_name = "PWBase";
7661            break;
7662        case 6:
7663            check_pw(ctx);
7664            gen_helper_mtc0_pwfield(cpu_env, arg);
7665            register_name = "PWField";
7666            break;
7667        case 7:
7668            check_pw(ctx);
7669            gen_helper_mtc0_pwsize(cpu_env, arg);
7670            register_name = "PWSize";
7671            break;
7672        default:
7673            goto cp0_unimplemented;
7674        }
7675        break;
7676    case CP0_REGISTER_06:
7677        switch (sel) {
7678        case 0:
7679            gen_helper_mtc0_wired(cpu_env, arg);
7680            register_name = "Wired";
7681            break;
7682        case 1:
7683            check_insn(ctx, ISA_MIPS32R2);
7684            gen_helper_mtc0_srsconf0(cpu_env, arg);
7685            register_name = "SRSConf0";
7686            break;
7687        case 2:
7688            check_insn(ctx, ISA_MIPS32R2);
7689            gen_helper_mtc0_srsconf1(cpu_env, arg);
7690            register_name = "SRSConf1";
7691            break;
7692        case 3:
7693            check_insn(ctx, ISA_MIPS32R2);
7694            gen_helper_mtc0_srsconf2(cpu_env, arg);
7695            register_name = "SRSConf2";
7696            break;
7697        case 4:
7698            check_insn(ctx, ISA_MIPS32R2);
7699            gen_helper_mtc0_srsconf3(cpu_env, arg);
7700            register_name = "SRSConf3";
7701            break;
7702        case 5:
7703            check_insn(ctx, ISA_MIPS32R2);
7704            gen_helper_mtc0_srsconf4(cpu_env, arg);
7705            register_name = "SRSConf4";
7706            break;
7707        case 6:
7708            check_pw(ctx);
7709            gen_helper_mtc0_pwctl(cpu_env, arg);
7710            register_name = "PWCtl";
7711            break;
7712        default:
7713            goto cp0_unimplemented;
7714        }
7715        break;
7716    case CP0_REGISTER_07:
7717        switch (sel) {
7718        case 0:
7719            check_insn(ctx, ISA_MIPS32R2);
7720            gen_helper_mtc0_hwrena(cpu_env, arg);
7721            ctx->base.is_jmp = DISAS_STOP;
7722            register_name = "HWREna";
7723            break;
7724        default:
7725            goto cp0_unimplemented;
7726        }
7727        break;
7728    case CP0_REGISTER_08:
7729        switch (sel) {
7730        case 0:
7731            /* ignored */
7732            register_name = "BadVAddr";
7733            break;
7734        case 1:
7735            /* ignored */
7736            register_name = "BadInstr";
7737            break;
7738        case 2:
7739            /* ignored */
7740            register_name = "BadInstrP";
7741            break;
7742        case 3:
7743            /* ignored */
7744            register_name = "BadInstrX";
7745            break;
7746        default:
7747            goto cp0_unimplemented;
7748        }
7749        break;
7750    case CP0_REGISTER_09:
7751        switch (sel) {
7752        case 0:
7753            gen_helper_mtc0_count(cpu_env, arg);
7754            register_name = "Count";
7755            break;
7756        case 6:
7757            CP0_CHECK(ctx->saar);
7758            gen_helper_mtc0_saari(cpu_env, arg);
7759            register_name = "SAARI";
7760            break;
7761        case 7:
7762            CP0_CHECK(ctx->saar);
7763            gen_helper_mtc0_saar(cpu_env, arg);
7764            register_name = "SAAR";
7765            break;
7766        default:
7767            goto cp0_unimplemented;
7768        }
7769        break;
7770    case CP0_REGISTER_10:
7771        switch (sel) {
7772        case 0:
7773            gen_helper_mtc0_entryhi(cpu_env, arg);
7774            register_name = "EntryHi";
7775            break;
7776        default:
7777            goto cp0_unimplemented;
7778        }
7779        break;
7780    case CP0_REGISTER_11:
7781        switch (sel) {
7782        case 0:
7783            gen_helper_mtc0_compare(cpu_env, arg);
7784            register_name = "Compare";
7785            break;
7786        /* 6,7 are implementation dependent */
7787        default:
7788            goto cp0_unimplemented;
7789        }
7790        break;
7791    case CP0_REGISTER_12:
7792        switch (sel) {
7793        case 0:
7794            save_cpu_state(ctx, 1);
7795            gen_helper_mtc0_status(cpu_env, arg);
7796            /* DISAS_STOP isn't good enough here, hflags may have changed. */
7797            gen_save_pc(ctx->base.pc_next + 4);
7798            ctx->base.is_jmp = DISAS_EXIT;
7799            register_name = "Status";
7800            break;
7801        case 1:
7802            check_insn(ctx, ISA_MIPS32R2);
7803            gen_helper_mtc0_intctl(cpu_env, arg);
7804            /* Stop translation as we may have switched the execution mode */
7805            ctx->base.is_jmp = DISAS_STOP;
7806            register_name = "IntCtl";
7807            break;
7808        case 2:
7809            check_insn(ctx, ISA_MIPS32R2);
7810            gen_helper_mtc0_srsctl(cpu_env, arg);
7811            /* Stop translation as we may have switched the execution mode */
7812            ctx->base.is_jmp = DISAS_STOP;
7813            register_name = "SRSCtl";
7814            break;
7815        case 3:
7816            check_insn(ctx, ISA_MIPS32R2);
7817            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7818            /* Stop translation as we may have switched the execution mode */
7819            ctx->base.is_jmp = DISAS_STOP;
7820            register_name = "SRSMap";
7821            break;
7822        default:
7823            goto cp0_unimplemented;
7824        }
7825        break;
7826    case CP0_REGISTER_13:
7827        switch (sel) {
7828        case 0:
7829            save_cpu_state(ctx, 1);
7830            gen_helper_mtc0_cause(cpu_env, arg);
7831            /* Stop translation as we may have triggered an interrupt.
7832             * DISAS_STOP isn't sufficient, we need to ensure we break out of
7833             * translated code to check for pending interrupts.  */
7834            gen_save_pc(ctx->base.pc_next + 4);
7835            ctx->base.is_jmp = DISAS_EXIT;
7836            register_name = "Cause";
7837            break;
7838        default:
7839            goto cp0_unimplemented;
7840        }
7841        break;
7842    case CP0_REGISTER_14:
7843        switch (sel) {
7844        case 0:
7845            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7846            register_name = "EPC";
7847            break;
7848        default:
7849            goto cp0_unimplemented;
7850        }
7851        break;
7852    case CP0_REGISTER_15:
7853        switch (sel) {
7854        case 0:
7855            /* ignored */
7856            register_name = "PRid";
7857            break;
7858        case 1:
7859            check_insn(ctx, ISA_MIPS32R2);
7860            gen_helper_mtc0_ebase(cpu_env, arg);
7861            register_name = "EBase";
7862            break;
7863        default:
7864            goto cp0_unimplemented;
7865        }
7866        break;
7867    case CP0_REGISTER_16:
7868        switch (sel) {
7869        case 0:
7870            gen_helper_mtc0_config0(cpu_env, arg);
7871            register_name = "Config";
7872            /* Stop translation as we may have switched the execution mode */
7873            ctx->base.is_jmp = DISAS_STOP;
7874            break;
7875        case 1:
7876            /* ignored, read only */
7877            register_name = "Config1";
7878            break;
7879        case 2:
7880            gen_helper_mtc0_config2(cpu_env, arg);
7881            register_name = "Config2";
7882            /* Stop translation as we may have switched the execution mode */
7883            ctx->base.is_jmp = DISAS_STOP;
7884            break;
7885        case 3:
7886            gen_helper_mtc0_config3(cpu_env, arg);
7887            register_name = "Config3";
7888            /* Stop translation as we may have switched the execution mode */
7889            ctx->base.is_jmp = DISAS_STOP;
7890            break;
7891        case 4:
7892            gen_helper_mtc0_config4(cpu_env, arg);
7893            register_name = "Config4";
7894            ctx->base.is_jmp = DISAS_STOP;
7895            break;
7896        case 5:
7897            gen_helper_mtc0_config5(cpu_env, arg);
7898            register_name = "Config5";
7899            /* Stop translation as we may have switched the execution mode */
7900            ctx->base.is_jmp = DISAS_STOP;
7901            break;
7902        /* 6,7 are implementation dependent */
7903        case 6:
7904            /* ignored */
7905            register_name = "Config6";
7906            break;
7907        case 7:
7908            /* ignored */
7909            register_name = "Config7";
7910            break;
7911        default:
7912            register_name = "Invalid config selector";
7913            goto cp0_unimplemented;
7914        }
7915        break;
7916    case CP0_REGISTER_17:
7917        switch (sel) {
7918        case 0:
7919            gen_helper_mtc0_lladdr(cpu_env, arg);
7920            register_name = "LLAddr";
7921            break;
7922        case 1:
7923            CP0_CHECK(ctx->mrp);
7924            gen_helper_mtc0_maar(cpu_env, arg);
7925            register_name = "MAAR";
7926            break;
7927        case 2:
7928            CP0_CHECK(ctx->mrp);
7929            gen_helper_mtc0_maari(cpu_env, arg);
7930            register_name = "MAARI";
7931            break;
7932        default:
7933            goto cp0_unimplemented;
7934        }
7935        break;
7936    case CP0_REGISTER_18:
7937        switch (sel) {
7938        case 0:
7939        case 1:
7940        case 2:
7941        case 3:
7942        case 4:
7943        case 5:
7944        case 6:
7945        case 7:
7946            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7947            gen_helper_0e1i(mtc0_watchlo, arg, sel);
7948            register_name = "WatchLo";
7949            break;
7950        default:
7951            goto cp0_unimplemented;
7952        }
7953        break;
7954    case CP0_REGISTER_19:
7955        switch (sel) {
7956        case 0:
7957        case 1:
7958        case 2:
7959        case 3:
7960        case 4:
7961        case 5:
7962        case 6:
7963        case 7:
7964            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7965            gen_helper_0e1i(mtc0_watchhi, arg, sel);
7966            register_name = "WatchHi";
7967            break;
7968        default:
7969            goto cp0_unimplemented;
7970        }
7971        break;
7972    case CP0_REGISTER_20:
7973        switch (sel) {
7974        case 0:
7975#if defined(TARGET_MIPS64)
7976            check_insn(ctx, ISA_MIPS3);
7977            gen_helper_mtc0_xcontext(cpu_env, arg);
7978            register_name = "XContext";
7979            break;
7980#endif
7981        default:
7982            goto cp0_unimplemented;
7983        }
7984        break;
7985    case CP0_REGISTER_21:
7986       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7987        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7988        switch (sel) {
7989        case 0:
7990            gen_helper_mtc0_framemask(cpu_env, arg);
7991            register_name = "Framemask";
7992            break;
7993        default:
7994            goto cp0_unimplemented;
7995        }
7996        break;
7997    case CP0_REGISTER_22:
7998        /* ignored */
7999        register_name = "Diagnostic"; /* implementation dependent */
8000        break;
8001    case CP0_REGISTER_23:
8002        switch (sel) {
8003        case 0:
8004            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
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 = "Debug";
8009            break;
8010        case 1:
8011//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8012            register_name = "TraceControl";
8013            /* Stop translation as we may have switched the execution mode */
8014            ctx->base.is_jmp = DISAS_STOP;
8015            goto cp0_unimplemented;
8016        case 2:
8017//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8018            register_name = "TraceControl2";
8019            /* Stop translation as we may have switched the execution mode */
8020            ctx->base.is_jmp = DISAS_STOP;
8021            goto cp0_unimplemented;
8022        case 3:
8023            /* Stop translation as we may have switched the execution mode */
8024            ctx->base.is_jmp = DISAS_STOP;
8025//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8026            register_name = "UserTraceData";
8027            /* Stop translation as we may have switched the execution mode */
8028            ctx->base.is_jmp = DISAS_STOP;
8029            goto cp0_unimplemented;
8030        case 4:
8031//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8032            /* Stop translation as we may have switched the execution mode */
8033            ctx->base.is_jmp = DISAS_STOP;
8034            register_name = "TraceBPC";
8035            goto cp0_unimplemented;
8036        default:
8037            goto cp0_unimplemented;
8038        }
8039        break;
8040    case CP0_REGISTER_24:
8041        switch (sel) {
8042        case 0:
8043            /* EJTAG support */
8044            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8045            register_name = "DEPC";
8046            break;
8047        default:
8048            goto cp0_unimplemented;
8049        }
8050        break;
8051    case CP0_REGISTER_25:
8052        switch (sel) {
8053        case 0:
8054            gen_helper_mtc0_performance0(cpu_env, arg);
8055            register_name = "Performance0";
8056            break;
8057        case 1:
8058//            gen_helper_mtc0_performance1(arg);
8059            register_name = "Performance1";
8060            goto cp0_unimplemented;
8061        case 2:
8062//            gen_helper_mtc0_performance2(arg);
8063            register_name = "Performance2";
8064            goto cp0_unimplemented;
8065        case 3:
8066//            gen_helper_mtc0_performance3(arg);
8067            register_name = "Performance3";
8068            goto cp0_unimplemented;
8069        case 4:
8070//            gen_helper_mtc0_performance4(arg);
8071            register_name = "Performance4";
8072            goto cp0_unimplemented;
8073        case 5:
8074//            gen_helper_mtc0_performance5(arg);
8075            register_name = "Performance5";
8076            goto cp0_unimplemented;
8077        case 6:
8078//            gen_helper_mtc0_performance6(arg);
8079            register_name = "Performance6";
8080            goto cp0_unimplemented;
8081        case 7:
8082//            gen_helper_mtc0_performance7(arg);
8083            register_name = "Performance7";
8084            goto cp0_unimplemented;
8085        default:
8086            goto cp0_unimplemented;
8087        }
8088       break;
8089    case CP0_REGISTER_26:
8090        switch (sel) {
8091        case 0:
8092            gen_helper_mtc0_errctl(cpu_env, arg);
8093            ctx->base.is_jmp = DISAS_STOP;
8094            register_name = "ErrCtl";
8095            break;
8096        default:
8097            goto cp0_unimplemented;
8098        }
8099        break;
8100    case CP0_REGISTER_27:
8101        switch (sel) {
8102        case 0:
8103        case 1:
8104        case 2:
8105        case 3:
8106            /* ignored */
8107            register_name = "CacheErr";
8108            break;
8109        default:
8110            goto cp0_unimplemented;
8111        }
8112       break;
8113    case CP0_REGISTER_28:
8114        switch (sel) {
8115        case 0:
8116        case 2:
8117        case 4:
8118        case 6:
8119            gen_helper_mtc0_taglo(cpu_env, arg);
8120            register_name = "TagLo";
8121            break;
8122        case 1:
8123        case 3:
8124        case 5:
8125        case 7:
8126            gen_helper_mtc0_datalo(cpu_env, arg);
8127            register_name = "DataLo";
8128            break;
8129        default:
8130            goto cp0_unimplemented;
8131        }
8132        break;
8133    case CP0_REGISTER_29:
8134        switch (sel) {
8135        case 0:
8136        case 2:
8137        case 4:
8138        case 6:
8139            gen_helper_mtc0_taghi(cpu_env, arg);
8140            register_name = "TagHi";
8141            break;
8142        case 1:
8143        case 3:
8144        case 5:
8145        case 7:
8146            gen_helper_mtc0_datahi(cpu_env, arg);
8147            register_name = "DataHi";
8148            break;
8149        default:
8150            register_name = "invalid sel";
8151            goto cp0_unimplemented;
8152        }
8153       break;
8154    case CP0_REGISTER_30:
8155        switch (sel) {
8156        case 0:
8157            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8158            register_name = "ErrorEPC";
8159            break;
8160        default:
8161            goto cp0_unimplemented;
8162        }
8163        break;
8164    case CP0_REGISTER_31:
8165        switch (sel) {
8166        case 0:
8167            /* EJTAG support */
8168            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8169            register_name = "DESAVE";
8170            break;
8171        case 2:
8172        case 3:
8173        case 4:
8174        case 5:
8175        case 6:
8176        case 7:
8177            CP0_CHECK(ctx->kscrexist & (1 << sel));
8178            tcg_gen_st_tl(arg, cpu_env,
8179                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8180            register_name = "KScratch";
8181            break;
8182        default:
8183            goto cp0_unimplemented;
8184        }
8185        break;
8186    default:
8187       goto cp0_unimplemented;
8188    }
8189    trace_mips_translate_c0("mtc0", register_name, reg, sel);
8190
8191    /* For simplicity assume that all writes can cause interrupts.  */
8192    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8193        gen_io_end();
8194        /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8195         * translated code to check for pending interrupts.  */
8196        gen_save_pc(ctx->base.pc_next + 4);
8197        ctx->base.is_jmp = DISAS_EXIT;
8198    }
8199    return;
8200
8201cp0_unimplemented:
8202    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8203                  register_name, reg, sel);
8204}
8205
8206#if defined(TARGET_MIPS64)
8207static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8208{
8209    const char *register_name = "invalid";
8210
8211    if (sel != 0)
8212        check_insn(ctx, ISA_MIPS64);
8213
8214    switch (reg) {
8215    case CP0_REGISTER_00:
8216        switch (sel) {
8217        case 0:
8218            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8219            register_name = "Index";
8220            break;
8221        case 1:
8222            CP0_CHECK(ctx->insn_flags & ASE_MT);
8223            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8224            register_name = "MVPControl";
8225            break;
8226        case 2:
8227            CP0_CHECK(ctx->insn_flags & ASE_MT);
8228            gen_helper_mfc0_mvpconf0(arg, cpu_env);
8229            register_name = "MVPConf0";
8230            break;
8231        case 3:
8232            CP0_CHECK(ctx->insn_flags & ASE_MT);
8233            gen_helper_mfc0_mvpconf1(arg, cpu_env);
8234            register_name = "MVPConf1";
8235            break;
8236        case 4:
8237            CP0_CHECK(ctx->vp);
8238            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8239            register_name = "VPControl";
8240            break;
8241        default:
8242            goto cp0_unimplemented;
8243        }
8244        break;
8245    case CP0_REGISTER_01:
8246        switch (sel) {
8247        case 0:
8248            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8249            gen_helper_mfc0_random(arg, cpu_env);
8250            register_name = "Random";
8251            break;
8252        case 1:
8253            CP0_CHECK(ctx->insn_flags & ASE_MT);
8254            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8255            register_name = "VPEControl";
8256            break;
8257        case 2:
8258            CP0_CHECK(ctx->insn_flags & ASE_MT);
8259            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8260            register_name = "VPEConf0";
8261            break;
8262        case 3:
8263            CP0_CHECK(ctx->insn_flags & ASE_MT);
8264            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8265            register_name = "VPEConf1";
8266            break;
8267        case 4:
8268            CP0_CHECK(ctx->insn_flags & ASE_MT);
8269            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8270            register_name = "YQMask";
8271            break;
8272        case 5:
8273            CP0_CHECK(ctx->insn_flags & ASE_MT);
8274            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8275            register_name = "VPESchedule";
8276            break;
8277        case 6:
8278            CP0_CHECK(ctx->insn_flags & ASE_MT);
8279            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8280            register_name = "VPEScheFBack";
8281            break;
8282        case 7:
8283            CP0_CHECK(ctx->insn_flags & ASE_MT);
8284            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8285            register_name = "VPEOpt";
8286            break;
8287        default:
8288            goto cp0_unimplemented;
8289        }
8290        break;
8291    case CP0_REGISTER_02:
8292        switch (sel) {
8293        case 0:
8294            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8295            register_name = "EntryLo0";
8296            break;
8297        case 1:
8298            CP0_CHECK(ctx->insn_flags & ASE_MT);
8299            gen_helper_mfc0_tcstatus(arg, cpu_env);
8300            register_name = "TCStatus";
8301            break;
8302        case 2:
8303            CP0_CHECK(ctx->insn_flags & ASE_MT);
8304            gen_helper_mfc0_tcbind(arg, cpu_env);
8305            register_name = "TCBind";
8306            break;
8307        case 3:
8308            CP0_CHECK(ctx->insn_flags & ASE_MT);
8309            gen_helper_dmfc0_tcrestart(arg, cpu_env);
8310            register_name = "TCRestart";
8311            break;
8312        case 4:
8313            CP0_CHECK(ctx->insn_flags & ASE_MT);
8314            gen_helper_dmfc0_tchalt(arg, cpu_env);
8315            register_name = "TCHalt";
8316            break;
8317        case 5:
8318            CP0_CHECK(ctx->insn_flags & ASE_MT);
8319            gen_helper_dmfc0_tccontext(arg, cpu_env);
8320            register_name = "TCContext";
8321            break;
8322        case 6:
8323            CP0_CHECK(ctx->insn_flags & ASE_MT);
8324            gen_helper_dmfc0_tcschedule(arg, cpu_env);
8325            register_name = "TCSchedule";
8326            break;
8327        case 7:
8328            CP0_CHECK(ctx->insn_flags & ASE_MT);
8329            gen_helper_dmfc0_tcschefback(arg, cpu_env);
8330            register_name = "TCScheFBack";
8331            break;
8332        default:
8333            goto cp0_unimplemented;
8334        }
8335        break;
8336    case CP0_REGISTER_03:
8337        switch (sel) {
8338        case 0:
8339            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8340            register_name = "EntryLo1";
8341            break;
8342        case 1:
8343            CP0_CHECK(ctx->vp);
8344            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8345            register_name = "GlobalNumber";
8346            break;
8347        default:
8348            goto cp0_unimplemented;
8349        }
8350        break;
8351    case CP0_REGISTER_04:
8352        switch (sel) {
8353        case 0:
8354            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8355            register_name = "Context";
8356            break;
8357        case 1:
8358//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8359            register_name = "ContextConfig";
8360            goto cp0_unimplemented;
8361        case 2:
8362            CP0_CHECK(ctx->ulri);
8363            tcg_gen_ld_tl(arg, cpu_env,
8364                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8365            register_name = "UserLocal";
8366            break;
8367        default:
8368            goto cp0_unimplemented;
8369        }
8370        break;
8371    case CP0_REGISTER_05:
8372        switch (sel) {
8373        case 0:
8374            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8375            register_name = "PageMask";
8376            break;
8377        case 1:
8378            check_insn(ctx, ISA_MIPS32R2);
8379            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8380            register_name = "PageGrain";
8381            break;
8382        case 2:
8383            CP0_CHECK(ctx->sc);
8384            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8385            register_name = "SegCtl0";
8386            break;
8387        case 3:
8388            CP0_CHECK(ctx->sc);
8389            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8390            register_name = "SegCtl1";
8391            break;
8392        case 4:
8393            CP0_CHECK(ctx->sc);
8394            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8395            register_name = "SegCtl2";
8396            break;
8397        case 5:
8398            check_pw(ctx);
8399            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8400            register_name = "PWBase";
8401            break;
8402        case 6:
8403            check_pw(ctx);
8404            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8405            register_name = "PWField";
8406            break;
8407        case 7:
8408            check_pw(ctx);
8409            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8410            register_name = "PWSize";
8411            break;
8412        default:
8413            goto cp0_unimplemented;
8414        }
8415        break;
8416    case CP0_REGISTER_06:
8417        switch (sel) {
8418        case 0:
8419            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8420            register_name = "Wired";
8421            break;
8422        case 1:
8423            check_insn(ctx, ISA_MIPS32R2);
8424            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8425            register_name = "SRSConf0";
8426            break;
8427        case 2:
8428            check_insn(ctx, ISA_MIPS32R2);
8429            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8430            register_name = "SRSConf1";
8431            break;
8432        case 3:
8433            check_insn(ctx, ISA_MIPS32R2);
8434            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8435            register_name = "SRSConf2";
8436            break;
8437        case 4:
8438            check_insn(ctx, ISA_MIPS32R2);
8439            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8440            register_name = "SRSConf3";
8441            break;
8442        case 5:
8443            check_insn(ctx, ISA_MIPS32R2);
8444            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8445            register_name = "SRSConf4";
8446            break;
8447        case 6:
8448            check_pw(ctx);
8449            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8450            register_name = "PWCtl";
8451            break;
8452        default:
8453            goto cp0_unimplemented;
8454        }
8455        break;
8456    case CP0_REGISTER_07:
8457        switch (sel) {
8458        case 0:
8459            check_insn(ctx, ISA_MIPS32R2);
8460            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8461            register_name = "HWREna";
8462            break;
8463        default:
8464            goto cp0_unimplemented;
8465        }
8466        break;
8467    case CP0_REGISTER_08:
8468        switch (sel) {
8469        case 0:
8470            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8471            register_name = "BadVAddr";
8472            break;
8473        case 1:
8474            CP0_CHECK(ctx->bi);
8475            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8476            register_name = "BadInstr";
8477            break;
8478        case 2:
8479            CP0_CHECK(ctx->bp);
8480            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8481            register_name = "BadInstrP";
8482            break;
8483        case 3:
8484            CP0_CHECK(ctx->bi);
8485            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8486            tcg_gen_andi_tl(arg, arg, ~0xffff);
8487            register_name = "BadInstrX";
8488            break;
8489        default:
8490            goto cp0_unimplemented;
8491        }
8492        break;
8493    case CP0_REGISTER_09:
8494        switch (sel) {
8495        case 0:
8496            /* Mark as an IO operation because we read the time.  */
8497            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8498                gen_io_start();
8499            }
8500            gen_helper_mfc0_count(arg, cpu_env);
8501            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8502                gen_io_end();
8503            }
8504            /* Break the TB to be able to take timer interrupts immediately
8505               after reading count. DISAS_STOP isn't sufficient, we need to
8506               ensure we break completely out of translated code.  */
8507            gen_save_pc(ctx->base.pc_next + 4);
8508            ctx->base.is_jmp = DISAS_EXIT;
8509            register_name = "Count";
8510            break;
8511        case 6:
8512            CP0_CHECK(ctx->saar);
8513            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8514            register_name = "SAARI";
8515            break;
8516        case 7:
8517            CP0_CHECK(ctx->saar);
8518            gen_helper_dmfc0_saar(arg, cpu_env);
8519            register_name = "SAAR";
8520            break;
8521        default:
8522            goto cp0_unimplemented;
8523        }
8524        break;
8525    case CP0_REGISTER_10:
8526        switch (sel) {
8527        case 0:
8528            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8529            register_name = "EntryHi";
8530            break;
8531        default:
8532            goto cp0_unimplemented;
8533        }
8534        break;
8535    case CP0_REGISTER_11:
8536        switch (sel) {
8537        case 0:
8538            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8539            register_name = "Compare";
8540            break;
8541        /* 6,7 are implementation dependent */
8542        default:
8543            goto cp0_unimplemented;
8544        }
8545        break;
8546    case CP0_REGISTER_12:
8547        switch (sel) {
8548        case 0:
8549            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8550            register_name = "Status";
8551            break;
8552        case 1:
8553            check_insn(ctx, ISA_MIPS32R2);
8554            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8555            register_name = "IntCtl";
8556            break;
8557        case 2:
8558            check_insn(ctx, ISA_MIPS32R2);
8559            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8560            register_name = "SRSCtl";
8561            break;
8562        case 3:
8563            check_insn(ctx, ISA_MIPS32R2);
8564            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8565            register_name = "SRSMap";
8566            break;
8567        default:
8568            goto cp0_unimplemented;
8569        }
8570        break;
8571    case CP0_REGISTER_13:
8572        switch (sel) {
8573        case 0:
8574            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8575            register_name = "Cause";
8576            break;
8577        default:
8578            goto cp0_unimplemented;
8579        }
8580        break;
8581    case CP0_REGISTER_14:
8582        switch (sel) {
8583        case 0:
8584            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8585            register_name = "EPC";
8586            break;
8587        default:
8588            goto cp0_unimplemented;
8589        }
8590        break;
8591    case CP0_REGISTER_15:
8592        switch (sel) {
8593        case 0:
8594            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8595            register_name = "PRid";
8596            break;
8597        case 1:
8598            check_insn(ctx, ISA_MIPS32R2);
8599            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8600            register_name = "EBase";
8601            break;
8602        case 3:
8603            check_insn(ctx, ISA_MIPS32R2);
8604            CP0_CHECK(ctx->cmgcr);
8605            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8606            register_name = "CMGCRBase";
8607            break;
8608        default:
8609            goto cp0_unimplemented;
8610        }
8611        break;
8612    case CP0_REGISTER_16:
8613        switch (sel) {
8614        case 0:
8615            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8616            register_name = "Config";
8617            break;
8618        case 1:
8619            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8620            register_name = "Config1";
8621            break;
8622        case 2:
8623            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8624            register_name = "Config2";
8625            break;
8626        case 3:
8627            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8628            register_name = "Config3";
8629            break;
8630        case 4:
8631            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8632            register_name = "Config4";
8633            break;
8634        case 5:
8635            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8636            register_name = "Config5";
8637            break;
8638       /* 6,7 are implementation dependent */
8639        case 6:
8640            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8641            register_name = "Config6";
8642            break;
8643        case 7:
8644            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8645            register_name = "Config7";
8646            break;
8647        default:
8648            goto cp0_unimplemented;
8649        }
8650        break;
8651    case CP0_REGISTER_17:
8652        switch (sel) {
8653        case 0:
8654            gen_helper_dmfc0_lladdr(arg, cpu_env);
8655            register_name = "LLAddr";
8656            break;
8657        case 1:
8658            CP0_CHECK(ctx->mrp);
8659            gen_helper_dmfc0_maar(arg, cpu_env);
8660            register_name = "MAAR";
8661            break;
8662        case 2:
8663            CP0_CHECK(ctx->mrp);
8664            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8665            register_name = "MAARI";
8666            break;
8667        default:
8668            goto cp0_unimplemented;
8669        }
8670        break;
8671    case CP0_REGISTER_18:
8672        switch (sel) {
8673        case 0:
8674        case 1:
8675        case 2:
8676        case 3:
8677        case 4:
8678        case 5:
8679        case 6:
8680        case 7:
8681            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8682            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8683            register_name = "WatchLo";
8684            break;
8685        default:
8686            goto cp0_unimplemented;
8687        }
8688        break;
8689    case CP0_REGISTER_19:
8690        switch (sel) {
8691        case 0:
8692        case 1:
8693        case 2:
8694        case 3:
8695        case 4:
8696        case 5:
8697        case 6:
8698        case 7:
8699            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8700            gen_helper_1e0i(mfc0_watchhi, arg, sel);
8701            register_name = "WatchHi";
8702            break;
8703        default:
8704            goto cp0_unimplemented;
8705        }
8706        break;
8707    case CP0_REGISTER_20:
8708        switch (sel) {
8709        case 0:
8710            check_insn(ctx, ISA_MIPS3);
8711            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8712            register_name = "XContext";
8713            break;
8714        default:
8715            goto cp0_unimplemented;
8716        }
8717        break;
8718    case CP0_REGISTER_21:
8719       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8720        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8721        switch (sel) {
8722        case 0:
8723            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8724            register_name = "Framemask";
8725            break;
8726        default:
8727            goto cp0_unimplemented;
8728        }
8729        break;
8730    case CP0_REGISTER_22:
8731        tcg_gen_movi_tl(arg, 0); /* unimplemented */
8732        register_name = "'Diagnostic"; /* implementation dependent */
8733        break;
8734    case CP0_REGISTER_23:
8735        switch (sel) {
8736        case 0:
8737            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8738            register_name = "Debug";
8739            break;
8740        case 1:
8741//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8742            register_name = "TraceControl";
8743            goto cp0_unimplemented;
8744        case 2:
8745//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8746            register_name = "TraceControl2";
8747            goto cp0_unimplemented;
8748        case 3:
8749//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8750            register_name = "UserTraceData";
8751            goto cp0_unimplemented;
8752        case 4:
8753//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8754            register_name = "TraceBPC";
8755            goto cp0_unimplemented;
8756        default:
8757            goto cp0_unimplemented;
8758        }
8759        break;
8760    case CP0_REGISTER_24:
8761        switch (sel) {
8762        case 0:
8763            /* EJTAG support */
8764            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8765            register_name = "DEPC";
8766            break;
8767        default:
8768            goto cp0_unimplemented;
8769        }
8770        break;
8771    case CP0_REGISTER_25:
8772        switch (sel) {
8773        case 0:
8774            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8775            register_name = "Performance0";
8776            break;
8777        case 1:
8778//            gen_helper_dmfc0_performance1(arg);
8779            register_name = "Performance1";
8780            goto cp0_unimplemented;
8781        case 2:
8782//            gen_helper_dmfc0_performance2(arg);
8783            register_name = "Performance2";
8784            goto cp0_unimplemented;
8785        case 3:
8786//            gen_helper_dmfc0_performance3(arg);
8787            register_name = "Performance3";
8788            goto cp0_unimplemented;
8789        case 4:
8790//            gen_helper_dmfc0_performance4(arg);
8791            register_name = "Performance4";
8792            goto cp0_unimplemented;
8793        case 5:
8794//            gen_helper_dmfc0_performance5(arg);
8795            register_name = "Performance5";
8796            goto cp0_unimplemented;
8797        case 6:
8798//            gen_helper_dmfc0_performance6(arg);
8799            register_name = "Performance6";
8800            goto cp0_unimplemented;
8801        case 7:
8802//            gen_helper_dmfc0_performance7(arg);
8803            register_name = "Performance7";
8804            goto cp0_unimplemented;
8805        default:
8806            goto cp0_unimplemented;
8807        }
8808        break;
8809    case CP0_REGISTER_26:
8810        switch (sel) {
8811        case 0:
8812            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8813            register_name = "ErrCtl";
8814            break;
8815        default:
8816            goto cp0_unimplemented;
8817        }
8818        break;
8819    case CP0_REGISTER_27:
8820        switch (sel) {
8821        /* ignored */
8822        case 0:
8823        case 1:
8824        case 2:
8825        case 3:
8826            tcg_gen_movi_tl(arg, 0); /* unimplemented */
8827            register_name = "CacheErr";
8828            break;
8829        default:
8830            goto cp0_unimplemented;
8831        }
8832        break;
8833    case CP0_REGISTER_28:
8834        switch (sel) {
8835        case 0:
8836        case 2:
8837        case 4:
8838        case 6:
8839            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8840            register_name = "TagLo";
8841            break;
8842        case 1:
8843        case 3:
8844        case 5:
8845        case 7:
8846            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8847            register_name = "DataLo";
8848            break;
8849        default:
8850            goto cp0_unimplemented;
8851        }
8852        break;
8853    case CP0_REGISTER_29:
8854        switch (sel) {
8855        case 0:
8856        case 2:
8857        case 4:
8858        case 6:
8859            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8860            register_name = "TagHi";
8861            break;
8862        case 1:
8863        case 3:
8864        case 5:
8865        case 7:
8866            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8867            register_name = "DataHi";
8868            break;
8869        default:
8870            goto cp0_unimplemented;
8871        }
8872        break;
8873    case CP0_REGISTER_30:
8874        switch (sel) {
8875        case 0:
8876            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8877            register_name = "ErrorEPC";
8878            break;
8879        default:
8880            goto cp0_unimplemented;
8881        }
8882        break;
8883    case CP0_REGISTER_31:
8884        switch (sel) {
8885        case 0:
8886            /* EJTAG support */
8887            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8888            register_name = "DESAVE";
8889            break;
8890        case 2:
8891        case 3:
8892        case 4:
8893        case 5:
8894        case 6:
8895        case 7:
8896            CP0_CHECK(ctx->kscrexist & (1 << sel));
8897            tcg_gen_ld_tl(arg, cpu_env,
8898                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8899            register_name = "KScratch";
8900            break;
8901        default:
8902            goto cp0_unimplemented;
8903        }
8904        break;
8905    default:
8906        goto cp0_unimplemented;
8907    }
8908    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8909    return;
8910
8911cp0_unimplemented:
8912    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8913                  register_name, reg, sel);
8914    gen_mfc0_unimplemented(ctx, arg);
8915}
8916
8917static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8918{
8919    const char *register_name = "invalid";
8920
8921    if (sel != 0)
8922        check_insn(ctx, ISA_MIPS64);
8923
8924    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8925        gen_io_start();
8926    }
8927
8928    switch (reg) {
8929    case CP0_REGISTER_00:
8930        switch (sel) {
8931        case 0:
8932            gen_helper_mtc0_index(cpu_env, arg);
8933            register_name = "Index";
8934            break;
8935        case 1:
8936            CP0_CHECK(ctx->insn_flags & ASE_MT);
8937            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8938            register_name = "MVPControl";
8939            break;
8940        case 2:
8941            CP0_CHECK(ctx->insn_flags & ASE_MT);
8942            /* ignored */
8943            register_name = "MVPConf0";
8944            break;
8945        case 3:
8946            CP0_CHECK(ctx->insn_flags & ASE_MT);
8947            /* ignored */
8948            register_name = "MVPConf1";
8949            break;
8950        case 4:
8951            CP0_CHECK(ctx->vp);
8952            /* ignored */
8953            register_name = "VPControl";
8954            break;
8955        default:
8956            goto cp0_unimplemented;
8957        }
8958        break;
8959    case CP0_REGISTER_01:
8960        switch (sel) {
8961        case 0:
8962            /* ignored */
8963            register_name = "Random";
8964            break;
8965        case 1:
8966            CP0_CHECK(ctx->insn_flags & ASE_MT);
8967            gen_helper_mtc0_vpecontrol(cpu_env, arg);
8968            register_name = "VPEControl";
8969            break;
8970        case 2:
8971            CP0_CHECK(ctx->insn_flags & ASE_MT);
8972            gen_helper_mtc0_vpeconf0(cpu_env, arg);
8973            register_name = "VPEConf0";
8974            break;
8975        case 3:
8976            CP0_CHECK(ctx->insn_flags & ASE_MT);
8977            gen_helper_mtc0_vpeconf1(cpu_env, arg);
8978            register_name = "VPEConf1";
8979            break;
8980        case 4:
8981            CP0_CHECK(ctx->insn_flags & ASE_MT);
8982            gen_helper_mtc0_yqmask(cpu_env, arg);
8983            register_name = "YQMask";
8984            break;
8985        case 5:
8986            CP0_CHECK(ctx->insn_flags & ASE_MT);
8987            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8988            register_name = "VPESchedule";
8989            break;
8990        case 6:
8991            CP0_CHECK(ctx->insn_flags & ASE_MT);
8992            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8993            register_name = "VPEScheFBack";
8994            break;
8995        case 7:
8996            CP0_CHECK(ctx->insn_flags & ASE_MT);
8997            gen_helper_mtc0_vpeopt(cpu_env, arg);
8998            register_name = "VPEOpt";
8999            break;
9000        default:
9001            goto cp0_unimplemented;
9002        }
9003        break;
9004    case CP0_REGISTER_02:
9005        switch (sel) {
9006        case 0:
9007            gen_helper_dmtc0_entrylo0(cpu_env, arg);
9008            register_name = "EntryLo0";
9009            break;
9010        case 1:
9011            CP0_CHECK(ctx->insn_flags & ASE_MT);
9012            gen_helper_mtc0_tcstatus(cpu_env, arg);
9013            register_name = "TCStatus";
9014            break;
9015        case 2:
9016            CP0_CHECK(ctx->insn_flags & ASE_MT);
9017            gen_helper_mtc0_tcbind(cpu_env, arg);
9018            register_name = "TCBind";
9019            break;
9020        case 3:
9021            CP0_CHECK(ctx->insn_flags & ASE_MT);
9022            gen_helper_mtc0_tcrestart(cpu_env, arg);
9023            register_name = "TCRestart";
9024            break;
9025        case 4:
9026            CP0_CHECK(ctx->insn_flags & ASE_MT);
9027            gen_helper_mtc0_tchalt(cpu_env, arg);
9028            register_name = "TCHalt";
9029            break;
9030        case 5:
9031            CP0_CHECK(ctx->insn_flags & ASE_MT);
9032            gen_helper_mtc0_tccontext(cpu_env, arg);
9033            register_name = "TCContext";
9034            break;
9035        case 6:
9036            CP0_CHECK(ctx->insn_flags & ASE_MT);
9037            gen_helper_mtc0_tcschedule(cpu_env, arg);
9038            register_name = "TCSchedule";
9039            break;
9040        case 7:
9041            CP0_CHECK(ctx->insn_flags & ASE_MT);
9042            gen_helper_mtc0_tcschefback(cpu_env, arg);
9043            register_name = "TCScheFBack";
9044            break;
9045        default:
9046            goto cp0_unimplemented;
9047        }
9048        break;
9049    case CP0_REGISTER_03:
9050        switch (sel) {
9051        case 0:
9052            gen_helper_dmtc0_entrylo1(cpu_env, arg);
9053            register_name = "EntryLo1";
9054            break;
9055        case 1:
9056            CP0_CHECK(ctx->vp);
9057            /* ignored */
9058            register_name = "GlobalNumber";
9059            break;
9060        default:
9061            goto cp0_unimplemented;
9062        }
9063        break;
9064    case CP0_REGISTER_04:
9065        switch (sel) {
9066        case 0:
9067            gen_helper_mtc0_context(cpu_env, arg);
9068            register_name = "Context";
9069            break;
9070        case 1:
9071//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9072            register_name = "ContextConfig";
9073            goto cp0_unimplemented;
9074        case 2:
9075            CP0_CHECK(ctx->ulri);
9076            tcg_gen_st_tl(arg, cpu_env,
9077                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9078            register_name = "UserLocal";
9079            break;
9080        default:
9081            goto cp0_unimplemented;
9082        }
9083        break;
9084    case CP0_REGISTER_05:
9085        switch (sel) {
9086        case 0:
9087            gen_helper_mtc0_pagemask(cpu_env, arg);
9088            register_name = "PageMask";
9089            break;
9090        case 1:
9091            check_insn(ctx, ISA_MIPS32R2);
9092            gen_helper_mtc0_pagegrain(cpu_env, arg);
9093            register_name = "PageGrain";
9094            break;
9095        case 2:
9096            CP0_CHECK(ctx->sc);
9097            gen_helper_mtc0_segctl0(cpu_env, arg);
9098            register_name = "SegCtl0";
9099            break;
9100        case 3:
9101            CP0_CHECK(ctx->sc);
9102            gen_helper_mtc0_segctl1(cpu_env, arg);
9103            register_name = "SegCtl1";
9104            break;
9105        case 4:
9106            CP0_CHECK(ctx->sc);
9107            gen_helper_mtc0_segctl2(cpu_env, arg);
9108            register_name = "SegCtl2";
9109            break;
9110        case 5:
9111            check_pw(ctx);
9112            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9113            register_name = "PWBase";
9114            break;
9115        case 6:
9116            check_pw(ctx);
9117            gen_helper_mtc0_pwfield(cpu_env, arg);
9118            register_name = "PWField";
9119            break;
9120        case 7:
9121            check_pw(ctx);
9122            gen_helper_mtc0_pwsize(cpu_env, arg);
9123            register_name = "PWSize";
9124            break;
9125        default:
9126            goto cp0_unimplemented;
9127        }
9128        break;
9129    case CP0_REGISTER_06:
9130        switch (sel) {
9131        case 0:
9132            gen_helper_mtc0_wired(cpu_env, arg);
9133            register_name = "Wired";
9134            break;
9135        case 1:
9136            check_insn(ctx, ISA_MIPS32R2);
9137            gen_helper_mtc0_srsconf0(cpu_env, arg);
9138            register_name = "SRSConf0";
9139            break;
9140        case 2:
9141            check_insn(ctx, ISA_MIPS32R2);
9142            gen_helper_mtc0_srsconf1(cpu_env, arg);
9143            register_name = "SRSConf1";
9144            break;
9145        case 3:
9146            check_insn(ctx, ISA_MIPS32R2);
9147            gen_helper_mtc0_srsconf2(cpu_env, arg);
9148            register_name = "SRSConf2";
9149            break;
9150        case 4:
9151            check_insn(ctx, ISA_MIPS32R2);
9152            gen_helper_mtc0_srsconf3(cpu_env, arg);
9153            register_name = "SRSConf3";
9154            break;
9155        case 5:
9156            check_insn(ctx, ISA_MIPS32R2);
9157            gen_helper_mtc0_srsconf4(cpu_env, arg);
9158            register_name = "SRSConf4";
9159            break;
9160        case 6:
9161            check_pw(ctx);
9162            gen_helper_mtc0_pwctl(cpu_env, arg);
9163            register_name = "PWCtl";
9164            break;
9165        default:
9166            goto cp0_unimplemented;
9167        }
9168        break;
9169    case CP0_REGISTER_07:
9170        switch (sel) {
9171        case 0:
9172            check_insn(ctx, ISA_MIPS32R2);
9173            gen_helper_mtc0_hwrena(cpu_env, arg);
9174            ctx->base.is_jmp = DISAS_STOP;
9175            register_name = "HWREna";
9176            break;
9177        default:
9178            goto cp0_unimplemented;
9179        }
9180        break;
9181    case CP0_REGISTER_08:
9182        switch (sel) {
9183        case 0:
9184            /* ignored */
9185            register_name = "BadVAddr";
9186            break;
9187        case 1:
9188            /* ignored */
9189            register_name = "BadInstr";
9190            break;
9191        case 2:
9192            /* ignored */
9193            register_name = "BadInstrP";
9194            break;
9195        case 3:
9196            /* ignored */
9197            register_name = "BadInstrX";
9198            break;
9199        default:
9200            goto cp0_unimplemented;
9201        }
9202        break;
9203    case CP0_REGISTER_09:
9204        switch (sel) {
9205        case 0:
9206            gen_helper_mtc0_count(cpu_env, arg);
9207            register_name = "Count";
9208            break;
9209        case 6:
9210            CP0_CHECK(ctx->saar);
9211            gen_helper_mtc0_saari(cpu_env, arg);
9212            register_name = "SAARI";
9213            break;
9214        case 7:
9215            CP0_CHECK(ctx->saar);
9216            gen_helper_mtc0_saar(cpu_env, arg);
9217            register_name = "SAAR";
9218            break;
9219        default:
9220            goto cp0_unimplemented;
9221        }
9222        /* Stop translation as we may have switched the execution mode */
9223        ctx->base.is_jmp = DISAS_STOP;
9224        break;
9225    case CP0_REGISTER_10:
9226        switch (sel) {
9227        case 0:
9228            gen_helper_mtc0_entryhi(cpu_env, arg);
9229            register_name = "EntryHi";
9230            break;
9231        default:
9232            goto cp0_unimplemented;
9233        }
9234        break;
9235    case CP0_REGISTER_11:
9236        switch (sel) {
9237        case 0:
9238            gen_helper_mtc0_compare(cpu_env, arg);
9239            register_name = "Compare";
9240            break;
9241        /* 6,7 are implementation dependent */
9242        default:
9243            goto cp0_unimplemented;
9244        }
9245        /* Stop translation as we may have switched the execution mode */
9246        ctx->base.is_jmp = DISAS_STOP;
9247        break;
9248    case CP0_REGISTER_12:
9249        switch (sel) {
9250        case 0:
9251            save_cpu_state(ctx, 1);
9252            gen_helper_mtc0_status(cpu_env, arg);
9253            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9254            gen_save_pc(ctx->base.pc_next + 4);
9255            ctx->base.is_jmp = DISAS_EXIT;
9256            register_name = "Status";
9257            break;
9258        case 1:
9259            check_insn(ctx, ISA_MIPS32R2);
9260            gen_helper_mtc0_intctl(cpu_env, arg);
9261            /* Stop translation as we may have switched the execution mode */
9262            ctx->base.is_jmp = DISAS_STOP;
9263            register_name = "IntCtl";
9264            break;
9265        case 2:
9266            check_insn(ctx, ISA_MIPS32R2);
9267            gen_helper_mtc0_srsctl(cpu_env, arg);
9268            /* Stop translation as we may have switched the execution mode */
9269            ctx->base.is_jmp = DISAS_STOP;
9270            register_name = "SRSCtl";
9271            break;
9272        case 3:
9273            check_insn(ctx, ISA_MIPS32R2);
9274            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9275            /* Stop translation as we may have switched the execution mode */
9276            ctx->base.is_jmp = DISAS_STOP;
9277            register_name = "SRSMap";
9278            break;
9279        default:
9280            goto cp0_unimplemented;
9281        }
9282        break;
9283    case CP0_REGISTER_13:
9284        switch (sel) {
9285        case 0:
9286            save_cpu_state(ctx, 1);
9287            gen_helper_mtc0_cause(cpu_env, arg);
9288            /* Stop translation as we may have triggered an interrupt.
9289             * DISAS_STOP isn't sufficient, we need to ensure we break out of
9290             * translated code to check for pending interrupts.  */
9291            gen_save_pc(ctx->base.pc_next + 4);
9292            ctx->base.is_jmp = DISAS_EXIT;
9293            register_name = "Cause";
9294            break;
9295        default:
9296            goto cp0_unimplemented;
9297        }
9298        break;
9299    case CP0_REGISTER_14:
9300        switch (sel) {
9301        case 0:
9302            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9303            register_name = "EPC";
9304            break;
9305        default:
9306            goto cp0_unimplemented;
9307        }
9308        break;
9309    case CP0_REGISTER_15:
9310        switch (sel) {
9311        case 0:
9312            /* ignored */
9313            register_name = "PRid";
9314            break;
9315        case 1:
9316            check_insn(ctx, ISA_MIPS32R2);
9317            gen_helper_mtc0_ebase(cpu_env, arg);
9318            register_name = "EBase";
9319            break;
9320        default:
9321            goto cp0_unimplemented;
9322        }
9323        break;
9324    case CP0_REGISTER_16:
9325        switch (sel) {
9326        case 0:
9327            gen_helper_mtc0_config0(cpu_env, arg);
9328            register_name = "Config";
9329            /* Stop translation as we may have switched the execution mode */
9330            ctx->base.is_jmp = DISAS_STOP;
9331            break;
9332        case 1:
9333            /* ignored, read only */
9334            register_name = "Config1";
9335            break;
9336        case 2:
9337            gen_helper_mtc0_config2(cpu_env, arg);
9338            register_name = "Config2";
9339            /* Stop translation as we may have switched the execution mode */
9340            ctx->base.is_jmp = DISAS_STOP;
9341            break;
9342        case 3:
9343            gen_helper_mtc0_config3(cpu_env, arg);
9344            register_name = "Config3";
9345            /* Stop translation as we may have switched the execution mode */
9346            ctx->base.is_jmp = DISAS_STOP;
9347            break;
9348        case 4:
9349            /* currently ignored */
9350            register_name = "Config4";
9351            break;
9352        case 5:
9353            gen_helper_mtc0_config5(cpu_env, arg);
9354            register_name = "Config5";
9355            /* Stop translation as we may have switched the execution mode */
9356            ctx->base.is_jmp = DISAS_STOP;
9357            break;
9358        /* 6,7 are implementation dependent */
9359        default:
9360            register_name = "Invalid config selector";
9361            goto cp0_unimplemented;
9362        }
9363        break;
9364    case CP0_REGISTER_17:
9365        switch (sel) {
9366        case 0:
9367            gen_helper_mtc0_lladdr(cpu_env, arg);
9368            register_name = "LLAddr";
9369            break;
9370        case 1:
9371            CP0_CHECK(ctx->mrp);
9372            gen_helper_mtc0_maar(cpu_env, arg);
9373            register_name = "MAAR";
9374            break;
9375        case 2:
9376            CP0_CHECK(ctx->mrp);
9377            gen_helper_mtc0_maari(cpu_env, arg);
9378            register_name = "MAARI";
9379            break;
9380        default:
9381            goto cp0_unimplemented;
9382        }
9383        break;
9384    case CP0_REGISTER_18:
9385        switch (sel) {
9386        case 0:
9387        case 1:
9388        case 2:
9389        case 3:
9390        case 4:
9391        case 5:
9392        case 6:
9393        case 7:
9394            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9395            gen_helper_0e1i(mtc0_watchlo, arg, sel);
9396            register_name = "WatchLo";
9397            break;
9398        default:
9399            goto cp0_unimplemented;
9400        }
9401        break;
9402    case CP0_REGISTER_19:
9403        switch (sel) {
9404        case 0:
9405        case 1:
9406        case 2:
9407        case 3:
9408        case 4:
9409        case 5:
9410        case 6:
9411        case 7:
9412            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9413            gen_helper_0e1i(mtc0_watchhi, arg, sel);
9414            register_name = "WatchHi";
9415            break;
9416        default:
9417            goto cp0_unimplemented;
9418        }
9419        break;
9420    case CP0_REGISTER_20:
9421        switch (sel) {
9422        case 0:
9423            check_insn(ctx, ISA_MIPS3);
9424            gen_helper_mtc0_xcontext(cpu_env, arg);
9425            register_name = "XContext";
9426            break;
9427        default:
9428            goto cp0_unimplemented;
9429        }
9430        break;
9431    case CP0_REGISTER_21:
9432       /* Officially reserved, but sel 0 is used for R1x000 framemask */
9433        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9434        switch (sel) {
9435        case 0:
9436            gen_helper_mtc0_framemask(cpu_env, arg);
9437            register_name = "Framemask";
9438            break;
9439        default:
9440            goto cp0_unimplemented;
9441        }
9442        break;
9443    case CP0_REGISTER_22:
9444        /* ignored */
9445        register_name = "Diagnostic"; /* implementation dependent */
9446        break;
9447    case CP0_REGISTER_23:
9448        switch (sel) {
9449        case 0:
9450            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9451            /* DISAS_STOP isn't good enough here, hflags may have changed. */
9452            gen_save_pc(ctx->base.pc_next + 4);
9453            ctx->base.is_jmp = DISAS_EXIT;
9454            register_name = "Debug";
9455            break;
9456        case 1:
9457//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9458            /* Stop translation as we may have switched the execution mode */
9459            ctx->base.is_jmp = DISAS_STOP;
9460            register_name = "TraceControl";
9461            goto cp0_unimplemented;
9462        case 2:
9463//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9464            /* Stop translation as we may have switched the execution mode */
9465            ctx->base.is_jmp = DISAS_STOP;
9466            register_name = "TraceControl2";
9467            goto cp0_unimplemented;
9468        case 3:
9469//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9470            /* Stop translation as we may have switched the execution mode */
9471            ctx->base.is_jmp = DISAS_STOP;
9472            register_name = "UserTraceData";
9473            goto cp0_unimplemented;
9474        case 4:
9475//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9476            /* Stop translation as we may have switched the execution mode */
9477            ctx->base.is_jmp = DISAS_STOP;
9478            register_name = "TraceBPC";
9479            goto cp0_unimplemented;
9480        default:
9481            goto cp0_unimplemented;
9482        }
9483        break;
9484    case CP0_REGISTER_24:
9485        switch (sel) {
9486        case 0:
9487            /* EJTAG support */
9488            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9489            register_name = "DEPC";
9490            break;
9491        default:
9492            goto cp0_unimplemented;
9493        }
9494        break;
9495    case CP0_REGISTER_25:
9496        switch (sel) {
9497        case 0:
9498            gen_helper_mtc0_performance0(cpu_env, arg);
9499            register_name = "Performance0";
9500            break;
9501        case 1:
9502//            gen_helper_mtc0_performance1(cpu_env, arg);
9503            register_name = "Performance1";
9504            goto cp0_unimplemented;
9505        case 2:
9506//            gen_helper_mtc0_performance2(cpu_env, arg);
9507            register_name = "Performance2";
9508            goto cp0_unimplemented;
9509        case 3:
9510//            gen_helper_mtc0_performance3(cpu_env, arg);
9511            register_name = "Performance3";
9512            goto cp0_unimplemented;
9513        case 4:
9514//            gen_helper_mtc0_performance4(cpu_env, arg);
9515            register_name = "Performance4";
9516            goto cp0_unimplemented;
9517        case 5:
9518//            gen_helper_mtc0_performance5(cpu_env, arg);
9519            register_name = "Performance5";
9520            goto cp0_unimplemented;
9521        case 6:
9522//            gen_helper_mtc0_performance6(cpu_env, arg);
9523            register_name = "Performance6";
9524            goto cp0_unimplemented;
9525        case 7:
9526//            gen_helper_mtc0_performance7(cpu_env, arg);
9527            register_name = "Performance7";
9528            goto cp0_unimplemented;
9529        default:
9530            goto cp0_unimplemented;
9531        }
9532        break;
9533    case CP0_REGISTER_26:
9534        switch (sel) {
9535        case 0:
9536            gen_helper_mtc0_errctl(cpu_env, arg);
9537            ctx->base.is_jmp = DISAS_STOP;
9538            register_name = "ErrCtl";
9539            break;
9540        default:
9541            goto cp0_unimplemented;
9542        }
9543        break;
9544    case CP0_REGISTER_27:
9545        switch (sel) {
9546        case 0:
9547        case 1:
9548        case 2:
9549        case 3:
9550            /* ignored */
9551            register_name = "CacheErr";
9552            break;
9553        default:
9554            goto cp0_unimplemented;
9555        }
9556        break;
9557    case CP0_REGISTER_28:
9558        switch (sel) {
9559        case 0:
9560        case 2:
9561        case 4:
9562        case 6:
9563            gen_helper_mtc0_taglo(cpu_env, arg);
9564            register_name = "TagLo";
9565            break;
9566        case 1:
9567        case 3:
9568        case 5:
9569        case 7:
9570            gen_helper_mtc0_datalo(cpu_env, arg);
9571            register_name = "DataLo";
9572            break;
9573        default:
9574            goto cp0_unimplemented;
9575        }
9576        break;
9577    case CP0_REGISTER_29:
9578        switch (sel) {
9579        case 0:
9580        case 2:
9581        case 4:
9582        case 6:
9583            gen_helper_mtc0_taghi(cpu_env, arg);
9584            register_name = "TagHi";
9585            break;
9586        case 1:
9587        case 3:
9588        case 5:
9589        case 7:
9590            gen_helper_mtc0_datahi(cpu_env, arg);
9591            register_name = "DataHi";
9592            break;
9593        default:
9594            register_name = "invalid sel";
9595            goto cp0_unimplemented;
9596        }
9597        break;
9598    case CP0_REGISTER_30:
9599        switch (sel) {
9600        case 0:
9601            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9602            register_name = "ErrorEPC";
9603            break;
9604        default:
9605            goto cp0_unimplemented;
9606        }
9607        break;
9608    case CP0_REGISTER_31:
9609        switch (sel) {
9610        case 0:
9611            /* EJTAG support */
9612            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9613            register_name = "DESAVE";
9614            break;
9615        case 2:
9616        case 3:
9617        case 4:
9618        case 5:
9619        case 6:
9620        case 7:
9621            CP0_CHECK(ctx->kscrexist & (1 << sel));
9622            tcg_gen_st_tl(arg, cpu_env,
9623                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9624            register_name = "KScratch";
9625            break;
9626        default:
9627            goto cp0_unimplemented;
9628        }
9629        break;
9630    default:
9631        goto cp0_unimplemented;
9632    }
9633    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9634
9635    /* For simplicity assume that all writes can cause interrupts.  */
9636    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9637        gen_io_end();
9638        /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9639         * translated code to check for pending interrupts.  */
9640        gen_save_pc(ctx->base.pc_next + 4);
9641        ctx->base.is_jmp = DISAS_EXIT;
9642    }
9643    return;
9644
9645cp0_unimplemented:
9646    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9647                  register_name, reg, sel);
9648}
9649#endif /* TARGET_MIPS64 */
9650
9651static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9652                     int u, int sel, int h)
9653{
9654    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9655    TCGv t0 = tcg_temp_local_new();
9656
9657    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9658        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9659         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9660        tcg_gen_movi_tl(t0, -1);
9661    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9662             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9663        tcg_gen_movi_tl(t0, -1);
9664    else if (u == 0) {
9665        switch (rt) {
9666        case 1:
9667            switch (sel) {
9668            case 1:
9669                gen_helper_mftc0_vpecontrol(t0, cpu_env);
9670                break;
9671            case 2:
9672                gen_helper_mftc0_vpeconf0(t0, cpu_env);
9673                break;
9674            default:
9675                goto die;
9676                break;
9677            }
9678            break;
9679        case 2:
9680            switch (sel) {
9681            case 1:
9682                gen_helper_mftc0_tcstatus(t0, cpu_env);
9683                break;
9684            case 2:
9685                gen_helper_mftc0_tcbind(t0, cpu_env);
9686                break;
9687            case 3:
9688                gen_helper_mftc0_tcrestart(t0, cpu_env);
9689                break;
9690            case 4:
9691                gen_helper_mftc0_tchalt(t0, cpu_env);
9692                break;
9693            case 5:
9694                gen_helper_mftc0_tccontext(t0, cpu_env);
9695                break;
9696            case 6:
9697                gen_helper_mftc0_tcschedule(t0, cpu_env);
9698                break;
9699            case 7:
9700                gen_helper_mftc0_tcschefback(t0, cpu_env);
9701                break;
9702            default:
9703                gen_mfc0(ctx, t0, rt, sel);
9704                break;
9705            }
9706            break;
9707        case 10:
9708            switch (sel) {
9709            case 0:
9710                gen_helper_mftc0_entryhi(t0, cpu_env);
9711                break;
9712            default:
9713                gen_mfc0(ctx, t0, rt, sel);
9714                break;
9715            }
9716        case 12:
9717            switch (sel) {
9718            case 0:
9719                gen_helper_mftc0_status(t0, cpu_env);
9720                break;
9721            default:
9722                gen_mfc0(ctx, t0, rt, sel);
9723                break;
9724            }
9725        case 13:
9726            switch (sel) {
9727            case 0:
9728                gen_helper_mftc0_cause(t0, cpu_env);
9729                break;
9730            default:
9731                goto die;
9732                break;
9733            }
9734            break;
9735        case 14:
9736            switch (sel) {
9737            case 0:
9738                gen_helper_mftc0_epc(t0, cpu_env);
9739                break;
9740            default:
9741                goto die;
9742                break;
9743            }
9744            break;
9745        case 15:
9746            switch (sel) {
9747            case 1:
9748                gen_helper_mftc0_ebase(t0, cpu_env);
9749                break;
9750            default:
9751                goto die;
9752                break;
9753            }
9754            break;
9755        case 16:
9756            switch (sel) {
9757            case 0:
9758            case 1:
9759            case 2:
9760            case 3:
9761            case 4:
9762            case 5:
9763            case 6:
9764            case 7:
9765                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9766                break;
9767            default:
9768                goto die;
9769                break;
9770            }
9771            break;
9772        case 23:
9773            switch (sel) {
9774            case 0:
9775                gen_helper_mftc0_debug(t0, cpu_env);
9776                break;
9777            default:
9778                gen_mfc0(ctx, t0, rt, sel);
9779                break;
9780            }
9781            break;
9782        default:
9783            gen_mfc0(ctx, t0, rt, sel);
9784        }
9785    } else switch (sel) {
9786    /* GPR registers. */
9787    case 0:
9788        gen_helper_1e0i(mftgpr, t0, rt);
9789        break;
9790    /* Auxiliary CPU registers */
9791    case 1:
9792        switch (rt) {
9793        case 0:
9794            gen_helper_1e0i(mftlo, t0, 0);
9795            break;
9796        case 1:
9797            gen_helper_1e0i(mfthi, t0, 0);
9798            break;
9799        case 2:
9800            gen_helper_1e0i(mftacx, t0, 0);
9801            break;
9802        case 4:
9803            gen_helper_1e0i(mftlo, t0, 1);
9804            break;
9805        case 5:
9806            gen_helper_1e0i(mfthi, t0, 1);
9807            break;
9808        case 6:
9809            gen_helper_1e0i(mftacx, t0, 1);
9810            break;
9811        case 8:
9812            gen_helper_1e0i(mftlo, t0, 2);
9813            break;
9814        case 9:
9815            gen_helper_1e0i(mfthi, t0, 2);
9816            break;
9817        case 10:
9818            gen_helper_1e0i(mftacx, t0, 2);
9819            break;
9820        case 12:
9821            gen_helper_1e0i(mftlo, t0, 3);
9822            break;
9823        case 13:
9824            gen_helper_1e0i(mfthi, t0, 3);
9825            break;
9826        case 14:
9827            gen_helper_1e0i(mftacx, t0, 3);
9828            break;
9829        case 16:
9830            gen_helper_mftdsp(t0, cpu_env);
9831            break;
9832        default:
9833            goto die;
9834        }
9835        break;
9836    /* Floating point (COP1). */
9837    case 2:
9838        /* XXX: For now we support only a single FPU context. */
9839        if (h == 0) {
9840            TCGv_i32 fp0 = tcg_temp_new_i32();
9841
9842            gen_load_fpr32(ctx, fp0, rt);
9843            tcg_gen_ext_i32_tl(t0, fp0);
9844            tcg_temp_free_i32(fp0);
9845        } else {
9846            TCGv_i32 fp0 = tcg_temp_new_i32();
9847
9848            gen_load_fpr32h(ctx, fp0, rt);
9849            tcg_gen_ext_i32_tl(t0, fp0);
9850            tcg_temp_free_i32(fp0);
9851        }
9852        break;
9853    case 3:
9854        /* XXX: For now we support only a single FPU context. */
9855        gen_helper_1e0i(cfc1, t0, rt);
9856        break;
9857    /* COP2: Not implemented. */
9858    case 4:
9859    case 5:
9860        /* fall through */
9861    default:
9862        goto die;
9863    }
9864    trace_mips_translate_tr("mftr", rt, u, sel, h);
9865    gen_store_gpr(t0, rd);
9866    tcg_temp_free(t0);
9867    return;
9868
9869die:
9870    tcg_temp_free(t0);
9871    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9872    generate_exception_end(ctx, EXCP_RI);
9873}
9874
9875static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9876                     int u, int sel, int h)
9877{
9878    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9879    TCGv t0 = tcg_temp_local_new();
9880
9881    gen_load_gpr(t0, rt);
9882    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9883        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9884         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9885        /* NOP */ ;
9886    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9887             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9888        /* NOP */ ;
9889    else if (u == 0) {
9890        switch (rd) {
9891        case 1:
9892            switch (sel) {
9893            case 1:
9894                gen_helper_mttc0_vpecontrol(cpu_env, t0);
9895                break;
9896            case 2:
9897                gen_helper_mttc0_vpeconf0(cpu_env, t0);
9898                break;
9899            default:
9900                goto die;
9901                break;
9902            }
9903            break;
9904        case 2:
9905            switch (sel) {
9906            case 1:
9907                gen_helper_mttc0_tcstatus(cpu_env, t0);
9908                break;
9909            case 2:
9910                gen_helper_mttc0_tcbind(cpu_env, t0);
9911                break;
9912            case 3:
9913                gen_helper_mttc0_tcrestart(cpu_env, t0);
9914                break;
9915            case 4:
9916                gen_helper_mttc0_tchalt(cpu_env, t0);
9917                break;
9918            case 5:
9919                gen_helper_mttc0_tccontext(cpu_env, t0);
9920                break;
9921            case 6:
9922                gen_helper_mttc0_tcschedule(cpu_env, t0);
9923                break;
9924            case 7:
9925                gen_helper_mttc0_tcschefback(cpu_env, t0);
9926                break;
9927            default:
9928                gen_mtc0(ctx, t0, rd, sel);
9929                break;
9930            }
9931            break;
9932        case 10:
9933            switch (sel) {
9934            case 0:
9935                gen_helper_mttc0_entryhi(cpu_env, t0);
9936                break;
9937            default:
9938                gen_mtc0(ctx, t0, rd, sel);
9939                break;
9940            }
9941        case 12:
9942            switch (sel) {
9943            case 0:
9944                gen_helper_mttc0_status(cpu_env, t0);
9945                break;
9946            default:
9947                gen_mtc0(ctx, t0, rd, sel);
9948                break;
9949            }
9950        case 13:
9951            switch (sel) {
9952            case 0:
9953                gen_helper_mttc0_cause(cpu_env, t0);
9954                break;
9955            default:
9956                goto die;
9957                break;
9958            }
9959            break;
9960        case 15:
9961            switch (sel) {
9962            case 1:
9963                gen_helper_mttc0_ebase(cpu_env, t0);
9964                break;
9965            default:
9966                goto die;
9967                break;
9968            }
9969            break;
9970        case 23:
9971            switch (sel) {
9972            case 0:
9973                gen_helper_mttc0_debug(cpu_env, t0);
9974                break;
9975            default:
9976                gen_mtc0(ctx, t0, rd, sel);
9977                break;
9978            }
9979            break;
9980        default:
9981            gen_mtc0(ctx, t0, rd, sel);
9982        }
9983    } else switch (sel) {
9984    /* GPR registers. */
9985    case 0:
9986        gen_helper_0e1i(mttgpr, t0, rd);
9987        break;
9988    /* Auxiliary CPU registers */
9989    case 1:
9990        switch (rd) {
9991        case 0:
9992            gen_helper_0e1i(mttlo, t0, 0);
9993            break;
9994        case 1:
9995            gen_helper_0e1i(mtthi, t0, 0);
9996            break;
9997        case 2:
9998            gen_helper_0e1i(mttacx, t0, 0);
9999            break;
10000        case 4:
10001            gen_helper_0e1i(mttlo, t0, 1);
10002            break;
10003        case 5:
10004            gen_helper_0e1i(mtthi, t0, 1);
10005            break;
10006        case 6:
10007            gen_helper_0e1i(mttacx, t0, 1);
10008            break;
10009        case 8:
10010            gen_helper_0e1i(mttlo, t0, 2);
10011            break;
10012        case 9:
10013            gen_helper_0e1i(mtthi, t0, 2);
10014            break;
10015        case 10:
10016            gen_helper_0e1i(mttacx, t0, 2);
10017            break;
10018        case 12:
10019            gen_helper_0e1i(mttlo, t0, 3);
10020            break;
10021        case 13:
10022            gen_helper_0e1i(mtthi, t0, 3);
10023            break;
10024        case 14:
10025            gen_helper_0e1i(mttacx, t0, 3);
10026            break;
10027        case 16:
10028            gen_helper_mttdsp(cpu_env, t0);
10029            break;
10030        default:
10031            goto die;
10032        }
10033        break;
10034    /* Floating point (COP1). */
10035    case 2:
10036        /* XXX: For now we support only a single FPU context. */
10037        if (h == 0) {
10038            TCGv_i32 fp0 = tcg_temp_new_i32();
10039
10040            tcg_gen_trunc_tl_i32(fp0, t0);
10041            gen_store_fpr32(ctx, fp0, rd);
10042            tcg_temp_free_i32(fp0);
10043        } else {
10044            TCGv_i32 fp0 = tcg_temp_new_i32();
10045
10046            tcg_gen_trunc_tl_i32(fp0, t0);
10047            gen_store_fpr32h(ctx, fp0, rd);
10048            tcg_temp_free_i32(fp0);
10049        }
10050        break;
10051    case 3:
10052        /* XXX: For now we support only a single FPU context. */
10053        {
10054            TCGv_i32 fs_tmp = tcg_const_i32(rd);
10055
10056            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10057            tcg_temp_free_i32(fs_tmp);
10058        }
10059        /* Stop translation as we may have changed hflags */
10060        ctx->base.is_jmp = DISAS_STOP;
10061        break;
10062    /* COP2: Not implemented. */
10063    case 4:
10064    case 5:
10065        /* fall through */
10066    default:
10067        goto die;
10068    }
10069    trace_mips_translate_tr("mttr", rd, u, sel, h);
10070    tcg_temp_free(t0);
10071    return;
10072
10073die:
10074    tcg_temp_free(t0);
10075    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10076    generate_exception_end(ctx, EXCP_RI);
10077}
10078
10079static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10080{
10081    const char *opn = "ldst";
10082
10083    check_cp0_enabled(ctx);
10084    switch (opc) {
10085    case OPC_MFC0:
10086        if (rt == 0) {
10087            /* Treat as NOP. */
10088            return;
10089        }
10090        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10091        opn = "mfc0";
10092        break;
10093    case OPC_MTC0:
10094        {
10095            TCGv t0 = tcg_temp_new();
10096
10097            gen_load_gpr(t0, rt);
10098            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10099            tcg_temp_free(t0);
10100        }
10101        opn = "mtc0";
10102        break;
10103#if defined(TARGET_MIPS64)
10104    case OPC_DMFC0:
10105        check_insn(ctx, ISA_MIPS3);
10106        if (rt == 0) {
10107            /* Treat as NOP. */
10108            return;
10109        }
10110        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10111        opn = "dmfc0";
10112        break;
10113    case OPC_DMTC0:
10114        check_insn(ctx, ISA_MIPS3);
10115        {
10116            TCGv t0 = tcg_temp_new();
10117
10118            gen_load_gpr(t0, rt);
10119            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10120            tcg_temp_free(t0);
10121        }
10122        opn = "dmtc0";
10123        break;
10124#endif
10125    case OPC_MFHC0:
10126        check_mvh(ctx);
10127        if (rt == 0) {
10128            /* Treat as NOP. */
10129            return;
10130        }
10131        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10132        opn = "mfhc0";
10133        break;
10134    case OPC_MTHC0:
10135        check_mvh(ctx);
10136        {
10137            TCGv t0 = tcg_temp_new();
10138            gen_load_gpr(t0, rt);
10139            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10140            tcg_temp_free(t0);
10141        }
10142        opn = "mthc0";
10143        break;
10144    case OPC_MFTR:
10145        check_cp0_enabled(ctx);
10146        if (rd == 0) {
10147            /* Treat as NOP. */
10148            return;
10149        }
10150        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10151                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10152        opn = "mftr";
10153        break;
10154    case OPC_MTTR:
10155        check_cp0_enabled(ctx);
10156        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10157                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10158        opn = "mttr";
10159        break;
10160    case OPC_TLBWI:
10161        opn = "tlbwi";
10162        if (!env->tlb->helper_tlbwi)
10163            goto die;
10164        gen_helper_tlbwi(cpu_env);
10165        break;
10166    case OPC_TLBINV:
10167        opn = "tlbinv";
10168        if (ctx->ie >= 2) {
10169            if (!env->tlb->helper_tlbinv) {
10170                goto die;
10171            }
10172            gen_helper_tlbinv(cpu_env);
10173        } /* treat as nop if TLBINV not supported */
10174        break;
10175    case OPC_TLBINVF:
10176        opn = "tlbinvf";
10177        if (ctx->ie >= 2) {
10178            if (!env->tlb->helper_tlbinvf) {
10179                goto die;
10180            }
10181            gen_helper_tlbinvf(cpu_env);
10182        } /* treat as nop if TLBINV not supported */
10183        break;
10184    case OPC_TLBWR:
10185        opn = "tlbwr";
10186        if (!env->tlb->helper_tlbwr)
10187            goto die;
10188        gen_helper_tlbwr(cpu_env);
10189        break;
10190    case OPC_TLBP:
10191        opn = "tlbp";
10192        if (!env->tlb->helper_tlbp)
10193            goto die;
10194        gen_helper_tlbp(cpu_env);
10195        break;
10196    case OPC_TLBR:
10197        opn = "tlbr";
10198        if (!env->tlb->helper_tlbr)
10199            goto die;
10200        gen_helper_tlbr(cpu_env);
10201        break;
10202    case OPC_ERET: /* OPC_ERETNC */
10203        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10204            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10205            goto die;
10206        } else {
10207            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10208            if (ctx->opcode & (1 << bit_shift)) {
10209                /* OPC_ERETNC */
10210                opn = "eretnc";
10211                check_insn(ctx, ISA_MIPS32R5);
10212                gen_helper_eretnc(cpu_env);
10213            } else {
10214                /* OPC_ERET */
10215                opn = "eret";
10216                check_insn(ctx, ISA_MIPS2);
10217                gen_helper_eret(cpu_env);
10218            }
10219            ctx->base.is_jmp = DISAS_EXIT;
10220        }
10221        break;
10222    case OPC_DERET:
10223        opn = "deret";
10224        check_insn(ctx, ISA_MIPS32);
10225        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10226            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10227            goto die;
10228        }
10229        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10230            MIPS_INVAL(opn);
10231            generate_exception_end(ctx, EXCP_RI);
10232        } else {
10233            gen_helper_deret(cpu_env);
10234            ctx->base.is_jmp = DISAS_EXIT;
10235        }
10236        break;
10237    case OPC_WAIT:
10238        opn = "wait";
10239        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10240        if ((ctx->insn_flags & ISA_MIPS32R6) &&
10241            (ctx->hflags & MIPS_HFLAG_BMASK)) {
10242            goto die;
10243        }
10244        /* If we get an exception, we want to restart at next instruction */
10245        ctx->base.pc_next += 4;
10246        save_cpu_state(ctx, 1);
10247        ctx->base.pc_next -= 4;
10248        gen_helper_wait(cpu_env);
10249        ctx->base.is_jmp = DISAS_NORETURN;
10250        break;
10251    default:
10252 die:
10253        MIPS_INVAL(opn);
10254        generate_exception_end(ctx, EXCP_RI);
10255        return;
10256    }
10257    (void)opn; /* avoid a compiler warning */
10258}
10259#endif /* !CONFIG_USER_ONLY */
10260
10261/* CP1 Branches (before delay slot) */
10262static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10263                                int32_t cc, int32_t offset)
10264{
10265    target_ulong btarget;
10266    TCGv_i32 t0 = tcg_temp_new_i32();
10267
10268    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10269        generate_exception_end(ctx, EXCP_RI);
10270        goto out;
10271    }
10272
10273    if (cc != 0)
10274        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10275
10276    btarget = ctx->base.pc_next + 4 + offset;
10277
10278    switch (op) {
10279    case OPC_BC1F:
10280        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10281        tcg_gen_not_i32(t0, t0);
10282        tcg_gen_andi_i32(t0, t0, 1);
10283        tcg_gen_extu_i32_tl(bcond, t0);
10284        goto not_likely;
10285    case OPC_BC1FL:
10286        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10287        tcg_gen_not_i32(t0, t0);
10288        tcg_gen_andi_i32(t0, t0, 1);
10289        tcg_gen_extu_i32_tl(bcond, t0);
10290        goto likely;
10291    case OPC_BC1T:
10292        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10293        tcg_gen_andi_i32(t0, t0, 1);
10294        tcg_gen_extu_i32_tl(bcond, t0);
10295        goto not_likely;
10296    case OPC_BC1TL:
10297        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10298        tcg_gen_andi_i32(t0, t0, 1);
10299        tcg_gen_extu_i32_tl(bcond, t0);
10300    likely:
10301        ctx->hflags |= MIPS_HFLAG_BL;
10302        break;
10303    case OPC_BC1FANY2:
10304        {
10305            TCGv_i32 t1 = tcg_temp_new_i32();
10306            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10307            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10308            tcg_gen_nand_i32(t0, t0, t1);
10309            tcg_temp_free_i32(t1);
10310            tcg_gen_andi_i32(t0, t0, 1);
10311            tcg_gen_extu_i32_tl(bcond, t0);
10312        }
10313        goto not_likely;
10314    case OPC_BC1TANY2:
10315        {
10316            TCGv_i32 t1 = tcg_temp_new_i32();
10317            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10318            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10319            tcg_gen_or_i32(t0, t0, t1);
10320            tcg_temp_free_i32(t1);
10321            tcg_gen_andi_i32(t0, t0, 1);
10322            tcg_gen_extu_i32_tl(bcond, t0);
10323        }
10324        goto not_likely;
10325    case OPC_BC1FANY4:
10326        {
10327            TCGv_i32 t1 = tcg_temp_new_i32();
10328            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10329            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10330            tcg_gen_and_i32(t0, t0, t1);
10331            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10332            tcg_gen_and_i32(t0, t0, t1);
10333            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10334            tcg_gen_nand_i32(t0, t0, t1);
10335            tcg_temp_free_i32(t1);
10336            tcg_gen_andi_i32(t0, t0, 1);
10337            tcg_gen_extu_i32_tl(bcond, t0);
10338        }
10339        goto not_likely;
10340    case OPC_BC1TANY4:
10341        {
10342            TCGv_i32 t1 = tcg_temp_new_i32();
10343            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10344            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10345            tcg_gen_or_i32(t0, t0, t1);
10346            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10347            tcg_gen_or_i32(t0, t0, t1);
10348            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10349            tcg_gen_or_i32(t0, t0, t1);
10350            tcg_temp_free_i32(t1);
10351            tcg_gen_andi_i32(t0, t0, 1);
10352            tcg_gen_extu_i32_tl(bcond, t0);
10353        }
10354    not_likely:
10355        ctx->hflags |= MIPS_HFLAG_BC;
10356        break;
10357    default:
10358        MIPS_INVAL("cp1 cond branch");
10359        generate_exception_end(ctx, EXCP_RI);
10360        goto out;
10361    }
10362    ctx->btarget = btarget;
10363    ctx->hflags |= MIPS_HFLAG_BDS32;
10364 out:
10365    tcg_temp_free_i32(t0);
10366}
10367
10368/* R6 CP1 Branches */
10369static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10370                                   int32_t ft, int32_t offset,
10371                                   int delayslot_size)
10372{
10373    target_ulong btarget;
10374    TCGv_i64 t0 = tcg_temp_new_i64();
10375
10376    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10377#ifdef MIPS_DEBUG_DISAS
10378        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10379                  "\n", ctx->base.pc_next);
10380#endif
10381        generate_exception_end(ctx, EXCP_RI);
10382        goto out;
10383    }
10384
10385    gen_load_fpr64(ctx, t0, ft);
10386    tcg_gen_andi_i64(t0, t0, 1);
10387
10388    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10389
10390    switch (op) {
10391    case OPC_BC1EQZ:
10392        tcg_gen_xori_i64(t0, t0, 1);
10393        ctx->hflags |= MIPS_HFLAG_BC;
10394        break;
10395    case OPC_BC1NEZ:
10396        /* t0 already set */
10397        ctx->hflags |= MIPS_HFLAG_BC;
10398        break;
10399    default:
10400        MIPS_INVAL("cp1 cond branch");
10401        generate_exception_end(ctx, EXCP_RI);
10402        goto out;
10403    }
10404
10405    tcg_gen_trunc_i64_tl(bcond, t0);
10406
10407    ctx->btarget = btarget;
10408
10409    switch (delayslot_size) {
10410    case 2:
10411        ctx->hflags |= MIPS_HFLAG_BDS16;
10412        break;
10413    case 4:
10414        ctx->hflags |= MIPS_HFLAG_BDS32;
10415        break;
10416    }
10417
10418out:
10419    tcg_temp_free_i64(t0);
10420}
10421
10422/* Coprocessor 1 (FPU) */
10423
10424#define FOP(func, fmt) (((fmt) << 21) | (func))
10425
10426enum fopcode {
10427    OPC_ADD_S = FOP(0, FMT_S),
10428    OPC_SUB_S = FOP(1, FMT_S),
10429    OPC_MUL_S = FOP(2, FMT_S),
10430    OPC_DIV_S = FOP(3, FMT_S),
10431    OPC_SQRT_S = FOP(4, FMT_S),
10432    OPC_ABS_S = FOP(5, FMT_S),
10433    OPC_MOV_S = FOP(6, FMT_S),
10434    OPC_NEG_S = FOP(7, FMT_S),
10435    OPC_ROUND_L_S = FOP(8, FMT_S),
10436    OPC_TRUNC_L_S = FOP(9, FMT_S),
10437    OPC_CEIL_L_S = FOP(10, FMT_S),
10438    OPC_FLOOR_L_S = FOP(11, FMT_S),
10439    OPC_ROUND_W_S = FOP(12, FMT_S),
10440    OPC_TRUNC_W_S = FOP(13, FMT_S),
10441    OPC_CEIL_W_S = FOP(14, FMT_S),
10442    OPC_FLOOR_W_S = FOP(15, FMT_S),
10443    OPC_SEL_S = FOP(16, FMT_S),
10444    OPC_MOVCF_S = FOP(17, FMT_S),
10445    OPC_MOVZ_S = FOP(18, FMT_S),
10446    OPC_MOVN_S = FOP(19, FMT_S),
10447    OPC_SELEQZ_S = FOP(20, FMT_S),
10448    OPC_RECIP_S = FOP(21, FMT_S),
10449    OPC_RSQRT_S = FOP(22, FMT_S),
10450    OPC_SELNEZ_S = FOP(23, FMT_S),
10451    OPC_MADDF_S = FOP(24, FMT_S),
10452    OPC_MSUBF_S = FOP(25, FMT_S),
10453    OPC_RINT_S = FOP(26, FMT_S),
10454    OPC_CLASS_S = FOP(27, FMT_S),
10455    OPC_MIN_S = FOP(28, FMT_S),
10456    OPC_RECIP2_S = FOP(28, FMT_S),
10457    OPC_MINA_S = FOP(29, FMT_S),
10458    OPC_RECIP1_S = FOP(29, FMT_S),
10459    OPC_MAX_S = FOP(30, FMT_S),
10460    OPC_RSQRT1_S = FOP(30, FMT_S),
10461    OPC_MAXA_S = FOP(31, FMT_S),
10462    OPC_RSQRT2_S = FOP(31, FMT_S),
10463    OPC_CVT_D_S = FOP(33, FMT_S),
10464    OPC_CVT_W_S = FOP(36, FMT_S),
10465    OPC_CVT_L_S = FOP(37, FMT_S),
10466    OPC_CVT_PS_S = FOP(38, FMT_S),
10467    OPC_CMP_F_S = FOP (48, FMT_S),
10468    OPC_CMP_UN_S = FOP (49, FMT_S),
10469    OPC_CMP_EQ_S = FOP (50, FMT_S),
10470    OPC_CMP_UEQ_S = FOP (51, FMT_S),
10471    OPC_CMP_OLT_S = FOP (52, FMT_S),
10472    OPC_CMP_ULT_S = FOP (53, FMT_S),
10473    OPC_CMP_OLE_S = FOP (54, FMT_S),
10474    OPC_CMP_ULE_S = FOP (55, FMT_S),
10475    OPC_CMP_SF_S = FOP (56, FMT_S),
10476    OPC_CMP_NGLE_S = FOP (57, FMT_S),
10477    OPC_CMP_SEQ_S = FOP (58, FMT_S),
10478    OPC_CMP_NGL_S = FOP (59, FMT_S),
10479    OPC_CMP_LT_S = FOP (60, FMT_S),
10480    OPC_CMP_NGE_S = FOP (61, FMT_S),
10481    OPC_CMP_LE_S = FOP (62, FMT_S),
10482    OPC_CMP_NGT_S = FOP (63, FMT_S),
10483
10484    OPC_ADD_D = FOP(0, FMT_D),
10485    OPC_SUB_D = FOP(1, FMT_D),
10486    OPC_MUL_D = FOP(2, FMT_D),
10487    OPC_DIV_D = FOP(3, FMT_D),
10488    OPC_SQRT_D = FOP(4, FMT_D),
10489    OPC_ABS_D = FOP(5, FMT_D),
10490    OPC_MOV_D = FOP(6, FMT_D),
10491    OPC_NEG_D = FOP(7, FMT_D),
10492    OPC_ROUND_L_D = FOP(8, FMT_D),
10493    OPC_TRUNC_L_D = FOP(9, FMT_D),
10494    OPC_CEIL_L_D = FOP(10, FMT_D),
10495    OPC_FLOOR_L_D = FOP(11, FMT_D),
10496    OPC_ROUND_W_D = FOP(12, FMT_D),
10497    OPC_TRUNC_W_D = FOP(13, FMT_D),
10498    OPC_CEIL_W_D = FOP(14, FMT_D),
10499    OPC_FLOOR_W_D = FOP(15, FMT_D),
10500    OPC_SEL_D = FOP(16, FMT_D),
10501    OPC_MOVCF_D = FOP(17, FMT_D),
10502    OPC_MOVZ_D = FOP(18, FMT_D),
10503    OPC_MOVN_D = FOP(19, FMT_D),
10504    OPC_SELEQZ_D = FOP(20, FMT_D),
10505    OPC_RECIP_D = FOP(21, FMT_D),
10506    OPC_RSQRT_D = FOP(22, FMT_D),
10507    OPC_SELNEZ_D = FOP(23, FMT_D),
10508    OPC_MADDF_D = FOP(24, FMT_D),
10509    OPC_MSUBF_D = FOP(25, FMT_D),
10510    OPC_RINT_D = FOP(26, FMT_D),
10511    OPC_CLASS_D = FOP(27, FMT_D),
10512    OPC_MIN_D = FOP(28, FMT_D),
10513    OPC_RECIP2_D = FOP(28, FMT_D),
10514    OPC_MINA_D = FOP(29, FMT_D),
10515    OPC_RECIP1_D = FOP(29, FMT_D),
10516    OPC_MAX_D = FOP(30, FMT_D),
10517    OPC_RSQRT1_D = FOP(30, FMT_D),
10518    OPC_MAXA_D = FOP(31, FMT_D),
10519    OPC_RSQRT2_D = FOP(31, FMT_D),
10520    OPC_CVT_S_D = FOP(32, FMT_D),
10521    OPC_CVT_W_D = FOP(36, FMT_D),
10522    OPC_CVT_L_D = FOP(37, FMT_D),
10523    OPC_CMP_F_D = FOP (48, FMT_D),
10524    OPC_CMP_UN_D = FOP (49, FMT_D),
10525    OPC_CMP_EQ_D = FOP (50, FMT_D),
10526    OPC_CMP_UEQ_D = FOP (51, FMT_D),
10527    OPC_CMP_OLT_D = FOP (52, FMT_D),
10528    OPC_CMP_ULT_D = FOP (53, FMT_D),
10529    OPC_CMP_OLE_D = FOP (54, FMT_D),
10530    OPC_CMP_ULE_D = FOP (55, FMT_D),
10531    OPC_CMP_SF_D = FOP (56, FMT_D),
10532    OPC_CMP_NGLE_D = FOP (57, FMT_D),
10533    OPC_CMP_SEQ_D = FOP (58, FMT_D),
10534    OPC_CMP_NGL_D = FOP (59, FMT_D),
10535    OPC_CMP_LT_D = FOP (60, FMT_D),
10536    OPC_CMP_NGE_D = FOP (61, FMT_D),
10537    OPC_CMP_LE_D = FOP (62, FMT_D),
10538    OPC_CMP_NGT_D = FOP (63, FMT_D),
10539
10540    OPC_CVT_S_W = FOP(32, FMT_W),
10541    OPC_CVT_D_W = FOP(33, FMT_W),
10542    OPC_CVT_S_L = FOP(32, FMT_L),
10543    OPC_CVT_D_L = FOP(33, FMT_L),
10544    OPC_CVT_PS_PW = FOP(38, FMT_W),
10545
10546    OPC_ADD_PS = FOP(0, FMT_PS),
10547    OPC_SUB_PS = FOP(1, FMT_PS),
10548    OPC_MUL_PS = FOP(2, FMT_PS),
10549    OPC_DIV_PS = FOP(3, FMT_PS),
10550    OPC_ABS_PS = FOP(5, FMT_PS),
10551    OPC_MOV_PS = FOP(6, FMT_PS),
10552    OPC_NEG_PS = FOP(7, FMT_PS),
10553    OPC_MOVCF_PS = FOP(17, FMT_PS),
10554    OPC_MOVZ_PS = FOP(18, FMT_PS),
10555    OPC_MOVN_PS = FOP(19, FMT_PS),
10556    OPC_ADDR_PS = FOP(24, FMT_PS),
10557    OPC_MULR_PS = FOP(26, FMT_PS),
10558    OPC_RECIP2_PS = FOP(28, FMT_PS),
10559    OPC_RECIP1_PS = FOP(29, FMT_PS),
10560    OPC_RSQRT1_PS = FOP(30, FMT_PS),
10561    OPC_RSQRT2_PS = FOP(31, FMT_PS),
10562
10563    OPC_CVT_S_PU = FOP(32, FMT_PS),
10564    OPC_CVT_PW_PS = FOP(36, FMT_PS),
10565    OPC_CVT_S_PL = FOP(40, FMT_PS),
10566    OPC_PLL_PS = FOP(44, FMT_PS),
10567    OPC_PLU_PS = FOP(45, FMT_PS),
10568    OPC_PUL_PS = FOP(46, FMT_PS),
10569    OPC_PUU_PS = FOP(47, FMT_PS),
10570    OPC_CMP_F_PS = FOP (48, FMT_PS),
10571    OPC_CMP_UN_PS = FOP (49, FMT_PS),
10572    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10573    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10574    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10575    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10576    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10577    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10578    OPC_CMP_SF_PS = FOP (56, FMT_PS),
10579    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10580    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10581    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10582    OPC_CMP_LT_PS = FOP (60, FMT_PS),
10583    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10584    OPC_CMP_LE_PS = FOP (62, FMT_PS),
10585    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10586};
10587
10588enum r6_f_cmp_op {
10589    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10590    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10591    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10592    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10593    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10594    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10595    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10596    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10597    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10598    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10599    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10600    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10601    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10602    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10603    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10604    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10605    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10606    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10607    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10608    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10609    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10610    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10611
10612    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10613    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10614    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10615    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10616    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10617    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10618    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10619    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10620    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10621    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10622    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10623    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10624    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10625    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10626    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10627    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10628    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10629    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10630    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10631    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10632    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10633    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10634};
10635static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10636{
10637    TCGv t0 = tcg_temp_new();
10638
10639    switch (opc) {
10640    case OPC_MFC1:
10641        {
10642            TCGv_i32 fp0 = tcg_temp_new_i32();
10643
10644            gen_load_fpr32(ctx, fp0, fs);
10645            tcg_gen_ext_i32_tl(t0, fp0);
10646            tcg_temp_free_i32(fp0);
10647        }
10648        gen_store_gpr(t0, rt);
10649        break;
10650    case OPC_MTC1:
10651        gen_load_gpr(t0, rt);
10652        {
10653            TCGv_i32 fp0 = tcg_temp_new_i32();
10654
10655            tcg_gen_trunc_tl_i32(fp0, t0);
10656            gen_store_fpr32(ctx, fp0, fs);
10657            tcg_temp_free_i32(fp0);
10658        }
10659        break;
10660    case OPC_CFC1:
10661        gen_helper_1e0i(cfc1, t0, fs);
10662        gen_store_gpr(t0, rt);
10663        break;
10664    case OPC_CTC1:
10665        gen_load_gpr(t0, rt);
10666        save_cpu_state(ctx, 0);
10667        {
10668            TCGv_i32 fs_tmp = tcg_const_i32(fs);
10669
10670            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10671            tcg_temp_free_i32(fs_tmp);
10672        }
10673        /* Stop translation as we may have changed hflags */
10674        ctx->base.is_jmp = DISAS_STOP;
10675        break;
10676#if defined(TARGET_MIPS64)
10677    case OPC_DMFC1:
10678        gen_load_fpr64(ctx, t0, fs);
10679        gen_store_gpr(t0, rt);
10680        break;
10681    case OPC_DMTC1:
10682        gen_load_gpr(t0, rt);
10683        gen_store_fpr64(ctx, t0, fs);
10684        break;
10685#endif
10686    case OPC_MFHC1:
10687        {
10688            TCGv_i32 fp0 = tcg_temp_new_i32();
10689
10690            gen_load_fpr32h(ctx, fp0, fs);
10691            tcg_gen_ext_i32_tl(t0, fp0);
10692            tcg_temp_free_i32(fp0);
10693        }
10694        gen_store_gpr(t0, rt);
10695        break;
10696    case OPC_MTHC1:
10697        gen_load_gpr(t0, rt);
10698        {
10699            TCGv_i32 fp0 = tcg_temp_new_i32();
10700
10701            tcg_gen_trunc_tl_i32(fp0, t0);
10702            gen_store_fpr32h(ctx, fp0, fs);
10703            tcg_temp_free_i32(fp0);
10704        }
10705        break;
10706    default:
10707        MIPS_INVAL("cp1 move");
10708        generate_exception_end(ctx, EXCP_RI);
10709        goto out;
10710    }
10711
10712 out:
10713    tcg_temp_free(t0);
10714}
10715
10716static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10717{
10718    TCGLabel *l1;
10719    TCGCond cond;
10720    TCGv_i32 t0;
10721
10722    if (rd == 0) {
10723        /* Treat as NOP. */
10724        return;
10725    }
10726
10727    if (tf)
10728        cond = TCG_COND_EQ;
10729    else
10730        cond = TCG_COND_NE;
10731
10732    l1 = gen_new_label();
10733    t0 = tcg_temp_new_i32();
10734    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10735    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10736    tcg_temp_free_i32(t0);
10737    if (rs == 0) {
10738        tcg_gen_movi_tl(cpu_gpr[rd], 0);
10739    } else {
10740        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10741    }
10742    gen_set_label(l1);
10743}
10744
10745static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10746                               int tf)
10747{
10748    int cond;
10749    TCGv_i32 t0 = tcg_temp_new_i32();
10750    TCGLabel *l1 = gen_new_label();
10751
10752    if (tf)
10753        cond = TCG_COND_EQ;
10754    else
10755        cond = TCG_COND_NE;
10756
10757    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10758    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10759    gen_load_fpr32(ctx, t0, fs);
10760    gen_store_fpr32(ctx, t0, fd);
10761    gen_set_label(l1);
10762    tcg_temp_free_i32(t0);
10763}
10764
10765static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10766{
10767    int cond;
10768    TCGv_i32 t0 = tcg_temp_new_i32();
10769    TCGv_i64 fp0;
10770    TCGLabel *l1 = gen_new_label();
10771
10772    if (tf)
10773        cond = TCG_COND_EQ;
10774    else
10775        cond = TCG_COND_NE;
10776
10777    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10778    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10779    tcg_temp_free_i32(t0);
10780    fp0 = tcg_temp_new_i64();
10781    gen_load_fpr64(ctx, fp0, fs);
10782    gen_store_fpr64(ctx, fp0, fd);
10783    tcg_temp_free_i64(fp0);
10784    gen_set_label(l1);
10785}
10786
10787static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10788                                int cc, int tf)
10789{
10790    int cond;
10791    TCGv_i32 t0 = tcg_temp_new_i32();
10792    TCGLabel *l1 = gen_new_label();
10793    TCGLabel *l2 = gen_new_label();
10794
10795    if (tf)
10796        cond = TCG_COND_EQ;
10797    else
10798        cond = TCG_COND_NE;
10799
10800    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10801    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10802    gen_load_fpr32(ctx, t0, fs);
10803    gen_store_fpr32(ctx, t0, fd);
10804    gen_set_label(l1);
10805
10806    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10807    tcg_gen_brcondi_i32(cond, t0, 0, l2);
10808    gen_load_fpr32h(ctx, t0, fs);
10809    gen_store_fpr32h(ctx, t0, fd);
10810    tcg_temp_free_i32(t0);
10811    gen_set_label(l2);
10812}
10813
10814static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10815                      int fs)
10816{
10817    TCGv_i32 t1 = tcg_const_i32(0);
10818    TCGv_i32 fp0 = tcg_temp_new_i32();
10819    TCGv_i32 fp1 = tcg_temp_new_i32();
10820    TCGv_i32 fp2 = tcg_temp_new_i32();
10821    gen_load_fpr32(ctx, fp0, fd);
10822    gen_load_fpr32(ctx, fp1, ft);
10823    gen_load_fpr32(ctx, fp2, fs);
10824
10825    switch (op1) {
10826    case OPC_SEL_S:
10827        tcg_gen_andi_i32(fp0, fp0, 1);
10828        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10829        break;
10830    case OPC_SELEQZ_S:
10831        tcg_gen_andi_i32(fp1, fp1, 1);
10832        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10833        break;
10834    case OPC_SELNEZ_S:
10835        tcg_gen_andi_i32(fp1, fp1, 1);
10836        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10837        break;
10838    default:
10839        MIPS_INVAL("gen_sel_s");
10840        generate_exception_end(ctx, EXCP_RI);
10841        break;
10842    }
10843
10844    gen_store_fpr32(ctx, fp0, fd);
10845    tcg_temp_free_i32(fp2);
10846    tcg_temp_free_i32(fp1);
10847    tcg_temp_free_i32(fp0);
10848    tcg_temp_free_i32(t1);
10849}
10850
10851static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10852                      int fs)
10853{
10854    TCGv_i64 t1 = tcg_const_i64(0);
10855    TCGv_i64 fp0 = tcg_temp_new_i64();
10856    TCGv_i64 fp1 = tcg_temp_new_i64();
10857    TCGv_i64 fp2 = tcg_temp_new_i64();
10858    gen_load_fpr64(ctx, fp0, fd);
10859    gen_load_fpr64(ctx, fp1, ft);
10860    gen_load_fpr64(ctx, fp2, fs);
10861
10862    switch (op1) {
10863    case OPC_SEL_D:
10864        tcg_gen_andi_i64(fp0, fp0, 1);
10865        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10866        break;
10867    case OPC_SELEQZ_D:
10868        tcg_gen_andi_i64(fp1, fp1, 1);
10869        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10870        break;
10871    case OPC_SELNEZ_D:
10872        tcg_gen_andi_i64(fp1, fp1, 1);
10873        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10874        break;
10875    default:
10876        MIPS_INVAL("gen_sel_d");
10877        generate_exception_end(ctx, EXCP_RI);
10878        break;
10879    }
10880
10881    gen_store_fpr64(ctx, fp0, fd);
10882    tcg_temp_free_i64(fp2);
10883    tcg_temp_free_i64(fp1);
10884    tcg_temp_free_i64(fp0);
10885    tcg_temp_free_i64(t1);
10886}
10887
10888static void gen_farith (DisasContext *ctx, enum fopcode op1,
10889                        int ft, int fs, int fd, int cc)
10890{
10891    uint32_t func = ctx->opcode & 0x3f;
10892    switch (op1) {
10893    case OPC_ADD_S:
10894        {
10895            TCGv_i32 fp0 = tcg_temp_new_i32();
10896            TCGv_i32 fp1 = tcg_temp_new_i32();
10897
10898            gen_load_fpr32(ctx, fp0, fs);
10899            gen_load_fpr32(ctx, fp1, ft);
10900            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10901            tcg_temp_free_i32(fp1);
10902            gen_store_fpr32(ctx, fp0, fd);
10903            tcg_temp_free_i32(fp0);
10904        }
10905        break;
10906    case OPC_SUB_S:
10907        {
10908            TCGv_i32 fp0 = tcg_temp_new_i32();
10909            TCGv_i32 fp1 = tcg_temp_new_i32();
10910
10911            gen_load_fpr32(ctx, fp0, fs);
10912            gen_load_fpr32(ctx, fp1, ft);
10913            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10914            tcg_temp_free_i32(fp1);
10915            gen_store_fpr32(ctx, fp0, fd);
10916            tcg_temp_free_i32(fp0);
10917        }
10918        break;
10919    case OPC_MUL_S:
10920        {
10921            TCGv_i32 fp0 = tcg_temp_new_i32();
10922            TCGv_i32 fp1 = tcg_temp_new_i32();
10923
10924            gen_load_fpr32(ctx, fp0, fs);
10925            gen_load_fpr32(ctx, fp1, ft);
10926            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10927            tcg_temp_free_i32(fp1);
10928            gen_store_fpr32(ctx, fp0, fd);
10929            tcg_temp_free_i32(fp0);
10930        }
10931        break;
10932    case OPC_DIV_S:
10933        {
10934            TCGv_i32 fp0 = tcg_temp_new_i32();
10935            TCGv_i32 fp1 = tcg_temp_new_i32();
10936
10937            gen_load_fpr32(ctx, fp0, fs);
10938            gen_load_fpr32(ctx, fp1, ft);
10939            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10940            tcg_temp_free_i32(fp1);
10941            gen_store_fpr32(ctx, fp0, fd);
10942            tcg_temp_free_i32(fp0);
10943        }
10944        break;
10945    case OPC_SQRT_S:
10946        {
10947            TCGv_i32 fp0 = tcg_temp_new_i32();
10948
10949            gen_load_fpr32(ctx, fp0, fs);
10950            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10951            gen_store_fpr32(ctx, fp0, fd);
10952            tcg_temp_free_i32(fp0);
10953        }
10954        break;
10955    case OPC_ABS_S:
10956        {
10957            TCGv_i32 fp0 = tcg_temp_new_i32();
10958
10959            gen_load_fpr32(ctx, fp0, fs);
10960            if (ctx->abs2008) {
10961                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10962            } else {
10963                gen_helper_float_abs_s(fp0, fp0);
10964            }
10965            gen_store_fpr32(ctx, fp0, fd);
10966            tcg_temp_free_i32(fp0);
10967        }
10968        break;
10969    case OPC_MOV_S:
10970        {
10971            TCGv_i32 fp0 = tcg_temp_new_i32();
10972
10973            gen_load_fpr32(ctx, fp0, fs);
10974            gen_store_fpr32(ctx, fp0, fd);
10975            tcg_temp_free_i32(fp0);
10976        }
10977        break;
10978    case OPC_NEG_S:
10979        {
10980            TCGv_i32 fp0 = tcg_temp_new_i32();
10981
10982            gen_load_fpr32(ctx, fp0, fs);
10983            if (ctx->abs2008) {
10984                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10985            } else {
10986                gen_helper_float_chs_s(fp0, fp0);
10987            }
10988            gen_store_fpr32(ctx, fp0, fd);
10989            tcg_temp_free_i32(fp0);
10990        }
10991        break;
10992    case OPC_ROUND_L_S:
10993        check_cp1_64bitmode(ctx);
10994        {
10995            TCGv_i32 fp32 = tcg_temp_new_i32();
10996            TCGv_i64 fp64 = tcg_temp_new_i64();
10997
10998            gen_load_fpr32(ctx, fp32, fs);
10999            if (ctx->nan2008) {
11000                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11001            } else {
11002                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11003            }
11004            tcg_temp_free_i32(fp32);
11005            gen_store_fpr64(ctx, fp64, fd);
11006            tcg_temp_free_i64(fp64);
11007        }
11008        break;
11009    case OPC_TRUNC_L_S:
11010        check_cp1_64bitmode(ctx);
11011        {
11012            TCGv_i32 fp32 = tcg_temp_new_i32();
11013            TCGv_i64 fp64 = tcg_temp_new_i64();
11014
11015            gen_load_fpr32(ctx, fp32, fs);
11016            if (ctx->nan2008) {
11017                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11018            } else {
11019                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11020            }
11021            tcg_temp_free_i32(fp32);
11022            gen_store_fpr64(ctx, fp64, fd);
11023            tcg_temp_free_i64(fp64);
11024        }
11025        break;
11026    case OPC_CEIL_L_S:
11027        check_cp1_64bitmode(ctx);
11028        {
11029            TCGv_i32 fp32 = tcg_temp_new_i32();
11030            TCGv_i64 fp64 = tcg_temp_new_i64();
11031
11032            gen_load_fpr32(ctx, fp32, fs);
11033            if (ctx->nan2008) {
11034                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11035            } else {
11036                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11037            }
11038            tcg_temp_free_i32(fp32);
11039            gen_store_fpr64(ctx, fp64, fd);
11040            tcg_temp_free_i64(fp64);
11041        }
11042        break;
11043    case OPC_FLOOR_L_S:
11044        check_cp1_64bitmode(ctx);
11045        {
11046            TCGv_i32 fp32 = tcg_temp_new_i32();
11047            TCGv_i64 fp64 = tcg_temp_new_i64();
11048
11049            gen_load_fpr32(ctx, fp32, fs);
11050            if (ctx->nan2008) {
11051                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11052            } else {
11053                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11054            }
11055            tcg_temp_free_i32(fp32);
11056            gen_store_fpr64(ctx, fp64, fd);
11057            tcg_temp_free_i64(fp64);
11058        }
11059        break;
11060    case OPC_ROUND_W_S:
11061        {
11062            TCGv_i32 fp0 = tcg_temp_new_i32();
11063
11064            gen_load_fpr32(ctx, fp0, fs);
11065            if (ctx->nan2008) {
11066                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11067            } else {
11068                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11069            }
11070            gen_store_fpr32(ctx, fp0, fd);
11071            tcg_temp_free_i32(fp0);
11072        }
11073        break;
11074    case OPC_TRUNC_W_S:
11075        {
11076            TCGv_i32 fp0 = tcg_temp_new_i32();
11077
11078            gen_load_fpr32(ctx, fp0, fs);
11079            if (ctx->nan2008) {
11080                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11081            } else {
11082                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11083            }
11084            gen_store_fpr32(ctx, fp0, fd);
11085            tcg_temp_free_i32(fp0);
11086        }
11087        break;
11088    case OPC_CEIL_W_S:
11089        {
11090            TCGv_i32 fp0 = tcg_temp_new_i32();
11091
11092            gen_load_fpr32(ctx, fp0, fs);
11093            if (ctx->nan2008) {
11094                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11095            } else {
11096                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11097            }
11098            gen_store_fpr32(ctx, fp0, fd);
11099            tcg_temp_free_i32(fp0);
11100        }
11101        break;
11102    case OPC_FLOOR_W_S:
11103        {
11104            TCGv_i32 fp0 = tcg_temp_new_i32();
11105
11106            gen_load_fpr32(ctx, fp0, fs);
11107            if (ctx->nan2008) {
11108                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11109            } else {
11110                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11111            }
11112            gen_store_fpr32(ctx, fp0, fd);
11113            tcg_temp_free_i32(fp0);
11114        }
11115        break;
11116    case OPC_SEL_S:
11117        check_insn(ctx, ISA_MIPS32R6);
11118        gen_sel_s(ctx, op1, fd, ft, fs);
11119        break;
11120    case OPC_SELEQZ_S:
11121        check_insn(ctx, ISA_MIPS32R6);
11122        gen_sel_s(ctx, op1, fd, ft, fs);
11123        break;
11124    case OPC_SELNEZ_S:
11125        check_insn(ctx, ISA_MIPS32R6);
11126        gen_sel_s(ctx, op1, fd, ft, fs);
11127        break;
11128    case OPC_MOVCF_S:
11129        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11130        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11131        break;
11132    case OPC_MOVZ_S:
11133        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11134        {
11135            TCGLabel *l1 = gen_new_label();
11136            TCGv_i32 fp0;
11137
11138            if (ft != 0) {
11139                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11140            }
11141            fp0 = tcg_temp_new_i32();
11142            gen_load_fpr32(ctx, fp0, fs);
11143            gen_store_fpr32(ctx, fp0, fd);
11144            tcg_temp_free_i32(fp0);
11145            gen_set_label(l1);
11146        }
11147        break;
11148    case OPC_MOVN_S:
11149        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11150        {
11151            TCGLabel *l1 = gen_new_label();
11152            TCGv_i32 fp0;
11153
11154            if (ft != 0) {
11155                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11156                fp0 = tcg_temp_new_i32();
11157                gen_load_fpr32(ctx, fp0, fs);
11158                gen_store_fpr32(ctx, fp0, fd);
11159                tcg_temp_free_i32(fp0);
11160                gen_set_label(l1);
11161            }
11162        }
11163        break;
11164    case OPC_RECIP_S:
11165        {
11166            TCGv_i32 fp0 = tcg_temp_new_i32();
11167
11168            gen_load_fpr32(ctx, fp0, fs);
11169            gen_helper_float_recip_s(fp0, cpu_env, fp0);
11170            gen_store_fpr32(ctx, fp0, fd);
11171            tcg_temp_free_i32(fp0);
11172        }
11173        break;
11174    case OPC_RSQRT_S:
11175        {
11176            TCGv_i32 fp0 = tcg_temp_new_i32();
11177
11178            gen_load_fpr32(ctx, fp0, fs);
11179            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11180            gen_store_fpr32(ctx, fp0, fd);
11181            tcg_temp_free_i32(fp0);
11182        }
11183        break;
11184    case OPC_MADDF_S:
11185        check_insn(ctx, ISA_MIPS32R6);
11186        {
11187            TCGv_i32 fp0 = tcg_temp_new_i32();
11188            TCGv_i32 fp1 = tcg_temp_new_i32();
11189            TCGv_i32 fp2 = tcg_temp_new_i32();
11190            gen_load_fpr32(ctx, fp0, fs);
11191            gen_load_fpr32(ctx, fp1, ft);
11192            gen_load_fpr32(ctx, fp2, fd);
11193            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11194            gen_store_fpr32(ctx, fp2, fd);
11195            tcg_temp_free_i32(fp2);
11196            tcg_temp_free_i32(fp1);
11197            tcg_temp_free_i32(fp0);
11198        }
11199        break;
11200    case OPC_MSUBF_S:
11201        check_insn(ctx, ISA_MIPS32R6);
11202        {
11203            TCGv_i32 fp0 = tcg_temp_new_i32();
11204            TCGv_i32 fp1 = tcg_temp_new_i32();
11205            TCGv_i32 fp2 = tcg_temp_new_i32();
11206            gen_load_fpr32(ctx, fp0, fs);
11207            gen_load_fpr32(ctx, fp1, ft);
11208            gen_load_fpr32(ctx, fp2, fd);
11209            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11210            gen_store_fpr32(ctx, fp2, fd);
11211            tcg_temp_free_i32(fp2);
11212            tcg_temp_free_i32(fp1);
11213            tcg_temp_free_i32(fp0);
11214        }
11215        break;
11216    case OPC_RINT_S:
11217        check_insn(ctx, ISA_MIPS32R6);
11218        {
11219            TCGv_i32 fp0 = tcg_temp_new_i32();
11220            gen_load_fpr32(ctx, fp0, fs);
11221            gen_helper_float_rint_s(fp0, cpu_env, fp0);
11222            gen_store_fpr32(ctx, fp0, fd);
11223            tcg_temp_free_i32(fp0);
11224        }
11225        break;
11226    case OPC_CLASS_S:
11227        check_insn(ctx, ISA_MIPS32R6);
11228        {
11229            TCGv_i32 fp0 = tcg_temp_new_i32();
11230            gen_load_fpr32(ctx, fp0, fs);
11231            gen_helper_float_class_s(fp0, cpu_env, fp0);
11232            gen_store_fpr32(ctx, fp0, fd);
11233            tcg_temp_free_i32(fp0);
11234        }
11235        break;
11236    case OPC_MIN_S: /* OPC_RECIP2_S */
11237        if (ctx->insn_flags & ISA_MIPS32R6) {
11238            /* OPC_MIN_S */
11239            TCGv_i32 fp0 = tcg_temp_new_i32();
11240            TCGv_i32 fp1 = tcg_temp_new_i32();
11241            TCGv_i32 fp2 = tcg_temp_new_i32();
11242            gen_load_fpr32(ctx, fp0, fs);
11243            gen_load_fpr32(ctx, fp1, ft);
11244            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11245            gen_store_fpr32(ctx, fp2, fd);
11246            tcg_temp_free_i32(fp2);
11247            tcg_temp_free_i32(fp1);
11248            tcg_temp_free_i32(fp0);
11249        } else {
11250            /* OPC_RECIP2_S */
11251            check_cp1_64bitmode(ctx);
11252            {
11253                TCGv_i32 fp0 = tcg_temp_new_i32();
11254                TCGv_i32 fp1 = tcg_temp_new_i32();
11255
11256                gen_load_fpr32(ctx, fp0, fs);
11257                gen_load_fpr32(ctx, fp1, ft);
11258                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11259                tcg_temp_free_i32(fp1);
11260                gen_store_fpr32(ctx, fp0, fd);
11261                tcg_temp_free_i32(fp0);
11262            }
11263        }
11264        break;
11265    case OPC_MINA_S: /* OPC_RECIP1_S */
11266        if (ctx->insn_flags & ISA_MIPS32R6) {
11267            /* OPC_MINA_S */
11268            TCGv_i32 fp0 = tcg_temp_new_i32();
11269            TCGv_i32 fp1 = tcg_temp_new_i32();
11270            TCGv_i32 fp2 = tcg_temp_new_i32();
11271            gen_load_fpr32(ctx, fp0, fs);
11272            gen_load_fpr32(ctx, fp1, ft);
11273            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11274            gen_store_fpr32(ctx, fp2, fd);
11275            tcg_temp_free_i32(fp2);
11276            tcg_temp_free_i32(fp1);
11277            tcg_temp_free_i32(fp0);
11278        } else {
11279            /* OPC_RECIP1_S */
11280            check_cp1_64bitmode(ctx);
11281            {
11282                TCGv_i32 fp0 = tcg_temp_new_i32();
11283
11284                gen_load_fpr32(ctx, fp0, fs);
11285                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11286                gen_store_fpr32(ctx, fp0, fd);
11287                tcg_temp_free_i32(fp0);
11288            }
11289        }
11290        break;
11291    case OPC_MAX_S: /* OPC_RSQRT1_S */
11292        if (ctx->insn_flags & ISA_MIPS32R6) {
11293            /* OPC_MAX_S */
11294            TCGv_i32 fp0 = tcg_temp_new_i32();
11295            TCGv_i32 fp1 = tcg_temp_new_i32();
11296            gen_load_fpr32(ctx, fp0, fs);
11297            gen_load_fpr32(ctx, fp1, ft);
11298            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11299            gen_store_fpr32(ctx, fp1, fd);
11300            tcg_temp_free_i32(fp1);
11301            tcg_temp_free_i32(fp0);
11302        } else {
11303            /* OPC_RSQRT1_S */
11304            check_cp1_64bitmode(ctx);
11305            {
11306                TCGv_i32 fp0 = tcg_temp_new_i32();
11307
11308                gen_load_fpr32(ctx, fp0, fs);
11309                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11310                gen_store_fpr32(ctx, fp0, fd);
11311                tcg_temp_free_i32(fp0);
11312            }
11313        }
11314        break;
11315    case OPC_MAXA_S: /* OPC_RSQRT2_S */
11316        if (ctx->insn_flags & ISA_MIPS32R6) {
11317            /* OPC_MAXA_S */
11318            TCGv_i32 fp0 = tcg_temp_new_i32();
11319            TCGv_i32 fp1 = tcg_temp_new_i32();
11320            gen_load_fpr32(ctx, fp0, fs);
11321            gen_load_fpr32(ctx, fp1, ft);
11322            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11323            gen_store_fpr32(ctx, fp1, fd);
11324            tcg_temp_free_i32(fp1);
11325            tcg_temp_free_i32(fp0);
11326        } else {
11327            /* OPC_RSQRT2_S */
11328            check_cp1_64bitmode(ctx);
11329            {
11330                TCGv_i32 fp0 = tcg_temp_new_i32();
11331                TCGv_i32 fp1 = tcg_temp_new_i32();
11332
11333                gen_load_fpr32(ctx, fp0, fs);
11334                gen_load_fpr32(ctx, fp1, ft);
11335                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11336                tcg_temp_free_i32(fp1);
11337                gen_store_fpr32(ctx, fp0, fd);
11338                tcg_temp_free_i32(fp0);
11339            }
11340        }
11341        break;
11342    case OPC_CVT_D_S:
11343        check_cp1_registers(ctx, fd);
11344        {
11345            TCGv_i32 fp32 = tcg_temp_new_i32();
11346            TCGv_i64 fp64 = tcg_temp_new_i64();
11347
11348            gen_load_fpr32(ctx, fp32, fs);
11349            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11350            tcg_temp_free_i32(fp32);
11351            gen_store_fpr64(ctx, fp64, fd);
11352            tcg_temp_free_i64(fp64);
11353        }
11354        break;
11355    case OPC_CVT_W_S:
11356        {
11357            TCGv_i32 fp0 = tcg_temp_new_i32();
11358
11359            gen_load_fpr32(ctx, fp0, fs);
11360            if (ctx->nan2008) {
11361                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11362            } else {
11363                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11364            }
11365            gen_store_fpr32(ctx, fp0, fd);
11366            tcg_temp_free_i32(fp0);
11367        }
11368        break;
11369    case OPC_CVT_L_S:
11370        check_cp1_64bitmode(ctx);
11371        {
11372            TCGv_i32 fp32 = tcg_temp_new_i32();
11373            TCGv_i64 fp64 = tcg_temp_new_i64();
11374
11375            gen_load_fpr32(ctx, fp32, fs);
11376            if (ctx->nan2008) {
11377                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11378            } else {
11379                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11380            }
11381            tcg_temp_free_i32(fp32);
11382            gen_store_fpr64(ctx, fp64, fd);
11383            tcg_temp_free_i64(fp64);
11384        }
11385        break;
11386    case OPC_CVT_PS_S:
11387        check_ps(ctx);
11388        {
11389            TCGv_i64 fp64 = tcg_temp_new_i64();
11390            TCGv_i32 fp32_0 = tcg_temp_new_i32();
11391            TCGv_i32 fp32_1 = tcg_temp_new_i32();
11392
11393            gen_load_fpr32(ctx, fp32_0, fs);
11394            gen_load_fpr32(ctx, fp32_1, ft);
11395            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11396            tcg_temp_free_i32(fp32_1);
11397            tcg_temp_free_i32(fp32_0);
11398            gen_store_fpr64(ctx, fp64, fd);
11399            tcg_temp_free_i64(fp64);
11400        }
11401        break;
11402    case OPC_CMP_F_S:
11403    case OPC_CMP_UN_S:
11404    case OPC_CMP_EQ_S:
11405    case OPC_CMP_UEQ_S:
11406    case OPC_CMP_OLT_S:
11407    case OPC_CMP_ULT_S:
11408    case OPC_CMP_OLE_S:
11409    case OPC_CMP_ULE_S:
11410    case OPC_CMP_SF_S:
11411    case OPC_CMP_NGLE_S:
11412    case OPC_CMP_SEQ_S:
11413    case OPC_CMP_NGL_S:
11414    case OPC_CMP_LT_S:
11415    case OPC_CMP_NGE_S:
11416    case OPC_CMP_LE_S:
11417    case OPC_CMP_NGT_S:
11418        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11419        if (ctx->opcode & (1 << 6)) {
11420            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11421        } else {
11422            gen_cmp_s(ctx, func-48, ft, fs, cc);
11423        }
11424        break;
11425    case OPC_ADD_D:
11426        check_cp1_registers(ctx, fs | ft | fd);
11427        {
11428            TCGv_i64 fp0 = tcg_temp_new_i64();
11429            TCGv_i64 fp1 = tcg_temp_new_i64();
11430
11431            gen_load_fpr64(ctx, fp0, fs);
11432            gen_load_fpr64(ctx, fp1, ft);
11433            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11434            tcg_temp_free_i64(fp1);
11435            gen_store_fpr64(ctx, fp0, fd);
11436            tcg_temp_free_i64(fp0);
11437        }
11438        break;
11439    case OPC_SUB_D:
11440        check_cp1_registers(ctx, fs | ft | fd);
11441        {
11442            TCGv_i64 fp0 = tcg_temp_new_i64();
11443            TCGv_i64 fp1 = tcg_temp_new_i64();
11444
11445            gen_load_fpr64(ctx, fp0, fs);
11446            gen_load_fpr64(ctx, fp1, ft);
11447            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11448            tcg_temp_free_i64(fp1);
11449            gen_store_fpr64(ctx, fp0, fd);
11450            tcg_temp_free_i64(fp0);
11451        }
11452        break;
11453    case OPC_MUL_D:
11454        check_cp1_registers(ctx, fs | ft | fd);
11455        {
11456            TCGv_i64 fp0 = tcg_temp_new_i64();
11457            TCGv_i64 fp1 = tcg_temp_new_i64();
11458
11459            gen_load_fpr64(ctx, fp0, fs);
11460            gen_load_fpr64(ctx, fp1, ft);
11461            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11462            tcg_temp_free_i64(fp1);
11463            gen_store_fpr64(ctx, fp0, fd);
11464            tcg_temp_free_i64(fp0);
11465        }
11466        break;
11467    case OPC_DIV_D:
11468        check_cp1_registers(ctx, fs | ft | fd);
11469        {
11470            TCGv_i64 fp0 = tcg_temp_new_i64();
11471            TCGv_i64 fp1 = tcg_temp_new_i64();
11472
11473            gen_load_fpr64(ctx, fp0, fs);
11474            gen_load_fpr64(ctx, fp1, ft);
11475            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11476            tcg_temp_free_i64(fp1);
11477            gen_store_fpr64(ctx, fp0, fd);
11478            tcg_temp_free_i64(fp0);
11479        }
11480        break;
11481    case OPC_SQRT_D:
11482        check_cp1_registers(ctx, fs | fd);
11483        {
11484            TCGv_i64 fp0 = tcg_temp_new_i64();
11485
11486            gen_load_fpr64(ctx, fp0, fs);
11487            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11488            gen_store_fpr64(ctx, fp0, fd);
11489            tcg_temp_free_i64(fp0);
11490        }
11491        break;
11492    case OPC_ABS_D:
11493        check_cp1_registers(ctx, fs | fd);
11494        {
11495            TCGv_i64 fp0 = tcg_temp_new_i64();
11496
11497            gen_load_fpr64(ctx, fp0, fs);
11498            if (ctx->abs2008) {
11499                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11500            } else {
11501                gen_helper_float_abs_d(fp0, fp0);
11502            }
11503            gen_store_fpr64(ctx, fp0, fd);
11504            tcg_temp_free_i64(fp0);
11505        }
11506        break;
11507    case OPC_MOV_D:
11508        check_cp1_registers(ctx, fs | fd);
11509        {
11510            TCGv_i64 fp0 = tcg_temp_new_i64();
11511
11512            gen_load_fpr64(ctx, fp0, fs);
11513            gen_store_fpr64(ctx, fp0, fd);
11514            tcg_temp_free_i64(fp0);
11515        }
11516        break;
11517    case OPC_NEG_D:
11518        check_cp1_registers(ctx, fs | fd);
11519        {
11520            TCGv_i64 fp0 = tcg_temp_new_i64();
11521
11522            gen_load_fpr64(ctx, fp0, fs);
11523            if (ctx->abs2008) {
11524                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11525            } else {
11526                gen_helper_float_chs_d(fp0, fp0);
11527            }
11528            gen_store_fpr64(ctx, fp0, fd);
11529            tcg_temp_free_i64(fp0);
11530        }
11531        break;
11532    case OPC_ROUND_L_D:
11533        check_cp1_64bitmode(ctx);
11534        {
11535            TCGv_i64 fp0 = tcg_temp_new_i64();
11536
11537            gen_load_fpr64(ctx, fp0, fs);
11538            if (ctx->nan2008) {
11539                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11540            } else {
11541                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11542            }
11543            gen_store_fpr64(ctx, fp0, fd);
11544            tcg_temp_free_i64(fp0);
11545        }
11546        break;
11547    case OPC_TRUNC_L_D:
11548        check_cp1_64bitmode(ctx);
11549        {
11550            TCGv_i64 fp0 = tcg_temp_new_i64();
11551
11552            gen_load_fpr64(ctx, fp0, fs);
11553            if (ctx->nan2008) {
11554                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11555            } else {
11556                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11557            }
11558            gen_store_fpr64(ctx, fp0, fd);
11559            tcg_temp_free_i64(fp0);
11560        }
11561        break;
11562    case OPC_CEIL_L_D:
11563        check_cp1_64bitmode(ctx);
11564        {
11565            TCGv_i64 fp0 = tcg_temp_new_i64();
11566
11567            gen_load_fpr64(ctx, fp0, fs);
11568            if (ctx->nan2008) {
11569                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11570            } else {
11571                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11572            }
11573            gen_store_fpr64(ctx, fp0, fd);
11574            tcg_temp_free_i64(fp0);
11575        }
11576        break;
11577    case OPC_FLOOR_L_D:
11578        check_cp1_64bitmode(ctx);
11579        {
11580            TCGv_i64 fp0 = tcg_temp_new_i64();
11581
11582            gen_load_fpr64(ctx, fp0, fs);
11583            if (ctx->nan2008) {
11584                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11585            } else {
11586                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11587            }
11588            gen_store_fpr64(ctx, fp0, fd);
11589            tcg_temp_free_i64(fp0);
11590        }
11591        break;
11592    case OPC_ROUND_W_D:
11593        check_cp1_registers(ctx, fs);
11594        {
11595            TCGv_i32 fp32 = tcg_temp_new_i32();
11596            TCGv_i64 fp64 = tcg_temp_new_i64();
11597
11598            gen_load_fpr64(ctx, fp64, fs);
11599            if (ctx->nan2008) {
11600                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11601            } else {
11602                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11603            }
11604            tcg_temp_free_i64(fp64);
11605            gen_store_fpr32(ctx, fp32, fd);
11606            tcg_temp_free_i32(fp32);
11607        }
11608        break;
11609    case OPC_TRUNC_W_D:
11610        check_cp1_registers(ctx, fs);
11611        {
11612            TCGv_i32 fp32 = tcg_temp_new_i32();
11613            TCGv_i64 fp64 = tcg_temp_new_i64();
11614
11615            gen_load_fpr64(ctx, fp64, fs);
11616            if (ctx->nan2008) {
11617                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11618            } else {
11619                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11620            }
11621            tcg_temp_free_i64(fp64);
11622            gen_store_fpr32(ctx, fp32, fd);
11623            tcg_temp_free_i32(fp32);
11624        }
11625        break;
11626    case OPC_CEIL_W_D:
11627        check_cp1_registers(ctx, fs);
11628        {
11629            TCGv_i32 fp32 = tcg_temp_new_i32();
11630            TCGv_i64 fp64 = tcg_temp_new_i64();
11631
11632            gen_load_fpr64(ctx, fp64, fs);
11633            if (ctx->nan2008) {
11634                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11635            } else {
11636                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11637            }
11638            tcg_temp_free_i64(fp64);
11639            gen_store_fpr32(ctx, fp32, fd);
11640            tcg_temp_free_i32(fp32);
11641        }
11642        break;
11643    case OPC_FLOOR_W_D:
11644        check_cp1_registers(ctx, fs);
11645        {
11646            TCGv_i32 fp32 = tcg_temp_new_i32();
11647            TCGv_i64 fp64 = tcg_temp_new_i64();
11648
11649            gen_load_fpr64(ctx, fp64, fs);
11650            if (ctx->nan2008) {
11651                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11652            } else {
11653                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11654            }
11655            tcg_temp_free_i64(fp64);
11656            gen_store_fpr32(ctx, fp32, fd);
11657            tcg_temp_free_i32(fp32);
11658        }
11659        break;
11660    case OPC_SEL_D:
11661        check_insn(ctx, ISA_MIPS32R6);
11662        gen_sel_d(ctx, op1, fd, ft, fs);
11663        break;
11664    case OPC_SELEQZ_D:
11665        check_insn(ctx, ISA_MIPS32R6);
11666        gen_sel_d(ctx, op1, fd, ft, fs);
11667        break;
11668    case OPC_SELNEZ_D:
11669        check_insn(ctx, ISA_MIPS32R6);
11670        gen_sel_d(ctx, op1, fd, ft, fs);
11671        break;
11672    case OPC_MOVCF_D:
11673        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11674        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11675        break;
11676    case OPC_MOVZ_D:
11677        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11678        {
11679            TCGLabel *l1 = gen_new_label();
11680            TCGv_i64 fp0;
11681
11682            if (ft != 0) {
11683                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11684            }
11685            fp0 = tcg_temp_new_i64();
11686            gen_load_fpr64(ctx, fp0, fs);
11687            gen_store_fpr64(ctx, fp0, fd);
11688            tcg_temp_free_i64(fp0);
11689            gen_set_label(l1);
11690        }
11691        break;
11692    case OPC_MOVN_D:
11693        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11694        {
11695            TCGLabel *l1 = gen_new_label();
11696            TCGv_i64 fp0;
11697
11698            if (ft != 0) {
11699                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11700                fp0 = tcg_temp_new_i64();
11701                gen_load_fpr64(ctx, fp0, fs);
11702                gen_store_fpr64(ctx, fp0, fd);
11703                tcg_temp_free_i64(fp0);
11704                gen_set_label(l1);
11705            }
11706        }
11707        break;
11708    case OPC_RECIP_D:
11709        check_cp1_registers(ctx, fs | fd);
11710        {
11711            TCGv_i64 fp0 = tcg_temp_new_i64();
11712
11713            gen_load_fpr64(ctx, fp0, fs);
11714            gen_helper_float_recip_d(fp0, cpu_env, fp0);
11715            gen_store_fpr64(ctx, fp0, fd);
11716            tcg_temp_free_i64(fp0);
11717        }
11718        break;
11719    case OPC_RSQRT_D:
11720        check_cp1_registers(ctx, fs | fd);
11721        {
11722            TCGv_i64 fp0 = tcg_temp_new_i64();
11723
11724            gen_load_fpr64(ctx, fp0, fs);
11725            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11726            gen_store_fpr64(ctx, fp0, fd);
11727            tcg_temp_free_i64(fp0);
11728        }
11729        break;
11730    case OPC_MADDF_D:
11731        check_insn(ctx, ISA_MIPS32R6);
11732        {
11733            TCGv_i64 fp0 = tcg_temp_new_i64();
11734            TCGv_i64 fp1 = tcg_temp_new_i64();
11735            TCGv_i64 fp2 = tcg_temp_new_i64();
11736            gen_load_fpr64(ctx, fp0, fs);
11737            gen_load_fpr64(ctx, fp1, ft);
11738            gen_load_fpr64(ctx, fp2, fd);
11739            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11740            gen_store_fpr64(ctx, fp2, fd);
11741            tcg_temp_free_i64(fp2);
11742            tcg_temp_free_i64(fp1);
11743            tcg_temp_free_i64(fp0);
11744        }
11745        break;
11746    case OPC_MSUBF_D:
11747        check_insn(ctx, ISA_MIPS32R6);
11748        {
11749            TCGv_i64 fp0 = tcg_temp_new_i64();
11750            TCGv_i64 fp1 = tcg_temp_new_i64();
11751            TCGv_i64 fp2 = tcg_temp_new_i64();
11752            gen_load_fpr64(ctx, fp0, fs);
11753            gen_load_fpr64(ctx, fp1, ft);
11754            gen_load_fpr64(ctx, fp2, fd);
11755            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11756            gen_store_fpr64(ctx, fp2, fd);
11757            tcg_temp_free_i64(fp2);
11758            tcg_temp_free_i64(fp1);
11759            tcg_temp_free_i64(fp0);
11760        }
11761        break;
11762    case OPC_RINT_D:
11763        check_insn(ctx, ISA_MIPS32R6);
11764        {
11765            TCGv_i64 fp0 = tcg_temp_new_i64();
11766            gen_load_fpr64(ctx, fp0, fs);
11767            gen_helper_float_rint_d(fp0, cpu_env, fp0);
11768            gen_store_fpr64(ctx, fp0, fd);
11769            tcg_temp_free_i64(fp0);
11770        }
11771        break;
11772    case OPC_CLASS_D:
11773        check_insn(ctx, ISA_MIPS32R6);
11774        {
11775            TCGv_i64 fp0 = tcg_temp_new_i64();
11776            gen_load_fpr64(ctx, fp0, fs);
11777            gen_helper_float_class_d(fp0, cpu_env, fp0);
11778            gen_store_fpr64(ctx, fp0, fd);
11779            tcg_temp_free_i64(fp0);
11780        }
11781        break;
11782    case OPC_MIN_D: /* OPC_RECIP2_D */
11783        if (ctx->insn_flags & ISA_MIPS32R6) {
11784            /* OPC_MIN_D */
11785            TCGv_i64 fp0 = tcg_temp_new_i64();
11786            TCGv_i64 fp1 = tcg_temp_new_i64();
11787            gen_load_fpr64(ctx, fp0, fs);
11788            gen_load_fpr64(ctx, fp1, ft);
11789            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11790            gen_store_fpr64(ctx, fp1, fd);
11791            tcg_temp_free_i64(fp1);
11792            tcg_temp_free_i64(fp0);
11793        } else {
11794            /* OPC_RECIP2_D */
11795            check_cp1_64bitmode(ctx);
11796            {
11797                TCGv_i64 fp0 = tcg_temp_new_i64();
11798                TCGv_i64 fp1 = tcg_temp_new_i64();
11799
11800                gen_load_fpr64(ctx, fp0, fs);
11801                gen_load_fpr64(ctx, fp1, ft);
11802                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11803                tcg_temp_free_i64(fp1);
11804                gen_store_fpr64(ctx, fp0, fd);
11805                tcg_temp_free_i64(fp0);
11806            }
11807        }
11808        break;
11809    case OPC_MINA_D: /* OPC_RECIP1_D */
11810        if (ctx->insn_flags & ISA_MIPS32R6) {
11811            /* OPC_MINA_D */
11812            TCGv_i64 fp0 = tcg_temp_new_i64();
11813            TCGv_i64 fp1 = tcg_temp_new_i64();
11814            gen_load_fpr64(ctx, fp0, fs);
11815            gen_load_fpr64(ctx, fp1, ft);
11816            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11817            gen_store_fpr64(ctx, fp1, fd);
11818            tcg_temp_free_i64(fp1);
11819            tcg_temp_free_i64(fp0);
11820        } else {
11821            /* OPC_RECIP1_D */
11822            check_cp1_64bitmode(ctx);
11823            {
11824                TCGv_i64 fp0 = tcg_temp_new_i64();
11825
11826                gen_load_fpr64(ctx, fp0, fs);
11827                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11828                gen_store_fpr64(ctx, fp0, fd);
11829                tcg_temp_free_i64(fp0);
11830            }
11831        }
11832        break;
11833    case OPC_MAX_D: /*  OPC_RSQRT1_D */
11834        if (ctx->insn_flags & ISA_MIPS32R6) {
11835            /* OPC_MAX_D */
11836            TCGv_i64 fp0 = tcg_temp_new_i64();
11837            TCGv_i64 fp1 = tcg_temp_new_i64();
11838            gen_load_fpr64(ctx, fp0, fs);
11839            gen_load_fpr64(ctx, fp1, ft);
11840            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11841            gen_store_fpr64(ctx, fp1, fd);
11842            tcg_temp_free_i64(fp1);
11843            tcg_temp_free_i64(fp0);
11844        } else {
11845            /* OPC_RSQRT1_D */
11846            check_cp1_64bitmode(ctx);
11847            {
11848                TCGv_i64 fp0 = tcg_temp_new_i64();
11849
11850                gen_load_fpr64(ctx, fp0, fs);
11851                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11852                gen_store_fpr64(ctx, fp0, fd);
11853                tcg_temp_free_i64(fp0);
11854            }
11855        }
11856        break;
11857    case OPC_MAXA_D: /* OPC_RSQRT2_D */
11858        if (ctx->insn_flags & ISA_MIPS32R6) {
11859            /* OPC_MAXA_D */
11860            TCGv_i64 fp0 = tcg_temp_new_i64();
11861            TCGv_i64 fp1 = tcg_temp_new_i64();
11862            gen_load_fpr64(ctx, fp0, fs);
11863            gen_load_fpr64(ctx, fp1, ft);
11864            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11865            gen_store_fpr64(ctx, fp1, fd);
11866            tcg_temp_free_i64(fp1);
11867            tcg_temp_free_i64(fp0);
11868        } else {
11869            /* OPC_RSQRT2_D */
11870            check_cp1_64bitmode(ctx);
11871            {
11872                TCGv_i64 fp0 = tcg_temp_new_i64();
11873                TCGv_i64 fp1 = tcg_temp_new_i64();
11874
11875                gen_load_fpr64(ctx, fp0, fs);
11876                gen_load_fpr64(ctx, fp1, ft);
11877                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11878                tcg_temp_free_i64(fp1);
11879                gen_store_fpr64(ctx, fp0, fd);
11880                tcg_temp_free_i64(fp0);
11881            }
11882        }
11883        break;
11884    case OPC_CMP_F_D:
11885    case OPC_CMP_UN_D:
11886    case OPC_CMP_EQ_D:
11887    case OPC_CMP_UEQ_D:
11888    case OPC_CMP_OLT_D:
11889    case OPC_CMP_ULT_D:
11890    case OPC_CMP_OLE_D:
11891    case OPC_CMP_ULE_D:
11892    case OPC_CMP_SF_D:
11893    case OPC_CMP_NGLE_D:
11894    case OPC_CMP_SEQ_D:
11895    case OPC_CMP_NGL_D:
11896    case OPC_CMP_LT_D:
11897    case OPC_CMP_NGE_D:
11898    case OPC_CMP_LE_D:
11899    case OPC_CMP_NGT_D:
11900        check_insn_opc_removed(ctx, ISA_MIPS32R6);
11901        if (ctx->opcode & (1 << 6)) {
11902            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11903        } else {
11904            gen_cmp_d(ctx, func-48, ft, fs, cc);
11905        }
11906        break;
11907    case OPC_CVT_S_D:
11908        check_cp1_registers(ctx, fs);
11909        {
11910            TCGv_i32 fp32 = tcg_temp_new_i32();
11911            TCGv_i64 fp64 = tcg_temp_new_i64();
11912
11913            gen_load_fpr64(ctx, fp64, fs);
11914            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11915            tcg_temp_free_i64(fp64);
11916            gen_store_fpr32(ctx, fp32, fd);
11917            tcg_temp_free_i32(fp32);
11918        }
11919        break;
11920    case OPC_CVT_W_D:
11921        check_cp1_registers(ctx, fs);
11922        {
11923            TCGv_i32 fp32 = tcg_temp_new_i32();
11924            TCGv_i64 fp64 = tcg_temp_new_i64();
11925
11926            gen_load_fpr64(ctx, fp64, fs);
11927            if (ctx->nan2008) {
11928                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11929            } else {
11930                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11931            }
11932            tcg_temp_free_i64(fp64);
11933            gen_store_fpr32(ctx, fp32, fd);
11934            tcg_temp_free_i32(fp32);
11935        }
11936        break;
11937    case OPC_CVT_L_D:
11938        check_cp1_64bitmode(ctx);
11939        {
11940            TCGv_i64 fp0 = tcg_temp_new_i64();
11941
11942            gen_load_fpr64(ctx, fp0, fs);
11943            if (ctx->nan2008) {
11944                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11945            } else {
11946                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11947            }
11948            gen_store_fpr64(ctx, fp0, fd);
11949            tcg_temp_free_i64(fp0);
11950        }
11951        break;
11952    case OPC_CVT_S_W:
11953        {
11954            TCGv_i32 fp0 = tcg_temp_new_i32();
11955
11956            gen_load_fpr32(ctx, fp0, fs);
11957            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11958            gen_store_fpr32(ctx, fp0, fd);
11959            tcg_temp_free_i32(fp0);
11960        }
11961        break;
11962    case OPC_CVT_D_W:
11963        check_cp1_registers(ctx, fd);
11964        {
11965            TCGv_i32 fp32 = tcg_temp_new_i32();
11966            TCGv_i64 fp64 = tcg_temp_new_i64();
11967
11968            gen_load_fpr32(ctx, fp32, fs);
11969            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11970            tcg_temp_free_i32(fp32);
11971            gen_store_fpr64(ctx, fp64, fd);
11972            tcg_temp_free_i64(fp64);
11973        }
11974        break;
11975    case OPC_CVT_S_L:
11976        check_cp1_64bitmode(ctx);
11977        {
11978            TCGv_i32 fp32 = tcg_temp_new_i32();
11979            TCGv_i64 fp64 = tcg_temp_new_i64();
11980
11981            gen_load_fpr64(ctx, fp64, fs);
11982            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11983            tcg_temp_free_i64(fp64);
11984            gen_store_fpr32(ctx, fp32, fd);
11985            tcg_temp_free_i32(fp32);
11986        }
11987        break;
11988    case OPC_CVT_D_L:
11989        check_cp1_64bitmode(ctx);
11990        {
11991            TCGv_i64 fp0 = tcg_temp_new_i64();
11992
11993            gen_load_fpr64(ctx, fp0, fs);
11994            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11995            gen_store_fpr64(ctx, fp0, fd);
11996            tcg_temp_free_i64(fp0);
11997        }
11998        break;
11999    case OPC_CVT_PS_PW:
12000        check_ps(ctx);
12001        {
12002            TCGv_i64 fp0 = tcg_temp_new_i64();
12003
12004            gen_load_fpr64(ctx, fp0, fs);
12005            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12006            gen_store_fpr64(ctx, fp0, fd);
12007            tcg_temp_free_i64(fp0);
12008        }
12009        break;
12010    case OPC_ADD_PS:
12011        check_ps(ctx);
12012        {
12013            TCGv_i64 fp0 = tcg_temp_new_i64();
12014            TCGv_i64 fp1 = tcg_temp_new_i64();
12015
12016            gen_load_fpr64(ctx, fp0, fs);
12017            gen_load_fpr64(ctx, fp1, ft);
12018            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12019            tcg_temp_free_i64(fp1);
12020            gen_store_fpr64(ctx, fp0, fd);
12021            tcg_temp_free_i64(fp0);
12022        }
12023        break;
12024    case OPC_SUB_PS:
12025        check_ps(ctx);
12026        {
12027            TCGv_i64 fp0 = tcg_temp_new_i64();
12028            TCGv_i64 fp1 = tcg_temp_new_i64();
12029
12030            gen_load_fpr64(ctx, fp0, fs);
12031            gen_load_fpr64(ctx, fp1, ft);
12032            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12033            tcg_temp_free_i64(fp1);
12034            gen_store_fpr64(ctx, fp0, fd);
12035            tcg_temp_free_i64(fp0);
12036        }
12037        break;
12038    case OPC_MUL_PS:
12039        check_ps(ctx);
12040        {
12041            TCGv_i64 fp0 = tcg_temp_new_i64();
12042            TCGv_i64 fp1 = tcg_temp_new_i64();
12043
12044            gen_load_fpr64(ctx, fp0, fs);
12045            gen_load_fpr64(ctx, fp1, ft);
12046            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12047            tcg_temp_free_i64(fp1);
12048            gen_store_fpr64(ctx, fp0, fd);
12049            tcg_temp_free_i64(fp0);
12050        }
12051        break;
12052    case OPC_ABS_PS:
12053        check_ps(ctx);
12054        {
12055            TCGv_i64 fp0 = tcg_temp_new_i64();
12056
12057            gen_load_fpr64(ctx, fp0, fs);
12058            gen_helper_float_abs_ps(fp0, fp0);
12059            gen_store_fpr64(ctx, fp0, fd);
12060            tcg_temp_free_i64(fp0);
12061        }
12062        break;
12063    case OPC_MOV_PS:
12064        check_ps(ctx);
12065        {
12066            TCGv_i64 fp0 = tcg_temp_new_i64();
12067
12068            gen_load_fpr64(ctx, fp0, fs);
12069            gen_store_fpr64(ctx, fp0, fd);
12070            tcg_temp_free_i64(fp0);
12071        }
12072        break;
12073    case OPC_NEG_PS:
12074        check_ps(ctx);
12075        {
12076            TCGv_i64 fp0 = tcg_temp_new_i64();
12077
12078            gen_load_fpr64(ctx, fp0, fs);
12079            gen_helper_float_chs_ps(fp0, fp0);
12080            gen_store_fpr64(ctx, fp0, fd);
12081            tcg_temp_free_i64(fp0);
12082        }
12083        break;
12084    case OPC_MOVCF_PS:
12085        check_ps(ctx);
12086        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12087        break;
12088    case OPC_MOVZ_PS:
12089        check_ps(ctx);
12090        {
12091            TCGLabel *l1 = gen_new_label();
12092            TCGv_i64 fp0;
12093
12094            if (ft != 0)
12095                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12096            fp0 = tcg_temp_new_i64();
12097            gen_load_fpr64(ctx, fp0, fs);
12098            gen_store_fpr64(ctx, fp0, fd);
12099            tcg_temp_free_i64(fp0);
12100            gen_set_label(l1);
12101        }
12102        break;
12103    case OPC_MOVN_PS:
12104        check_ps(ctx);
12105        {
12106            TCGLabel *l1 = gen_new_label();
12107            TCGv_i64 fp0;
12108
12109            if (ft != 0) {
12110                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12111                fp0 = tcg_temp_new_i64();
12112                gen_load_fpr64(ctx, fp0, fs);
12113                gen_store_fpr64(ctx, fp0, fd);
12114                tcg_temp_free_i64(fp0);
12115                gen_set_label(l1);
12116            }
12117        }
12118        break;
12119    case OPC_ADDR_PS:
12120        check_ps(ctx);
12121        {
12122            TCGv_i64 fp0 = tcg_temp_new_i64();
12123            TCGv_i64 fp1 = tcg_temp_new_i64();
12124
12125            gen_load_fpr64(ctx, fp0, ft);
12126            gen_load_fpr64(ctx, fp1, fs);
12127            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12128            tcg_temp_free_i64(fp1);
12129            gen_store_fpr64(ctx, fp0, fd);
12130            tcg_temp_free_i64(fp0);
12131        }
12132        break;
12133    case OPC_MULR_PS:
12134        check_ps(ctx);
12135        {
12136            TCGv_i64 fp0 = tcg_temp_new_i64();
12137            TCGv_i64 fp1 = tcg_temp_new_i64();
12138
12139            gen_load_fpr64(ctx, fp0, ft);
12140            gen_load_fpr64(ctx, fp1, fs);
12141            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12142            tcg_temp_free_i64(fp1);
12143            gen_store_fpr64(ctx, fp0, fd);
12144            tcg_temp_free_i64(fp0);
12145        }
12146        break;
12147    case OPC_RECIP2_PS:
12148        check_ps(ctx);
12149        {
12150            TCGv_i64 fp0 = tcg_temp_new_i64();
12151            TCGv_i64 fp1 = tcg_temp_new_i64();
12152
12153            gen_load_fpr64(ctx, fp0, fs);
12154            gen_load_fpr64(ctx, fp1, ft);
12155            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12156            tcg_temp_free_i64(fp1);
12157            gen_store_fpr64(ctx, fp0, fd);
12158            tcg_temp_free_i64(fp0);
12159        }
12160        break;
12161    case OPC_RECIP1_PS:
12162        check_ps(ctx);
12163        {
12164            TCGv_i64 fp0 = tcg_temp_new_i64();
12165
12166            gen_load_fpr64(ctx, fp0, fs);
12167            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12168            gen_store_fpr64(ctx, fp0, fd);
12169            tcg_temp_free_i64(fp0);
12170        }
12171        break;
12172    case OPC_RSQRT1_PS:
12173        check_ps(ctx);
12174        {
12175            TCGv_i64 fp0 = tcg_temp_new_i64();
12176
12177            gen_load_fpr64(ctx, fp0, fs);
12178            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12179            gen_store_fpr64(ctx, fp0, fd);
12180            tcg_temp_free_i64(fp0);
12181        }
12182        break;
12183    case OPC_RSQRT2_PS:
12184        check_ps(ctx);
12185        {
12186            TCGv_i64 fp0 = tcg_temp_new_i64();
12187            TCGv_i64 fp1 = tcg_temp_new_i64();
12188
12189            gen_load_fpr64(ctx, fp0, fs);
12190            gen_load_fpr64(ctx, fp1, ft);
12191            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12192            tcg_temp_free_i64(fp1);
12193            gen_store_fpr64(ctx, fp0, fd);
12194            tcg_temp_free_i64(fp0);
12195        }
12196        break;
12197    case OPC_CVT_S_PU:
12198        check_cp1_64bitmode(ctx);
12199        {
12200            TCGv_i32 fp0 = tcg_temp_new_i32();
12201
12202            gen_load_fpr32h(ctx, fp0, fs);
12203            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12204            gen_store_fpr32(ctx, fp0, fd);
12205            tcg_temp_free_i32(fp0);
12206        }
12207        break;
12208    case OPC_CVT_PW_PS:
12209        check_ps(ctx);
12210        {
12211            TCGv_i64 fp0 = tcg_temp_new_i64();
12212
12213            gen_load_fpr64(ctx, fp0, fs);
12214            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12215            gen_store_fpr64(ctx, fp0, fd);
12216            tcg_temp_free_i64(fp0);
12217        }
12218        break;
12219    case OPC_CVT_S_PL:
12220        check_cp1_64bitmode(ctx);
12221        {
12222            TCGv_i32 fp0 = tcg_temp_new_i32();
12223
12224            gen_load_fpr32(ctx, fp0, fs);
12225            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12226            gen_store_fpr32(ctx, fp0, fd);
12227            tcg_temp_free_i32(fp0);
12228        }
12229        break;
12230    case OPC_PLL_PS:
12231        check_ps(ctx);
12232        {
12233            TCGv_i32 fp0 = tcg_temp_new_i32();
12234            TCGv_i32 fp1 = tcg_temp_new_i32();
12235
12236            gen_load_fpr32(ctx, fp0, fs);
12237            gen_load_fpr32(ctx, fp1, ft);
12238            gen_store_fpr32h(ctx, fp0, fd);
12239            gen_store_fpr32(ctx, fp1, fd);
12240            tcg_temp_free_i32(fp0);
12241            tcg_temp_free_i32(fp1);
12242        }
12243        break;
12244    case OPC_PLU_PS:
12245        check_ps(ctx);
12246        {
12247            TCGv_i32 fp0 = tcg_temp_new_i32();
12248            TCGv_i32 fp1 = tcg_temp_new_i32();
12249
12250            gen_load_fpr32(ctx, fp0, fs);
12251            gen_load_fpr32h(ctx, fp1, ft);
12252            gen_store_fpr32(ctx, fp1, fd);
12253            gen_store_fpr32h(ctx, fp0, fd);
12254            tcg_temp_free_i32(fp0);
12255            tcg_temp_free_i32(fp1);
12256        }
12257        break;
12258    case OPC_PUL_PS:
12259        check_ps(ctx);
12260        {
12261            TCGv_i32 fp0 = tcg_temp_new_i32();
12262            TCGv_i32 fp1 = tcg_temp_new_i32();
12263
12264            gen_load_fpr32h(ctx, fp0, fs);
12265            gen_load_fpr32(ctx, fp1, ft);
12266            gen_store_fpr32(ctx, fp1, fd);
12267            gen_store_fpr32h(ctx, fp0, fd);
12268            tcg_temp_free_i32(fp0);
12269            tcg_temp_free_i32(fp1);
12270        }
12271        break;
12272    case OPC_PUU_PS:
12273        check_ps(ctx);
12274        {
12275            TCGv_i32 fp0 = tcg_temp_new_i32();
12276            TCGv_i32 fp1 = tcg_temp_new_i32();
12277
12278            gen_load_fpr32h(ctx, fp0, fs);
12279            gen_load_fpr32h(ctx, fp1, ft);
12280            gen_store_fpr32(ctx, fp1, fd);
12281            gen_store_fpr32h(ctx, fp0, fd);
12282            tcg_temp_free_i32(fp0);
12283            tcg_temp_free_i32(fp1);
12284        }
12285        break;
12286    case OPC_CMP_F_PS:
12287    case OPC_CMP_UN_PS:
12288    case OPC_CMP_EQ_PS:
12289    case OPC_CMP_UEQ_PS:
12290    case OPC_CMP_OLT_PS:
12291    case OPC_CMP_ULT_PS:
12292    case OPC_CMP_OLE_PS:
12293    case OPC_CMP_ULE_PS:
12294    case OPC_CMP_SF_PS:
12295    case OPC_CMP_NGLE_PS:
12296    case OPC_CMP_SEQ_PS:
12297    case OPC_CMP_NGL_PS:
12298    case OPC_CMP_LT_PS:
12299    case OPC_CMP_NGE_PS:
12300    case OPC_CMP_LE_PS:
12301    case OPC_CMP_NGT_PS:
12302        if (ctx->opcode & (1 << 6)) {
12303            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12304        } else {
12305            gen_cmp_ps(ctx, func-48, ft, fs, cc);
12306        }
12307        break;
12308    default:
12309        MIPS_INVAL("farith");
12310        generate_exception_end(ctx, EXCP_RI);
12311        return;
12312    }
12313}
12314
12315/* Coprocessor 3 (FPU) */
12316static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12317                           int fd, int fs, int base, int index)
12318{
12319    TCGv t0 = tcg_temp_new();
12320
12321    if (base == 0) {
12322        gen_load_gpr(t0, index);
12323    } else if (index == 0) {
12324        gen_load_gpr(t0, base);
12325    } else {
12326        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12327    }
12328    /* Don't do NOP if destination is zero: we must perform the actual
12329       memory access. */
12330    switch (opc) {
12331    case OPC_LWXC1:
12332        check_cop1x(ctx);
12333        {
12334            TCGv_i32 fp0 = tcg_temp_new_i32();
12335
12336            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12337            tcg_gen_trunc_tl_i32(fp0, t0);
12338            gen_store_fpr32(ctx, fp0, fd);
12339            tcg_temp_free_i32(fp0);
12340        }
12341        break;
12342    case OPC_LDXC1:
12343        check_cop1x(ctx);
12344        check_cp1_registers(ctx, fd);
12345        {
12346            TCGv_i64 fp0 = tcg_temp_new_i64();
12347            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12348            gen_store_fpr64(ctx, fp0, fd);
12349            tcg_temp_free_i64(fp0);
12350        }
12351        break;
12352    case OPC_LUXC1:
12353        check_cp1_64bitmode(ctx);
12354        tcg_gen_andi_tl(t0, t0, ~0x7);
12355        {
12356            TCGv_i64 fp0 = tcg_temp_new_i64();
12357
12358            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12359            gen_store_fpr64(ctx, fp0, fd);
12360            tcg_temp_free_i64(fp0);
12361        }
12362        break;
12363    case OPC_SWXC1:
12364        check_cop1x(ctx);
12365        {
12366            TCGv_i32 fp0 = tcg_temp_new_i32();
12367            gen_load_fpr32(ctx, fp0, fs);
12368            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12369            tcg_temp_free_i32(fp0);
12370        }
12371        break;
12372    case OPC_SDXC1:
12373        check_cop1x(ctx);
12374        check_cp1_registers(ctx, fs);
12375        {
12376            TCGv_i64 fp0 = tcg_temp_new_i64();
12377            gen_load_fpr64(ctx, fp0, fs);
12378            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12379            tcg_temp_free_i64(fp0);
12380        }
12381        break;
12382    case OPC_SUXC1:
12383        check_cp1_64bitmode(ctx);
12384        tcg_gen_andi_tl(t0, t0, ~0x7);
12385        {
12386            TCGv_i64 fp0 = tcg_temp_new_i64();
12387            gen_load_fpr64(ctx, fp0, fs);
12388            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12389            tcg_temp_free_i64(fp0);
12390        }
12391        break;
12392    }
12393    tcg_temp_free(t0);
12394}
12395
12396static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12397                            int fd, int fr, int fs, int ft)
12398{
12399    switch (opc) {
12400    case OPC_ALNV_PS:
12401        check_ps(ctx);
12402        {
12403            TCGv t0 = tcg_temp_local_new();
12404            TCGv_i32 fp = tcg_temp_new_i32();
12405            TCGv_i32 fph = tcg_temp_new_i32();
12406            TCGLabel *l1 = gen_new_label();
12407            TCGLabel *l2 = gen_new_label();
12408
12409            gen_load_gpr(t0, fr);
12410            tcg_gen_andi_tl(t0, t0, 0x7);
12411
12412            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12413            gen_load_fpr32(ctx, fp, fs);
12414            gen_load_fpr32h(ctx, fph, fs);
12415            gen_store_fpr32(ctx, fp, fd);
12416            gen_store_fpr32h(ctx, fph, fd);
12417            tcg_gen_br(l2);
12418            gen_set_label(l1);
12419            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12420            tcg_temp_free(t0);
12421#ifdef TARGET_WORDS_BIGENDIAN
12422            gen_load_fpr32(ctx, fp, fs);
12423            gen_load_fpr32h(ctx, fph, ft);
12424            gen_store_fpr32h(ctx, fp, fd);
12425            gen_store_fpr32(ctx, fph, fd);
12426#else
12427            gen_load_fpr32h(ctx, fph, fs);
12428            gen_load_fpr32(ctx, fp, ft);
12429            gen_store_fpr32(ctx, fph, fd);
12430            gen_store_fpr32h(ctx, fp, fd);
12431#endif
12432            gen_set_label(l2);
12433            tcg_temp_free_i32(fp);
12434            tcg_temp_free_i32(fph);
12435        }
12436        break;
12437    case OPC_MADD_S:
12438        check_cop1x(ctx);
12439        {
12440            TCGv_i32 fp0 = tcg_temp_new_i32();
12441            TCGv_i32 fp1 = tcg_temp_new_i32();
12442            TCGv_i32 fp2 = tcg_temp_new_i32();
12443
12444            gen_load_fpr32(ctx, fp0, fs);
12445            gen_load_fpr32(ctx, fp1, ft);
12446            gen_load_fpr32(ctx, fp2, fr);
12447            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12448            tcg_temp_free_i32(fp0);
12449            tcg_temp_free_i32(fp1);
12450            gen_store_fpr32(ctx, fp2, fd);
12451            tcg_temp_free_i32(fp2);
12452        }
12453        break;
12454    case OPC_MADD_D:
12455        check_cop1x(ctx);
12456        check_cp1_registers(ctx, fd | fs | ft | fr);
12457        {
12458            TCGv_i64 fp0 = tcg_temp_new_i64();
12459            TCGv_i64 fp1 = tcg_temp_new_i64();
12460            TCGv_i64 fp2 = tcg_temp_new_i64();
12461
12462            gen_load_fpr64(ctx, fp0, fs);
12463            gen_load_fpr64(ctx, fp1, ft);
12464            gen_load_fpr64(ctx, fp2, fr);
12465            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12466            tcg_temp_free_i64(fp0);
12467            tcg_temp_free_i64(fp1);
12468            gen_store_fpr64(ctx, fp2, fd);
12469            tcg_temp_free_i64(fp2);
12470        }
12471        break;
12472    case OPC_MADD_PS:
12473        check_ps(ctx);
12474        {
12475            TCGv_i64 fp0 = tcg_temp_new_i64();
12476            TCGv_i64 fp1 = tcg_temp_new_i64();
12477            TCGv_i64 fp2 = tcg_temp_new_i64();
12478
12479            gen_load_fpr64(ctx, fp0, fs);
12480            gen_load_fpr64(ctx, fp1, ft);
12481            gen_load_fpr64(ctx, fp2, fr);
12482            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12483            tcg_temp_free_i64(fp0);
12484            tcg_temp_free_i64(fp1);
12485            gen_store_fpr64(ctx, fp2, fd);
12486            tcg_temp_free_i64(fp2);
12487        }
12488        break;
12489    case OPC_MSUB_S:
12490        check_cop1x(ctx);
12491        {
12492            TCGv_i32 fp0 = tcg_temp_new_i32();
12493            TCGv_i32 fp1 = tcg_temp_new_i32();
12494            TCGv_i32 fp2 = tcg_temp_new_i32();
12495
12496            gen_load_fpr32(ctx, fp0, fs);
12497            gen_load_fpr32(ctx, fp1, ft);
12498            gen_load_fpr32(ctx, fp2, fr);
12499            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12500            tcg_temp_free_i32(fp0);
12501            tcg_temp_free_i32(fp1);
12502            gen_store_fpr32(ctx, fp2, fd);
12503            tcg_temp_free_i32(fp2);
12504        }
12505        break;
12506    case OPC_MSUB_D:
12507        check_cop1x(ctx);
12508        check_cp1_registers(ctx, fd | fs | ft | fr);
12509        {
12510            TCGv_i64 fp0 = tcg_temp_new_i64();
12511            TCGv_i64 fp1 = tcg_temp_new_i64();
12512            TCGv_i64 fp2 = tcg_temp_new_i64();
12513
12514            gen_load_fpr64(ctx, fp0, fs);
12515            gen_load_fpr64(ctx, fp1, ft);
12516            gen_load_fpr64(ctx, fp2, fr);
12517            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12518            tcg_temp_free_i64(fp0);
12519            tcg_temp_free_i64(fp1);
12520            gen_store_fpr64(ctx, fp2, fd);
12521            tcg_temp_free_i64(fp2);
12522        }
12523        break;
12524    case OPC_MSUB_PS:
12525        check_ps(ctx);
12526        {
12527            TCGv_i64 fp0 = tcg_temp_new_i64();
12528            TCGv_i64 fp1 = tcg_temp_new_i64();
12529            TCGv_i64 fp2 = tcg_temp_new_i64();
12530
12531            gen_load_fpr64(ctx, fp0, fs);
12532            gen_load_fpr64(ctx, fp1, ft);
12533            gen_load_fpr64(ctx, fp2, fr);
12534            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12535            tcg_temp_free_i64(fp0);
12536            tcg_temp_free_i64(fp1);
12537            gen_store_fpr64(ctx, fp2, fd);
12538            tcg_temp_free_i64(fp2);
12539        }
12540        break;
12541    case OPC_NMADD_S:
12542        check_cop1x(ctx);
12543        {
12544            TCGv_i32 fp0 = tcg_temp_new_i32();
12545            TCGv_i32 fp1 = tcg_temp_new_i32();
12546            TCGv_i32 fp2 = tcg_temp_new_i32();
12547
12548            gen_load_fpr32(ctx, fp0, fs);
12549            gen_load_fpr32(ctx, fp1, ft);
12550            gen_load_fpr32(ctx, fp2, fr);
12551            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12552            tcg_temp_free_i32(fp0);
12553            tcg_temp_free_i32(fp1);
12554            gen_store_fpr32(ctx, fp2, fd);
12555            tcg_temp_free_i32(fp2);
12556        }
12557        break;
12558    case OPC_NMADD_D:
12559        check_cop1x(ctx);
12560        check_cp1_registers(ctx, fd | fs | ft | fr);
12561        {
12562            TCGv_i64 fp0 = tcg_temp_new_i64();
12563            TCGv_i64 fp1 = tcg_temp_new_i64();
12564            TCGv_i64 fp2 = tcg_temp_new_i64();
12565
12566            gen_load_fpr64(ctx, fp0, fs);
12567            gen_load_fpr64(ctx, fp1, ft);
12568            gen_load_fpr64(ctx, fp2, fr);
12569            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12570            tcg_temp_free_i64(fp0);
12571            tcg_temp_free_i64(fp1);
12572            gen_store_fpr64(ctx, fp2, fd);
12573            tcg_temp_free_i64(fp2);
12574        }
12575        break;
12576    case OPC_NMADD_PS:
12577        check_ps(ctx);
12578        {
12579            TCGv_i64 fp0 = tcg_temp_new_i64();
12580            TCGv_i64 fp1 = tcg_temp_new_i64();
12581            TCGv_i64 fp2 = tcg_temp_new_i64();
12582
12583            gen_load_fpr64(ctx, fp0, fs);
12584            gen_load_fpr64(ctx, fp1, ft);
12585            gen_load_fpr64(ctx, fp2, fr);
12586            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12587            tcg_temp_free_i64(fp0);
12588            tcg_temp_free_i64(fp1);
12589            gen_store_fpr64(ctx, fp2, fd);
12590            tcg_temp_free_i64(fp2);
12591        }
12592        break;
12593    case OPC_NMSUB_S:
12594        check_cop1x(ctx);
12595        {
12596            TCGv_i32 fp0 = tcg_temp_new_i32();
12597            TCGv_i32 fp1 = tcg_temp_new_i32();
12598            TCGv_i32 fp2 = tcg_temp_new_i32();
12599
12600            gen_load_fpr32(ctx, fp0, fs);
12601            gen_load_fpr32(ctx, fp1, ft);
12602            gen_load_fpr32(ctx, fp2, fr);
12603            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12604            tcg_temp_free_i32(fp0);
12605            tcg_temp_free_i32(fp1);
12606            gen_store_fpr32(ctx, fp2, fd);
12607            tcg_temp_free_i32(fp2);
12608        }
12609        break;
12610    case OPC_NMSUB_D:
12611        check_cop1x(ctx);
12612        check_cp1_registers(ctx, fd | fs | ft | fr);
12613        {
12614            TCGv_i64 fp0 = tcg_temp_new_i64();
12615            TCGv_i64 fp1 = tcg_temp_new_i64();
12616            TCGv_i64 fp2 = tcg_temp_new_i64();
12617
12618            gen_load_fpr64(ctx, fp0, fs);
12619            gen_load_fpr64(ctx, fp1, ft);
12620            gen_load_fpr64(ctx, fp2, fr);
12621            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12622            tcg_temp_free_i64(fp0);
12623            tcg_temp_free_i64(fp1);
12624            gen_store_fpr64(ctx, fp2, fd);
12625            tcg_temp_free_i64(fp2);
12626        }
12627        break;
12628    case OPC_NMSUB_PS:
12629        check_ps(ctx);
12630        {
12631            TCGv_i64 fp0 = tcg_temp_new_i64();
12632            TCGv_i64 fp1 = tcg_temp_new_i64();
12633            TCGv_i64 fp2 = tcg_temp_new_i64();
12634
12635            gen_load_fpr64(ctx, fp0, fs);
12636            gen_load_fpr64(ctx, fp1, ft);
12637            gen_load_fpr64(ctx, fp2, fr);
12638            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12639            tcg_temp_free_i64(fp0);
12640            tcg_temp_free_i64(fp1);
12641            gen_store_fpr64(ctx, fp2, fd);
12642            tcg_temp_free_i64(fp2);
12643        }
12644        break;
12645    default:
12646        MIPS_INVAL("flt3_arith");
12647        generate_exception_end(ctx, EXCP_RI);
12648        return;
12649    }
12650}
12651
12652static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12653{
12654    TCGv t0;
12655
12656#if !defined(CONFIG_USER_ONLY)
12657    /* The Linux kernel will emulate rdhwr if it's not supported natively.
12658       Therefore only check the ISA in system mode.  */
12659    check_insn(ctx, ISA_MIPS32R2);
12660#endif
12661    t0 = tcg_temp_new();
12662
12663    switch (rd) {
12664    case 0:
12665        gen_helper_rdhwr_cpunum(t0, cpu_env);
12666        gen_store_gpr(t0, rt);
12667        break;
12668    case 1:
12669        gen_helper_rdhwr_synci_step(t0, cpu_env);
12670        gen_store_gpr(t0, rt);
12671        break;
12672    case 2:
12673        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12674            gen_io_start();
12675        }
12676        gen_helper_rdhwr_cc(t0, cpu_env);
12677        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12678            gen_io_end();
12679        }
12680        gen_store_gpr(t0, rt);
12681        /* Break the TB to be able to take timer interrupts immediately
12682           after reading count. DISAS_STOP isn't sufficient, we need to ensure
12683           we break completely out of translated code.  */
12684        gen_save_pc(ctx->base.pc_next + 4);
12685        ctx->base.is_jmp = DISAS_EXIT;
12686        break;
12687    case 3:
12688        gen_helper_rdhwr_ccres(t0, cpu_env);
12689        gen_store_gpr(t0, rt);
12690        break;
12691    case 4:
12692        check_insn(ctx, ISA_MIPS32R6);
12693        if (sel != 0) {
12694            /* Performance counter registers are not implemented other than
12695             * control register 0.
12696             */
12697            generate_exception(ctx, EXCP_RI);
12698        }
12699        gen_helper_rdhwr_performance(t0, cpu_env);
12700        gen_store_gpr(t0, rt);
12701        break;
12702    case 5:
12703        check_insn(ctx, ISA_MIPS32R6);
12704        gen_helper_rdhwr_xnp(t0, cpu_env);
12705        gen_store_gpr(t0, rt);
12706        break;
12707    case 29:
12708#if defined(CONFIG_USER_ONLY)
12709        tcg_gen_ld_tl(t0, cpu_env,
12710                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12711        gen_store_gpr(t0, rt);
12712        break;
12713#else
12714        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12715            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12716            tcg_gen_ld_tl(t0, cpu_env,
12717                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12718            gen_store_gpr(t0, rt);
12719        } else {
12720            generate_exception_end(ctx, EXCP_RI);
12721        }
12722        break;
12723#endif
12724    default:            /* Invalid */
12725        MIPS_INVAL("rdhwr");
12726        generate_exception_end(ctx, EXCP_RI);
12727        break;
12728    }
12729    tcg_temp_free(t0);
12730}
12731
12732static inline void clear_branch_hflags(DisasContext *ctx)
12733{
12734    ctx->hflags &= ~MIPS_HFLAG_BMASK;
12735    if (ctx->base.is_jmp == DISAS_NEXT) {
12736        save_cpu_state(ctx, 0);
12737    } else {
12738        /* it is not safe to save ctx->hflags as hflags may be changed
12739           in execution time by the instruction in delay / forbidden slot. */
12740        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12741    }
12742}
12743
12744static void gen_branch(DisasContext *ctx, int insn_bytes)
12745{
12746    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12747        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12748        /* Branches completion */
12749        clear_branch_hflags(ctx);
12750        ctx->base.is_jmp = DISAS_NORETURN;
12751        /* FIXME: Need to clear can_do_io.  */
12752        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12753        case MIPS_HFLAG_FBNSLOT:
12754            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12755            break;
12756        case MIPS_HFLAG_B:
12757            /* unconditional branch */
12758            if (proc_hflags & MIPS_HFLAG_BX) {
12759                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12760            }
12761            gen_goto_tb(ctx, 0, ctx->btarget);
12762            break;
12763        case MIPS_HFLAG_BL:
12764            /* blikely taken case */
12765            gen_goto_tb(ctx, 0, ctx->btarget);
12766            break;
12767        case MIPS_HFLAG_BC:
12768            /* Conditional branch */
12769            {
12770                TCGLabel *l1 = gen_new_label();
12771
12772                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12773                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12774                gen_set_label(l1);
12775                gen_goto_tb(ctx, 0, ctx->btarget);
12776            }
12777            break;
12778        case MIPS_HFLAG_BR:
12779            /* unconditional branch to register */
12780            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12781                TCGv t0 = tcg_temp_new();
12782                TCGv_i32 t1 = tcg_temp_new_i32();
12783
12784                tcg_gen_andi_tl(t0, btarget, 0x1);
12785                tcg_gen_trunc_tl_i32(t1, t0);
12786                tcg_temp_free(t0);
12787                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12788                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12789                tcg_gen_or_i32(hflags, hflags, t1);
12790                tcg_temp_free_i32(t1);
12791
12792                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12793            } else {
12794                tcg_gen_mov_tl(cpu_PC, btarget);
12795            }
12796            if (ctx->base.singlestep_enabled) {
12797                save_cpu_state(ctx, 0);
12798                gen_helper_raise_exception_debug(cpu_env);
12799            }
12800            tcg_gen_lookup_and_goto_ptr();
12801            break;
12802        default:
12803            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12804            abort();
12805        }
12806    }
12807}
12808
12809/* Compact Branches */
12810static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12811                                       int rs, int rt, int32_t offset)
12812{
12813    int bcond_compute = 0;
12814    TCGv t0 = tcg_temp_new();
12815    TCGv t1 = tcg_temp_new();
12816    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12817
12818    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12819#ifdef MIPS_DEBUG_DISAS
12820        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12821                  "\n", ctx->base.pc_next);
12822#endif
12823        generate_exception_end(ctx, EXCP_RI);
12824        goto out;
12825    }
12826
12827    /* Load needed operands and calculate btarget */
12828    switch (opc) {
12829    /* compact branch */
12830    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12831    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12832        gen_load_gpr(t0, rs);
12833        gen_load_gpr(t1, rt);
12834        bcond_compute = 1;
12835        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12836        if (rs <= rt && rs == 0) {
12837            /* OPC_BEQZALC, OPC_BNEZALC */
12838            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12839        }
12840        break;
12841    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12842    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12843        gen_load_gpr(t0, rs);
12844        gen_load_gpr(t1, rt);
12845        bcond_compute = 1;
12846        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12847        break;
12848    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12849    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12850        if (rs == 0 || rs == rt) {
12851            /* OPC_BLEZALC, OPC_BGEZALC */
12852            /* OPC_BGTZALC, OPC_BLTZALC */
12853            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12854        }
12855        gen_load_gpr(t0, rs);
12856        gen_load_gpr(t1, rt);
12857        bcond_compute = 1;
12858        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12859        break;
12860    case OPC_BC:
12861    case OPC_BALC:
12862        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12863        break;
12864    case OPC_BEQZC:
12865    case OPC_BNEZC:
12866        if (rs != 0) {
12867            /* OPC_BEQZC, OPC_BNEZC */
12868            gen_load_gpr(t0, rs);
12869            bcond_compute = 1;
12870            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12871        } else {
12872            /* OPC_JIC, OPC_JIALC */
12873            TCGv tbase = tcg_temp_new();
12874            TCGv toffset = tcg_temp_new();
12875
12876            gen_load_gpr(tbase, rt);
12877            tcg_gen_movi_tl(toffset, offset);
12878            gen_op_addr_add(ctx, btarget, tbase, toffset);
12879            tcg_temp_free(tbase);
12880            tcg_temp_free(toffset);
12881        }
12882        break;
12883    default:
12884        MIPS_INVAL("Compact branch/jump");
12885        generate_exception_end(ctx, EXCP_RI);
12886        goto out;
12887    }
12888
12889    if (bcond_compute == 0) {
12890        /* Uncoditional compact branch */
12891        switch (opc) {
12892        case OPC_JIALC:
12893            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12894            /* Fallthrough */
12895        case OPC_JIC:
12896            ctx->hflags |= MIPS_HFLAG_BR;
12897            break;
12898        case OPC_BALC:
12899            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12900            /* Fallthrough */
12901        case OPC_BC:
12902            ctx->hflags |= MIPS_HFLAG_B;
12903            break;
12904        default:
12905            MIPS_INVAL("Compact branch/jump");
12906            generate_exception_end(ctx, EXCP_RI);
12907            goto out;
12908        }
12909
12910        /* Generating branch here as compact branches don't have delay slot */
12911        gen_branch(ctx, 4);
12912    } else {
12913        /* Conditional compact branch */
12914        TCGLabel *fs = gen_new_label();
12915        save_cpu_state(ctx, 0);
12916
12917        switch (opc) {
12918        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12919            if (rs == 0 && rt != 0) {
12920                /* OPC_BLEZALC */
12921                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12922            } else if (rs != 0 && rt != 0 && rs == rt) {
12923                /* OPC_BGEZALC */
12924                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12925            } else {
12926                /* OPC_BGEUC */
12927                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12928            }
12929            break;
12930        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12931            if (rs == 0 && rt != 0) {
12932                /* OPC_BGTZALC */
12933                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12934            } else if (rs != 0 && rt != 0 && rs == rt) {
12935                /* OPC_BLTZALC */
12936                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12937            } else {
12938                /* OPC_BLTUC */
12939                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12940            }
12941            break;
12942        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12943            if (rs == 0 && rt != 0) {
12944                /* OPC_BLEZC */
12945                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12946            } else if (rs != 0 && rt != 0 && rs == rt) {
12947                /* OPC_BGEZC */
12948                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12949            } else {
12950                /* OPC_BGEC */
12951                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12952            }
12953            break;
12954        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12955            if (rs == 0 && rt != 0) {
12956                /* OPC_BGTZC */
12957                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12958            } else if (rs != 0 && rt != 0 && rs == rt) {
12959                /* OPC_BLTZC */
12960                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12961            } else {
12962                /* OPC_BLTC */
12963                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12964            }
12965            break;
12966        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12967        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12968            if (rs >= rt) {
12969                /* OPC_BOVC, OPC_BNVC */
12970                TCGv t2 = tcg_temp_new();
12971                TCGv t3 = tcg_temp_new();
12972                TCGv t4 = tcg_temp_new();
12973                TCGv input_overflow = tcg_temp_new();
12974
12975                gen_load_gpr(t0, rs);
12976                gen_load_gpr(t1, rt);
12977                tcg_gen_ext32s_tl(t2, t0);
12978                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12979                tcg_gen_ext32s_tl(t3, t1);
12980                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12981                tcg_gen_or_tl(input_overflow, input_overflow, t4);
12982
12983                tcg_gen_add_tl(t4, t2, t3);
12984                tcg_gen_ext32s_tl(t4, t4);
12985                tcg_gen_xor_tl(t2, t2, t3);
12986                tcg_gen_xor_tl(t3, t4, t3);
12987                tcg_gen_andc_tl(t2, t3, t2);
12988                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12989                tcg_gen_or_tl(t4, t4, input_overflow);
12990                if (opc == OPC_BOVC) {
12991                    /* OPC_BOVC */
12992                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12993                } else {
12994                    /* OPC_BNVC */
12995                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12996                }
12997                tcg_temp_free(input_overflow);
12998                tcg_temp_free(t4);
12999                tcg_temp_free(t3);
13000                tcg_temp_free(t2);
13001            } else if (rs < rt && rs == 0) {
13002                /* OPC_BEQZALC, OPC_BNEZALC */
13003                if (opc == OPC_BEQZALC) {
13004                    /* OPC_BEQZALC */
13005                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13006                } else {
13007                    /* OPC_BNEZALC */
13008                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13009                }
13010            } else {
13011                /* OPC_BEQC, OPC_BNEC */
13012                if (opc == OPC_BEQC) {
13013                    /* OPC_BEQC */
13014                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13015                } else {
13016                    /* OPC_BNEC */
13017                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13018                }
13019            }
13020            break;
13021        case OPC_BEQZC:
13022            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13023            break;
13024        case OPC_BNEZC:
13025            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13026            break;
13027        default:
13028            MIPS_INVAL("Compact conditional branch/jump");
13029            generate_exception_end(ctx, EXCP_RI);
13030            goto out;
13031        }
13032
13033        /* Generating branch here as compact branches don't have delay slot */
13034        gen_goto_tb(ctx, 1, ctx->btarget);
13035        gen_set_label(fs);
13036
13037        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13038    }
13039
13040out:
13041    tcg_temp_free(t0);
13042    tcg_temp_free(t1);
13043}
13044
13045/* ISA extensions (ASEs) */
13046/* MIPS16 extension to MIPS32 */
13047
13048/* MIPS16 major opcodes */
13049enum {
13050  M16_OPC_ADDIUSP = 0x00,
13051  M16_OPC_ADDIUPC = 0x01,
13052  M16_OPC_B = 0x02,
13053  M16_OPC_JAL = 0x03,
13054  M16_OPC_BEQZ = 0x04,
13055  M16_OPC_BNEQZ = 0x05,
13056  M16_OPC_SHIFT = 0x06,
13057  M16_OPC_LD = 0x07,
13058  M16_OPC_RRIA = 0x08,
13059  M16_OPC_ADDIU8 = 0x09,
13060  M16_OPC_SLTI = 0x0a,
13061  M16_OPC_SLTIU = 0x0b,
13062  M16_OPC_I8 = 0x0c,
13063  M16_OPC_LI = 0x0d,
13064  M16_OPC_CMPI = 0x0e,
13065  M16_OPC_SD = 0x0f,
13066  M16_OPC_LB = 0x10,
13067  M16_OPC_LH = 0x11,
13068  M16_OPC_LWSP = 0x12,
13069  M16_OPC_LW = 0x13,
13070  M16_OPC_LBU = 0x14,
13071  M16_OPC_LHU = 0x15,
13072  M16_OPC_LWPC = 0x16,
13073  M16_OPC_LWU = 0x17,
13074  M16_OPC_SB = 0x18,
13075  M16_OPC_SH = 0x19,
13076  M16_OPC_SWSP = 0x1a,
13077  M16_OPC_SW = 0x1b,
13078  M16_OPC_RRR = 0x1c,
13079  M16_OPC_RR = 0x1d,
13080  M16_OPC_EXTEND = 0x1e,
13081  M16_OPC_I64 = 0x1f
13082};
13083
13084/* I8 funct field */
13085enum {
13086  I8_BTEQZ = 0x0,
13087  I8_BTNEZ = 0x1,
13088  I8_SWRASP = 0x2,
13089  I8_ADJSP = 0x3,
13090  I8_SVRS = 0x4,
13091  I8_MOV32R = 0x5,
13092  I8_MOVR32 = 0x7
13093};
13094
13095/* RRR f field */
13096enum {
13097  RRR_DADDU = 0x0,
13098  RRR_ADDU = 0x1,
13099  RRR_DSUBU = 0x2,
13100  RRR_SUBU = 0x3
13101};
13102
13103/* RR funct field */
13104enum {
13105  RR_JR = 0x00,
13106  RR_SDBBP = 0x01,
13107  RR_SLT = 0x02,
13108  RR_SLTU = 0x03,
13109  RR_SLLV = 0x04,
13110  RR_BREAK = 0x05,
13111  RR_SRLV = 0x06,
13112  RR_SRAV = 0x07,
13113  RR_DSRL = 0x08,
13114  RR_CMP = 0x0a,
13115  RR_NEG = 0x0b,
13116  RR_AND = 0x0c,
13117  RR_OR = 0x0d,
13118  RR_XOR = 0x0e,
13119  RR_NOT = 0x0f,
13120  RR_MFHI = 0x10,
13121  RR_CNVT = 0x11,
13122  RR_MFLO = 0x12,
13123  RR_DSRA = 0x13,
13124  RR_DSLLV = 0x14,
13125  RR_DSRLV = 0x16,
13126  RR_DSRAV = 0x17,
13127  RR_MULT = 0x18,
13128  RR_MULTU = 0x19,
13129  RR_DIV = 0x1a,
13130  RR_DIVU = 0x1b,
13131  RR_DMULT = 0x1c,
13132  RR_DMULTU = 0x1d,
13133  RR_DDIV = 0x1e,
13134  RR_DDIVU = 0x1f
13135};
13136
13137/* I64 funct field */
13138enum {
13139  I64_LDSP = 0x0,
13140  I64_SDSP = 0x1,
13141  I64_SDRASP = 0x2,
13142  I64_DADJSP = 0x3,
13143  I64_LDPC = 0x4,
13144  I64_DADDIU5 = 0x5,
13145  I64_DADDIUPC = 0x6,
13146  I64_DADDIUSP = 0x7
13147};
13148
13149/* RR ry field for CNVT */
13150enum {
13151  RR_RY_CNVT_ZEB = 0x0,
13152  RR_RY_CNVT_ZEH = 0x1,
13153  RR_RY_CNVT_ZEW = 0x2,
13154  RR_RY_CNVT_SEB = 0x4,
13155  RR_RY_CNVT_SEH = 0x5,
13156  RR_RY_CNVT_SEW = 0x6,
13157};
13158
13159static int xlat (int r)
13160{
13161  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13162
13163  return map[r];
13164}
13165
13166static void gen_mips16_save (DisasContext *ctx,
13167                             int xsregs, int aregs,
13168                             int do_ra, int do_s0, int do_s1,
13169                             int framesize)
13170{
13171    TCGv t0 = tcg_temp_new();
13172    TCGv t1 = tcg_temp_new();
13173    TCGv t2 = tcg_temp_new();
13174    int args, astatic;
13175
13176    switch (aregs) {
13177    case 0:
13178    case 1:
13179    case 2:
13180    case 3:
13181    case 11:
13182        args = 0;
13183        break;
13184    case 4:
13185    case 5:
13186    case 6:
13187    case 7:
13188        args = 1;
13189        break;
13190    case 8:
13191    case 9:
13192    case 10:
13193        args = 2;
13194        break;
13195    case 12:
13196    case 13:
13197        args = 3;
13198        break;
13199    case 14:
13200        args = 4;
13201        break;
13202    default:
13203        generate_exception_end(ctx, EXCP_RI);
13204        return;
13205    }
13206
13207    switch (args) {
13208    case 4:
13209        gen_base_offset_addr(ctx, t0, 29, 12);
13210        gen_load_gpr(t1, 7);
13211        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13212        /* Fall through */
13213    case 3:
13214        gen_base_offset_addr(ctx, t0, 29, 8);
13215        gen_load_gpr(t1, 6);
13216        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13217        /* Fall through */
13218    case 2:
13219        gen_base_offset_addr(ctx, t0, 29, 4);
13220        gen_load_gpr(t1, 5);
13221        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13222        /* Fall through */
13223    case 1:
13224        gen_base_offset_addr(ctx, t0, 29, 0);
13225        gen_load_gpr(t1, 4);
13226        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13227    }
13228
13229    gen_load_gpr(t0, 29);
13230
13231#define DECR_AND_STORE(reg) do {                                 \
13232        tcg_gen_movi_tl(t2, -4);                                 \
13233        gen_op_addr_add(ctx, t0, t0, t2);                        \
13234        gen_load_gpr(t1, reg);                                   \
13235        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13236    } while (0)
13237
13238    if (do_ra) {
13239        DECR_AND_STORE(31);
13240    }
13241
13242    switch (xsregs) {
13243    case 7:
13244        DECR_AND_STORE(30);
13245        /* Fall through */
13246    case 6:
13247        DECR_AND_STORE(23);
13248        /* Fall through */
13249    case 5:
13250        DECR_AND_STORE(22);
13251        /* Fall through */
13252    case 4:
13253        DECR_AND_STORE(21);
13254        /* Fall through */
13255    case 3:
13256        DECR_AND_STORE(20);
13257        /* Fall through */
13258    case 2:
13259        DECR_AND_STORE(19);
13260        /* Fall through */
13261    case 1:
13262        DECR_AND_STORE(18);
13263    }
13264
13265    if (do_s1) {
13266        DECR_AND_STORE(17);
13267    }
13268    if (do_s0) {
13269        DECR_AND_STORE(16);
13270    }
13271
13272    switch (aregs) {
13273    case 0:
13274    case 4:
13275    case 8:
13276    case 12:
13277    case 14:
13278        astatic = 0;
13279        break;
13280    case 1:
13281    case 5:
13282    case 9:
13283    case 13:
13284        astatic = 1;
13285        break;
13286    case 2:
13287    case 6:
13288    case 10:
13289        astatic = 2;
13290        break;
13291    case 3:
13292    case 7:
13293        astatic = 3;
13294        break;
13295    case 11:
13296        astatic = 4;
13297        break;
13298    default:
13299        generate_exception_end(ctx, EXCP_RI);
13300        return;
13301    }
13302
13303    if (astatic > 0) {
13304        DECR_AND_STORE(7);
13305        if (astatic > 1) {
13306            DECR_AND_STORE(6);
13307            if (astatic > 2) {
13308                DECR_AND_STORE(5);
13309                if (astatic > 3) {
13310                    DECR_AND_STORE(4);
13311                }
13312            }
13313        }
13314    }
13315#undef DECR_AND_STORE
13316
13317    tcg_gen_movi_tl(t2, -framesize);
13318    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13319    tcg_temp_free(t0);
13320    tcg_temp_free(t1);
13321    tcg_temp_free(t2);
13322}
13323
13324static void gen_mips16_restore (DisasContext *ctx,
13325                                int xsregs, int aregs,
13326                                int do_ra, int do_s0, int do_s1,
13327                                int framesize)
13328{
13329    int astatic;
13330    TCGv t0 = tcg_temp_new();
13331    TCGv t1 = tcg_temp_new();
13332    TCGv t2 = tcg_temp_new();
13333
13334    tcg_gen_movi_tl(t2, framesize);
13335    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13336
13337#define DECR_AND_LOAD(reg) do {                            \
13338        tcg_gen_movi_tl(t2, -4);                           \
13339        gen_op_addr_add(ctx, t0, t0, t2);                  \
13340        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13341        gen_store_gpr(t1, reg);                            \
13342    } while (0)
13343
13344    if (do_ra) {
13345        DECR_AND_LOAD(31);
13346    }
13347
13348    switch (xsregs) {
13349    case 7:
13350        DECR_AND_LOAD(30);
13351        /* Fall through */
13352    case 6:
13353        DECR_AND_LOAD(23);
13354        /* Fall through */
13355    case 5:
13356        DECR_AND_LOAD(22);
13357        /* Fall through */
13358    case 4:
13359        DECR_AND_LOAD(21);
13360        /* Fall through */
13361    case 3:
13362        DECR_AND_LOAD(20);
13363        /* Fall through */
13364    case 2:
13365        DECR_AND_LOAD(19);
13366        /* Fall through */
13367    case 1:
13368        DECR_AND_LOAD(18);
13369    }
13370
13371    if (do_s1) {
13372        DECR_AND_LOAD(17);
13373    }
13374    if (do_s0) {
13375        DECR_AND_LOAD(16);
13376    }
13377
13378    switch (aregs) {
13379    case 0:
13380    case 4:
13381    case 8:
13382    case 12:
13383    case 14:
13384        astatic = 0;
13385        break;
13386    case 1:
13387    case 5:
13388    case 9:
13389    case 13:
13390        astatic = 1;
13391        break;
13392    case 2:
13393    case 6:
13394    case 10:
13395        astatic = 2;
13396        break;
13397    case 3:
13398    case 7:
13399        astatic = 3;
13400        break;
13401    case 11:
13402        astatic = 4;
13403        break;
13404    default:
13405        generate_exception_end(ctx, EXCP_RI);
13406        return;
13407    }
13408
13409    if (astatic > 0) {
13410        DECR_AND_LOAD(7);
13411        if (astatic > 1) {
13412            DECR_AND_LOAD(6);
13413            if (astatic > 2) {
13414                DECR_AND_LOAD(5);
13415                if (astatic > 3) {
13416                    DECR_AND_LOAD(4);
13417                }
13418            }
13419        }
13420    }
13421#undef DECR_AND_LOAD
13422
13423    tcg_gen_movi_tl(t2, framesize);
13424    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13425    tcg_temp_free(t0);
13426    tcg_temp_free(t1);
13427    tcg_temp_free(t2);
13428}
13429
13430static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13431                         int is_64_bit, int extended)
13432{
13433    TCGv t0;
13434
13435    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13436        generate_exception_end(ctx, EXCP_RI);
13437        return;
13438    }
13439
13440    t0 = tcg_temp_new();
13441
13442    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13443    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13444    if (!is_64_bit) {
13445        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13446    }
13447
13448    tcg_temp_free(t0);
13449}
13450
13451static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13452                                int16_t offset)
13453{
13454    TCGv_i32 t0 = tcg_const_i32(op);
13455    TCGv t1 = tcg_temp_new();
13456    gen_base_offset_addr(ctx, t1, base, offset);
13457    gen_helper_cache(cpu_env, t1, t0);
13458}
13459
13460#if defined(TARGET_MIPS64)
13461static void decode_i64_mips16 (DisasContext *ctx,
13462                               int ry, int funct, int16_t offset,
13463                               int extended)
13464{
13465    switch (funct) {
13466    case I64_LDSP:
13467        check_insn(ctx, ISA_MIPS3);
13468        check_mips_64(ctx);
13469        offset = extended ? offset : offset << 3;
13470        gen_ld(ctx, OPC_LD, ry, 29, offset);
13471        break;
13472    case I64_SDSP:
13473        check_insn(ctx, ISA_MIPS3);
13474        check_mips_64(ctx);
13475        offset = extended ? offset : offset << 3;
13476        gen_st(ctx, OPC_SD, ry, 29, offset);
13477        break;
13478    case I64_SDRASP:
13479        check_insn(ctx, ISA_MIPS3);
13480        check_mips_64(ctx);
13481        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13482        gen_st(ctx, OPC_SD, 31, 29, offset);
13483        break;
13484    case I64_DADJSP:
13485        check_insn(ctx, ISA_MIPS3);
13486        check_mips_64(ctx);
13487        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13488        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13489        break;
13490    case I64_LDPC:
13491        check_insn(ctx, ISA_MIPS3);
13492        check_mips_64(ctx);
13493        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13494            generate_exception_end(ctx, EXCP_RI);
13495        } else {
13496            offset = extended ? offset : offset << 3;
13497            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13498        }
13499        break;
13500    case I64_DADDIU5:
13501        check_insn(ctx, ISA_MIPS3);
13502        check_mips_64(ctx);
13503        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13504        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13505        break;
13506    case I64_DADDIUPC:
13507        check_insn(ctx, ISA_MIPS3);
13508        check_mips_64(ctx);
13509        offset = extended ? offset : offset << 2;
13510        gen_addiupc(ctx, ry, offset, 1, extended);
13511        break;
13512    case I64_DADDIUSP:
13513        check_insn(ctx, ISA_MIPS3);
13514        check_mips_64(ctx);
13515        offset = extended ? offset : offset << 2;
13516        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13517        break;
13518    }
13519}
13520#endif
13521
13522static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13523{
13524    int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13525    int op, rx, ry, funct, sa;
13526    int16_t imm, offset;
13527
13528    ctx->opcode = (ctx->opcode << 16) | extend;
13529    op = (ctx->opcode >> 11) & 0x1f;
13530    sa = (ctx->opcode >> 22) & 0x1f;
13531    funct = (ctx->opcode >> 8) & 0x7;
13532    rx = xlat((ctx->opcode >> 8) & 0x7);
13533    ry = xlat((ctx->opcode >> 5) & 0x7);
13534    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13535                              | ((ctx->opcode >> 21) & 0x3f) << 5
13536                              | (ctx->opcode & 0x1f));
13537
13538    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13539       counterparts.  */
13540    switch (op) {
13541    case M16_OPC_ADDIUSP:
13542        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13543        break;
13544    case M16_OPC_ADDIUPC:
13545        gen_addiupc(ctx, rx, imm, 0, 1);
13546        break;
13547    case M16_OPC_B:
13548        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13549        /* No delay slot, so just process as a normal instruction */
13550        break;
13551    case M16_OPC_BEQZ:
13552        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13553        /* No delay slot, so just process as a normal instruction */
13554        break;
13555    case M16_OPC_BNEQZ:
13556        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13557        /* No delay slot, so just process as a normal instruction */
13558        break;
13559    case M16_OPC_SHIFT:
13560        switch (ctx->opcode & 0x3) {
13561        case 0x0:
13562            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13563            break;
13564        case 0x1:
13565#if defined(TARGET_MIPS64)
13566            check_mips_64(ctx);
13567            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13568#else
13569            generate_exception_end(ctx, EXCP_RI);
13570#endif
13571            break;
13572        case 0x2:
13573            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13574            break;
13575        case 0x3:
13576            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13577            break;
13578        }
13579        break;
13580#if defined(TARGET_MIPS64)
13581    case M16_OPC_LD:
13582        check_insn(ctx, ISA_MIPS3);
13583        check_mips_64(ctx);
13584        gen_ld(ctx, OPC_LD, ry, rx, offset);
13585        break;
13586#endif
13587    case M16_OPC_RRIA:
13588        imm = ctx->opcode & 0xf;
13589        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13590        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13591        imm = (int16_t) (imm << 1) >> 1;
13592        if ((ctx->opcode >> 4) & 0x1) {
13593#if defined(TARGET_MIPS64)
13594            check_mips_64(ctx);
13595            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13596#else
13597            generate_exception_end(ctx, EXCP_RI);
13598#endif
13599        } else {
13600            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13601        }
13602        break;
13603    case M16_OPC_ADDIU8:
13604        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13605        break;
13606    case M16_OPC_SLTI:
13607        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13608        break;
13609    case M16_OPC_SLTIU:
13610        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13611        break;
13612    case M16_OPC_I8:
13613        switch (funct) {
13614        case I8_BTEQZ:
13615            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13616            break;
13617        case I8_BTNEZ:
13618            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13619            break;
13620        case I8_SWRASP:
13621            gen_st(ctx, OPC_SW, 31, 29, imm);
13622            break;
13623        case I8_ADJSP:
13624            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13625            break;
13626        case I8_SVRS:
13627            check_insn(ctx, ISA_MIPS32);
13628            {
13629                int xsregs = (ctx->opcode >> 24) & 0x7;
13630                int aregs = (ctx->opcode >> 16) & 0xf;
13631                int do_ra = (ctx->opcode >> 6) & 0x1;
13632                int do_s0 = (ctx->opcode >> 5) & 0x1;
13633                int do_s1 = (ctx->opcode >> 4) & 0x1;
13634                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13635                                 | (ctx->opcode & 0xf)) << 3;
13636
13637                if (ctx->opcode & (1 << 7)) {
13638                    gen_mips16_save(ctx, xsregs, aregs,
13639                                    do_ra, do_s0, do_s1,
13640                                    framesize);
13641                } else {
13642                    gen_mips16_restore(ctx, xsregs, aregs,
13643                                       do_ra, do_s0, do_s1,
13644                                       framesize);
13645                }
13646            }
13647            break;
13648        default:
13649            generate_exception_end(ctx, EXCP_RI);
13650            break;
13651        }
13652        break;
13653    case M16_OPC_LI:
13654        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13655        break;
13656    case M16_OPC_CMPI:
13657        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13658        break;
13659#if defined(TARGET_MIPS64)
13660    case M16_OPC_SD:
13661        check_insn(ctx, ISA_MIPS3);
13662        check_mips_64(ctx);
13663        gen_st(ctx, OPC_SD, ry, rx, offset);
13664        break;
13665#endif
13666    case M16_OPC_LB:
13667        gen_ld(ctx, OPC_LB, ry, rx, offset);
13668        break;
13669    case M16_OPC_LH:
13670        gen_ld(ctx, OPC_LH, ry, rx, offset);
13671        break;
13672    case M16_OPC_LWSP:
13673        gen_ld(ctx, OPC_LW, rx, 29, offset);
13674        break;
13675    case M16_OPC_LW:
13676        gen_ld(ctx, OPC_LW, ry, rx, offset);
13677        break;
13678    case M16_OPC_LBU:
13679        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13680        break;
13681    case M16_OPC_LHU:
13682        gen_ld(ctx, OPC_LHU, ry, rx, offset);
13683        break;
13684    case M16_OPC_LWPC:
13685        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13686        break;
13687#if defined(TARGET_MIPS64)
13688    case M16_OPC_LWU:
13689        check_insn(ctx, ISA_MIPS3);
13690        check_mips_64(ctx);
13691        gen_ld(ctx, OPC_LWU, ry, rx, offset);
13692        break;
13693#endif
13694    case M16_OPC_SB:
13695        gen_st(ctx, OPC_SB, ry, rx, offset);
13696        break;
13697    case M16_OPC_SH:
13698        gen_st(ctx, OPC_SH, ry, rx, offset);
13699        break;
13700    case M16_OPC_SWSP:
13701        gen_st(ctx, OPC_SW, rx, 29, offset);
13702        break;
13703    case M16_OPC_SW:
13704        gen_st(ctx, OPC_SW, ry, rx, offset);
13705        break;
13706#if defined(TARGET_MIPS64)
13707    case M16_OPC_I64:
13708        decode_i64_mips16(ctx, ry, funct, offset, 1);
13709        break;
13710#endif
13711    default:
13712        generate_exception_end(ctx, EXCP_RI);
13713        break;
13714    }
13715
13716    return 4;
13717}
13718
13719static inline bool is_uhi(int sdbbp_code)
13720{
13721#ifdef CONFIG_USER_ONLY
13722    return false;
13723#else
13724    return semihosting_enabled() && sdbbp_code == 1;
13725#endif
13726}
13727
13728static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13729{
13730    int rx, ry;
13731    int sa;
13732    int op, cnvt_op, op1, offset;
13733    int funct;
13734    int n_bytes;
13735
13736    op = (ctx->opcode >> 11) & 0x1f;
13737    sa = (ctx->opcode >> 2) & 0x7;
13738    sa = sa == 0 ? 8 : sa;
13739    rx = xlat((ctx->opcode >> 8) & 0x7);
13740    cnvt_op = (ctx->opcode >> 5) & 0x7;
13741    ry = xlat((ctx->opcode >> 5) & 0x7);
13742    op1 = offset = ctx->opcode & 0x1f;
13743
13744    n_bytes = 2;
13745
13746    switch (op) {
13747    case M16_OPC_ADDIUSP:
13748        {
13749            int16_t imm = ((uint8_t) ctx->opcode) << 2;
13750
13751            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13752        }
13753        break;
13754    case M16_OPC_ADDIUPC:
13755        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13756        break;
13757    case M16_OPC_B:
13758        offset = (ctx->opcode & 0x7ff) << 1;
13759        offset = (int16_t)(offset << 4) >> 4;
13760        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13761        /* No delay slot, so just process as a normal instruction */
13762        break;
13763    case M16_OPC_JAL:
13764        offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13765        offset = (((ctx->opcode & 0x1f) << 21)
13766                  | ((ctx->opcode >> 5) & 0x1f) << 16
13767                  | offset) << 2;
13768        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13769        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13770        n_bytes = 4;
13771        break;
13772    case M16_OPC_BEQZ:
13773        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13774                           ((int8_t)ctx->opcode) << 1, 0);
13775        /* No delay slot, so just process as a normal instruction */
13776        break;
13777    case M16_OPC_BNEQZ:
13778        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13779                           ((int8_t)ctx->opcode) << 1, 0);
13780        /* No delay slot, so just process as a normal instruction */
13781        break;
13782    case M16_OPC_SHIFT:
13783        switch (ctx->opcode & 0x3) {
13784        case 0x0:
13785            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13786            break;
13787        case 0x1:
13788#if defined(TARGET_MIPS64)
13789            check_insn(ctx, ISA_MIPS3);
13790            check_mips_64(ctx);
13791            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13792#else
13793            generate_exception_end(ctx, EXCP_RI);
13794#endif
13795            break;
13796        case 0x2:
13797            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13798            break;
13799        case 0x3:
13800            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13801            break;
13802        }
13803        break;
13804#if defined(TARGET_MIPS64)
13805    case M16_OPC_LD:
13806        check_insn(ctx, ISA_MIPS3);
13807        check_mips_64(ctx);
13808        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13809        break;
13810#endif
13811    case M16_OPC_RRIA:
13812        {
13813            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13814
13815            if ((ctx->opcode >> 4) & 1) {
13816#if defined(TARGET_MIPS64)
13817                check_insn(ctx, ISA_MIPS3);
13818                check_mips_64(ctx);
13819                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13820#else
13821                generate_exception_end(ctx, EXCP_RI);
13822#endif
13823            } else {
13824                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13825            }
13826        }
13827        break;
13828    case M16_OPC_ADDIU8:
13829        {
13830            int16_t imm = (int8_t) ctx->opcode;
13831
13832            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13833        }
13834        break;
13835    case M16_OPC_SLTI:
13836        {
13837            int16_t imm = (uint8_t) ctx->opcode;
13838            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13839        }
13840        break;
13841    case M16_OPC_SLTIU:
13842        {
13843            int16_t imm = (uint8_t) ctx->opcode;
13844            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13845        }
13846        break;
13847    case M16_OPC_I8:
13848        {
13849            int reg32;
13850
13851            funct = (ctx->opcode >> 8) & 0x7;
13852            switch (funct) {
13853            case I8_BTEQZ:
13854                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13855                                   ((int8_t)ctx->opcode) << 1, 0);
13856                break;
13857            case I8_BTNEZ:
13858                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13859                                   ((int8_t)ctx->opcode) << 1, 0);
13860                break;
13861            case I8_SWRASP:
13862                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13863                break;
13864            case I8_ADJSP:
13865                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13866                              ((int8_t)ctx->opcode) << 3);
13867                break;
13868            case I8_SVRS:
13869                check_insn(ctx, ISA_MIPS32);
13870                {
13871                    int do_ra = ctx->opcode & (1 << 6);
13872                    int do_s0 = ctx->opcode & (1 << 5);
13873                    int do_s1 = ctx->opcode & (1 << 4);
13874                    int framesize = ctx->opcode & 0xf;
13875
13876                    if (framesize == 0) {
13877                        framesize = 128;
13878                    } else {
13879                        framesize = framesize << 3;
13880                    }
13881
13882                    if (ctx->opcode & (1 << 7)) {
13883                        gen_mips16_save(ctx, 0, 0,
13884                                        do_ra, do_s0, do_s1, framesize);
13885                    } else {
13886                        gen_mips16_restore(ctx, 0, 0,
13887                                           do_ra, do_s0, do_s1, framesize);
13888                    }
13889                }
13890                break;
13891            case I8_MOV32R:
13892                {
13893                    int rz = xlat(ctx->opcode & 0x7);
13894
13895                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13896                        ((ctx->opcode >> 5) & 0x7);
13897                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13898                }
13899                break;
13900            case I8_MOVR32:
13901                reg32 = ctx->opcode & 0x1f;
13902                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13903                break;
13904            default:
13905                generate_exception_end(ctx, EXCP_RI);
13906                break;
13907            }
13908        }
13909        break;
13910    case M16_OPC_LI:
13911        {
13912            int16_t imm = (uint8_t) ctx->opcode;
13913
13914            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13915        }
13916        break;
13917    case M16_OPC_CMPI:
13918        {
13919            int16_t imm = (uint8_t) ctx->opcode;
13920            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13921        }
13922        break;
13923#if defined(TARGET_MIPS64)
13924    case M16_OPC_SD:
13925        check_insn(ctx, ISA_MIPS3);
13926        check_mips_64(ctx);
13927        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13928        break;
13929#endif
13930    case M16_OPC_LB:
13931        gen_ld(ctx, OPC_LB, ry, rx, offset);
13932        break;
13933    case M16_OPC_LH:
13934        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13935        break;
13936    case M16_OPC_LWSP:
13937        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13938        break;
13939    case M16_OPC_LW:
13940        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13941        break;
13942    case M16_OPC_LBU:
13943        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13944        break;
13945    case M16_OPC_LHU:
13946        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13947        break;
13948    case M16_OPC_LWPC:
13949        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13950        break;
13951#if defined (TARGET_MIPS64)
13952    case M16_OPC_LWU:
13953        check_insn(ctx, ISA_MIPS3);
13954        check_mips_64(ctx);
13955        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13956        break;
13957#endif
13958    case M16_OPC_SB:
13959        gen_st(ctx, OPC_SB, ry, rx, offset);
13960        break;
13961    case M16_OPC_SH:
13962        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13963        break;
13964    case M16_OPC_SWSP:
13965        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13966        break;
13967    case M16_OPC_SW:
13968        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13969        break;
13970    case M16_OPC_RRR:
13971        {
13972            int rz = xlat((ctx->opcode >> 2) & 0x7);
13973            int mips32_op;
13974
13975            switch (ctx->opcode & 0x3) {
13976            case RRR_ADDU:
13977                mips32_op = OPC_ADDU;
13978                break;
13979            case RRR_SUBU:
13980                mips32_op = OPC_SUBU;
13981                break;
13982#if defined(TARGET_MIPS64)
13983            case RRR_DADDU:
13984                mips32_op = OPC_DADDU;
13985                check_insn(ctx, ISA_MIPS3);
13986                check_mips_64(ctx);
13987                break;
13988            case RRR_DSUBU:
13989                mips32_op = OPC_DSUBU;
13990                check_insn(ctx, ISA_MIPS3);
13991                check_mips_64(ctx);
13992                break;
13993#endif
13994            default:
13995                generate_exception_end(ctx, EXCP_RI);
13996                goto done;
13997            }
13998
13999            gen_arith(ctx, mips32_op, rz, rx, ry);
14000        done:
14001            ;
14002        }
14003        break;
14004    case M16_OPC_RR:
14005        switch (op1) {
14006        case RR_JR:
14007            {
14008                int nd = (ctx->opcode >> 7) & 0x1;
14009                int link = (ctx->opcode >> 6) & 0x1;
14010                int ra = (ctx->opcode >> 5) & 0x1;
14011
14012                if (nd) {
14013                    check_insn(ctx, ISA_MIPS32);
14014                }
14015
14016                if (link) {
14017                    op = OPC_JALR;
14018                } else {
14019                    op = OPC_JR;
14020                }
14021
14022                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14023                                   (nd ? 0 : 2));
14024            }
14025            break;
14026        case RR_SDBBP:
14027            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14028                gen_helper_do_semihosting(cpu_env);
14029            } else {
14030                /* XXX: not clear which exception should be raised
14031                 *      when in debug mode...
14032                 */
14033                check_insn(ctx, ISA_MIPS32);
14034                generate_exception_end(ctx, EXCP_DBp);
14035            }
14036            break;
14037        case RR_SLT:
14038            gen_slt(ctx, OPC_SLT, 24, rx, ry);
14039            break;
14040        case RR_SLTU:
14041            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14042            break;
14043        case RR_BREAK:
14044            generate_exception_end(ctx, EXCP_BREAK);
14045            break;
14046        case RR_SLLV:
14047            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14048            break;
14049        case RR_SRLV:
14050            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14051            break;
14052        case RR_SRAV:
14053            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14054            break;
14055#if defined (TARGET_MIPS64)
14056        case RR_DSRL:
14057            check_insn(ctx, ISA_MIPS3);
14058            check_mips_64(ctx);
14059            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14060            break;
14061#endif
14062        case RR_CMP:
14063            gen_logic(ctx, OPC_XOR, 24, rx, ry);
14064            break;
14065        case RR_NEG:
14066            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14067            break;
14068        case RR_AND:
14069            gen_logic(ctx, OPC_AND, rx, rx, ry);
14070            break;
14071        case RR_OR:
14072            gen_logic(ctx, OPC_OR, rx, rx, ry);
14073            break;
14074        case RR_XOR:
14075            gen_logic(ctx, OPC_XOR, rx, rx, ry);
14076            break;
14077        case RR_NOT:
14078            gen_logic(ctx, OPC_NOR, rx, ry, 0);
14079            break;
14080        case RR_MFHI:
14081            gen_HILO(ctx, OPC_MFHI, 0, rx);
14082            break;
14083        case RR_CNVT:
14084            check_insn(ctx, ISA_MIPS32);
14085            switch (cnvt_op) {
14086            case RR_RY_CNVT_ZEB:
14087                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14088                break;
14089            case RR_RY_CNVT_ZEH:
14090                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14091                break;
14092            case RR_RY_CNVT_SEB:
14093                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14094                break;
14095            case RR_RY_CNVT_SEH:
14096                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14097                break;
14098#if defined (TARGET_MIPS64)
14099            case RR_RY_CNVT_ZEW:
14100                check_insn(ctx, ISA_MIPS64);
14101                check_mips_64(ctx);
14102                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14103                break;
14104            case RR_RY_CNVT_SEW:
14105                check_insn(ctx, ISA_MIPS64);
14106                check_mips_64(ctx);
14107                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14108                break;
14109#endif
14110            default:
14111                generate_exception_end(ctx, EXCP_RI);
14112                break;
14113            }
14114            break;
14115        case RR_MFLO:
14116            gen_HILO(ctx, OPC_MFLO, 0, rx);
14117            break;
14118#if defined (TARGET_MIPS64)
14119        case RR_DSRA:
14120            check_insn(ctx, ISA_MIPS3);
14121            check_mips_64(ctx);
14122            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14123            break;
14124        case RR_DSLLV:
14125            check_insn(ctx, ISA_MIPS3);
14126            check_mips_64(ctx);
14127            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14128            break;
14129        case RR_DSRLV:
14130            check_insn(ctx, ISA_MIPS3);
14131            check_mips_64(ctx);
14132            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14133            break;
14134        case RR_DSRAV:
14135            check_insn(ctx, ISA_MIPS3);
14136            check_mips_64(ctx);
14137            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14138            break;
14139#endif
14140        case RR_MULT:
14141            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14142            break;
14143        case RR_MULTU:
14144            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14145            break;
14146        case RR_DIV:
14147            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14148            break;
14149        case RR_DIVU:
14150            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14151            break;
14152#if defined (TARGET_MIPS64)
14153        case RR_DMULT:
14154            check_insn(ctx, ISA_MIPS3);
14155            check_mips_64(ctx);
14156            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14157            break;
14158        case RR_DMULTU:
14159            check_insn(ctx, ISA_MIPS3);
14160            check_mips_64(ctx);
14161            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14162            break;
14163        case RR_DDIV:
14164            check_insn(ctx, ISA_MIPS3);
14165            check_mips_64(ctx);
14166            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14167            break;
14168        case RR_DDIVU:
14169            check_insn(ctx, ISA_MIPS3);
14170            check_mips_64(ctx);
14171            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14172            break;
14173#endif
14174        default:
14175            generate_exception_end(ctx, EXCP_RI);
14176            break;
14177        }
14178        break;
14179    case M16_OPC_EXTEND:
14180        decode_extended_mips16_opc(env, ctx);
14181        n_bytes = 4;
14182        break;
14183#if defined(TARGET_MIPS64)
14184    case M16_OPC_I64:
14185        funct = (ctx->opcode >> 8) & 0x7;
14186        decode_i64_mips16(ctx, ry, funct, offset, 0);
14187        break;
14188#endif
14189    default:
14190        generate_exception_end(ctx, EXCP_RI);
14191        break;
14192    }
14193
14194    return n_bytes;
14195}
14196
14197/* microMIPS extension to MIPS32/MIPS64 */
14198
14199/*
14200 * microMIPS32/microMIPS64 major opcodes
14201 *
14202 * 1. MIPS Architecture for Programmers Volume II-B:
14203 *      The microMIPS32 Instruction Set (Revision 3.05)
14204 *
14205 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14206 *
14207 * 2. MIPS Architecture For Programmers Volume II-A:
14208 *      The MIPS64 Instruction Set (Revision 3.51)
14209 */
14210
14211enum {
14212    POOL32A = 0x00,
14213    POOL16A = 0x01,
14214    LBU16 = 0x02,
14215    MOVE16 = 0x03,
14216    ADDI32 = 0x04,
14217    R6_LUI = 0x04,
14218    AUI = 0x04,
14219    LBU32 = 0x05,
14220    SB32 = 0x06,
14221    LB32 = 0x07,
14222
14223    POOL32B = 0x08,
14224    POOL16B = 0x09,
14225    LHU16 = 0x0a,
14226    ANDI16 = 0x0b,
14227    ADDIU32 = 0x0c,
14228    LHU32 = 0x0d,
14229    SH32 = 0x0e,
14230    LH32 = 0x0f,
14231
14232    POOL32I = 0x10,
14233    POOL16C = 0x11,
14234    LWSP16 = 0x12,
14235    POOL16D = 0x13,
14236    ORI32 = 0x14,
14237    POOL32F = 0x15,
14238    POOL32S = 0x16,  /* MIPS64 */
14239    DADDIU32 = 0x17, /* MIPS64 */
14240
14241    POOL32C = 0x18,
14242    LWGP16 = 0x19,
14243    LW16 = 0x1a,
14244    POOL16E = 0x1b,
14245    XORI32 = 0x1c,
14246    JALS32 = 0x1d,
14247    BOVC = 0x1d,
14248    BEQC = 0x1d,
14249    BEQZALC = 0x1d,
14250    ADDIUPC = 0x1e,
14251    PCREL = 0x1e,
14252    BNVC = 0x1f,
14253    BNEC = 0x1f,
14254    BNEZALC = 0x1f,
14255
14256    R6_BEQZC = 0x20,
14257    JIC = 0x20,
14258    POOL16F = 0x21,
14259    SB16 = 0x22,
14260    BEQZ16 = 0x23,
14261    BEQZC16 = 0x23,
14262    SLTI32 = 0x24,
14263    BEQ32 = 0x25,
14264    BC = 0x25,
14265    SWC132 = 0x26,
14266    LWC132 = 0x27,
14267
14268    /* 0x29 is reserved */
14269    RES_29 = 0x29,
14270    R6_BNEZC = 0x28,
14271    JIALC = 0x28,
14272    SH16 = 0x2a,
14273    BNEZ16 = 0x2b,
14274    BNEZC16 = 0x2b,
14275    SLTIU32 = 0x2c,
14276    BNE32 = 0x2d,
14277    BALC = 0x2d,
14278    SDC132 = 0x2e,
14279    LDC132 = 0x2f,
14280
14281    /* 0x31 is reserved */
14282    RES_31 = 0x31,
14283    BLEZALC = 0x30,
14284    BGEZALC = 0x30,
14285    BGEUC = 0x30,
14286    SWSP16 = 0x32,
14287    B16 = 0x33,
14288    BC16 = 0x33,
14289    ANDI32 = 0x34,
14290    J32 = 0x35,
14291    BGTZC = 0x35,
14292    BLTZC = 0x35,
14293    BLTC = 0x35,
14294    SD32 = 0x36, /* MIPS64 */
14295    LD32 = 0x37, /* MIPS64 */
14296
14297    /* 0x39 is reserved */
14298    RES_39 = 0x39,
14299    BGTZALC = 0x38,
14300    BLTZALC = 0x38,
14301    BLTUC = 0x38,
14302    SW16 = 0x3a,
14303    LI16 = 0x3b,
14304    JALX32 = 0x3c,
14305    JAL32 = 0x3d,
14306    BLEZC = 0x3d,
14307    BGEZC = 0x3d,
14308    BGEC = 0x3d,
14309    SW32 = 0x3e,
14310    LW32 = 0x3f
14311};
14312
14313/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14314enum {
14315    ADDIUPC_00 = 0x00,
14316    ADDIUPC_01 = 0x01,
14317    ADDIUPC_02 = 0x02,
14318    ADDIUPC_03 = 0x03,
14319    ADDIUPC_04 = 0x04,
14320    ADDIUPC_05 = 0x05,
14321    ADDIUPC_06 = 0x06,
14322    ADDIUPC_07 = 0x07,
14323    AUIPC = 0x1e,
14324    ALUIPC = 0x1f,
14325    LWPC_08 = 0x08,
14326    LWPC_09 = 0x09,
14327    LWPC_0A = 0x0A,
14328    LWPC_0B = 0x0B,
14329    LWPC_0C = 0x0C,
14330    LWPC_0D = 0x0D,
14331    LWPC_0E = 0x0E,
14332    LWPC_0F = 0x0F,
14333};
14334
14335/* POOL32A encoding of minor opcode field */
14336
14337enum {
14338    /* These opcodes are distinguished only by bits 9..6; those bits are
14339     * what are recorded below. */
14340    SLL32 = 0x0,
14341    SRL32 = 0x1,
14342    SRA = 0x2,
14343    ROTR = 0x3,
14344    SELEQZ = 0x5,
14345    SELNEZ = 0x6,
14346    R6_RDHWR = 0x7,
14347
14348    SLLV = 0x0,
14349    SRLV = 0x1,
14350    SRAV = 0x2,
14351    ROTRV = 0x3,
14352    ADD = 0x4,
14353    ADDU32 = 0x5,
14354    SUB = 0x6,
14355    SUBU32 = 0x7,
14356    MUL = 0x8,
14357    AND = 0x9,
14358    OR32 = 0xa,
14359    NOR = 0xb,
14360    XOR32 = 0xc,
14361    SLT = 0xd,
14362    SLTU = 0xe,
14363
14364    MOVN = 0x0,
14365    R6_MUL  = 0x0,
14366    MOVZ = 0x1,
14367    MUH  = 0x1,
14368    MULU = 0x2,
14369    MUHU = 0x3,
14370    LWXS = 0x4,
14371    R6_DIV  = 0x4,
14372    MOD  = 0x5,
14373    R6_DIVU = 0x6,
14374    MODU = 0x7,
14375
14376    /* The following can be distinguished by their lower 6 bits. */
14377    BREAK32 = 0x07,
14378    INS = 0x0c,
14379    LSA = 0x0f,
14380    ALIGN = 0x1f,
14381    EXT = 0x2c,
14382    POOL32AXF = 0x3c,
14383    SIGRIE = 0x3f
14384};
14385
14386/* POOL32AXF encoding of minor opcode field extension */
14387
14388/*
14389 * 1. MIPS Architecture for Programmers Volume II-B:
14390 *      The microMIPS32 Instruction Set (Revision 3.05)
14391 *
14392 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14393 *
14394 * 2. MIPS Architecture for Programmers VolumeIV-e:
14395 *      The MIPS DSP Application-Specific Extension
14396 *        to the microMIPS32 Architecture (Revision 2.34)
14397 *
14398 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14399 */
14400
14401enum {
14402    /* bits 11..6 */
14403    TEQ = 0x00,
14404    TGE = 0x08,
14405    TGEU = 0x10,
14406    TLT = 0x20,
14407    TLTU = 0x28,
14408    TNE = 0x30,
14409
14410    MFC0 = 0x03,
14411    MTC0 = 0x0b,
14412
14413    /* begin of microMIPS32 DSP */
14414
14415    /* bits 13..12 for 0x01 */
14416    MFHI_ACC = 0x0,
14417    MFLO_ACC = 0x1,
14418    MTHI_ACC = 0x2,
14419    MTLO_ACC = 0x3,
14420
14421    /* bits 13..12 for 0x2a */
14422    MADD_ACC = 0x0,
14423    MADDU_ACC = 0x1,
14424    MSUB_ACC = 0x2,
14425    MSUBU_ACC = 0x3,
14426
14427    /* bits 13..12 for 0x32 */
14428    MULT_ACC = 0x0,
14429    MULTU_ACC = 0x1,
14430
14431    /* end of microMIPS32 DSP */
14432
14433    /* bits 15..12 for 0x2c */
14434    BITSWAP = 0x0,
14435    SEB = 0x2,
14436    SEH = 0x3,
14437    CLO = 0x4,
14438    CLZ = 0x5,
14439    RDHWR = 0x6,
14440    WSBH = 0x7,
14441    MULT = 0x8,
14442    MULTU = 0x9,
14443    DIV = 0xa,
14444    DIVU = 0xb,
14445    MADD = 0xc,
14446    MADDU = 0xd,
14447    MSUB = 0xe,
14448    MSUBU = 0xf,
14449
14450    /* bits 15..12 for 0x34 */
14451    MFC2 = 0x4,
14452    MTC2 = 0x5,
14453    MFHC2 = 0x8,
14454    MTHC2 = 0x9,
14455    CFC2 = 0xc,
14456    CTC2 = 0xd,
14457
14458    /* bits 15..12 for 0x3c */
14459    JALR = 0x0,
14460    JR = 0x0,                   /* alias */
14461    JALRC = 0x0,
14462    JRC = 0x0,
14463    JALR_HB = 0x1,
14464    JALRC_HB = 0x1,
14465    JALRS = 0x4,
14466    JALRS_HB = 0x5,
14467
14468    /* bits 15..12 for 0x05 */
14469    RDPGPR = 0xe,
14470    WRPGPR = 0xf,
14471
14472    /* bits 15..12 for 0x0d */
14473    TLBP = 0x0,
14474    TLBR = 0x1,
14475    TLBWI = 0x2,
14476    TLBWR = 0x3,
14477    TLBINV = 0x4,
14478    TLBINVF = 0x5,
14479    WAIT = 0x9,
14480    IRET = 0xd,
14481    DERET = 0xe,
14482    ERET = 0xf,
14483
14484    /* bits 15..12 for 0x15 */
14485    DMT = 0x0,
14486    DVPE = 0x1,
14487    EMT = 0x2,
14488    EVPE = 0x3,
14489
14490    /* bits 15..12 for 0x1d */
14491    DI = 0x4,
14492    EI = 0x5,
14493
14494    /* bits 15..12 for 0x2d */
14495    SYNC = 0x6,
14496    SYSCALL = 0x8,
14497    SDBBP = 0xd,
14498
14499    /* bits 15..12 for 0x35 */
14500    MFHI32 = 0x0,
14501    MFLO32 = 0x1,
14502    MTHI32 = 0x2,
14503    MTLO32 = 0x3,
14504};
14505
14506/* POOL32B encoding of minor opcode field (bits 15..12) */
14507
14508enum {
14509    LWC2 = 0x0,
14510    LWP = 0x1,
14511    LDP = 0x4,
14512    LWM32 = 0x5,
14513    CACHE = 0x6,
14514    LDM = 0x7,
14515    SWC2 = 0x8,
14516    SWP = 0x9,
14517    SDP = 0xc,
14518    SWM32 = 0xd,
14519    SDM = 0xf
14520};
14521
14522/* POOL32C encoding of minor opcode field (bits 15..12) */
14523
14524enum {
14525    LWL = 0x0,
14526    SWL = 0x8,
14527    LWR = 0x1,
14528    SWR = 0x9,
14529    PREF = 0x2,
14530    ST_EVA = 0xa,
14531    LL = 0x3,
14532    SC = 0xb,
14533    LDL = 0x4,
14534    SDL = 0xc,
14535    LDR = 0x5,
14536    SDR = 0xd,
14537    LD_EVA = 0x6,
14538    LWU = 0xe,
14539    LLD = 0x7,
14540    SCD = 0xf
14541};
14542
14543/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14544
14545enum {
14546    LBUE = 0x0,
14547    LHUE = 0x1,
14548    LWLE = 0x2,
14549    LWRE = 0x3,
14550    LBE = 0x4,
14551    LHE = 0x5,
14552    LLE = 0x6,
14553    LWE = 0x7,
14554};
14555
14556/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14557
14558enum {
14559    SWLE = 0x0,
14560    SWRE = 0x1,
14561    PREFE = 0x2,
14562    CACHEE = 0x3,
14563    SBE = 0x4,
14564    SHE = 0x5,
14565    SCE = 0x6,
14566    SWE = 0x7,
14567};
14568
14569/* POOL32F encoding of minor opcode field (bits 5..0) */
14570
14571enum {
14572    /* These are the bit 7..6 values */
14573    ADD_FMT = 0x0,
14574
14575    SUB_FMT = 0x1,
14576
14577    MUL_FMT = 0x2,
14578
14579    DIV_FMT = 0x3,
14580
14581    /* These are the bit 8..6 values */
14582    MOVN_FMT = 0x0,
14583    RSQRT2_FMT = 0x0,
14584    MOVF_FMT = 0x0,
14585    RINT_FMT = 0x0,
14586    SELNEZ_FMT = 0x0,
14587
14588    MOVZ_FMT = 0x1,
14589    LWXC1 = 0x1,
14590    MOVT_FMT = 0x1,
14591    CLASS_FMT = 0x1,
14592    SELEQZ_FMT = 0x1,
14593
14594    PLL_PS = 0x2,
14595    SWXC1 = 0x2,
14596    SEL_FMT = 0x2,
14597
14598    PLU_PS = 0x3,
14599    LDXC1 = 0x3,
14600
14601    MOVN_FMT_04 = 0x4,
14602    PUL_PS = 0x4,
14603    SDXC1 = 0x4,
14604    RECIP2_FMT = 0x4,
14605
14606    MOVZ_FMT_05 = 0x05,
14607    PUU_PS = 0x5,
14608    LUXC1 = 0x5,
14609
14610    CVT_PS_S = 0x6,
14611    SUXC1 = 0x6,
14612    ADDR_PS = 0x6,
14613    PREFX = 0x6,
14614    MADDF_FMT = 0x6,
14615
14616    MULR_PS = 0x7,
14617    MSUBF_FMT = 0x7,
14618
14619    MADD_S = 0x01,
14620    MADD_D = 0x09,
14621    MADD_PS = 0x11,
14622    ALNV_PS = 0x19,
14623    MSUB_S = 0x21,
14624    MSUB_D = 0x29,
14625    MSUB_PS = 0x31,
14626
14627    NMADD_S = 0x02,
14628    NMADD_D = 0x0a,
14629    NMADD_PS = 0x12,
14630    NMSUB_S = 0x22,
14631    NMSUB_D = 0x2a,
14632    NMSUB_PS = 0x32,
14633
14634    MIN_FMT = 0x3,
14635    MAX_FMT = 0xb,
14636    MINA_FMT = 0x23,
14637    MAXA_FMT = 0x2b,
14638    POOL32FXF = 0x3b,
14639
14640    CABS_COND_FMT = 0x1c,              /* MIPS3D */
14641    C_COND_FMT = 0x3c,
14642
14643    CMP_CONDN_S = 0x5,
14644    CMP_CONDN_D = 0x15
14645};
14646
14647/* POOL32Fxf encoding of minor opcode extension field */
14648
14649enum {
14650    CVT_L = 0x04,
14651    RSQRT_FMT = 0x08,
14652    FLOOR_L = 0x0c,
14653    CVT_PW_PS = 0x1c,
14654    CVT_W = 0x24,
14655    SQRT_FMT = 0x28,
14656    FLOOR_W = 0x2c,
14657    CVT_PS_PW = 0x3c,
14658    CFC1 = 0x40,
14659    RECIP_FMT = 0x48,
14660    CEIL_L = 0x4c,
14661    CTC1 = 0x60,
14662    CEIL_W = 0x6c,
14663    MFC1 = 0x80,
14664    CVT_S_PL = 0x84,
14665    TRUNC_L = 0x8c,
14666    MTC1 = 0xa0,
14667    CVT_S_PU = 0xa4,
14668    TRUNC_W = 0xac,
14669    MFHC1 = 0xc0,
14670    ROUND_L = 0xcc,
14671    MTHC1 = 0xe0,
14672    ROUND_W = 0xec,
14673
14674    MOV_FMT = 0x01,
14675    MOVF = 0x05,
14676    ABS_FMT = 0x0d,
14677    RSQRT1_FMT = 0x1d,
14678    MOVT = 0x25,
14679    NEG_FMT = 0x2d,
14680    CVT_D = 0x4d,
14681    RECIP1_FMT = 0x5d,
14682    CVT_S = 0x6d
14683};
14684
14685/* POOL32I encoding of minor opcode field (bits 25..21) */
14686
14687enum {
14688    BLTZ = 0x00,
14689    BLTZAL = 0x01,
14690    BGEZ = 0x02,
14691    BGEZAL = 0x03,
14692    BLEZ = 0x04,
14693    BNEZC = 0x05,
14694    BGTZ = 0x06,
14695    BEQZC = 0x07,
14696    TLTI = 0x08,
14697    BC1EQZC = 0x08,
14698    TGEI = 0x09,
14699    BC1NEZC = 0x09,
14700    TLTIU = 0x0a,
14701    BC2EQZC = 0x0a,
14702    TGEIU = 0x0b,
14703    BC2NEZC = 0x0a,
14704    TNEI = 0x0c,
14705    R6_SYNCI = 0x0c,
14706    LUI = 0x0d,
14707    TEQI = 0x0e,
14708    SYNCI = 0x10,
14709    BLTZALS = 0x11,
14710    BGEZALS = 0x13,
14711    BC2F = 0x14,
14712    BC2T = 0x15,
14713    BPOSGE64 = 0x1a,
14714    BPOSGE32 = 0x1b,
14715    /* These overlap and are distinguished by bit16 of the instruction */
14716    BC1F = 0x1c,
14717    BC1T = 0x1d,
14718    BC1ANY2F = 0x1c,
14719    BC1ANY2T = 0x1d,
14720    BC1ANY4F = 0x1e,
14721    BC1ANY4T = 0x1f
14722};
14723
14724/* POOL16A encoding of minor opcode field */
14725
14726enum {
14727    ADDU16 = 0x0,
14728    SUBU16 = 0x1
14729};
14730
14731/* POOL16B encoding of minor opcode field */
14732
14733enum {
14734    SLL16 = 0x0,
14735    SRL16 = 0x1
14736};
14737
14738/* POOL16C encoding of minor opcode field */
14739
14740enum {
14741    NOT16 = 0x00,
14742    XOR16 = 0x04,
14743    AND16 = 0x08,
14744    OR16 = 0x0c,
14745    LWM16 = 0x10,
14746    SWM16 = 0x14,
14747    JR16 = 0x18,
14748    JRC16 = 0x1a,
14749    JALR16 = 0x1c,
14750    JALR16S = 0x1e,
14751    MFHI16 = 0x20,
14752    MFLO16 = 0x24,
14753    BREAK16 = 0x28,
14754    SDBBP16 = 0x2c,
14755    JRADDIUSP = 0x30
14756};
14757
14758/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14759
14760enum {
14761    R6_NOT16    = 0x00,
14762    R6_AND16    = 0x01,
14763    R6_LWM16    = 0x02,
14764    R6_JRC16    = 0x03,
14765    MOVEP       = 0x04,
14766    MOVEP_05    = 0x05,
14767    MOVEP_06    = 0x06,
14768    MOVEP_07    = 0x07,
14769    R6_XOR16    = 0x08,
14770    R6_OR16     = 0x09,
14771    R6_SWM16    = 0x0a,
14772    JALRC16     = 0x0b,
14773    MOVEP_0C    = 0x0c,
14774    MOVEP_0D    = 0x0d,
14775    MOVEP_0E    = 0x0e,
14776    MOVEP_0F    = 0x0f,
14777    JRCADDIUSP  = 0x13,
14778    R6_BREAK16  = 0x1b,
14779    R6_SDBBP16  = 0x3b
14780};
14781
14782/* POOL16D encoding of minor opcode field */
14783
14784enum {
14785    ADDIUS5 = 0x0,
14786    ADDIUSP = 0x1
14787};
14788
14789/* POOL16E encoding of minor opcode field */
14790
14791enum {
14792    ADDIUR2 = 0x0,
14793    ADDIUR1SP = 0x1
14794};
14795
14796static int mmreg (int r)
14797{
14798    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14799
14800    return map[r];
14801}
14802
14803/* Used for 16-bit store instructions.  */
14804static int mmreg2 (int r)
14805{
14806    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14807
14808    return map[r];
14809}
14810
14811#define uMIPS_RD(op) ((op >> 7) & 0x7)
14812#define uMIPS_RS(op) ((op >> 4) & 0x7)
14813#define uMIPS_RS2(op) uMIPS_RS(op)
14814#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14815#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14816#define uMIPS_RS5(op) (op & 0x1f)
14817
14818/* Signed immediate */
14819#define SIMM(op, start, width)                                          \
14820    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14821               << (32-width))                                           \
14822     >> (32-width))
14823/* Zero-extended immediate */
14824#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14825
14826static void gen_addiur1sp(DisasContext *ctx)
14827{
14828    int rd = mmreg(uMIPS_RD(ctx->opcode));
14829
14830    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14831}
14832
14833static void gen_addiur2(DisasContext *ctx)
14834{
14835    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14836    int rd = mmreg(uMIPS_RD(ctx->opcode));
14837    int rs = mmreg(uMIPS_RS(ctx->opcode));
14838
14839    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14840}
14841
14842static void gen_addiusp(DisasContext *ctx)
14843{
14844    int encoded = ZIMM(ctx->opcode, 1, 9);
14845    int decoded;
14846
14847    if (encoded <= 1) {
14848        decoded = 256 + encoded;
14849    } else if (encoded <= 255) {
14850        decoded = encoded;
14851    } else if (encoded <= 509) {
14852        decoded = encoded - 512;
14853    } else {
14854        decoded = encoded - 768;
14855    }
14856
14857    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14858}
14859
14860static void gen_addius5(DisasContext *ctx)
14861{
14862    int imm = SIMM(ctx->opcode, 1, 4);
14863    int rd = (ctx->opcode >> 5) & 0x1f;
14864
14865    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14866}
14867
14868static void gen_andi16(DisasContext *ctx)
14869{
14870    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14871                                 31, 32, 63, 64, 255, 32768, 65535 };
14872    int rd = mmreg(uMIPS_RD(ctx->opcode));
14873    int rs = mmreg(uMIPS_RS(ctx->opcode));
14874    int encoded = ZIMM(ctx->opcode, 0, 4);
14875
14876    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14877}
14878
14879static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14880                               int base, int16_t offset)
14881{
14882    TCGv t0, t1;
14883    TCGv_i32 t2;
14884
14885    if (ctx->hflags & MIPS_HFLAG_BMASK) {
14886        generate_exception_end(ctx, EXCP_RI);
14887        return;
14888    }
14889
14890    t0 = tcg_temp_new();
14891
14892    gen_base_offset_addr(ctx, t0, base, offset);
14893
14894    t1 = tcg_const_tl(reglist);
14895    t2 = tcg_const_i32(ctx->mem_idx);
14896
14897    save_cpu_state(ctx, 1);
14898    switch (opc) {
14899    case LWM32:
14900        gen_helper_lwm(cpu_env, t0, t1, t2);
14901        break;
14902    case SWM32:
14903        gen_helper_swm(cpu_env, t0, t1, t2);
14904        break;
14905#ifdef TARGET_MIPS64
14906    case LDM:
14907        gen_helper_ldm(cpu_env, t0, t1, t2);
14908        break;
14909    case SDM:
14910        gen_helper_sdm(cpu_env, t0, t1, t2);
14911        break;
14912#endif
14913    }
14914    tcg_temp_free(t0);
14915    tcg_temp_free(t1);
14916    tcg_temp_free_i32(t2);
14917}
14918
14919
14920static void gen_pool16c_insn(DisasContext *ctx)
14921{
14922    int rd = mmreg((ctx->opcode >> 3) & 0x7);
14923    int rs = mmreg(ctx->opcode & 0x7);
14924
14925    switch (((ctx->opcode) >> 4) & 0x3f) {
14926    case NOT16 + 0:
14927    case NOT16 + 1:
14928    case NOT16 + 2:
14929    case NOT16 + 3:
14930        gen_logic(ctx, OPC_NOR, rd, rs, 0);
14931        break;
14932    case XOR16 + 0:
14933    case XOR16 + 1:
14934    case XOR16 + 2:
14935    case XOR16 + 3:
14936        gen_logic(ctx, OPC_XOR, rd, rd, rs);
14937        break;
14938    case AND16 + 0:
14939    case AND16 + 1:
14940    case AND16 + 2:
14941    case AND16 + 3:
14942        gen_logic(ctx, OPC_AND, rd, rd, rs);
14943        break;
14944    case OR16 + 0:
14945    case OR16 + 1:
14946    case OR16 + 2:
14947    case OR16 + 3:
14948        gen_logic(ctx, OPC_OR, rd, rd, rs);
14949        break;
14950    case LWM16 + 0:
14951    case LWM16 + 1:
14952    case LWM16 + 2:
14953    case LWM16 + 3:
14954        {
14955            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14956            int offset = ZIMM(ctx->opcode, 0, 4);
14957
14958            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14959                              29, offset << 2);
14960        }
14961        break;
14962    case SWM16 + 0:
14963    case SWM16 + 1:
14964    case SWM16 + 2:
14965    case SWM16 + 3:
14966        {
14967            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14968            int offset = ZIMM(ctx->opcode, 0, 4);
14969
14970            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14971                              29, offset << 2);
14972        }
14973        break;
14974    case JR16 + 0:
14975    case JR16 + 1:
14976        {
14977            int reg = ctx->opcode & 0x1f;
14978
14979            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14980        }
14981        break;
14982    case JRC16 + 0:
14983    case JRC16 + 1:
14984        {
14985            int reg = ctx->opcode & 0x1f;
14986            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14987            /* Let normal delay slot handling in our caller take us
14988               to the branch target.  */
14989        }
14990        break;
14991    case JALR16 + 0:
14992    case JALR16 + 1:
14993        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14994        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14995        break;
14996    case JALR16S + 0:
14997    case JALR16S + 1:
14998        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14999        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15000        break;
15001    case MFHI16 + 0:
15002    case MFHI16 + 1:
15003        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15004        break;
15005    case MFLO16 + 0:
15006    case MFLO16 + 1:
15007        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15008        break;
15009    case BREAK16:
15010        generate_exception_end(ctx, EXCP_BREAK);
15011        break;
15012    case SDBBP16:
15013        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15014            gen_helper_do_semihosting(cpu_env);
15015        } else {
15016            /* XXX: not clear which exception should be raised
15017             *      when in debug mode...
15018             */
15019            check_insn(ctx, ISA_MIPS32);
15020            generate_exception_end(ctx, EXCP_DBp);
15021        }
15022        break;
15023    case JRADDIUSP + 0:
15024    case JRADDIUSP + 1:
15025        {
15026            int imm = ZIMM(ctx->opcode, 0, 5);
15027            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15028            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15029            /* Let normal delay slot handling in our caller take us
15030               to the branch target.  */
15031        }
15032        break;
15033    default:
15034        generate_exception_end(ctx, EXCP_RI);
15035        break;
15036    }
15037}
15038
15039static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15040                             int enc_rs)
15041{
15042    int rd, rs, re, rt;
15043    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15044    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15045    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15046    rd = rd_enc[enc_dest];
15047    re = re_enc[enc_dest];
15048    rs = rs_rt_enc[enc_rs];
15049    rt = rs_rt_enc[enc_rt];
15050    if (rs) {
15051        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15052    } else {
15053        tcg_gen_movi_tl(cpu_gpr[rd], 0);
15054    }
15055    if (rt) {
15056        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15057    } else {
15058        tcg_gen_movi_tl(cpu_gpr[re], 0);
15059    }
15060}
15061
15062static void gen_pool16c_r6_insn(DisasContext *ctx)
15063{
15064    int rt = mmreg((ctx->opcode >> 7) & 0x7);
15065    int rs = mmreg((ctx->opcode >> 4) & 0x7);
15066
15067    switch (ctx->opcode & 0xf) {
15068    case R6_NOT16:
15069        gen_logic(ctx, OPC_NOR, rt, rs, 0);
15070        break;
15071    case R6_AND16:
15072        gen_logic(ctx, OPC_AND, rt, rt, rs);
15073        break;
15074    case R6_LWM16:
15075        {
15076            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15077            int offset = extract32(ctx->opcode, 4, 4);
15078            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15079        }
15080        break;
15081    case R6_JRC16: /* JRCADDIUSP */
15082        if ((ctx->opcode >> 4) & 1) {
15083            /* JRCADDIUSP */
15084            int imm = extract32(ctx->opcode, 5, 5);
15085            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15086            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15087        } else {
15088            /* JRC16 */
15089            rs = extract32(ctx->opcode, 5, 5);
15090            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15091        }
15092        break;
15093    case MOVEP:
15094    case MOVEP_05:
15095    case MOVEP_06:
15096    case MOVEP_07:
15097    case MOVEP_0C:
15098    case MOVEP_0D:
15099    case MOVEP_0E:
15100    case MOVEP_0F:
15101        {
15102            int enc_dest = uMIPS_RD(ctx->opcode);
15103            int enc_rt = uMIPS_RS2(ctx->opcode);
15104            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15105            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15106        }
15107        break;
15108    case R6_XOR16:
15109        gen_logic(ctx, OPC_XOR, rt, rt, rs);
15110        break;
15111    case R6_OR16:
15112        gen_logic(ctx, OPC_OR, rt, rt, rs);
15113        break;
15114    case R6_SWM16:
15115        {
15116            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15117            int offset = extract32(ctx->opcode, 4, 4);
15118            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15119        }
15120        break;
15121    case JALRC16: /* BREAK16, SDBBP16 */
15122        switch (ctx->opcode & 0x3f) {
15123        case JALRC16:
15124        case JALRC16 + 0x20:
15125            /* JALRC16 */
15126            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15127                               31, 0, 0);
15128            break;
15129        case R6_BREAK16:
15130            /* BREAK16 */
15131            generate_exception(ctx, EXCP_BREAK);
15132            break;
15133        case R6_SDBBP16:
15134            /* SDBBP16 */
15135            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15136                gen_helper_do_semihosting(cpu_env);
15137            } else {
15138                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15139                    generate_exception(ctx, EXCP_RI);
15140                } else {
15141                    generate_exception(ctx, EXCP_DBp);
15142                }
15143            }
15144            break;
15145        }
15146        break;
15147    default:
15148        generate_exception(ctx, EXCP_RI);
15149        break;
15150    }
15151}
15152
15153static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15154{
15155    TCGv t0 = tcg_temp_new();
15156    TCGv t1 = tcg_temp_new();
15157
15158    gen_load_gpr(t0, base);
15159
15160    if (index != 0) {
15161        gen_load_gpr(t1, index);
15162        tcg_gen_shli_tl(t1, t1, 2);
15163        gen_op_addr_add(ctx, t0, t1, t0);
15164    }
15165
15166    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15167    gen_store_gpr(t1, rd);
15168
15169    tcg_temp_free(t0);
15170    tcg_temp_free(t1);
15171}
15172
15173static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15174                           int base, int16_t offset)
15175{
15176    TCGv t0, t1;
15177
15178    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15179        generate_exception_end(ctx, EXCP_RI);
15180        return;
15181    }
15182
15183    t0 = tcg_temp_new();
15184    t1 = tcg_temp_new();
15185
15186    gen_base_offset_addr(ctx, t0, base, offset);
15187
15188    switch (opc) {
15189    case LWP:
15190        if (rd == base) {
15191            generate_exception_end(ctx, EXCP_RI);
15192            return;
15193        }
15194        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15195        gen_store_gpr(t1, rd);
15196        tcg_gen_movi_tl(t1, 4);
15197        gen_op_addr_add(ctx, t0, t0, t1);
15198        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15199        gen_store_gpr(t1, rd+1);
15200        break;
15201    case SWP:
15202        gen_load_gpr(t1, rd);
15203        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15204        tcg_gen_movi_tl(t1, 4);
15205        gen_op_addr_add(ctx, t0, t0, t1);
15206        gen_load_gpr(t1, rd+1);
15207        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15208        break;
15209#ifdef TARGET_MIPS64
15210    case LDP:
15211        if (rd == base) {
15212            generate_exception_end(ctx, EXCP_RI);
15213            return;
15214        }
15215        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15216        gen_store_gpr(t1, rd);
15217        tcg_gen_movi_tl(t1, 8);
15218        gen_op_addr_add(ctx, t0, t0, t1);
15219        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15220        gen_store_gpr(t1, rd+1);
15221        break;
15222    case SDP:
15223        gen_load_gpr(t1, rd);
15224        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15225        tcg_gen_movi_tl(t1, 8);
15226        gen_op_addr_add(ctx, t0, t0, t1);
15227        gen_load_gpr(t1, rd+1);
15228        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15229        break;
15230#endif
15231    }
15232    tcg_temp_free(t0);
15233    tcg_temp_free(t1);
15234}
15235
15236static void gen_sync(int stype)
15237{
15238    TCGBar tcg_mo = TCG_BAR_SC;
15239
15240    switch (stype) {
15241    case 0x4: /* SYNC_WMB */
15242        tcg_mo |= TCG_MO_ST_ST;
15243        break;
15244    case 0x10: /* SYNC_MB */
15245        tcg_mo |= TCG_MO_ALL;
15246        break;
15247    case 0x11: /* SYNC_ACQUIRE */
15248        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15249        break;
15250    case 0x12: /* SYNC_RELEASE */
15251        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15252        break;
15253    case 0x13: /* SYNC_RMB */
15254        tcg_mo |= TCG_MO_LD_LD;
15255        break;
15256    default:
15257        tcg_mo |= TCG_MO_ALL;
15258        break;
15259    }
15260
15261    tcg_gen_mb(tcg_mo);
15262}
15263
15264static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15265{
15266    int extension = (ctx->opcode >> 6) & 0x3f;
15267    int minor = (ctx->opcode >> 12) & 0xf;
15268    uint32_t mips32_op;
15269
15270    switch (extension) {
15271    case TEQ:
15272        mips32_op = OPC_TEQ;
15273        goto do_trap;
15274    case TGE:
15275        mips32_op = OPC_TGE;
15276        goto do_trap;
15277    case TGEU:
15278        mips32_op = OPC_TGEU;
15279        goto do_trap;
15280    case TLT:
15281        mips32_op = OPC_TLT;
15282        goto do_trap;
15283    case TLTU:
15284        mips32_op = OPC_TLTU;
15285        goto do_trap;
15286    case TNE:
15287        mips32_op = OPC_TNE;
15288    do_trap:
15289        gen_trap(ctx, mips32_op, rs, rt, -1);
15290        break;
15291#ifndef CONFIG_USER_ONLY
15292    case MFC0:
15293    case MFC0 + 32:
15294        check_cp0_enabled(ctx);
15295        if (rt == 0) {
15296            /* Treat as NOP. */
15297            break;
15298        }
15299        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15300        break;
15301    case MTC0:
15302    case MTC0 + 32:
15303        check_cp0_enabled(ctx);
15304        {
15305            TCGv t0 = tcg_temp_new();
15306
15307            gen_load_gpr(t0, rt);
15308            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15309            tcg_temp_free(t0);
15310        }
15311        break;
15312#endif
15313    case 0x2a:
15314        switch (minor & 3) {
15315        case MADD_ACC:
15316            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15317            break;
15318        case MADDU_ACC:
15319            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15320            break;
15321        case MSUB_ACC:
15322            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15323            break;
15324        case MSUBU_ACC:
15325            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15326            break;
15327        default:
15328            goto pool32axf_invalid;
15329        }
15330        break;
15331    case 0x32:
15332        switch (minor & 3) {
15333        case MULT_ACC:
15334            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15335            break;
15336        case MULTU_ACC:
15337            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15338            break;
15339        default:
15340            goto pool32axf_invalid;
15341        }
15342        break;
15343    case 0x2c:
15344        switch (minor) {
15345        case BITSWAP:
15346            check_insn(ctx, ISA_MIPS32R6);
15347            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15348            break;
15349        case SEB:
15350            gen_bshfl(ctx, OPC_SEB, rs, rt);
15351            break;
15352        case SEH:
15353            gen_bshfl(ctx, OPC_SEH, rs, rt);
15354            break;
15355        case CLO:
15356            mips32_op = OPC_CLO;
15357            goto do_cl;
15358        case CLZ:
15359            mips32_op = OPC_CLZ;
15360        do_cl:
15361            check_insn(ctx, ISA_MIPS32);
15362            gen_cl(ctx, mips32_op, rt, rs);
15363            break;
15364        case RDHWR:
15365            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15366            gen_rdhwr(ctx, rt, rs, 0);
15367            break;
15368        case WSBH:
15369            gen_bshfl(ctx, OPC_WSBH, rs, rt);
15370            break;
15371        case MULT:
15372            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15373            mips32_op = OPC_MULT;
15374            goto do_mul;
15375        case MULTU:
15376            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15377            mips32_op = OPC_MULTU;
15378            goto do_mul;
15379        case DIV:
15380            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15381            mips32_op = OPC_DIV;
15382            goto do_div;
15383        case DIVU:
15384            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15385            mips32_op = OPC_DIVU;
15386            goto do_div;
15387        do_div:
15388            check_insn(ctx, ISA_MIPS32);
15389            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15390            break;
15391        case MADD:
15392            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15393            mips32_op = OPC_MADD;
15394            goto do_mul;
15395        case MADDU:
15396            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15397            mips32_op = OPC_MADDU;
15398            goto do_mul;
15399        case MSUB:
15400            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15401            mips32_op = OPC_MSUB;
15402            goto do_mul;
15403        case MSUBU:
15404            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15405            mips32_op = OPC_MSUBU;
15406        do_mul:
15407            check_insn(ctx, ISA_MIPS32);
15408            gen_muldiv(ctx, mips32_op, 0, rs, rt);
15409            break;
15410        default:
15411            goto pool32axf_invalid;
15412        }
15413        break;
15414    case 0x34:
15415        switch (minor) {
15416        case MFC2:
15417        case MTC2:
15418        case MFHC2:
15419        case MTHC2:
15420        case CFC2:
15421        case CTC2:
15422            generate_exception_err(ctx, EXCP_CpU, 2);
15423            break;
15424        default:
15425            goto pool32axf_invalid;
15426        }
15427        break;
15428    case 0x3c:
15429        switch (minor) {
15430        case JALR:    /* JALRC */
15431        case JALR_HB: /* JALRC_HB */
15432            if (ctx->insn_flags & ISA_MIPS32R6) {
15433                /* JALRC, JALRC_HB */
15434                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15435            } else {
15436                /* JALR, JALR_HB */
15437                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15438                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15439            }
15440            break;
15441        case JALRS:
15442        case JALRS_HB:
15443            check_insn_opc_removed(ctx, ISA_MIPS32R6);
15444            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15445            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15446            break;
15447        default:
15448            goto pool32axf_invalid;
15449        }
15450        break;
15451    case 0x05:
15452        switch (minor) {
15453        case RDPGPR:
15454            check_cp0_enabled(ctx);
15455            check_insn(ctx, ISA_MIPS32R2);
15456            gen_load_srsgpr(rs, rt);
15457            break;
15458        case WRPGPR:
15459            check_cp0_enabled(ctx);
15460            check_insn(ctx, ISA_MIPS32R2);
15461            gen_store_srsgpr(rs, rt);
15462            break;
15463        default:
15464            goto pool32axf_invalid;
15465        }
15466        break;
15467#ifndef CONFIG_USER_ONLY
15468    case 0x0d:
15469        switch (minor) {
15470        case TLBP:
15471            mips32_op = OPC_TLBP;
15472            goto do_cp0;
15473        case TLBR:
15474            mips32_op = OPC_TLBR;
15475            goto do_cp0;
15476        case TLBWI:
15477            mips32_op = OPC_TLBWI;
15478            goto do_cp0;
15479        case TLBWR:
15480            mips32_op = OPC_TLBWR;
15481            goto do_cp0;
15482        case TLBINV:
15483            mips32_op = OPC_TLBINV;
15484            goto do_cp0;
15485        case TLBINVF:
15486            mips32_op = OPC_TLBINVF;
15487            goto do_cp0;
15488        case WAIT:
15489            mips32_op = OPC_WAIT;
15490            goto do_cp0;
15491        case DERET:
15492            mips32_op = OPC_DERET;
15493            goto do_cp0;
15494        case ERET:
15495            mips32_op = OPC_ERET;
15496        do_cp0:
15497            gen_cp0(env, ctx, mips32_op, rt, rs);
15498            break;
15499        default:
15500            goto pool32axf_invalid;
15501        }
15502        break;
15503    case 0x1d:
15504        switch (minor) {
15505        case DI:
15506            check_cp0_enabled(ctx);
15507            {
15508                TCGv t0 = tcg_temp_new();
15509
15510                save_cpu_state(ctx, 1);
15511                gen_helper_di(t0, cpu_env);
15512                gen_store_gpr(t0, rs);
15513                /* Stop translation as we may have switched the execution mode */
15514                ctx->base.is_jmp = DISAS_STOP;
15515                tcg_temp_free(t0);
15516            }
15517            break;
15518        case EI:
15519            check_cp0_enabled(ctx);
15520            {
15521                TCGv t0 = tcg_temp_new();
15522
15523                save_cpu_state(ctx, 1);
15524                gen_helper_ei(t0, cpu_env);
15525                gen_store_gpr(t0, rs);
15526                /* DISAS_STOP isn't sufficient, we need to ensure we break out
15527                   of translated code to check for pending interrupts.  */
15528                gen_save_pc(ctx->base.pc_next + 4);
15529                ctx->base.is_jmp = DISAS_EXIT;
15530                tcg_temp_free(t0);
15531            }
15532            break;
15533        default:
15534            goto pool32axf_invalid;
15535        }
15536        break;
15537#endif
15538    case 0x2d:
15539        switch (minor) {
15540        case SYNC:
15541            gen_sync(extract32(ctx->opcode, 16, 5));
15542            break;
15543        case SYSCALL:
15544            generate_exception_end(ctx, EXCP_SYSCALL);
15545            break;
15546        case SDBBP:
15547            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15548                gen_helper_do_semihosting(cpu_env);
15549            } else {
15550                check_insn(ctx, ISA_MIPS32);
15551                if (ctx->hflags & MIPS_HFLAG_SBRI) {
15552                    generate_exception_end(ctx, EXCP_RI);
15553                } else {
15554                    generate_exception_end(ctx, EXCP_DBp);
15555                }
15556            }
15557            break;
15558        default:
15559            goto pool32axf_invalid;
15560        }
15561        break;
15562    case 0x01:
15563        switch (minor & 3) {
15564        case MFHI_ACC:
15565            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15566            break;
15567        case MFLO_ACC:
15568            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15569            break;
15570        case MTHI_ACC:
15571            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15572            break;
15573        case MTLO_ACC:
15574            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15575            break;
15576        default:
15577            goto pool32axf_invalid;
15578        }
15579        break;
15580    case 0x35:
15581        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15582        switch (minor) {
15583        case MFHI32:
15584            gen_HILO(ctx, OPC_MFHI, 0, rs);
15585            break;
15586        case MFLO32:
15587            gen_HILO(ctx, OPC_MFLO, 0, rs);
15588            break;
15589        case MTHI32:
15590            gen_HILO(ctx, OPC_MTHI, 0, rs);
15591            break;
15592        case MTLO32:
15593            gen_HILO(ctx, OPC_MTLO, 0, rs);
15594            break;
15595        default:
15596            goto pool32axf_invalid;
15597        }
15598        break;
15599    default:
15600    pool32axf_invalid:
15601        MIPS_INVAL("pool32axf");
15602        generate_exception_end(ctx, EXCP_RI);
15603        break;
15604    }
15605}
15606
15607/* Values for microMIPS fmt field.  Variable-width, depending on which
15608   formats the instruction supports.  */
15609
15610enum {
15611    FMT_SD_S = 0,
15612    FMT_SD_D = 1,
15613
15614    FMT_SDPS_S = 0,
15615    FMT_SDPS_D = 1,
15616    FMT_SDPS_PS = 2,
15617
15618    FMT_SWL_S = 0,
15619    FMT_SWL_W = 1,
15620    FMT_SWL_L = 2,
15621
15622    FMT_DWL_D = 0,
15623    FMT_DWL_W = 1,
15624    FMT_DWL_L = 2
15625};
15626
15627static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15628{
15629    int extension = (ctx->opcode >> 6) & 0x3ff;
15630    uint32_t mips32_op;
15631
15632#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15633#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15634#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15635
15636    switch (extension) {
15637    case FLOAT_1BIT_FMT(CFC1, 0):
15638        mips32_op = OPC_CFC1;
15639        goto do_cp1;
15640    case FLOAT_1BIT_FMT(CTC1, 0):
15641        mips32_op = OPC_CTC1;
15642        goto do_cp1;
15643    case FLOAT_1BIT_FMT(MFC1, 0):
15644        mips32_op = OPC_MFC1;
15645        goto do_cp1;
15646    case FLOAT_1BIT_FMT(MTC1, 0):
15647        mips32_op = OPC_MTC1;
15648        goto do_cp1;
15649    case FLOAT_1BIT_FMT(MFHC1, 0):
15650        mips32_op = OPC_MFHC1;
15651        goto do_cp1;
15652    case FLOAT_1BIT_FMT(MTHC1, 0):
15653        mips32_op = OPC_MTHC1;
15654    do_cp1:
15655        gen_cp1(ctx, mips32_op, rt, rs);
15656        break;
15657
15658        /* Reciprocal square root */
15659    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15660        mips32_op = OPC_RSQRT_S;
15661        goto do_unaryfp;
15662    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15663        mips32_op = OPC_RSQRT_D;
15664        goto do_unaryfp;
15665
15666        /* Square root */
15667    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15668        mips32_op = OPC_SQRT_S;
15669        goto do_unaryfp;
15670    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15671        mips32_op = OPC_SQRT_D;
15672        goto do_unaryfp;
15673
15674        /* Reciprocal */
15675    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15676        mips32_op = OPC_RECIP_S;
15677        goto do_unaryfp;
15678    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15679        mips32_op = OPC_RECIP_D;
15680        goto do_unaryfp;
15681
15682        /* Floor */
15683    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15684        mips32_op = OPC_FLOOR_L_S;
15685        goto do_unaryfp;
15686    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15687        mips32_op = OPC_FLOOR_L_D;
15688        goto do_unaryfp;
15689    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15690        mips32_op = OPC_FLOOR_W_S;
15691        goto do_unaryfp;
15692    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15693        mips32_op = OPC_FLOOR_W_D;
15694        goto do_unaryfp;
15695
15696        /* Ceiling */
15697    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15698        mips32_op = OPC_CEIL_L_S;
15699        goto do_unaryfp;
15700    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15701        mips32_op = OPC_CEIL_L_D;
15702        goto do_unaryfp;
15703    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15704        mips32_op = OPC_CEIL_W_S;
15705        goto do_unaryfp;
15706    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15707        mips32_op = OPC_CEIL_W_D;
15708        goto do_unaryfp;
15709
15710        /* Truncation */
15711    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15712        mips32_op = OPC_TRUNC_L_S;
15713        goto do_unaryfp;
15714    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15715        mips32_op = OPC_TRUNC_L_D;
15716        goto do_unaryfp;
15717    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15718        mips32_op = OPC_TRUNC_W_S;
15719        goto do_unaryfp;
15720    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15721        mips32_op = OPC_TRUNC_W_D;
15722        goto do_unaryfp;
15723
15724        /* Round */
15725    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15726        mips32_op = OPC_ROUND_L_S;
15727        goto do_unaryfp;
15728    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15729        mips32_op = OPC_ROUND_L_D;
15730        goto do_unaryfp;
15731    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15732        mips32_op = OPC_ROUND_W_S;
15733        goto do_unaryfp;
15734    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15735        mips32_op = OPC_ROUND_W_D;
15736        goto do_unaryfp;
15737
15738        /* Integer to floating-point conversion */
15739    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15740        mips32_op = OPC_CVT_L_S;
15741        goto do_unaryfp;
15742    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15743        mips32_op = OPC_CVT_L_D;
15744        goto do_unaryfp;
15745    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15746        mips32_op = OPC_CVT_W_S;
15747        goto do_unaryfp;
15748    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15749        mips32_op = OPC_CVT_W_D;
15750        goto do_unaryfp;
15751
15752        /* Paired-foo conversions */
15753    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15754        mips32_op = OPC_CVT_S_PL;
15755        goto do_unaryfp;
15756    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15757        mips32_op = OPC_CVT_S_PU;
15758        goto do_unaryfp;
15759    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15760        mips32_op = OPC_CVT_PW_PS;
15761        goto do_unaryfp;
15762    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15763        mips32_op = OPC_CVT_PS_PW;
15764        goto do_unaryfp;
15765
15766        /* Floating-point moves */
15767    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15768        mips32_op = OPC_MOV_S;
15769        goto do_unaryfp;
15770    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15771        mips32_op = OPC_MOV_D;
15772        goto do_unaryfp;
15773    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15774        mips32_op = OPC_MOV_PS;
15775        goto do_unaryfp;
15776
15777        /* Absolute value */
15778    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15779        mips32_op = OPC_ABS_S;
15780        goto do_unaryfp;
15781    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15782        mips32_op = OPC_ABS_D;
15783        goto do_unaryfp;
15784    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15785        mips32_op = OPC_ABS_PS;
15786        goto do_unaryfp;
15787
15788        /* Negation */
15789    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15790        mips32_op = OPC_NEG_S;
15791        goto do_unaryfp;
15792    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15793        mips32_op = OPC_NEG_D;
15794        goto do_unaryfp;
15795    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15796        mips32_op = OPC_NEG_PS;
15797        goto do_unaryfp;
15798
15799        /* Reciprocal square root step */
15800    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15801        mips32_op = OPC_RSQRT1_S;
15802        goto do_unaryfp;
15803    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15804        mips32_op = OPC_RSQRT1_D;
15805        goto do_unaryfp;
15806    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15807        mips32_op = OPC_RSQRT1_PS;
15808        goto do_unaryfp;
15809
15810        /* Reciprocal step */
15811    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15812        mips32_op = OPC_RECIP1_S;
15813        goto do_unaryfp;
15814    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15815        mips32_op = OPC_RECIP1_S;
15816        goto do_unaryfp;
15817    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15818        mips32_op = OPC_RECIP1_PS;
15819        goto do_unaryfp;
15820
15821        /* Conversions from double */
15822    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15823        mips32_op = OPC_CVT_D_S;
15824        goto do_unaryfp;
15825    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15826        mips32_op = OPC_CVT_D_W;
15827        goto do_unaryfp;
15828    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15829        mips32_op = OPC_CVT_D_L;
15830        goto do_unaryfp;
15831
15832        /* Conversions from single */
15833    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15834        mips32_op = OPC_CVT_S_D;
15835        goto do_unaryfp;
15836    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15837        mips32_op = OPC_CVT_S_W;
15838        goto do_unaryfp;
15839    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15840        mips32_op = OPC_CVT_S_L;
15841    do_unaryfp:
15842        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15843        break;
15844
15845        /* Conditional moves on floating-point codes */
15846    case COND_FLOAT_MOV(MOVT, 0):
15847    case COND_FLOAT_MOV(MOVT, 1):
15848    case COND_FLOAT_MOV(MOVT, 2):
15849    case COND_FLOAT_MOV(MOVT, 3):
15850    case COND_FLOAT_MOV(MOVT, 4):
15851    case COND_FLOAT_MOV(MOVT, 5):
15852    case COND_FLOAT_MOV(MOVT, 6):
15853    case COND_FLOAT_MOV(MOVT, 7):
15854        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15855        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15856        break;
15857    case COND_FLOAT_MOV(MOVF, 0):
15858    case COND_FLOAT_MOV(MOVF, 1):
15859    case COND_FLOAT_MOV(MOVF, 2):
15860    case COND_FLOAT_MOV(MOVF, 3):
15861    case COND_FLOAT_MOV(MOVF, 4):
15862    case COND_FLOAT_MOV(MOVF, 5):
15863    case COND_FLOAT_MOV(MOVF, 6):
15864    case COND_FLOAT_MOV(MOVF, 7):
15865        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15866        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15867        break;
15868    default:
15869        MIPS_INVAL("pool32fxf");
15870        generate_exception_end(ctx, EXCP_RI);
15871        break;
15872    }
15873}
15874
15875static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15876{
15877    int32_t offset;
15878    uint16_t insn;
15879    int rt, rs, rd, rr;
15880    int16_t imm;
15881    uint32_t op, minor, minor2, mips32_op;
15882    uint32_t cond, fmt, cc;
15883
15884    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15885    ctx->opcode = (ctx->opcode << 16) | insn;
15886
15887    rt = (ctx->opcode >> 21) & 0x1f;
15888    rs = (ctx->opcode >> 16) & 0x1f;
15889    rd = (ctx->opcode >> 11) & 0x1f;
15890    rr = (ctx->opcode >> 6) & 0x1f;
15891    imm = (int16_t) ctx->opcode;
15892
15893    op = (ctx->opcode >> 26) & 0x3f;
15894    switch (op) {
15895    case POOL32A:
15896        minor = ctx->opcode & 0x3f;
15897        switch (minor) {
15898        case 0x00:
15899            minor = (ctx->opcode >> 6) & 0xf;
15900            switch (minor) {
15901            case SLL32:
15902                mips32_op = OPC_SLL;
15903                goto do_shifti;
15904            case SRA:
15905                mips32_op = OPC_SRA;
15906                goto do_shifti;
15907            case SRL32:
15908                mips32_op = OPC_SRL;
15909                goto do_shifti;
15910            case ROTR:
15911                mips32_op = OPC_ROTR;
15912            do_shifti:
15913                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15914                break;
15915            case SELEQZ:
15916                check_insn(ctx, ISA_MIPS32R6);
15917                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15918                break;
15919            case SELNEZ:
15920                check_insn(ctx, ISA_MIPS32R6);
15921                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15922                break;
15923            case R6_RDHWR:
15924                check_insn(ctx, ISA_MIPS32R6);
15925                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15926                break;
15927            default:
15928                goto pool32a_invalid;
15929            }
15930            break;
15931        case 0x10:
15932            minor = (ctx->opcode >> 6) & 0xf;
15933            switch (minor) {
15934                /* Arithmetic */
15935            case ADD:
15936                mips32_op = OPC_ADD;
15937                goto do_arith;
15938            case ADDU32:
15939                mips32_op = OPC_ADDU;
15940                goto do_arith;
15941            case SUB:
15942                mips32_op = OPC_SUB;
15943                goto do_arith;
15944            case SUBU32:
15945                mips32_op = OPC_SUBU;
15946                goto do_arith;
15947            case MUL:
15948                check_insn_opc_removed(ctx, ISA_MIPS32R6);
15949                mips32_op = OPC_MUL;
15950            do_arith:
15951                gen_arith(ctx, mips32_op, rd, rs, rt);
15952                break;
15953                /* Shifts */
15954            case SLLV:
15955                mips32_op = OPC_SLLV;
15956                goto do_shift;
15957            case SRLV:
15958                mips32_op = OPC_SRLV;
15959                goto do_shift;
15960            case SRAV:
15961                mips32_op = OPC_SRAV;
15962                goto do_shift;
15963            case ROTRV:
15964                mips32_op = OPC_ROTRV;
15965            do_shift:
15966                gen_shift(ctx, mips32_op, rd, rs, rt);
15967                break;
15968                /* Logical operations */
15969            case AND:
15970                mips32_op = OPC_AND;
15971                goto do_logic;
15972            case OR32:
15973                mips32_op = OPC_OR;
15974                goto do_logic;
15975            case NOR:
15976                mips32_op = OPC_NOR;
15977                goto do_logic;
15978            case XOR32:
15979                mips32_op = OPC_XOR;
15980            do_logic:
15981                gen_logic(ctx, mips32_op, rd, rs, rt);
15982                break;
15983                /* Set less than */
15984            case SLT:
15985                mips32_op = OPC_SLT;
15986                goto do_slt;
15987            case SLTU:
15988                mips32_op = OPC_SLTU;
15989            do_slt:
15990                gen_slt(ctx, mips32_op, rd, rs, rt);
15991                break;
15992            default:
15993                goto pool32a_invalid;
15994            }
15995            break;
15996        case 0x18:
15997            minor = (ctx->opcode >> 6) & 0xf;
15998            switch (minor) {
15999                /* Conditional moves */
16000            case MOVN: /* MUL */
16001                if (ctx->insn_flags & ISA_MIPS32R6) {
16002                    /* MUL */
16003                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16004                } else {
16005                    /* MOVN */
16006                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16007                }
16008                break;
16009            case MOVZ: /* MUH */
16010                if (ctx->insn_flags & ISA_MIPS32R6) {
16011                    /* MUH */
16012                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16013                } else {
16014                    /* MOVZ */
16015                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16016                }
16017                break;
16018            case MULU:
16019                check_insn(ctx, ISA_MIPS32R6);
16020                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16021                break;
16022            case MUHU:
16023                check_insn(ctx, ISA_MIPS32R6);
16024                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16025                break;
16026            case LWXS: /* DIV */
16027                if (ctx->insn_flags & ISA_MIPS32R6) {
16028                    /* DIV */
16029                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16030                } else {
16031                    /* LWXS */
16032                    gen_ldxs(ctx, rs, rt, rd);
16033                }
16034                break;
16035            case MOD:
16036                check_insn(ctx, ISA_MIPS32R6);
16037                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16038                break;
16039            case R6_DIVU:
16040                check_insn(ctx, ISA_MIPS32R6);
16041                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16042                break;
16043            case MODU:
16044                check_insn(ctx, ISA_MIPS32R6);
16045                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16046                break;
16047            default:
16048                goto pool32a_invalid;
16049            }
16050            break;
16051        case INS:
16052            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16053            return;
16054        case LSA:
16055            check_insn(ctx, ISA_MIPS32R6);
16056            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16057                    extract32(ctx->opcode, 9, 2));
16058            break;
16059        case ALIGN:
16060            check_insn(ctx, ISA_MIPS32R6);
16061            gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16062            break;
16063        case EXT:
16064            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16065            return;
16066        case POOL32AXF:
16067            gen_pool32axf(env, ctx, rt, rs);
16068            break;
16069        case BREAK32:
16070            generate_exception_end(ctx, EXCP_BREAK);
16071            break;
16072        case SIGRIE:
16073            check_insn(ctx, ISA_MIPS32R6);
16074            generate_exception_end(ctx, EXCP_RI);
16075            break;
16076        default:
16077        pool32a_invalid:
16078                MIPS_INVAL("pool32a");
16079                generate_exception_end(ctx, EXCP_RI);
16080                break;
16081        }
16082        break;
16083    case POOL32B:
16084        minor = (ctx->opcode >> 12) & 0xf;
16085        switch (minor) {
16086        case CACHE:
16087            check_cp0_enabled(ctx);
16088            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16089                gen_cache_operation(ctx, rt, rs, imm);
16090            }
16091            break;
16092        case LWC2:
16093        case SWC2:
16094            /* COP2: Not implemented. */
16095            generate_exception_err(ctx, EXCP_CpU, 2);
16096            break;
16097#ifdef TARGET_MIPS64
16098        case LDP:
16099        case SDP:
16100            check_insn(ctx, ISA_MIPS3);
16101            check_mips_64(ctx);
16102#endif
16103            /* fall through */
16104        case LWP:
16105        case SWP:
16106            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16107            break;
16108#ifdef TARGET_MIPS64
16109        case LDM:
16110        case SDM:
16111            check_insn(ctx, ISA_MIPS3);
16112            check_mips_64(ctx);
16113#endif
16114            /* fall through */
16115        case LWM32:
16116        case SWM32:
16117            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16118            break;
16119        default:
16120            MIPS_INVAL("pool32b");
16121            generate_exception_end(ctx, EXCP_RI);
16122            break;
16123        }
16124        break;
16125    case POOL32F:
16126        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16127            minor = ctx->opcode & 0x3f;
16128            check_cp1_enabled(ctx);
16129            switch (minor) {
16130            case ALNV_PS:
16131                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16132                mips32_op = OPC_ALNV_PS;
16133                goto do_madd;
16134            case MADD_S:
16135                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16136                mips32_op = OPC_MADD_S;
16137                goto do_madd;
16138            case MADD_D:
16139                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16140                mips32_op = OPC_MADD_D;
16141                goto do_madd;
16142            case MADD_PS:
16143                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16144                mips32_op = OPC_MADD_PS;
16145                goto do_madd;
16146            case MSUB_S:
16147                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16148                mips32_op = OPC_MSUB_S;
16149                goto do_madd;
16150            case MSUB_D:
16151                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16152                mips32_op = OPC_MSUB_D;
16153                goto do_madd;
16154            case MSUB_PS:
16155                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16156                mips32_op = OPC_MSUB_PS;
16157                goto do_madd;
16158            case NMADD_S:
16159                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16160                mips32_op = OPC_NMADD_S;
16161                goto do_madd;
16162            case NMADD_D:
16163                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16164                mips32_op = OPC_NMADD_D;
16165                goto do_madd;
16166            case NMADD_PS:
16167                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16168                mips32_op = OPC_NMADD_PS;
16169                goto do_madd;
16170            case NMSUB_S:
16171                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16172                mips32_op = OPC_NMSUB_S;
16173                goto do_madd;
16174            case NMSUB_D:
16175                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16176                mips32_op = OPC_NMSUB_D;
16177                goto do_madd;
16178            case NMSUB_PS:
16179                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16180                mips32_op = OPC_NMSUB_PS;
16181            do_madd:
16182                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16183                break;
16184            case CABS_COND_FMT:
16185                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16186                cond = (ctx->opcode >> 6) & 0xf;
16187                cc = (ctx->opcode >> 13) & 0x7;
16188                fmt = (ctx->opcode >> 10) & 0x3;
16189                switch (fmt) {
16190                case 0x0:
16191                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
16192                    break;
16193                case 0x1:
16194                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
16195                    break;
16196                case 0x2:
16197                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16198                    break;
16199                default:
16200                    goto pool32f_invalid;
16201                }
16202                break;
16203            case C_COND_FMT:
16204                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16205                cond = (ctx->opcode >> 6) & 0xf;
16206                cc = (ctx->opcode >> 13) & 0x7;
16207                fmt = (ctx->opcode >> 10) & 0x3;
16208                switch (fmt) {
16209                case 0x0:
16210                    gen_cmp_s(ctx, cond, rt, rs, cc);
16211                    break;
16212                case 0x1:
16213                    gen_cmp_d(ctx, cond, rt, rs, cc);
16214                    break;
16215                case 0x2:
16216                    gen_cmp_ps(ctx, cond, rt, rs, cc);
16217                    break;
16218                default:
16219                    goto pool32f_invalid;
16220                }
16221                break;
16222            case CMP_CONDN_S:
16223                check_insn(ctx, ISA_MIPS32R6);
16224                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16225                break;
16226            case CMP_CONDN_D:
16227                check_insn(ctx, ISA_MIPS32R6);
16228                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16229                break;
16230            case POOL32FXF:
16231                gen_pool32fxf(ctx, rt, rs);
16232                break;
16233            case 0x00:
16234                /* PLL foo */
16235                switch ((ctx->opcode >> 6) & 0x7) {
16236                case PLL_PS:
16237                    mips32_op = OPC_PLL_PS;
16238                    goto do_ps;
16239                case PLU_PS:
16240                    mips32_op = OPC_PLU_PS;
16241                    goto do_ps;
16242                case PUL_PS:
16243                    mips32_op = OPC_PUL_PS;
16244                    goto do_ps;
16245                case PUU_PS:
16246                    mips32_op = OPC_PUU_PS;
16247                    goto do_ps;
16248                case CVT_PS_S:
16249                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16250                    mips32_op = OPC_CVT_PS_S;
16251                do_ps:
16252                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16253                    break;
16254                default:
16255                    goto pool32f_invalid;
16256                }
16257                break;
16258            case MIN_FMT:
16259                check_insn(ctx, ISA_MIPS32R6);
16260                switch ((ctx->opcode >> 9) & 0x3) {
16261                case FMT_SDPS_S:
16262                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16263                    break;
16264                case FMT_SDPS_D:
16265                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16266                    break;
16267                default:
16268                    goto pool32f_invalid;
16269                }
16270                break;
16271            case 0x08:
16272                /* [LS][WDU]XC1 */
16273                switch ((ctx->opcode >> 6) & 0x7) {
16274                case LWXC1:
16275                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16276                    mips32_op = OPC_LWXC1;
16277                    goto do_ldst_cp1;
16278                case SWXC1:
16279                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16280                    mips32_op = OPC_SWXC1;
16281                    goto do_ldst_cp1;
16282                case LDXC1:
16283                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16284                    mips32_op = OPC_LDXC1;
16285                    goto do_ldst_cp1;
16286                case SDXC1:
16287                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16288                    mips32_op = OPC_SDXC1;
16289                    goto do_ldst_cp1;
16290                case LUXC1:
16291                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16292                    mips32_op = OPC_LUXC1;
16293                    goto do_ldst_cp1;
16294                case SUXC1:
16295                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16296                    mips32_op = OPC_SUXC1;
16297                do_ldst_cp1:
16298                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16299                    break;
16300                default:
16301                    goto pool32f_invalid;
16302                }
16303                break;
16304            case MAX_FMT:
16305                check_insn(ctx, ISA_MIPS32R6);
16306                switch ((ctx->opcode >> 9) & 0x3) {
16307                case FMT_SDPS_S:
16308                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16309                    break;
16310                case FMT_SDPS_D:
16311                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16312                    break;
16313                default:
16314                    goto pool32f_invalid;
16315                }
16316                break;
16317            case 0x18:
16318                /* 3D insns */
16319                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16320                fmt = (ctx->opcode >> 9) & 0x3;
16321                switch ((ctx->opcode >> 6) & 0x7) {
16322                case RSQRT2_FMT:
16323                    switch (fmt) {
16324                    case FMT_SDPS_S:
16325                        mips32_op = OPC_RSQRT2_S;
16326                        goto do_3d;
16327                    case FMT_SDPS_D:
16328                        mips32_op = OPC_RSQRT2_D;
16329                        goto do_3d;
16330                    case FMT_SDPS_PS:
16331                        mips32_op = OPC_RSQRT2_PS;
16332                        goto do_3d;
16333                    default:
16334                        goto pool32f_invalid;
16335                    }
16336                    break;
16337                case RECIP2_FMT:
16338                    switch (fmt) {
16339                    case FMT_SDPS_S:
16340                        mips32_op = OPC_RECIP2_S;
16341                        goto do_3d;
16342                    case FMT_SDPS_D:
16343                        mips32_op = OPC_RECIP2_D;
16344                        goto do_3d;
16345                    case FMT_SDPS_PS:
16346                        mips32_op = OPC_RECIP2_PS;
16347                        goto do_3d;
16348                    default:
16349                        goto pool32f_invalid;
16350                    }
16351                    break;
16352                case ADDR_PS:
16353                    mips32_op = OPC_ADDR_PS;
16354                    goto do_3d;
16355                case MULR_PS:
16356                    mips32_op = OPC_MULR_PS;
16357                do_3d:
16358                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16359                    break;
16360                default:
16361                    goto pool32f_invalid;
16362                }
16363                break;
16364            case 0x20:
16365                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16366                cc = (ctx->opcode >> 13) & 0x7;
16367                fmt = (ctx->opcode >> 9) & 0x3;
16368                switch ((ctx->opcode >> 6) & 0x7) {
16369                case MOVF_FMT: /* RINT_FMT */
16370                    if (ctx->insn_flags & ISA_MIPS32R6) {
16371                        /* RINT_FMT */
16372                        switch (fmt) {
16373                        case FMT_SDPS_S:
16374                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16375                            break;
16376                        case FMT_SDPS_D:
16377                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16378                            break;
16379                        default:
16380                            goto pool32f_invalid;
16381                        }
16382                    } else {
16383                        /* MOVF_FMT */
16384                        switch (fmt) {
16385                        case FMT_SDPS_S:
16386                            gen_movcf_s(ctx, rs, rt, cc, 0);
16387                            break;
16388                        case FMT_SDPS_D:
16389                            gen_movcf_d(ctx, rs, rt, cc, 0);
16390                            break;
16391                        case FMT_SDPS_PS:
16392                            check_ps(ctx);
16393                            gen_movcf_ps(ctx, rs, rt, cc, 0);
16394                            break;
16395                        default:
16396                            goto pool32f_invalid;
16397                        }
16398                    }
16399                    break;
16400                case MOVT_FMT: /* CLASS_FMT */
16401                    if (ctx->insn_flags & ISA_MIPS32R6) {
16402                        /* CLASS_FMT */
16403                        switch (fmt) {
16404                        case FMT_SDPS_S:
16405                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16406                            break;
16407                        case FMT_SDPS_D:
16408                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16409                            break;
16410                        default:
16411                            goto pool32f_invalid;
16412                        }
16413                    } else {
16414                        /* MOVT_FMT */
16415                        switch (fmt) {
16416                        case FMT_SDPS_S:
16417                            gen_movcf_s(ctx, rs, rt, cc, 1);
16418                            break;
16419                        case FMT_SDPS_D:
16420                            gen_movcf_d(ctx, rs, rt, cc, 1);
16421                            break;
16422                        case FMT_SDPS_PS:
16423                            check_ps(ctx);
16424                            gen_movcf_ps(ctx, rs, rt, cc, 1);
16425                            break;
16426                        default:
16427                            goto pool32f_invalid;
16428                        }
16429                    }
16430                    break;
16431                case PREFX:
16432                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16433                    break;
16434                default:
16435                    goto pool32f_invalid;
16436                }
16437                break;
16438#define FINSN_3ARG_SDPS(prfx)                           \
16439                switch ((ctx->opcode >> 8) & 0x3) {     \
16440                case FMT_SDPS_S:                        \
16441                    mips32_op = OPC_##prfx##_S;         \
16442                    goto do_fpop;                       \
16443                case FMT_SDPS_D:                        \
16444                    mips32_op = OPC_##prfx##_D;         \
16445                    goto do_fpop;                       \
16446                case FMT_SDPS_PS:                       \
16447                    check_ps(ctx);                      \
16448                    mips32_op = OPC_##prfx##_PS;        \
16449                    goto do_fpop;                       \
16450                default:                                \
16451                    goto pool32f_invalid;               \
16452                }
16453            case MINA_FMT:
16454                check_insn(ctx, ISA_MIPS32R6);
16455                switch ((ctx->opcode >> 9) & 0x3) {
16456                case FMT_SDPS_S:
16457                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16458                    break;
16459                case FMT_SDPS_D:
16460                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16461                    break;
16462                default:
16463                    goto pool32f_invalid;
16464                }
16465                break;
16466            case MAXA_FMT:
16467                check_insn(ctx, ISA_MIPS32R6);
16468                switch ((ctx->opcode >> 9) & 0x3) {
16469                case FMT_SDPS_S:
16470                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16471                    break;
16472                case FMT_SDPS_D:
16473                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16474                    break;
16475                default:
16476                    goto pool32f_invalid;
16477                }
16478                break;
16479            case 0x30:
16480                /* regular FP ops */
16481                switch ((ctx->opcode >> 6) & 0x3) {
16482                case ADD_FMT:
16483                    FINSN_3ARG_SDPS(ADD);
16484                    break;
16485                case SUB_FMT:
16486                    FINSN_3ARG_SDPS(SUB);
16487                    break;
16488                case MUL_FMT:
16489                    FINSN_3ARG_SDPS(MUL);
16490                    break;
16491                case DIV_FMT:
16492                    fmt = (ctx->opcode >> 8) & 0x3;
16493                    if (fmt == 1) {
16494                        mips32_op = OPC_DIV_D;
16495                    } else if (fmt == 0) {
16496                        mips32_op = OPC_DIV_S;
16497                    } else {
16498                        goto pool32f_invalid;
16499                    }
16500                    goto do_fpop;
16501                default:
16502                    goto pool32f_invalid;
16503                }
16504                break;
16505            case 0x38:
16506                /* cmovs */
16507                switch ((ctx->opcode >> 6) & 0x7) {
16508                case MOVN_FMT: /* SELEQZ_FMT */
16509                    if (ctx->insn_flags & ISA_MIPS32R6) {
16510                        /* SELEQZ_FMT */
16511                        switch ((ctx->opcode >> 9) & 0x3) {
16512                        case FMT_SDPS_S:
16513                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16514                            break;
16515                        case FMT_SDPS_D:
16516                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16517                            break;
16518                        default:
16519                            goto pool32f_invalid;
16520                        }
16521                    } else {
16522                        /* MOVN_FMT */
16523                        FINSN_3ARG_SDPS(MOVN);
16524                    }
16525                    break;
16526                case MOVN_FMT_04:
16527                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16528                    FINSN_3ARG_SDPS(MOVN);
16529                    break;
16530                case MOVZ_FMT: /* SELNEZ_FMT */
16531                    if (ctx->insn_flags & ISA_MIPS32R6) {
16532                        /* SELNEZ_FMT */
16533                        switch ((ctx->opcode >> 9) & 0x3) {
16534                        case FMT_SDPS_S:
16535                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16536                            break;
16537                        case FMT_SDPS_D:
16538                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16539                            break;
16540                        default:
16541                            goto pool32f_invalid;
16542                        }
16543                    } else {
16544                        /* MOVZ_FMT */
16545                        FINSN_3ARG_SDPS(MOVZ);
16546                    }
16547                    break;
16548                case MOVZ_FMT_05:
16549                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
16550                    FINSN_3ARG_SDPS(MOVZ);
16551                    break;
16552                case SEL_FMT:
16553                    check_insn(ctx, ISA_MIPS32R6);
16554                    switch ((ctx->opcode >> 9) & 0x3) {
16555                    case FMT_SDPS_S:
16556                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16557                        break;
16558                    case FMT_SDPS_D:
16559                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16560                        break;
16561                    default:
16562                        goto pool32f_invalid;
16563                    }
16564                    break;
16565                case MADDF_FMT:
16566                    check_insn(ctx, ISA_MIPS32R6);
16567                    switch ((ctx->opcode >> 9) & 0x3) {
16568                    case FMT_SDPS_S:
16569                        mips32_op = OPC_MADDF_S;
16570                        goto do_fpop;
16571                    case FMT_SDPS_D:
16572                        mips32_op = OPC_MADDF_D;
16573                        goto do_fpop;
16574                    default:
16575                        goto pool32f_invalid;
16576                    }
16577                    break;
16578                case MSUBF_FMT:
16579                    check_insn(ctx, ISA_MIPS32R6);
16580                    switch ((ctx->opcode >> 9) & 0x3) {
16581                    case FMT_SDPS_S:
16582                        mips32_op = OPC_MSUBF_S;
16583                        goto do_fpop;
16584                    case FMT_SDPS_D:
16585                        mips32_op = OPC_MSUBF_D;
16586                        goto do_fpop;
16587                    default:
16588                        goto pool32f_invalid;
16589                    }
16590                    break;
16591                default:
16592                    goto pool32f_invalid;
16593                }
16594                break;
16595            do_fpop:
16596                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16597                break;
16598            default:
16599            pool32f_invalid:
16600                MIPS_INVAL("pool32f");
16601                generate_exception_end(ctx, EXCP_RI);
16602                break;
16603            }
16604        } else {
16605            generate_exception_err(ctx, EXCP_CpU, 1);
16606        }
16607        break;
16608    case POOL32I:
16609        minor = (ctx->opcode >> 21) & 0x1f;
16610        switch (minor) {
16611        case BLTZ:
16612            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16613            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16614            break;
16615        case BLTZAL:
16616            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16617            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16618            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16619            break;
16620        case BLTZALS:
16621            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16622            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16623            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16624            break;
16625        case BGEZ:
16626            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16627            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16628            break;
16629        case BGEZAL:
16630            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16631            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16632            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16633            break;
16634        case BGEZALS:
16635            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16636            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16637            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16638            break;
16639        case BLEZ:
16640            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16641            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16642            break;
16643        case BGTZ:
16644            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16645            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16646            break;
16647
16648            /* Traps */
16649        case TLTI: /* BC1EQZC */
16650            if (ctx->insn_flags & ISA_MIPS32R6) {
16651                /* BC1EQZC */
16652                check_cp1_enabled(ctx);
16653                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16654            } else {
16655                /* TLTI */
16656                mips32_op = OPC_TLTI;
16657                goto do_trapi;
16658            }
16659            break;
16660        case TGEI: /* BC1NEZC */
16661            if (ctx->insn_flags & ISA_MIPS32R6) {
16662                /* BC1NEZC */
16663                check_cp1_enabled(ctx);
16664                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16665            } else {
16666                /* TGEI */
16667                mips32_op = OPC_TGEI;
16668                goto do_trapi;
16669            }
16670            break;
16671        case TLTIU:
16672            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16673            mips32_op = OPC_TLTIU;
16674            goto do_trapi;
16675        case TGEIU:
16676            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16677            mips32_op = OPC_TGEIU;
16678            goto do_trapi;
16679        case TNEI: /* SYNCI */
16680            if (ctx->insn_flags & ISA_MIPS32R6) {
16681                /* SYNCI */
16682                /* Break the TB to be able to sync copied instructions
16683                   immediately */
16684                ctx->base.is_jmp = DISAS_STOP;
16685            } else {
16686                /* TNEI */
16687                mips32_op = OPC_TNEI;
16688                goto do_trapi;
16689            }
16690            break;
16691        case TEQI:
16692            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16693            mips32_op = OPC_TEQI;
16694        do_trapi:
16695            gen_trap(ctx, mips32_op, rs, -1, imm);
16696            break;
16697
16698        case BNEZC:
16699        case BEQZC:
16700            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16701            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16702                               4, rs, 0, imm << 1, 0);
16703            /* Compact branches don't have a delay slot, so just let
16704               the normal delay slot handling take us to the branch
16705               target. */
16706            break;
16707        case LUI:
16708            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16709            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16710            break;
16711        case SYNCI:
16712            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16713            /* Break the TB to be able to sync copied instructions
16714               immediately */
16715            ctx->base.is_jmp = DISAS_STOP;
16716            break;
16717        case BC2F:
16718        case BC2T:
16719            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16720            /* COP2: Not implemented. */
16721            generate_exception_err(ctx, EXCP_CpU, 2);
16722            break;
16723        case BC1F:
16724            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16725            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16726            goto do_cp1branch;
16727        case BC1T:
16728            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16729            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16730            goto do_cp1branch;
16731        case BC1ANY4F:
16732            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16733            mips32_op = OPC_BC1FANY4;
16734            goto do_cp1mips3d;
16735        case BC1ANY4T:
16736            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16737            mips32_op = OPC_BC1TANY4;
16738        do_cp1mips3d:
16739            check_cop1x(ctx);
16740            check_insn(ctx, ASE_MIPS3D);
16741            /* Fall through */
16742        do_cp1branch:
16743            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16744                check_cp1_enabled(ctx);
16745                gen_compute_branch1(ctx, mips32_op,
16746                                    (ctx->opcode >> 18) & 0x7, imm << 1);
16747            } else {
16748                generate_exception_err(ctx, EXCP_CpU, 1);
16749            }
16750            break;
16751        case BPOSGE64:
16752        case BPOSGE32:
16753            /* MIPS DSP: not implemented */
16754            /* Fall through */
16755        default:
16756            MIPS_INVAL("pool32i");
16757            generate_exception_end(ctx, EXCP_RI);
16758            break;
16759        }
16760        break;
16761    case POOL32C:
16762        minor = (ctx->opcode >> 12) & 0xf;
16763        offset = sextract32(ctx->opcode, 0,
16764                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16765        switch (minor) {
16766        case LWL:
16767            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16768            mips32_op = OPC_LWL;
16769            goto do_ld_lr;
16770        case SWL:
16771            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16772            mips32_op = OPC_SWL;
16773            goto do_st_lr;
16774        case LWR:
16775            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16776            mips32_op = OPC_LWR;
16777            goto do_ld_lr;
16778        case SWR:
16779            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16780            mips32_op = OPC_SWR;
16781            goto do_st_lr;
16782#if defined(TARGET_MIPS64)
16783        case LDL:
16784            check_insn(ctx, ISA_MIPS3);
16785            check_mips_64(ctx);
16786            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16787            mips32_op = OPC_LDL;
16788            goto do_ld_lr;
16789        case SDL:
16790            check_insn(ctx, ISA_MIPS3);
16791            check_mips_64(ctx);
16792            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16793            mips32_op = OPC_SDL;
16794            goto do_st_lr;
16795        case LDR:
16796            check_insn(ctx, ISA_MIPS3);
16797            check_mips_64(ctx);
16798            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16799            mips32_op = OPC_LDR;
16800            goto do_ld_lr;
16801        case SDR:
16802            check_insn(ctx, ISA_MIPS3);
16803            check_mips_64(ctx);
16804            check_insn_opc_removed(ctx, ISA_MIPS32R6);
16805            mips32_op = OPC_SDR;
16806            goto do_st_lr;
16807        case LWU:
16808            check_insn(ctx, ISA_MIPS3);
16809            check_mips_64(ctx);
16810            mips32_op = OPC_LWU;
16811            goto do_ld_lr;
16812        case LLD:
16813            check_insn(ctx, ISA_MIPS3);
16814            check_mips_64(ctx);
16815            mips32_op = OPC_LLD;
16816            goto do_ld_lr;
16817#endif
16818        case LL:
16819            mips32_op = OPC_LL;
16820            goto do_ld_lr;
16821        do_ld_lr:
16822            gen_ld(ctx, mips32_op, rt, rs, offset);
16823            break;
16824        do_st_lr:
16825            gen_st(ctx, mips32_op, rt, rs, offset);
16826            break;
16827        case SC:
16828            gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16829            break;
16830#if defined(TARGET_MIPS64)
16831        case SCD:
16832            check_insn(ctx, ISA_MIPS3);
16833            check_mips_64(ctx);
16834            gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
16835            break;
16836#endif
16837        case LD_EVA:
16838            if (!ctx->eva) {
16839                MIPS_INVAL("pool32c ld-eva");
16840                generate_exception_end(ctx, EXCP_RI);
16841                break;
16842            }
16843            check_cp0_enabled(ctx);
16844
16845            minor2 = (ctx->opcode >> 9) & 0x7;
16846            offset = sextract32(ctx->opcode, 0, 9);
16847            switch (minor2) {
16848            case LBUE:
16849                mips32_op = OPC_LBUE;
16850                goto do_ld_lr;
16851            case LHUE:
16852                mips32_op = OPC_LHUE;
16853                goto do_ld_lr;
16854            case LWLE:
16855                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16856                mips32_op = OPC_LWLE;
16857                goto do_ld_lr;
16858            case LWRE:
16859                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16860                mips32_op = OPC_LWRE;
16861                goto do_ld_lr;
16862            case LBE:
16863                mips32_op = OPC_LBE;
16864                goto do_ld_lr;
16865            case LHE:
16866                mips32_op = OPC_LHE;
16867                goto do_ld_lr;
16868            case LLE:
16869                mips32_op = OPC_LLE;
16870                goto do_ld_lr;
16871            case LWE:
16872                mips32_op = OPC_LWE;
16873                goto do_ld_lr;
16874            };
16875            break;
16876        case ST_EVA:
16877            if (!ctx->eva) {
16878                MIPS_INVAL("pool32c st-eva");
16879                generate_exception_end(ctx, EXCP_RI);
16880                break;
16881            }
16882            check_cp0_enabled(ctx);
16883
16884            minor2 = (ctx->opcode >> 9) & 0x7;
16885            offset = sextract32(ctx->opcode, 0, 9);
16886            switch (minor2) {
16887            case SWLE:
16888                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16889                mips32_op = OPC_SWLE;
16890                goto do_st_lr;
16891            case SWRE:
16892                check_insn_opc_removed(ctx, ISA_MIPS32R6);
16893                mips32_op = OPC_SWRE;
16894                goto do_st_lr;
16895            case PREFE:
16896                /* Treat as no-op */
16897                if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16898                    /* hint codes 24-31 are reserved and signal RI */
16899                    generate_exception(ctx, EXCP_RI);
16900                }
16901                break;
16902            case CACHEE:
16903                /* Treat as no-op */
16904                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16905                    gen_cache_operation(ctx, rt, rs, offset);
16906                }
16907                break;
16908            case SBE:
16909                mips32_op = OPC_SBE;
16910                goto do_st_lr;
16911            case SHE:
16912                mips32_op = OPC_SHE;
16913                goto do_st_lr;
16914            case SCE:
16915                gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
16916                break;
16917            case SWE:
16918                mips32_op = OPC_SWE;
16919                goto do_st_lr;
16920            };
16921            break;
16922        case PREF:
16923            /* Treat as no-op */
16924            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16925                /* hint codes 24-31 are reserved and signal RI */
16926                generate_exception(ctx, EXCP_RI);
16927            }
16928            break;
16929        default:
16930            MIPS_INVAL("pool32c");
16931            generate_exception_end(ctx, EXCP_RI);
16932            break;
16933        }
16934        break;
16935    case ADDI32: /* AUI, LUI */
16936        if (ctx->insn_flags & ISA_MIPS32R6) {
16937            /* AUI, LUI */
16938            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16939        } else {
16940            /* ADDI32 */
16941            mips32_op = OPC_ADDI;
16942            goto do_addi;
16943        }
16944        break;
16945    case ADDIU32:
16946        mips32_op = OPC_ADDIU;
16947    do_addi:
16948        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16949        break;
16950
16951        /* Logical operations */
16952    case ORI32:
16953        mips32_op = OPC_ORI;
16954        goto do_logici;
16955    case XORI32:
16956        mips32_op = OPC_XORI;
16957        goto do_logici;
16958    case ANDI32:
16959        mips32_op = OPC_ANDI;
16960    do_logici:
16961        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16962        break;
16963
16964        /* Set less than immediate */
16965    case SLTI32:
16966        mips32_op = OPC_SLTI;
16967        goto do_slti;
16968    case SLTIU32:
16969        mips32_op = OPC_SLTIU;
16970    do_slti:
16971        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16972        break;
16973    case JALX32:
16974        check_insn_opc_removed(ctx, ISA_MIPS32R6);
16975        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16976        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16977        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16978        break;
16979    case JALS32: /* BOVC, BEQC, BEQZALC */
16980        if (ctx->insn_flags & ISA_MIPS32R6) {
16981            if (rs >= rt) {
16982                /* BOVC */
16983                mips32_op = OPC_BOVC;
16984            } else if (rs < rt && rs == 0) {
16985                /* BEQZALC */
16986                mips32_op = OPC_BEQZALC;
16987            } else {
16988                /* BEQC */
16989                mips32_op = OPC_BEQC;
16990            }
16991            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16992        } else {
16993            /* JALS32 */
16994            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16995            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16996            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16997        }
16998        break;
16999    case BEQ32: /* BC */
17000        if (ctx->insn_flags & ISA_MIPS32R6) {
17001            /* BC */
17002            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17003                                       sextract32(ctx->opcode << 1, 0, 27));
17004        } else {
17005            /* BEQ32 */
17006            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17007        }
17008        break;
17009    case BNE32: /* BALC */
17010        if (ctx->insn_flags & ISA_MIPS32R6) {
17011            /* BALC */
17012            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17013                                       sextract32(ctx->opcode << 1, 0, 27));
17014        } else {
17015            /* BNE32 */
17016            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17017        }
17018        break;
17019    case J32: /* BGTZC, BLTZC, BLTC */
17020        if (ctx->insn_flags & ISA_MIPS32R6) {
17021            if (rs == 0 && rt != 0) {
17022                /* BGTZC */
17023                mips32_op = OPC_BGTZC;
17024            } else if (rs != 0 && rt != 0 && rs == rt) {
17025                /* BLTZC */
17026                mips32_op = OPC_BLTZC;
17027            } else {
17028                /* BLTC */
17029                mips32_op = OPC_BLTC;
17030            }
17031            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17032        } else {
17033            /* J32 */
17034            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17035                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17036        }
17037        break;
17038    case JAL32: /* BLEZC, BGEZC, BGEC */
17039        if (ctx->insn_flags & ISA_MIPS32R6) {
17040            if (rs == 0 && rt != 0) {
17041                /* BLEZC */
17042                mips32_op = OPC_BLEZC;
17043            } else if (rs != 0 && rt != 0 && rs == rt) {
17044                /* BGEZC */
17045                mips32_op = OPC_BGEZC;
17046            } else {
17047                /* BGEC */
17048                mips32_op = OPC_BGEC;
17049            }
17050            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17051        } else {
17052            /* JAL32 */
17053            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17054                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17055            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17056        }
17057        break;
17058        /* Floating point (COP1) */
17059    case LWC132:
17060        mips32_op = OPC_LWC1;
17061        goto do_cop1;
17062    case LDC132:
17063        mips32_op = OPC_LDC1;
17064        goto do_cop1;
17065    case SWC132:
17066        mips32_op = OPC_SWC1;
17067        goto do_cop1;
17068    case SDC132:
17069        mips32_op = OPC_SDC1;
17070    do_cop1:
17071        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17072        break;
17073    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17074        if (ctx->insn_flags & ISA_MIPS32R6) {
17075            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17076            switch ((ctx->opcode >> 16) & 0x1f) {
17077            case ADDIUPC_00:
17078            case ADDIUPC_01:
17079            case ADDIUPC_02:
17080            case ADDIUPC_03:
17081            case ADDIUPC_04:
17082            case ADDIUPC_05:
17083            case ADDIUPC_06:
17084            case ADDIUPC_07:
17085                gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17086                break;
17087            case AUIPC:
17088                gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17089                break;
17090            case ALUIPC:
17091                gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17092                break;
17093            case LWPC_08:
17094            case LWPC_09:
17095            case LWPC_0A:
17096            case LWPC_0B:
17097            case LWPC_0C:
17098            case LWPC_0D:
17099            case LWPC_0E:
17100            case LWPC_0F:
17101                gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17102                break;
17103            default:
17104                generate_exception(ctx, EXCP_RI);
17105                break;
17106            }
17107        } else {
17108            /* ADDIUPC */
17109            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17110            offset = SIMM(ctx->opcode, 0, 23) << 2;
17111
17112            gen_addiupc(ctx, reg, offset, 0, 0);
17113        }
17114        break;
17115    case BNVC: /* BNEC, BNEZALC */
17116        check_insn(ctx, ISA_MIPS32R6);
17117        if (rs >= rt) {
17118            /* BNVC */
17119            mips32_op = OPC_BNVC;
17120        } else if (rs < rt && rs == 0) {
17121            /* BNEZALC */
17122            mips32_op = OPC_BNEZALC;
17123        } else {
17124            /* BNEC */
17125            mips32_op = OPC_BNEC;
17126        }
17127        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17128        break;
17129    case R6_BNEZC: /* JIALC */
17130        check_insn(ctx, ISA_MIPS32R6);
17131        if (rt != 0) {
17132            /* BNEZC */
17133            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17134                                       sextract32(ctx->opcode << 1, 0, 22));
17135        } else {
17136            /* JIALC */
17137            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17138        }
17139        break;
17140    case R6_BEQZC: /* JIC */
17141        check_insn(ctx, ISA_MIPS32R6);
17142        if (rt != 0) {
17143            /* BEQZC */
17144            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17145                                       sextract32(ctx->opcode << 1, 0, 22));
17146        } else {
17147            /* JIC */
17148            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17149        }
17150        break;
17151    case BLEZALC: /* BGEZALC, BGEUC */
17152        check_insn(ctx, ISA_MIPS32R6);
17153        if (rs == 0 && rt != 0) {
17154            /* BLEZALC */
17155            mips32_op = OPC_BLEZALC;
17156        } else if (rs != 0 && rt != 0 && rs == rt) {
17157            /* BGEZALC */
17158            mips32_op = OPC_BGEZALC;
17159        } else {
17160            /* BGEUC */
17161            mips32_op = OPC_BGEUC;
17162        }
17163        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17164        break;
17165    case BGTZALC: /* BLTZALC, BLTUC */
17166        check_insn(ctx, ISA_MIPS32R6);
17167        if (rs == 0 && rt != 0) {
17168            /* BGTZALC */
17169            mips32_op = OPC_BGTZALC;
17170        } else if (rs != 0 && rt != 0 && rs == rt) {
17171            /* BLTZALC */
17172            mips32_op = OPC_BLTZALC;
17173        } else {
17174            /* BLTUC */
17175            mips32_op = OPC_BLTUC;
17176        }
17177        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17178        break;
17179        /* Loads and stores */
17180    case LB32:
17181        mips32_op = OPC_LB;
17182        goto do_ld;
17183    case LBU32:
17184        mips32_op = OPC_LBU;
17185        goto do_ld;
17186    case LH32:
17187        mips32_op = OPC_LH;
17188        goto do_ld;
17189    case LHU32:
17190        mips32_op = OPC_LHU;
17191        goto do_ld;
17192    case LW32:
17193        mips32_op = OPC_LW;
17194        goto do_ld;
17195#ifdef TARGET_MIPS64
17196    case LD32:
17197        check_insn(ctx, ISA_MIPS3);
17198        check_mips_64(ctx);
17199        mips32_op = OPC_LD;
17200        goto do_ld;
17201    case SD32:
17202        check_insn(ctx, ISA_MIPS3);
17203        check_mips_64(ctx);
17204        mips32_op = OPC_SD;
17205        goto do_st;
17206#endif
17207    case SB32:
17208        mips32_op = OPC_SB;
17209        goto do_st;
17210    case SH32:
17211        mips32_op = OPC_SH;
17212        goto do_st;
17213    case SW32:
17214        mips32_op = OPC_SW;
17215        goto do_st;
17216    do_ld:
17217        gen_ld(ctx, mips32_op, rt, rs, imm);
17218        break;
17219    do_st:
17220        gen_st(ctx, mips32_op, rt, rs, imm);
17221        break;
17222    default:
17223        generate_exception_end(ctx, EXCP_RI);
17224        break;
17225    }
17226}
17227
17228static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17229{
17230    uint32_t op;
17231
17232    /* make sure instructions are on a halfword boundary */
17233    if (ctx->base.pc_next & 0x1) {
17234        env->CP0_BadVAddr = ctx->base.pc_next;
17235        generate_exception_end(ctx, EXCP_AdEL);
17236        return 2;
17237    }
17238
17239    op = (ctx->opcode >> 10) & 0x3f;
17240    /* Enforce properly-sized instructions in a delay slot */
17241    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17242        switch (op & 0x7) { /* MSB-3..MSB-5 */
17243        case 0:
17244        /* POOL32A, POOL32B, POOL32I, POOL32C */
17245        case 4:
17246        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17247        case 5:
17248        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17249        case 6:
17250        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17251        case 7:
17252        /* LB32, LH32, LWC132, LDC132, LW32 */
17253            if (ctx->hflags & MIPS_HFLAG_BDS16) {
17254                generate_exception_end(ctx, EXCP_RI);
17255                return 2;
17256            }
17257            break;
17258        case 1:
17259        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17260        case 2:
17261        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17262        case 3:
17263        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17264            if (ctx->hflags & MIPS_HFLAG_BDS32) {
17265                generate_exception_end(ctx, EXCP_RI);
17266                return 2;
17267            }
17268            break;
17269        }
17270    }
17271
17272    switch (op) {
17273    case POOL16A:
17274        {
17275            int rd = mmreg(uMIPS_RD(ctx->opcode));
17276            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17277            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17278            uint32_t opc = 0;
17279
17280            switch (ctx->opcode & 0x1) {
17281            case ADDU16:
17282                opc = OPC_ADDU;
17283                break;
17284            case SUBU16:
17285                opc = OPC_SUBU;
17286                break;
17287            }
17288            if (ctx->insn_flags & ISA_MIPS32R6) {
17289                /* In the Release 6 the register number location in
17290                 * the instruction encoding has changed.
17291                 */
17292                gen_arith(ctx, opc, rs1, rd, rs2);
17293            } else {
17294                gen_arith(ctx, opc, rd, rs1, rs2);
17295            }
17296        }
17297        break;
17298    case POOL16B:
17299        {
17300            int rd = mmreg(uMIPS_RD(ctx->opcode));
17301            int rs = mmreg(uMIPS_RS(ctx->opcode));
17302            int amount = (ctx->opcode >> 1) & 0x7;
17303            uint32_t opc = 0;
17304            amount = amount == 0 ? 8 : amount;
17305
17306            switch (ctx->opcode & 0x1) {
17307            case SLL16:
17308                opc = OPC_SLL;
17309                break;
17310            case SRL16:
17311                opc = OPC_SRL;
17312                break;
17313            }
17314
17315            gen_shift_imm(ctx, opc, rd, rs, amount);
17316        }
17317        break;
17318    case POOL16C:
17319        if (ctx->insn_flags & ISA_MIPS32R6) {
17320            gen_pool16c_r6_insn(ctx);
17321        } else {
17322            gen_pool16c_insn(ctx);
17323        }
17324        break;
17325    case LWGP16:
17326        {
17327            int rd = mmreg(uMIPS_RD(ctx->opcode));
17328            int rb = 28;            /* GP */
17329            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17330
17331            gen_ld(ctx, OPC_LW, rd, rb, offset);
17332        }
17333        break;
17334    case POOL16F:
17335        check_insn_opc_removed(ctx, ISA_MIPS32R6);
17336        if (ctx->opcode & 1) {
17337            generate_exception_end(ctx, EXCP_RI);
17338        } else {
17339            /* MOVEP */
17340            int enc_dest = uMIPS_RD(ctx->opcode);
17341            int enc_rt = uMIPS_RS2(ctx->opcode);
17342            int enc_rs = uMIPS_RS1(ctx->opcode);
17343            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17344        }
17345        break;
17346    case LBU16:
17347        {
17348            int rd = mmreg(uMIPS_RD(ctx->opcode));
17349            int rb = mmreg(uMIPS_RS(ctx->opcode));
17350            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17351            offset = (offset == 0xf ? -1 : offset);
17352
17353            gen_ld(ctx, OPC_LBU, rd, rb, offset);
17354        }
17355        break;
17356    case LHU16:
17357        {
17358            int rd = mmreg(uMIPS_RD(ctx->opcode));
17359            int rb = mmreg(uMIPS_RS(ctx->opcode));
17360            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17361
17362            gen_ld(ctx, OPC_LHU, rd, rb, offset);
17363        }
17364        break;
17365    case LWSP16:
17366        {
17367            int rd = (ctx->opcode >> 5) & 0x1f;
17368            int rb = 29;            /* SP */
17369            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17370
17371            gen_ld(ctx, OPC_LW, rd, rb, offset);
17372        }
17373        break;
17374    case LW16:
17375        {
17376            int rd = mmreg(uMIPS_RD(ctx->opcode));
17377            int rb = mmreg(uMIPS_RS(ctx->opcode));
17378            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17379
17380            gen_ld(ctx, OPC_LW, rd, rb, offset);
17381        }
17382        break;
17383    case SB16:
17384        {
17385            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17386            int rb = mmreg(uMIPS_RS(ctx->opcode));
17387            int16_t offset = ZIMM(ctx->opcode, 0, 4);
17388
17389            gen_st(ctx, OPC_SB, rd, rb, offset);
17390        }
17391        break;
17392    case SH16:
17393        {
17394            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17395            int rb = mmreg(uMIPS_RS(ctx->opcode));
17396            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17397
17398            gen_st(ctx, OPC_SH, rd, rb, offset);
17399        }
17400        break;
17401    case SWSP16:
17402        {
17403            int rd = (ctx->opcode >> 5) & 0x1f;
17404            int rb = 29;            /* SP */
17405            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17406
17407            gen_st(ctx, OPC_SW, rd, rb, offset);
17408        }
17409        break;
17410    case SW16:
17411        {
17412            int rd = mmreg2(uMIPS_RD(ctx->opcode));
17413            int rb = mmreg(uMIPS_RS(ctx->opcode));
17414            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17415
17416            gen_st(ctx, OPC_SW, rd, rb, offset);
17417        }
17418        break;
17419    case MOVE16:
17420        {
17421            int rd = uMIPS_RD5(ctx->opcode);
17422            int rs = uMIPS_RS5(ctx->opcode);
17423
17424            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17425        }
17426        break;
17427    case ANDI16:
17428        gen_andi16(ctx);
17429        break;
17430    case POOL16D:
17431        switch (ctx->opcode & 0x1) {
17432        case ADDIUS5:
17433            gen_addius5(ctx);
17434            break;
17435        case ADDIUSP:
17436            gen_addiusp(ctx);
17437            break;
17438        }
17439        break;
17440    case POOL16E:
17441        switch (ctx->opcode & 0x1) {
17442        case ADDIUR2:
17443            gen_addiur2(ctx);
17444            break;
17445        case ADDIUR1SP:
17446            gen_addiur1sp(ctx);
17447            break;
17448        }
17449        break;
17450    case B16: /* BC16 */
17451        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17452                           sextract32(ctx->opcode, 0, 10) << 1,
17453                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17454        break;
17455    case BNEZ16: /* BNEZC16 */
17456    case BEQZ16: /* BEQZC16 */
17457        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17458                           mmreg(uMIPS_RD(ctx->opcode)),
17459                           0, sextract32(ctx->opcode, 0, 7) << 1,
17460                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17461
17462        break;
17463    case LI16:
17464        {
17465            int reg = mmreg(uMIPS_RD(ctx->opcode));
17466            int imm = ZIMM(ctx->opcode, 0, 7);
17467
17468            imm = (imm == 0x7f ? -1 : imm);
17469            tcg_gen_movi_tl(cpu_gpr[reg], imm);
17470        }
17471        break;
17472    case RES_29:
17473    case RES_31:
17474    case RES_39:
17475        generate_exception_end(ctx, EXCP_RI);
17476        break;
17477    default:
17478        decode_micromips32_opc(env, ctx);
17479        return 4;
17480    }
17481
17482    return 2;
17483}
17484
17485/*
17486 *
17487 * nanoMIPS opcodes
17488 *
17489 */
17490
17491/* MAJOR, P16, and P32 pools opcodes */
17492enum {
17493    NM_P_ADDIU      = 0x00,
17494    NM_ADDIUPC      = 0x01,
17495    NM_MOVE_BALC    = 0x02,
17496    NM_P16_MV       = 0x04,
17497    NM_LW16         = 0x05,
17498    NM_BC16         = 0x06,
17499    NM_P16_SR       = 0x07,
17500
17501    NM_POOL32A      = 0x08,
17502    NM_P_BAL        = 0x0a,
17503    NM_P16_SHIFT    = 0x0c,
17504    NM_LWSP16       = 0x0d,
17505    NM_BALC16       = 0x0e,
17506    NM_P16_4X4      = 0x0f,
17507
17508    NM_P_GP_W       = 0x10,
17509    NM_P_GP_BH      = 0x11,
17510    NM_P_J          = 0x12,
17511    NM_P16C         = 0x14,
17512    NM_LWGP16       = 0x15,
17513    NM_P16_LB       = 0x17,
17514
17515    NM_P48I         = 0x18,
17516    NM_P16_A1       = 0x1c,
17517    NM_LW4X4        = 0x1d,
17518    NM_P16_LH       = 0x1f,
17519
17520    NM_P_U12        = 0x20,
17521    NM_P_LS_U12     = 0x21,
17522    NM_P_BR1        = 0x22,
17523    NM_P16_A2       = 0x24,
17524    NM_SW16         = 0x25,
17525    NM_BEQZC16      = 0x26,
17526
17527    NM_POOL32F      = 0x28,
17528    NM_P_LS_S9      = 0x29,
17529    NM_P_BR2        = 0x2a,
17530
17531    NM_P16_ADDU     = 0x2c,
17532    NM_SWSP16       = 0x2d,
17533    NM_BNEZC16      = 0x2e,
17534    NM_MOVEP        = 0x2f,
17535
17536    NM_POOL32S      = 0x30,
17537    NM_P_BRI        = 0x32,
17538    NM_LI16         = 0x34,
17539    NM_SWGP16       = 0x35,
17540    NM_P16_BR       = 0x36,
17541
17542    NM_P_LUI        = 0x38,
17543    NM_ANDI16       = 0x3c,
17544    NM_SW4X4        = 0x3d,
17545    NM_MOVEPREV     = 0x3f,
17546};
17547
17548/* POOL32A instruction pool */
17549enum {
17550    NM_POOL32A0    = 0x00,
17551    NM_SPECIAL2    = 0x01,
17552    NM_COP2_1      = 0x02,
17553    NM_UDI         = 0x03,
17554    NM_POOL32A5    = 0x05,
17555    NM_POOL32A7    = 0x07,
17556};
17557
17558/* P.GP.W instruction pool */
17559enum {
17560    NM_ADDIUGP_W = 0x00,
17561    NM_LWGP      = 0x02,
17562    NM_SWGP      = 0x03,
17563};
17564
17565/* P48I instruction pool */
17566enum {
17567    NM_LI48        = 0x00,
17568    NM_ADDIU48     = 0x01,
17569    NM_ADDIUGP48   = 0x02,
17570    NM_ADDIUPC48   = 0x03,
17571    NM_LWPC48      = 0x0b,
17572    NM_SWPC48      = 0x0f,
17573};
17574
17575/* P.U12 instruction pool */
17576enum {
17577    NM_ORI      = 0x00,
17578    NM_XORI     = 0x01,
17579    NM_ANDI     = 0x02,
17580    NM_P_SR     = 0x03,
17581    NM_SLTI     = 0x04,
17582    NM_SLTIU    = 0x05,
17583    NM_SEQI     = 0x06,
17584    NM_ADDIUNEG = 0x08,
17585    NM_P_SHIFT  = 0x0c,
17586    NM_P_ROTX   = 0x0d,
17587    NM_P_INS    = 0x0e,
17588    NM_P_EXT    = 0x0f,
17589};
17590
17591/* POOL32F instruction pool */
17592enum {
17593    NM_POOL32F_0   = 0x00,
17594    NM_POOL32F_3   = 0x03,
17595    NM_POOL32F_5   = 0x05,
17596};
17597
17598/* POOL32S instruction pool */
17599enum {
17600    NM_POOL32S_0   = 0x00,
17601    NM_POOL32S_4   = 0x04,
17602};
17603
17604/* P.LUI instruction pool */
17605enum {
17606    NM_LUI      = 0x00,
17607    NM_ALUIPC   = 0x01,
17608};
17609
17610/* P.GP.BH instruction pool */
17611enum {
17612    NM_LBGP      = 0x00,
17613    NM_SBGP      = 0x01,
17614    NM_LBUGP     = 0x02,
17615    NM_ADDIUGP_B = 0x03,
17616    NM_P_GP_LH   = 0x04,
17617    NM_P_GP_SH   = 0x05,
17618    NM_P_GP_CP1  = 0x06,
17619};
17620
17621/* P.LS.U12 instruction pool */
17622enum {
17623    NM_LB        = 0x00,
17624    NM_SB        = 0x01,
17625    NM_LBU       = 0x02,
17626    NM_P_PREFU12 = 0x03,
17627    NM_LH        = 0x04,
17628    NM_SH        = 0x05,
17629    NM_LHU       = 0x06,
17630    NM_LWU       = 0x07,
17631    NM_LW        = 0x08,
17632    NM_SW        = 0x09,
17633    NM_LWC1      = 0x0a,
17634    NM_SWC1      = 0x0b,
17635    NM_LDC1      = 0x0e,
17636    NM_SDC1      = 0x0f,
17637};
17638
17639/* P.LS.S9 instruction pool */
17640enum {
17641    NM_P_LS_S0         = 0x00,
17642    NM_P_LS_S1         = 0x01,
17643    NM_P_LS_E0         = 0x02,
17644    NM_P_LS_WM         = 0x04,
17645    NM_P_LS_UAWM       = 0x05,
17646};
17647
17648/* P.BAL instruction pool */
17649enum {
17650    NM_BC       = 0x00,
17651    NM_BALC     = 0x01,
17652};
17653
17654/* P.J instruction pool */
17655enum {
17656    NM_JALRC    = 0x00,
17657    NM_JALRC_HB = 0x01,
17658    NM_P_BALRSC = 0x08,
17659};
17660
17661/* P.BR1 instruction pool */
17662enum {
17663    NM_BEQC     = 0x00,
17664    NM_P_BR3A   = 0x01,
17665    NM_BGEC     = 0x02,
17666    NM_BGEUC    = 0x03,
17667};
17668
17669/* P.BR2 instruction pool */
17670enum {
17671    NM_BNEC     = 0x00,
17672    NM_BLTC     = 0x02,
17673    NM_BLTUC    = 0x03,
17674};
17675
17676/* P.BRI instruction pool */
17677enum {
17678    NM_BEQIC    = 0x00,
17679    NM_BBEQZC   = 0x01,
17680    NM_BGEIC    = 0x02,
17681    NM_BGEIUC   = 0x03,
17682    NM_BNEIC    = 0x04,
17683    NM_BBNEZC   = 0x05,
17684    NM_BLTIC    = 0x06,
17685    NM_BLTIUC   = 0x07,
17686};
17687
17688/* P16.SHIFT instruction pool */
17689enum {
17690    NM_SLL16    = 0x00,
17691    NM_SRL16    = 0x01,
17692};
17693
17694/* POOL16C instruction pool */
17695enum {
17696    NM_POOL16C_0  = 0x00,
17697    NM_LWXS16     = 0x01,
17698};
17699
17700/* P16.A1 instruction pool */
17701enum {
17702    NM_ADDIUR1SP = 0x01,
17703};
17704
17705/* P16.A2 instruction pool */
17706enum {
17707    NM_ADDIUR2  = 0x00,
17708    NM_P_ADDIURS5  = 0x01,
17709};
17710
17711/* P16.ADDU instruction pool */
17712enum {
17713    NM_ADDU16     = 0x00,
17714    NM_SUBU16     = 0x01,
17715};
17716
17717/* P16.SR instruction pool */
17718enum {
17719    NM_SAVE16        = 0x00,
17720    NM_RESTORE_JRC16 = 0x01,
17721};
17722
17723/* P16.4X4 instruction pool */
17724enum {
17725    NM_ADDU4X4      = 0x00,
17726    NM_MUL4X4       = 0x01,
17727};
17728
17729/* P16.LB instruction pool */
17730enum {
17731    NM_LB16       = 0x00,
17732    NM_SB16       = 0x01,
17733    NM_LBU16      = 0x02,
17734};
17735
17736/* P16.LH  instruction pool */
17737enum {
17738    NM_LH16     = 0x00,
17739    NM_SH16     = 0x01,
17740    NM_LHU16    = 0x02,
17741};
17742
17743/* P.RI instruction pool */
17744enum {
17745    NM_SIGRIE       = 0x00,
17746    NM_P_SYSCALL    = 0x01,
17747    NM_BREAK        = 0x02,
17748    NM_SDBBP        = 0x03,
17749};
17750
17751/* POOL32A0 instruction pool */
17752enum {
17753    NM_P_TRAP   = 0x00,
17754    NM_SEB      = 0x01,
17755    NM_SLLV     = 0x02,
17756    NM_MUL      = 0x03,
17757    NM_MFC0     = 0x06,
17758    NM_MFHC0    = 0x07,
17759    NM_SEH      = 0x09,
17760    NM_SRLV     = 0x0a,
17761    NM_MUH      = 0x0b,
17762    NM_MTC0     = 0x0e,
17763    NM_MTHC0    = 0x0f,
17764    NM_SRAV     = 0x12,
17765    NM_MULU     = 0x13,
17766    NM_ROTRV    = 0x1a,
17767    NM_MUHU     = 0x1b,
17768    NM_ADD      = 0x22,
17769    NM_DIV      = 0x23,
17770    NM_ADDU     = 0x2a,
17771    NM_MOD      = 0x2b,
17772    NM_SUB      = 0x32,
17773    NM_DIVU     = 0x33,
17774    NM_RDHWR    = 0x38,
17775    NM_SUBU     = 0x3a,
17776    NM_MODU     = 0x3b,
17777    NM_P_CMOVE  = 0x42,
17778    NM_FORK     = 0x45,
17779    NM_MFTR     = 0x46,
17780    NM_MFHTR    = 0x47,
17781    NM_AND      = 0x4a,
17782    NM_YIELD    = 0x4d,
17783    NM_MTTR     = 0x4e,
17784    NM_MTHTR    = 0x4f,
17785    NM_OR       = 0x52,
17786    NM_D_E_MT_VPE = 0x56,
17787    NM_NOR      = 0x5a,
17788    NM_XOR      = 0x62,
17789    NM_SLT      = 0x6a,
17790    NM_P_SLTU   = 0x72,
17791    NM_SOV      = 0x7a,
17792};
17793
17794/* CRC32 instruction pool */
17795enum {
17796    NM_CRC32B   = 0x00,
17797    NM_CRC32H   = 0x01,
17798    NM_CRC32W   = 0x02,
17799    NM_CRC32CB  = 0x04,
17800    NM_CRC32CH  = 0x05,
17801    NM_CRC32CW  = 0x06,
17802};
17803
17804/* POOL32A5 instruction pool */
17805enum {
17806    NM_CMP_EQ_PH        = 0x00,
17807    NM_CMP_LT_PH        = 0x08,
17808    NM_CMP_LE_PH        = 0x10,
17809    NM_CMPGU_EQ_QB      = 0x18,
17810    NM_CMPGU_LT_QB      = 0x20,
17811    NM_CMPGU_LE_QB      = 0x28,
17812    NM_CMPGDU_EQ_QB     = 0x30,
17813    NM_CMPGDU_LT_QB     = 0x38,
17814    NM_CMPGDU_LE_QB     = 0x40,
17815    NM_CMPU_EQ_QB       = 0x48,
17816    NM_CMPU_LT_QB       = 0x50,
17817    NM_CMPU_LE_QB       = 0x58,
17818    NM_ADDQ_S_W         = 0x60,
17819    NM_SUBQ_S_W         = 0x68,
17820    NM_ADDSC            = 0x70,
17821    NM_ADDWC            = 0x78,
17822
17823    NM_ADDQ_S_PH   = 0x01,
17824    NM_ADDQH_R_PH  = 0x09,
17825    NM_ADDQH_R_W   = 0x11,
17826    NM_ADDU_S_QB   = 0x19,
17827    NM_ADDU_S_PH   = 0x21,
17828    NM_ADDUH_R_QB  = 0x29,
17829    NM_SHRAV_R_PH  = 0x31,
17830    NM_SHRAV_R_QB  = 0x39,
17831    NM_SUBQ_S_PH   = 0x41,
17832    NM_SUBQH_R_PH  = 0x49,
17833    NM_SUBQH_R_W   = 0x51,
17834    NM_SUBU_S_QB   = 0x59,
17835    NM_SUBU_S_PH   = 0x61,
17836    NM_SUBUH_R_QB  = 0x69,
17837    NM_SHLLV_S_PH  = 0x71,
17838    NM_PRECR_SRA_R_PH_W = 0x79,
17839
17840    NM_MULEU_S_PH_QBL   = 0x12,
17841    NM_MULEU_S_PH_QBR   = 0x1a,
17842    NM_MULQ_RS_PH       = 0x22,
17843    NM_MULQ_S_PH        = 0x2a,
17844    NM_MULQ_RS_W        = 0x32,
17845    NM_MULQ_S_W         = 0x3a,
17846    NM_APPEND           = 0x42,
17847    NM_MODSUB           = 0x52,
17848    NM_SHRAV_R_W        = 0x5a,
17849    NM_SHRLV_PH         = 0x62,
17850    NM_SHRLV_QB         = 0x6a,
17851    NM_SHLLV_QB         = 0x72,
17852    NM_SHLLV_S_W        = 0x7a,
17853
17854    NM_SHILO            = 0x03,
17855
17856    NM_MULEQ_S_W_PHL    = 0x04,
17857    NM_MULEQ_S_W_PHR    = 0x0c,
17858
17859    NM_MUL_S_PH         = 0x05,
17860    NM_PRECR_QB_PH      = 0x0d,
17861    NM_PRECRQ_QB_PH     = 0x15,
17862    NM_PRECRQ_PH_W      = 0x1d,
17863    NM_PRECRQ_RS_PH_W   = 0x25,
17864    NM_PRECRQU_S_QB_PH  = 0x2d,
17865    NM_PACKRL_PH        = 0x35,
17866    NM_PICK_QB          = 0x3d,
17867    NM_PICK_PH          = 0x45,
17868
17869    NM_SHRA_R_W         = 0x5e,
17870    NM_SHRA_R_PH        = 0x66,
17871    NM_SHLL_S_PH        = 0x76,
17872    NM_SHLL_S_W         = 0x7e,
17873
17874    NM_REPL_PH          = 0x07
17875};
17876
17877/* POOL32A7 instruction pool */
17878enum {
17879    NM_P_LSX        = 0x00,
17880    NM_LSA          = 0x01,
17881    NM_EXTW         = 0x03,
17882    NM_POOL32AXF    = 0x07,
17883};
17884
17885/* P.SR instruction pool */
17886enum {
17887    NM_PP_SR           = 0x00,
17888    NM_P_SR_F          = 0x01,
17889};
17890
17891/* P.SHIFT instruction pool */
17892enum {
17893    NM_P_SLL        = 0x00,
17894    NM_SRL          = 0x02,
17895    NM_SRA          = 0x04,
17896    NM_ROTR         = 0x06,
17897};
17898
17899/* P.ROTX instruction pool */
17900enum {
17901    NM_ROTX         = 0x00,
17902};
17903
17904/* P.INS instruction pool */
17905enum {
17906    NM_INS          = 0x00,
17907};
17908
17909/* P.EXT instruction pool */
17910enum {
17911    NM_EXT          = 0x00,
17912};
17913
17914/* POOL32F_0 (fmt) instruction pool */
17915enum {
17916    NM_RINT_S              = 0x04,
17917    NM_RINT_D              = 0x44,
17918    NM_ADD_S               = 0x06,
17919    NM_SELEQZ_S            = 0x07,
17920    NM_SELEQZ_D            = 0x47,
17921    NM_CLASS_S             = 0x0c,
17922    NM_CLASS_D             = 0x4c,
17923    NM_SUB_S               = 0x0e,
17924    NM_SELNEZ_S            = 0x0f,
17925    NM_SELNEZ_D            = 0x4f,
17926    NM_MUL_S               = 0x16,
17927    NM_SEL_S               = 0x17,
17928    NM_SEL_D               = 0x57,
17929    NM_DIV_S               = 0x1e,
17930    NM_ADD_D               = 0x26,
17931    NM_SUB_D               = 0x2e,
17932    NM_MUL_D               = 0x36,
17933    NM_MADDF_S             = 0x37,
17934    NM_MADDF_D             = 0x77,
17935    NM_DIV_D               = 0x3e,
17936    NM_MSUBF_S             = 0x3f,
17937    NM_MSUBF_D             = 0x7f,
17938};
17939
17940/* POOL32F_3  instruction pool */
17941enum {
17942    NM_MIN_FMT         = 0x00,
17943    NM_MAX_FMT         = 0x01,
17944    NM_MINA_FMT        = 0x04,
17945    NM_MAXA_FMT        = 0x05,
17946    NM_POOL32FXF       = 0x07,
17947};
17948
17949/* POOL32F_5  instruction pool */
17950enum {
17951    NM_CMP_CONDN_S     = 0x00,
17952    NM_CMP_CONDN_D     = 0x02,
17953};
17954
17955/* P.GP.LH instruction pool */
17956enum {
17957    NM_LHGP    = 0x00,
17958    NM_LHUGP   = 0x01,
17959};
17960
17961/* P.GP.SH instruction pool */
17962enum {
17963    NM_SHGP    = 0x00,
17964};
17965
17966/* P.GP.CP1 instruction pool */
17967enum {
17968    NM_LWC1GP       = 0x00,
17969    NM_SWC1GP       = 0x01,
17970    NM_LDC1GP       = 0x02,
17971    NM_SDC1GP       = 0x03,
17972};
17973
17974/* P.LS.S0 instruction pool */
17975enum {
17976    NM_LBS9     = 0x00,
17977    NM_LHS9     = 0x04,
17978    NM_LWS9     = 0x08,
17979    NM_LDS9     = 0x0c,
17980
17981    NM_SBS9     = 0x01,
17982    NM_SHS9     = 0x05,
17983    NM_SWS9     = 0x09,
17984    NM_SDS9     = 0x0d,
17985
17986    NM_LBUS9    = 0x02,
17987    NM_LHUS9    = 0x06,
17988    NM_LWC1S9   = 0x0a,
17989    NM_LDC1S9   = 0x0e,
17990
17991    NM_P_PREFS9 = 0x03,
17992    NM_LWUS9    = 0x07,
17993    NM_SWC1S9   = 0x0b,
17994    NM_SDC1S9   = 0x0f,
17995};
17996
17997/* P.LS.S1 instruction pool */
17998enum {
17999    NM_ASET_ACLR = 0x02,
18000    NM_UALH      = 0x04,
18001    NM_UASH      = 0x05,
18002    NM_CACHE     = 0x07,
18003    NM_P_LL      = 0x0a,
18004    NM_P_SC      = 0x0b,
18005};
18006
18007/* P.LS.E0 instruction pool */
18008enum {
18009    NM_LBE      = 0x00,
18010    NM_SBE      = 0x01,
18011    NM_LBUE     = 0x02,
18012    NM_P_PREFE  = 0x03,
18013    NM_LHE      = 0x04,
18014    NM_SHE      = 0x05,
18015    NM_LHUE     = 0x06,
18016    NM_CACHEE   = 0x07,
18017    NM_LWE      = 0x08,
18018    NM_SWE      = 0x09,
18019    NM_P_LLE    = 0x0a,
18020    NM_P_SCE    = 0x0b,
18021};
18022
18023/* P.PREFE instruction pool */
18024enum {
18025    NM_SYNCIE   = 0x00,
18026    NM_PREFE    = 0x01,
18027};
18028
18029/* P.LLE instruction pool */
18030enum {
18031    NM_LLE      = 0x00,
18032    NM_LLWPE    = 0x01,
18033};
18034
18035/* P.SCE instruction pool */
18036enum {
18037    NM_SCE      = 0x00,
18038    NM_SCWPE    = 0x01,
18039};
18040
18041/* P.LS.WM instruction pool */
18042enum {
18043    NM_LWM       = 0x00,
18044    NM_SWM       = 0x01,
18045};
18046
18047/* P.LS.UAWM instruction pool */
18048enum {
18049    NM_UALWM       = 0x00,
18050    NM_UASWM       = 0x01,
18051};
18052
18053/* P.BR3A instruction pool */
18054enum {
18055    NM_BC1EQZC          = 0x00,
18056    NM_BC1NEZC          = 0x01,
18057    NM_BC2EQZC          = 0x02,
18058    NM_BC2NEZC          = 0x03,
18059    NM_BPOSGE32C        = 0x04,
18060};
18061
18062/* P16.RI instruction pool */
18063enum {
18064    NM_P16_SYSCALL  = 0x01,
18065    NM_BREAK16      = 0x02,
18066    NM_SDBBP16      = 0x03,
18067};
18068
18069/* POOL16C_0 instruction pool */
18070enum {
18071    NM_POOL16C_00      = 0x00,
18072};
18073
18074/* P16.JRC instruction pool */
18075enum {
18076    NM_JRC          = 0x00,
18077    NM_JALRC16      = 0x01,
18078};
18079
18080/* P.SYSCALL instruction pool */
18081enum {
18082    NM_SYSCALL      = 0x00,
18083    NM_HYPCALL      = 0x01,
18084};
18085
18086/* P.TRAP instruction pool */
18087enum {
18088    NM_TEQ          = 0x00,
18089    NM_TNE          = 0x01,
18090};
18091
18092/* P.CMOVE instruction pool */
18093enum {
18094    NM_MOVZ            = 0x00,
18095    NM_MOVN            = 0x01,
18096};
18097
18098/* POOL32Axf instruction pool */
18099enum {
18100    NM_POOL32AXF_1 = 0x01,
18101    NM_POOL32AXF_2 = 0x02,
18102    NM_POOL32AXF_4 = 0x04,
18103    NM_POOL32AXF_5 = 0x05,
18104    NM_POOL32AXF_7 = 0x07,
18105};
18106
18107/* POOL32Axf_1 instruction pool */
18108enum {
18109    NM_POOL32AXF_1_0 = 0x00,
18110    NM_POOL32AXF_1_1 = 0x01,
18111    NM_POOL32AXF_1_3 = 0x03,
18112    NM_POOL32AXF_1_4 = 0x04,
18113    NM_POOL32AXF_1_5 = 0x05,
18114    NM_POOL32AXF_1_7 = 0x07,
18115};
18116
18117/* POOL32Axf_2 instruction pool */
18118enum {
18119    NM_POOL32AXF_2_0_7     = 0x00,
18120    NM_POOL32AXF_2_8_15    = 0x01,
18121    NM_POOL32AXF_2_16_23   = 0x02,
18122    NM_POOL32AXF_2_24_31   = 0x03,
18123};
18124
18125/* POOL32Axf_7 instruction pool */
18126enum {
18127    NM_SHRA_R_QB    = 0x0,
18128    NM_SHRL_PH      = 0x1,
18129    NM_REPL_QB      = 0x2,
18130};
18131
18132/* POOL32Axf_1_0 instruction pool */
18133enum {
18134    NM_MFHI = 0x0,
18135    NM_MFLO = 0x1,
18136    NM_MTHI = 0x2,
18137    NM_MTLO = 0x3,
18138};
18139
18140/* POOL32Axf_1_1 instruction pool */
18141enum {
18142    NM_MTHLIP = 0x0,
18143    NM_SHILOV = 0x1,
18144};
18145
18146/* POOL32Axf_1_3 instruction pool */
18147enum {
18148    NM_RDDSP    = 0x0,
18149    NM_WRDSP    = 0x1,
18150    NM_EXTP     = 0x2,
18151    NM_EXTPDP   = 0x3,
18152};
18153
18154/* POOL32Axf_1_4 instruction pool */
18155enum {
18156    NM_SHLL_QB  = 0x0,
18157    NM_SHRL_QB  = 0x1,
18158};
18159
18160/* POOL32Axf_1_5 instruction pool */
18161enum {
18162    NM_MAQ_S_W_PHR   = 0x0,
18163    NM_MAQ_S_W_PHL   = 0x1,
18164    NM_MAQ_SA_W_PHR  = 0x2,
18165    NM_MAQ_SA_W_PHL  = 0x3,
18166};
18167
18168/* POOL32Axf_1_7 instruction pool */
18169enum {
18170    NM_EXTR_W       = 0x0,
18171    NM_EXTR_R_W     = 0x1,
18172    NM_EXTR_RS_W    = 0x2,
18173    NM_EXTR_S_H     = 0x3,
18174};
18175
18176/* POOL32Axf_2_0_7 instruction pool */
18177enum {
18178    NM_DPA_W_PH     = 0x0,
18179    NM_DPAQ_S_W_PH  = 0x1,
18180    NM_DPS_W_PH     = 0x2,
18181    NM_DPSQ_S_W_PH  = 0x3,
18182    NM_BALIGN       = 0x4,
18183    NM_MADD         = 0x5,
18184    NM_MULT         = 0x6,
18185    NM_EXTRV_W      = 0x7,
18186};
18187
18188/* POOL32Axf_2_8_15 instruction pool */
18189enum {
18190    NM_DPAX_W_PH    = 0x0,
18191    NM_DPAQ_SA_L_W  = 0x1,
18192    NM_DPSX_W_PH    = 0x2,
18193    NM_DPSQ_SA_L_W  = 0x3,
18194    NM_MADDU        = 0x5,
18195    NM_MULTU        = 0x6,
18196    NM_EXTRV_R_W    = 0x7,
18197};
18198
18199/* POOL32Axf_2_16_23 instruction pool */
18200enum {
18201    NM_DPAU_H_QBL       = 0x0,
18202    NM_DPAQX_S_W_PH     = 0x1,
18203    NM_DPSU_H_QBL       = 0x2,
18204    NM_DPSQX_S_W_PH     = 0x3,
18205    NM_EXTPV            = 0x4,
18206    NM_MSUB             = 0x5,
18207    NM_MULSA_W_PH       = 0x6,
18208    NM_EXTRV_RS_W       = 0x7,
18209};
18210
18211/* POOL32Axf_2_24_31 instruction pool */
18212enum {
18213    NM_DPAU_H_QBR       = 0x0,
18214    NM_DPAQX_SA_W_PH    = 0x1,
18215    NM_DPSU_H_QBR       = 0x2,
18216    NM_DPSQX_SA_W_PH    = 0x3,
18217    NM_EXTPDPV          = 0x4,
18218    NM_MSUBU            = 0x5,
18219    NM_MULSAQ_S_W_PH    = 0x6,
18220    NM_EXTRV_S_H        = 0x7,
18221};
18222
18223/* POOL32Axf_{4, 5} instruction pool */
18224enum {
18225    NM_CLO      = 0x25,
18226    NM_CLZ      = 0x2d,
18227
18228    NM_TLBP     = 0x01,
18229    NM_TLBR     = 0x09,
18230    NM_TLBWI    = 0x11,
18231    NM_TLBWR    = 0x19,
18232    NM_TLBINV   = 0x03,
18233    NM_TLBINVF  = 0x0b,
18234    NM_DI       = 0x23,
18235    NM_EI       = 0x2b,
18236    NM_RDPGPR   = 0x70,
18237    NM_WRPGPR   = 0x78,
18238    NM_WAIT     = 0x61,
18239    NM_DERET    = 0x71,
18240    NM_ERETX    = 0x79,
18241
18242    /* nanoMIPS DSP instructions */
18243    NM_ABSQ_S_QB        = 0x00,
18244    NM_ABSQ_S_PH        = 0x08,
18245    NM_ABSQ_S_W         = 0x10,
18246    NM_PRECEQ_W_PHL     = 0x28,
18247    NM_PRECEQ_W_PHR     = 0x30,
18248    NM_PRECEQU_PH_QBL   = 0x38,
18249    NM_PRECEQU_PH_QBR   = 0x48,
18250    NM_PRECEU_PH_QBL    = 0x58,
18251    NM_PRECEU_PH_QBR    = 0x68,
18252    NM_PRECEQU_PH_QBLA  = 0x39,
18253    NM_PRECEQU_PH_QBRA  = 0x49,
18254    NM_PRECEU_PH_QBLA   = 0x59,
18255    NM_PRECEU_PH_QBRA   = 0x69,
18256    NM_REPLV_PH         = 0x01,
18257    NM_REPLV_QB         = 0x09,
18258    NM_BITREV           = 0x18,
18259    NM_INSV             = 0x20,
18260    NM_RADDU_W_QB       = 0x78,
18261
18262    NM_BITSWAP          = 0x05,
18263    NM_WSBH             = 0x3d,
18264};
18265
18266/* PP.SR instruction pool */
18267enum {
18268    NM_SAVE         = 0x00,
18269    NM_RESTORE      = 0x02,
18270    NM_RESTORE_JRC  = 0x03,
18271};
18272
18273/* P.SR.F instruction pool */
18274enum {
18275    NM_SAVEF        = 0x00,
18276    NM_RESTOREF     = 0x01,
18277};
18278
18279/* P16.SYSCALL  instruction pool */
18280enum {
18281    NM_SYSCALL16     = 0x00,
18282    NM_HYPCALL16     = 0x01,
18283};
18284
18285/* POOL16C_00 instruction pool */
18286enum {
18287    NM_NOT16           = 0x00,
18288    NM_XOR16           = 0x01,
18289    NM_AND16           = 0x02,
18290    NM_OR16            = 0x03,
18291};
18292
18293/* PP.LSX and PP.LSXS instruction pool */
18294enum {
18295    NM_LBX      = 0x00,
18296    NM_LHX      = 0x04,
18297    NM_LWX      = 0x08,
18298    NM_LDX      = 0x0c,
18299
18300    NM_SBX      = 0x01,
18301    NM_SHX      = 0x05,
18302    NM_SWX      = 0x09,
18303    NM_SDX      = 0x0d,
18304
18305    NM_LBUX     = 0x02,
18306    NM_LHUX     = 0x06,
18307    NM_LWC1X    = 0x0a,
18308    NM_LDC1X    = 0x0e,
18309
18310    NM_LWUX     = 0x07,
18311    NM_SWC1X    = 0x0b,
18312    NM_SDC1X    = 0x0f,
18313
18314    NM_LHXS     = 0x04,
18315    NM_LWXS     = 0x08,
18316    NM_LDXS     = 0x0c,
18317
18318    NM_SHXS     = 0x05,
18319    NM_SWXS     = 0x09,
18320    NM_SDXS     = 0x0d,
18321
18322    NM_LHUXS    = 0x06,
18323    NM_LWC1XS   = 0x0a,
18324    NM_LDC1XS   = 0x0e,
18325
18326    NM_LWUXS    = 0x07,
18327    NM_SWC1XS   = 0x0b,
18328    NM_SDC1XS   = 0x0f,
18329};
18330
18331/* ERETx instruction pool */
18332enum {
18333    NM_ERET     = 0x00,
18334    NM_ERETNC   = 0x01,
18335};
18336
18337/* POOL32FxF_{0, 1} insturction pool */
18338enum {
18339    NM_CFC1     = 0x40,
18340    NM_CTC1     = 0x60,
18341    NM_MFC1     = 0x80,
18342    NM_MTC1     = 0xa0,
18343    NM_MFHC1    = 0xc0,
18344    NM_MTHC1    = 0xe0,
18345
18346    NM_CVT_S_PL = 0x84,
18347    NM_CVT_S_PU = 0xa4,
18348
18349    NM_CVT_L_S     = 0x004,
18350    NM_CVT_L_D     = 0x104,
18351    NM_CVT_W_S     = 0x024,
18352    NM_CVT_W_D     = 0x124,
18353
18354    NM_RSQRT_S     = 0x008,
18355    NM_RSQRT_D     = 0x108,
18356
18357    NM_SQRT_S      = 0x028,
18358    NM_SQRT_D      = 0x128,
18359
18360    NM_RECIP_S     = 0x048,
18361    NM_RECIP_D     = 0x148,
18362
18363    NM_FLOOR_L_S   = 0x00c,
18364    NM_FLOOR_L_D   = 0x10c,
18365
18366    NM_FLOOR_W_S   = 0x02c,
18367    NM_FLOOR_W_D   = 0x12c,
18368
18369    NM_CEIL_L_S    = 0x04c,
18370    NM_CEIL_L_D    = 0x14c,
18371    NM_CEIL_W_S    = 0x06c,
18372    NM_CEIL_W_D    = 0x16c,
18373    NM_TRUNC_L_S   = 0x08c,
18374    NM_TRUNC_L_D   = 0x18c,
18375    NM_TRUNC_W_S   = 0x0ac,
18376    NM_TRUNC_W_D   = 0x1ac,
18377    NM_ROUND_L_S   = 0x0cc,
18378    NM_ROUND_L_D   = 0x1cc,
18379    NM_ROUND_W_S   = 0x0ec,
18380    NM_ROUND_W_D   = 0x1ec,
18381
18382    NM_MOV_S       = 0x01,
18383    NM_MOV_D       = 0x81,
18384    NM_ABS_S       = 0x0d,
18385    NM_ABS_D       = 0x8d,
18386    NM_NEG_S       = 0x2d,
18387    NM_NEG_D       = 0xad,
18388    NM_CVT_D_S     = 0x04d,
18389    NM_CVT_D_W     = 0x0cd,
18390    NM_CVT_D_L     = 0x14d,
18391    NM_CVT_S_D     = 0x06d,
18392    NM_CVT_S_W     = 0x0ed,
18393    NM_CVT_S_L     = 0x16d,
18394};
18395
18396/* P.LL instruction pool */
18397enum {
18398    NM_LL       = 0x00,
18399    NM_LLWP     = 0x01,
18400};
18401
18402/* P.SC instruction pool */
18403enum {
18404    NM_SC       = 0x00,
18405    NM_SCWP     = 0x01,
18406};
18407
18408/* P.DVP instruction pool */
18409enum {
18410    NM_DVP      = 0x00,
18411    NM_EVP      = 0x01,
18412};
18413
18414
18415/*
18416 *
18417 * nanoMIPS decoding engine
18418 *
18419 */
18420
18421
18422/* extraction utilities */
18423
18424#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18425#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18426#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18427#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18428#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18429
18430/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18431static inline int decode_gpr_gpr3(int r)
18432{
18433    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18434
18435    return map[r & 0x7];
18436}
18437
18438/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18439static inline int decode_gpr_gpr3_src_store(int r)
18440{
18441    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18442
18443    return map[r & 0x7];
18444}
18445
18446/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18447static inline int decode_gpr_gpr4(int r)
18448{
18449    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18450                               16, 17, 18, 19, 20, 21, 22, 23 };
18451
18452    return map[r & 0xf];
18453}
18454
18455/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18456static inline int decode_gpr_gpr4_zero(int r)
18457{
18458    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18459                               16, 17, 18, 19, 20, 21, 22, 23 };
18460
18461    return map[r & 0xf];
18462}
18463
18464
18465static void gen_adjust_sp(DisasContext *ctx, int u)
18466{
18467    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18468}
18469
18470static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18471                     uint8_t gp, uint16_t u)
18472{
18473    int counter = 0;
18474    TCGv va = tcg_temp_new();
18475    TCGv t0 = tcg_temp_new();
18476
18477    while (counter != count) {
18478        bool use_gp = gp && (counter == count - 1);
18479        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18480        int this_offset = -((counter + 1) << 2);
18481        gen_base_offset_addr(ctx, va, 29, this_offset);
18482        gen_load_gpr(t0, this_rt);
18483        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18484                           (MO_TEUL | ctx->default_tcg_memop_mask));
18485        counter++;
18486    }
18487
18488    /* adjust stack pointer */
18489    gen_adjust_sp(ctx, -u);
18490
18491    tcg_temp_free(t0);
18492    tcg_temp_free(va);
18493}
18494
18495static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18496                        uint8_t gp, uint16_t u)
18497{
18498    int counter = 0;
18499    TCGv va = tcg_temp_new();
18500    TCGv t0 = tcg_temp_new();
18501
18502    while (counter != count) {
18503        bool use_gp = gp && (counter == count - 1);
18504        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18505        int this_offset = u - ((counter + 1) << 2);
18506        gen_base_offset_addr(ctx, va, 29, this_offset);
18507        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18508                        ctx->default_tcg_memop_mask);
18509        tcg_gen_ext32s_tl(t0, t0);
18510        gen_store_gpr(t0, this_rt);
18511        counter++;
18512    }
18513
18514    /* adjust stack pointer */
18515    gen_adjust_sp(ctx, u);
18516
18517    tcg_temp_free(t0);
18518    tcg_temp_free(va);
18519}
18520
18521static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18522{
18523    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18524    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18525
18526    switch (extract32(ctx->opcode, 2, 2)) {
18527    case NM_NOT16:
18528        gen_logic(ctx, OPC_NOR, rt, rs, 0);
18529        break;
18530    case NM_AND16:
18531        gen_logic(ctx, OPC_AND, rt, rt, rs);
18532        break;
18533    case NM_XOR16:
18534        gen_logic(ctx, OPC_XOR, rt, rt, rs);
18535        break;
18536    case NM_OR16:
18537        gen_logic(ctx, OPC_OR, rt, rt, rs);
18538        break;
18539    }
18540}
18541
18542static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18543{
18544    int rt = extract32(ctx->opcode, 21, 5);
18545    int rs = extract32(ctx->opcode, 16, 5);
18546    int rd = extract32(ctx->opcode, 11, 5);
18547
18548    switch (extract32(ctx->opcode, 3, 7)) {
18549    case NM_P_TRAP:
18550        switch (extract32(ctx->opcode, 10, 1)) {
18551        case NM_TEQ:
18552            check_nms(ctx);
18553            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18554            break;
18555        case NM_TNE:
18556            check_nms(ctx);
18557            gen_trap(ctx, OPC_TNE, rs, rt, -1);
18558            break;
18559        }
18560        break;
18561    case NM_RDHWR:
18562        check_nms(ctx);
18563        gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18564        break;
18565    case NM_SEB:
18566        check_nms(ctx);
18567        gen_bshfl(ctx, OPC_SEB, rs, rt);
18568        break;
18569    case NM_SEH:
18570        gen_bshfl(ctx, OPC_SEH, rs, rt);
18571        break;
18572    case NM_SLLV:
18573        gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18574        break;
18575    case NM_SRLV:
18576        gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18577        break;
18578    case NM_SRAV:
18579        gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18580        break;
18581    case NM_ROTRV:
18582        gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18583        break;
18584    case NM_ADD:
18585        gen_arith(ctx, OPC_ADD, rd, rs, rt);
18586        break;
18587    case NM_ADDU:
18588        gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18589        break;
18590    case NM_SUB:
18591        check_nms(ctx);
18592        gen_arith(ctx, OPC_SUB, rd, rs, rt);
18593        break;
18594    case NM_SUBU:
18595        gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18596        break;
18597    case NM_P_CMOVE:
18598        switch (extract32(ctx->opcode, 10, 1)) {
18599        case NM_MOVZ:
18600            gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18601            break;
18602        case NM_MOVN:
18603            gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18604            break;
18605        }
18606        break;
18607    case NM_AND:
18608        gen_logic(ctx, OPC_AND, rd, rs, rt);
18609        break;
18610    case NM_OR:
18611        gen_logic(ctx, OPC_OR, rd, rs, rt);
18612        break;
18613    case NM_NOR:
18614        gen_logic(ctx, OPC_NOR, rd, rs, rt);
18615        break;
18616    case NM_XOR:
18617        gen_logic(ctx, OPC_XOR, rd, rs, rt);
18618        break;
18619    case NM_SLT:
18620        gen_slt(ctx, OPC_SLT, rd, rs, rt);
18621        break;
18622    case NM_P_SLTU:
18623        if (rd == 0) {
18624            /* P_DVP */
18625#ifndef CONFIG_USER_ONLY
18626            TCGv t0 = tcg_temp_new();
18627            switch (extract32(ctx->opcode, 10, 1)) {
18628            case NM_DVP:
18629                if (ctx->vp) {
18630                    check_cp0_enabled(ctx);
18631                    gen_helper_dvp(t0, cpu_env);
18632                    gen_store_gpr(t0, rt);
18633                }
18634                break;
18635            case NM_EVP:
18636                if (ctx->vp) {
18637                    check_cp0_enabled(ctx);
18638                    gen_helper_evp(t0, cpu_env);
18639                    gen_store_gpr(t0, rt);
18640                }
18641                break;
18642            }
18643            tcg_temp_free(t0);
18644#endif
18645        } else {
18646            gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18647        }
18648        break;
18649    case NM_SOV:
18650        {
18651            TCGv t0 = tcg_temp_new();
18652            TCGv t1 = tcg_temp_new();
18653            TCGv t2 = tcg_temp_new();
18654
18655            gen_load_gpr(t1, rs);
18656            gen_load_gpr(t2, rt);
18657            tcg_gen_add_tl(t0, t1, t2);
18658            tcg_gen_ext32s_tl(t0, t0);
18659            tcg_gen_xor_tl(t1, t1, t2);
18660            tcg_gen_xor_tl(t2, t0, t2);
18661            tcg_gen_andc_tl(t1, t2, t1);
18662
18663            /* operands of same sign, result different sign */
18664            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18665            gen_store_gpr(t0, rd);
18666
18667            tcg_temp_free(t0);
18668            tcg_temp_free(t1);
18669            tcg_temp_free(t2);
18670        }
18671        break;
18672    case NM_MUL:
18673        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18674        break;
18675    case NM_MUH:
18676        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18677        break;
18678    case NM_MULU:
18679        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18680        break;
18681    case NM_MUHU:
18682        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18683        break;
18684    case NM_DIV:
18685        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18686        break;
18687    case NM_MOD:
18688        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18689        break;
18690    case NM_DIVU:
18691        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18692        break;
18693    case NM_MODU:
18694        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18695        break;
18696#ifndef CONFIG_USER_ONLY
18697    case NM_MFC0:
18698        check_cp0_enabled(ctx);
18699        if (rt == 0) {
18700            /* Treat as NOP. */
18701            break;
18702        }
18703        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18704        break;
18705    case NM_MTC0:
18706        check_cp0_enabled(ctx);
18707        {
18708            TCGv t0 = tcg_temp_new();
18709
18710            gen_load_gpr(t0, rt);
18711            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18712            tcg_temp_free(t0);
18713        }
18714        break;
18715    case NM_D_E_MT_VPE:
18716        {
18717            uint8_t sc = extract32(ctx->opcode, 10, 1);
18718            TCGv t0 = tcg_temp_new();
18719
18720            switch (sc) {
18721            case 0:
18722                if (rs == 1) {
18723                    /* DMT */
18724                    check_cp0_mt(ctx);
18725                    gen_helper_dmt(t0);
18726                    gen_store_gpr(t0, rt);
18727                } else if (rs == 0) {
18728                    /* DVPE */
18729                    check_cp0_mt(ctx);
18730                    gen_helper_dvpe(t0, cpu_env);
18731                    gen_store_gpr(t0, rt);
18732                } else {
18733                    generate_exception_end(ctx, EXCP_RI);
18734                }
18735                break;
18736            case 1:
18737                if (rs == 1) {
18738                    /* EMT */
18739                    check_cp0_mt(ctx);
18740                    gen_helper_emt(t0);
18741                    gen_store_gpr(t0, rt);
18742                } else if (rs == 0) {
18743                    /* EVPE */
18744                    check_cp0_mt(ctx);
18745                    gen_helper_evpe(t0, cpu_env);
18746                    gen_store_gpr(t0, rt);
18747                } else {
18748                    generate_exception_end(ctx, EXCP_RI);
18749                }
18750                break;
18751            }
18752
18753            tcg_temp_free(t0);
18754        }
18755        break;
18756    case NM_FORK:
18757        check_mt(ctx);
18758        {
18759            TCGv t0 = tcg_temp_new();
18760            TCGv t1 = tcg_temp_new();
18761
18762            gen_load_gpr(t0, rt);
18763            gen_load_gpr(t1, rs);
18764            gen_helper_fork(t0, t1);
18765            tcg_temp_free(t0);
18766            tcg_temp_free(t1);
18767        }
18768        break;
18769    case NM_MFTR:
18770    case NM_MFHTR:
18771        check_cp0_enabled(ctx);
18772        if (rd == 0) {
18773            /* Treat as NOP. */
18774            return;
18775        }
18776        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18777                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18778        break;
18779    case NM_MTTR:
18780    case NM_MTHTR:
18781        check_cp0_enabled(ctx);
18782        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18783                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18784        break;
18785    case NM_YIELD:
18786        check_mt(ctx);
18787        {
18788            TCGv t0 = tcg_temp_new();
18789
18790            gen_load_gpr(t0, rs);
18791            gen_helper_yield(t0, cpu_env, t0);
18792            gen_store_gpr(t0, rt);
18793            tcg_temp_free(t0);
18794        }
18795        break;
18796#endif
18797    default:
18798        generate_exception_end(ctx, EXCP_RI);
18799        break;
18800    }
18801}
18802
18803/* dsp */
18804static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18805                                            int ret, int v1, int v2)
18806{
18807    TCGv_i32 t0;
18808    TCGv v0_t;
18809    TCGv v1_t;
18810
18811    t0 = tcg_temp_new_i32();
18812
18813    v0_t = tcg_temp_new();
18814    v1_t = tcg_temp_new();
18815
18816    tcg_gen_movi_i32(t0, v2 >> 3);
18817
18818    gen_load_gpr(v0_t, ret);
18819    gen_load_gpr(v1_t, v1);
18820
18821    switch (opc) {
18822    case NM_MAQ_S_W_PHR:
18823        check_dsp(ctx);
18824        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18825        break;
18826    case NM_MAQ_S_W_PHL:
18827        check_dsp(ctx);
18828        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18829        break;
18830    case NM_MAQ_SA_W_PHR:
18831        check_dsp(ctx);
18832        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18833        break;
18834    case NM_MAQ_SA_W_PHL:
18835        check_dsp(ctx);
18836        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18837        break;
18838    default:
18839        generate_exception_end(ctx, EXCP_RI);
18840        break;
18841    }
18842
18843    tcg_temp_free_i32(t0);
18844
18845    tcg_temp_free(v0_t);
18846    tcg_temp_free(v1_t);
18847}
18848
18849
18850static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18851                                    int ret, int v1, int v2)
18852{
18853    int16_t imm;
18854    TCGv t0 = tcg_temp_new();
18855    TCGv t1 = tcg_temp_new();
18856    TCGv v0_t = tcg_temp_new();
18857
18858    gen_load_gpr(v0_t, v1);
18859
18860    switch (opc) {
18861    case NM_POOL32AXF_1_0:
18862        check_dsp(ctx);
18863        switch (extract32(ctx->opcode, 12, 2)) {
18864        case NM_MFHI:
18865            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18866            break;
18867        case NM_MFLO:
18868            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18869            break;
18870        case NM_MTHI:
18871            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18872            break;
18873        case NM_MTLO:
18874            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18875            break;
18876        }
18877        break;
18878    case NM_POOL32AXF_1_1:
18879        check_dsp(ctx);
18880        switch (extract32(ctx->opcode, 12, 2)) {
18881        case NM_MTHLIP:
18882            tcg_gen_movi_tl(t0, v2);
18883            gen_helper_mthlip(t0, v0_t, cpu_env);
18884            break;
18885        case NM_SHILOV:
18886            tcg_gen_movi_tl(t0, v2 >> 3);
18887            gen_helper_shilo(t0, v0_t, cpu_env);
18888            break;
18889        default:
18890            generate_exception_end(ctx, EXCP_RI);
18891            break;
18892        }
18893        break;
18894    case NM_POOL32AXF_1_3:
18895        check_dsp(ctx);
18896        imm = extract32(ctx->opcode, 14, 7);
18897        switch (extract32(ctx->opcode, 12, 2)) {
18898        case NM_RDDSP:
18899            tcg_gen_movi_tl(t0, imm);
18900            gen_helper_rddsp(t0, t0, cpu_env);
18901            gen_store_gpr(t0, ret);
18902            break;
18903        case NM_WRDSP:
18904            gen_load_gpr(t0, ret);
18905            tcg_gen_movi_tl(t1, imm);
18906            gen_helper_wrdsp(t0, t1, cpu_env);
18907            break;
18908        case NM_EXTP:
18909            tcg_gen_movi_tl(t0, v2 >> 3);
18910            tcg_gen_movi_tl(t1, v1);
18911            gen_helper_extp(t0, t0, t1, cpu_env);
18912            gen_store_gpr(t0, ret);
18913            break;
18914        case NM_EXTPDP:
18915            tcg_gen_movi_tl(t0, v2 >> 3);
18916            tcg_gen_movi_tl(t1, v1);
18917            gen_helper_extpdp(t0, t0, t1, cpu_env);
18918            gen_store_gpr(t0, ret);
18919            break;
18920        }
18921        break;
18922    case NM_POOL32AXF_1_4:
18923        check_dsp(ctx);
18924        tcg_gen_movi_tl(t0, v2 >> 2);
18925        switch (extract32(ctx->opcode, 12, 1)) {
18926        case NM_SHLL_QB:
18927            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18928            gen_store_gpr(t0, ret);
18929            break;
18930        case NM_SHRL_QB:
18931            gen_helper_shrl_qb(t0, t0, v0_t);
18932            gen_store_gpr(t0, ret);
18933            break;
18934        }
18935        break;
18936    case NM_POOL32AXF_1_5:
18937        opc = extract32(ctx->opcode, 12, 2);
18938        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18939        break;
18940    case NM_POOL32AXF_1_7:
18941        check_dsp(ctx);
18942        tcg_gen_movi_tl(t0, v2 >> 3);
18943        tcg_gen_movi_tl(t1, v1);
18944        switch (extract32(ctx->opcode, 12, 2)) {
18945        case NM_EXTR_W:
18946            gen_helper_extr_w(t0, t0, t1, cpu_env);
18947            gen_store_gpr(t0, ret);
18948            break;
18949        case NM_EXTR_R_W:
18950            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18951            gen_store_gpr(t0, ret);
18952            break;
18953        case NM_EXTR_RS_W:
18954            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18955            gen_store_gpr(t0, ret);
18956            break;
18957        case NM_EXTR_S_H:
18958            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18959            gen_store_gpr(t0, ret);
18960            break;
18961        }
18962        break;
18963    default:
18964        generate_exception_end(ctx, EXCP_RI);
18965        break;
18966    }
18967
18968    tcg_temp_free(t0);
18969    tcg_temp_free(t1);
18970    tcg_temp_free(v0_t);
18971}
18972
18973static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18974                                    TCGv v0, TCGv v1, int rd)
18975{
18976    TCGv_i32 t0;
18977
18978    t0 = tcg_temp_new_i32();
18979
18980    tcg_gen_movi_i32(t0, rd >> 3);
18981
18982    switch (opc) {
18983    case NM_POOL32AXF_2_0_7:
18984        switch (extract32(ctx->opcode, 9, 3)) {
18985        case NM_DPA_W_PH:
18986            check_dsp_r2(ctx);
18987            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18988            break;
18989        case NM_DPAQ_S_W_PH:
18990            check_dsp(ctx);
18991            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18992            break;
18993        case NM_DPS_W_PH:
18994            check_dsp_r2(ctx);
18995            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18996            break;
18997        case NM_DPSQ_S_W_PH:
18998            check_dsp(ctx);
18999            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19000            break;
19001        default:
19002            generate_exception_end(ctx, EXCP_RI);
19003            break;
19004        }
19005        break;
19006    case NM_POOL32AXF_2_8_15:
19007        switch (extract32(ctx->opcode, 9, 3)) {
19008        case NM_DPAX_W_PH:
19009            check_dsp_r2(ctx);
19010            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19011            break;
19012        case NM_DPAQ_SA_L_W:
19013            check_dsp(ctx);
19014            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19015            break;
19016        case NM_DPSX_W_PH:
19017            check_dsp_r2(ctx);
19018            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19019            break;
19020        case NM_DPSQ_SA_L_W:
19021            check_dsp(ctx);
19022            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19023            break;
19024        default:
19025            generate_exception_end(ctx, EXCP_RI);
19026            break;
19027        }
19028        break;
19029    case NM_POOL32AXF_2_16_23:
19030        switch (extract32(ctx->opcode, 9, 3)) {
19031        case NM_DPAU_H_QBL:
19032            check_dsp(ctx);
19033            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19034            break;
19035        case NM_DPAQX_S_W_PH:
19036            check_dsp_r2(ctx);
19037            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19038            break;
19039        case NM_DPSU_H_QBL:
19040            check_dsp(ctx);
19041            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19042            break;
19043        case NM_DPSQX_S_W_PH:
19044            check_dsp_r2(ctx);
19045            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19046            break;
19047        case NM_MULSA_W_PH:
19048            check_dsp_r2(ctx);
19049            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19050            break;
19051        default:
19052            generate_exception_end(ctx, EXCP_RI);
19053            break;
19054        }
19055        break;
19056    case NM_POOL32AXF_2_24_31:
19057        switch (extract32(ctx->opcode, 9, 3)) {
19058        case NM_DPAU_H_QBR:
19059            check_dsp(ctx);
19060            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19061            break;
19062        case NM_DPAQX_SA_W_PH:
19063            check_dsp_r2(ctx);
19064            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19065            break;
19066        case NM_DPSU_H_QBR:
19067            check_dsp(ctx);
19068            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19069            break;
19070        case NM_DPSQX_SA_W_PH:
19071            check_dsp_r2(ctx);
19072            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19073            break;
19074        case NM_MULSAQ_S_W_PH:
19075            check_dsp(ctx);
19076            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19077            break;
19078        default:
19079            generate_exception_end(ctx, EXCP_RI);
19080            break;
19081        }
19082        break;
19083    default:
19084        generate_exception_end(ctx, EXCP_RI);
19085        break;
19086    }
19087
19088    tcg_temp_free_i32(t0);
19089}
19090
19091static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19092                                          int rt, int rs, int rd)
19093{
19094    int ret = rt;
19095    TCGv t0 = tcg_temp_new();
19096    TCGv t1 = tcg_temp_new();
19097    TCGv v0_t = tcg_temp_new();
19098    TCGv v1_t = tcg_temp_new();
19099
19100    gen_load_gpr(v0_t, rt);
19101    gen_load_gpr(v1_t, rs);
19102
19103    switch (opc) {
19104    case NM_POOL32AXF_2_0_7:
19105        switch (extract32(ctx->opcode, 9, 3)) {
19106        case NM_DPA_W_PH:
19107        case NM_DPAQ_S_W_PH:
19108        case NM_DPS_W_PH:
19109        case NM_DPSQ_S_W_PH:
19110            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19111            break;
19112        case NM_BALIGN:
19113            check_dsp_r2(ctx);
19114            if (rt != 0) {
19115                gen_load_gpr(t0, rs);
19116                rd &= 3;
19117                if (rd != 0 && rd != 2) {
19118                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19119                    tcg_gen_ext32u_tl(t0, t0);
19120                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19121                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19122                }
19123                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19124            }
19125            break;
19126        case NM_MADD:
19127            check_dsp(ctx);
19128            {
19129                int acc = extract32(ctx->opcode, 14, 2);
19130                TCGv_i64 t2 = tcg_temp_new_i64();
19131                TCGv_i64 t3 = tcg_temp_new_i64();
19132
19133                gen_load_gpr(t0, rt);
19134                gen_load_gpr(t1, rs);
19135                tcg_gen_ext_tl_i64(t2, t0);
19136                tcg_gen_ext_tl_i64(t3, t1);
19137                tcg_gen_mul_i64(t2, t2, t3);
19138                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19139                tcg_gen_add_i64(t2, t2, t3);
19140                tcg_temp_free_i64(t3);
19141                gen_move_low32(cpu_LO[acc], t2);
19142                gen_move_high32(cpu_HI[acc], t2);
19143                tcg_temp_free_i64(t2);
19144            }
19145            break;
19146        case NM_MULT:
19147            check_dsp(ctx);
19148            {
19149                int acc = extract32(ctx->opcode, 14, 2);
19150                TCGv_i32 t2 = tcg_temp_new_i32();
19151                TCGv_i32 t3 = tcg_temp_new_i32();
19152
19153                gen_load_gpr(t0, rs);
19154                gen_load_gpr(t1, rt);
19155                tcg_gen_trunc_tl_i32(t2, t0);
19156                tcg_gen_trunc_tl_i32(t3, t1);
19157                tcg_gen_muls2_i32(t2, t3, t2, t3);
19158                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19159                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19160                tcg_temp_free_i32(t2);
19161                tcg_temp_free_i32(t3);
19162            }
19163            break;
19164        case NM_EXTRV_W:
19165            check_dsp(ctx);
19166            gen_load_gpr(v1_t, rs);
19167            tcg_gen_movi_tl(t0, rd >> 3);
19168            gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19169            gen_store_gpr(t0, ret);
19170            break;
19171        }
19172        break;
19173    case NM_POOL32AXF_2_8_15:
19174        switch (extract32(ctx->opcode, 9, 3)) {
19175        case NM_DPAX_W_PH:
19176        case NM_DPAQ_SA_L_W:
19177        case NM_DPSX_W_PH:
19178        case NM_DPSQ_SA_L_W:
19179            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19180            break;
19181        case NM_MADDU:
19182            check_dsp(ctx);
19183            {
19184                int acc = extract32(ctx->opcode, 14, 2);
19185                TCGv_i64 t2 = tcg_temp_new_i64();
19186                TCGv_i64 t3 = tcg_temp_new_i64();
19187
19188                gen_load_gpr(t0, rs);
19189                gen_load_gpr(t1, rt);
19190                tcg_gen_ext32u_tl(t0, t0);
19191                tcg_gen_ext32u_tl(t1, t1);
19192                tcg_gen_extu_tl_i64(t2, t0);
19193                tcg_gen_extu_tl_i64(t3, t1);
19194                tcg_gen_mul_i64(t2, t2, t3);
19195                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19196                tcg_gen_add_i64(t2, t2, t3);
19197                tcg_temp_free_i64(t3);
19198                gen_move_low32(cpu_LO[acc], t2);
19199                gen_move_high32(cpu_HI[acc], t2);
19200                tcg_temp_free_i64(t2);
19201            }
19202            break;
19203        case NM_MULTU:
19204            check_dsp(ctx);
19205            {
19206                int acc = extract32(ctx->opcode, 14, 2);
19207                TCGv_i32 t2 = tcg_temp_new_i32();
19208                TCGv_i32 t3 = tcg_temp_new_i32();
19209
19210                gen_load_gpr(t0, rs);
19211                gen_load_gpr(t1, rt);
19212                tcg_gen_trunc_tl_i32(t2, t0);
19213                tcg_gen_trunc_tl_i32(t3, t1);
19214                tcg_gen_mulu2_i32(t2, t3, t2, t3);
19215                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19216                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19217                tcg_temp_free_i32(t2);
19218                tcg_temp_free_i32(t3);
19219            }
19220            break;
19221        case NM_EXTRV_R_W:
19222            check_dsp(ctx);
19223            tcg_gen_movi_tl(t0, rd >> 3);
19224            gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19225            gen_store_gpr(t0, ret);
19226            break;
19227        default:
19228            generate_exception_end(ctx, EXCP_RI);
19229            break;
19230        }
19231        break;
19232    case NM_POOL32AXF_2_16_23:
19233        switch (extract32(ctx->opcode, 9, 3)) {
19234        case NM_DPAU_H_QBL:
19235        case NM_DPAQX_S_W_PH:
19236        case NM_DPSU_H_QBL:
19237        case NM_DPSQX_S_W_PH:
19238        case NM_MULSA_W_PH:
19239            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19240            break;
19241        case NM_EXTPV:
19242            check_dsp(ctx);
19243            tcg_gen_movi_tl(t0, rd >> 3);
19244            gen_helper_extp(t0, t0, v1_t, cpu_env);
19245            gen_store_gpr(t0, ret);
19246            break;
19247        case NM_MSUB:
19248            check_dsp(ctx);
19249            {
19250                int acc = extract32(ctx->opcode, 14, 2);
19251                TCGv_i64 t2 = tcg_temp_new_i64();
19252                TCGv_i64 t3 = tcg_temp_new_i64();
19253
19254                gen_load_gpr(t0, rs);
19255                gen_load_gpr(t1, rt);
19256                tcg_gen_ext_tl_i64(t2, t0);
19257                tcg_gen_ext_tl_i64(t3, t1);
19258                tcg_gen_mul_i64(t2, t2, t3);
19259                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19260                tcg_gen_sub_i64(t2, t3, t2);
19261                tcg_temp_free_i64(t3);
19262                gen_move_low32(cpu_LO[acc], t2);
19263                gen_move_high32(cpu_HI[acc], t2);
19264                tcg_temp_free_i64(t2);
19265            }
19266            break;
19267        case NM_EXTRV_RS_W:
19268            check_dsp(ctx);
19269            tcg_gen_movi_tl(t0, rd >> 3);
19270            gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19271            gen_store_gpr(t0, ret);
19272            break;
19273        }
19274        break;
19275    case NM_POOL32AXF_2_24_31:
19276        switch (extract32(ctx->opcode, 9, 3)) {
19277        case NM_DPAU_H_QBR:
19278        case NM_DPAQX_SA_W_PH:
19279        case NM_DPSU_H_QBR:
19280        case NM_DPSQX_SA_W_PH:
19281        case NM_MULSAQ_S_W_PH:
19282            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19283            break;
19284        case NM_EXTPDPV:
19285            check_dsp(ctx);
19286            tcg_gen_movi_tl(t0, rd >> 3);
19287            gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19288            gen_store_gpr(t0, ret);
19289            break;
19290        case NM_MSUBU:
19291            check_dsp(ctx);
19292            {
19293                int acc = extract32(ctx->opcode, 14, 2);
19294                TCGv_i64 t2 = tcg_temp_new_i64();
19295                TCGv_i64 t3 = tcg_temp_new_i64();
19296
19297                gen_load_gpr(t0, rs);
19298                gen_load_gpr(t1, rt);
19299                tcg_gen_ext32u_tl(t0, t0);
19300                tcg_gen_ext32u_tl(t1, t1);
19301                tcg_gen_extu_tl_i64(t2, t0);
19302                tcg_gen_extu_tl_i64(t3, t1);
19303                tcg_gen_mul_i64(t2, t2, t3);
19304                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19305                tcg_gen_sub_i64(t2, t3, t2);
19306                tcg_temp_free_i64(t3);
19307                gen_move_low32(cpu_LO[acc], t2);
19308                gen_move_high32(cpu_HI[acc], t2);
19309                tcg_temp_free_i64(t2);
19310            }
19311            break;
19312        case NM_EXTRV_S_H:
19313            check_dsp(ctx);
19314            tcg_gen_movi_tl(t0, rd >> 3);
19315            gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19316            gen_store_gpr(t0, ret);
19317            break;
19318        }
19319        break;
19320    default:
19321        generate_exception_end(ctx, EXCP_RI);
19322        break;
19323    }
19324
19325    tcg_temp_free(t0);
19326    tcg_temp_free(t1);
19327
19328    tcg_temp_free(v0_t);
19329    tcg_temp_free(v1_t);
19330}
19331
19332static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19333                                          int rt, int rs)
19334{
19335    int ret = rt;
19336    TCGv t0 = tcg_temp_new();
19337    TCGv v0_t = tcg_temp_new();
19338
19339    gen_load_gpr(v0_t, rs);
19340
19341    switch (opc) {
19342    case NM_ABSQ_S_QB:
19343        check_dsp_r2(ctx);
19344        gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19345        gen_store_gpr(v0_t, ret);
19346        break;
19347    case NM_ABSQ_S_PH:
19348        check_dsp(ctx);
19349        gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19350        gen_store_gpr(v0_t, ret);
19351        break;
19352    case NM_ABSQ_S_W:
19353        check_dsp(ctx);
19354        gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19355        gen_store_gpr(v0_t, ret);
19356        break;
19357    case NM_PRECEQ_W_PHL:
19358        check_dsp(ctx);
19359        tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19360        tcg_gen_ext32s_tl(v0_t, v0_t);
19361        gen_store_gpr(v0_t, ret);
19362        break;
19363    case NM_PRECEQ_W_PHR:
19364        check_dsp(ctx);
19365        tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19366        tcg_gen_shli_tl(v0_t, v0_t, 16);
19367        tcg_gen_ext32s_tl(v0_t, v0_t);
19368        gen_store_gpr(v0_t, ret);
19369        break;
19370    case NM_PRECEQU_PH_QBL:
19371        check_dsp(ctx);
19372        gen_helper_precequ_ph_qbl(v0_t, v0_t);
19373        gen_store_gpr(v0_t, ret);
19374        break;
19375    case NM_PRECEQU_PH_QBR:
19376        check_dsp(ctx);
19377        gen_helper_precequ_ph_qbr(v0_t, v0_t);
19378        gen_store_gpr(v0_t, ret);
19379        break;
19380    case NM_PRECEQU_PH_QBLA:
19381        check_dsp(ctx);
19382        gen_helper_precequ_ph_qbla(v0_t, v0_t);
19383        gen_store_gpr(v0_t, ret);
19384        break;
19385    case NM_PRECEQU_PH_QBRA:
19386        check_dsp(ctx);
19387        gen_helper_precequ_ph_qbra(v0_t, v0_t);
19388        gen_store_gpr(v0_t, ret);
19389        break;
19390    case NM_PRECEU_PH_QBL:
19391        check_dsp(ctx);
19392        gen_helper_preceu_ph_qbl(v0_t, v0_t);
19393        gen_store_gpr(v0_t, ret);
19394        break;
19395    case NM_PRECEU_PH_QBR:
19396        check_dsp(ctx);
19397        gen_helper_preceu_ph_qbr(v0_t, v0_t);
19398        gen_store_gpr(v0_t, ret);
19399        break;
19400    case NM_PRECEU_PH_QBLA:
19401        check_dsp(ctx);
19402        gen_helper_preceu_ph_qbla(v0_t, v0_t);
19403        gen_store_gpr(v0_t, ret);
19404        break;
19405    case NM_PRECEU_PH_QBRA:
19406        check_dsp(ctx);
19407        gen_helper_preceu_ph_qbra(v0_t, v0_t);
19408        gen_store_gpr(v0_t, ret);
19409        break;
19410    case NM_REPLV_PH:
19411        check_dsp(ctx);
19412        tcg_gen_ext16u_tl(v0_t, v0_t);
19413        tcg_gen_shli_tl(t0, v0_t, 16);
19414        tcg_gen_or_tl(v0_t, v0_t, t0);
19415        tcg_gen_ext32s_tl(v0_t, v0_t);
19416        gen_store_gpr(v0_t, ret);
19417        break;
19418    case NM_REPLV_QB:
19419        check_dsp(ctx);
19420        tcg_gen_ext8u_tl(v0_t, v0_t);
19421        tcg_gen_shli_tl(t0, v0_t, 8);
19422        tcg_gen_or_tl(v0_t, v0_t, t0);
19423        tcg_gen_shli_tl(t0, v0_t, 16);
19424        tcg_gen_or_tl(v0_t, v0_t, t0);
19425        tcg_gen_ext32s_tl(v0_t, v0_t);
19426        gen_store_gpr(v0_t, ret);
19427        break;
19428    case NM_BITREV:
19429        check_dsp(ctx);
19430        gen_helper_bitrev(v0_t, v0_t);
19431        gen_store_gpr(v0_t, ret);
19432        break;
19433    case NM_INSV:
19434        check_dsp(ctx);
19435        {
19436            TCGv tv0 = tcg_temp_new();
19437
19438            gen_load_gpr(tv0, rt);
19439            gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19440            gen_store_gpr(v0_t, ret);
19441            tcg_temp_free(tv0);
19442        }
19443        break;
19444    case NM_RADDU_W_QB:
19445        check_dsp(ctx);
19446        gen_helper_raddu_w_qb(v0_t, v0_t);
19447        gen_store_gpr(v0_t, ret);
19448        break;
19449    case NM_BITSWAP:
19450        gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19451        break;
19452    case NM_CLO:
19453        check_nms(ctx);
19454        gen_cl(ctx, OPC_CLO, ret, rs);
19455        break;
19456    case NM_CLZ:
19457        check_nms(ctx);
19458        gen_cl(ctx, OPC_CLZ, ret, rs);
19459        break;
19460    case NM_WSBH:
19461        gen_bshfl(ctx, OPC_WSBH, ret, rs);
19462        break;
19463    default:
19464        generate_exception_end(ctx, EXCP_RI);
19465        break;
19466    }
19467
19468    tcg_temp_free(v0_t);
19469    tcg_temp_free(t0);
19470}
19471
19472static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19473                                          int rt, int rs, int rd)
19474{
19475    TCGv t0 = tcg_temp_new();
19476    TCGv rs_t = tcg_temp_new();
19477
19478    gen_load_gpr(rs_t, rs);
19479
19480    switch (opc) {
19481    case NM_SHRA_R_QB:
19482        check_dsp_r2(ctx);
19483        tcg_gen_movi_tl(t0, rd >> 2);
19484        switch (extract32(ctx->opcode, 12, 1)) {
19485        case 0:
19486            /* NM_SHRA_QB */
19487            gen_helper_shra_qb(t0, t0, rs_t);
19488            gen_store_gpr(t0, rt);
19489            break;
19490        case 1:
19491            /* NM_SHRA_R_QB */
19492            gen_helper_shra_r_qb(t0, t0, rs_t);
19493            gen_store_gpr(t0, rt);
19494            break;
19495        }
19496        break;
19497    case NM_SHRL_PH:
19498        check_dsp_r2(ctx);
19499        tcg_gen_movi_tl(t0, rd >> 1);
19500        gen_helper_shrl_ph(t0, t0, rs_t);
19501        gen_store_gpr(t0, rt);
19502        break;
19503    case NM_REPL_QB:
19504        check_dsp(ctx);
19505        {
19506            int16_t imm;
19507            target_long result;
19508            imm = extract32(ctx->opcode, 13, 8);
19509            result = (uint32_t)imm << 24 |
19510                     (uint32_t)imm << 16 |
19511                     (uint32_t)imm << 8  |
19512                     (uint32_t)imm;
19513            result = (int32_t)result;
19514            tcg_gen_movi_tl(t0, result);
19515            gen_store_gpr(t0, rt);
19516        }
19517        break;
19518    default:
19519        generate_exception_end(ctx, EXCP_RI);
19520        break;
19521    }
19522    tcg_temp_free(t0);
19523    tcg_temp_free(rs_t);
19524}
19525
19526
19527static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19528{
19529    int rt = extract32(ctx->opcode, 21, 5);
19530    int rs = extract32(ctx->opcode, 16, 5);
19531    int rd = extract32(ctx->opcode, 11, 5);
19532
19533    switch (extract32(ctx->opcode, 6, 3)) {
19534    case NM_POOL32AXF_1:
19535        {
19536            int32_t op1 = extract32(ctx->opcode, 9, 3);
19537            gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19538        }
19539        break;
19540    case NM_POOL32AXF_2:
19541        {
19542            int32_t op1 = extract32(ctx->opcode, 12, 2);
19543            gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19544        }
19545        break;
19546    case NM_POOL32AXF_4:
19547        {
19548            int32_t op1 = extract32(ctx->opcode, 9, 7);
19549            gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19550        }
19551        break;
19552    case NM_POOL32AXF_5:
19553        switch (extract32(ctx->opcode, 9, 7)) {
19554#ifndef CONFIG_USER_ONLY
19555        case NM_TLBP:
19556            gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19557            break;
19558        case NM_TLBR:
19559            gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19560            break;
19561        case NM_TLBWI:
19562            gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19563            break;
19564        case NM_TLBWR:
19565            gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19566            break;
19567        case NM_TLBINV:
19568            gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19569            break;
19570        case NM_TLBINVF:
19571            gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19572            break;
19573        case NM_DI:
19574            check_cp0_enabled(ctx);
19575            {
19576                TCGv t0 = tcg_temp_new();
19577
19578                save_cpu_state(ctx, 1);
19579                gen_helper_di(t0, cpu_env);
19580                gen_store_gpr(t0, rt);
19581            /* Stop translation as we may have switched the execution mode */
19582                ctx->base.is_jmp = DISAS_STOP;
19583                tcg_temp_free(t0);
19584            }
19585            break;
19586        case NM_EI:
19587            check_cp0_enabled(ctx);
19588            {
19589                TCGv t0 = tcg_temp_new();
19590
19591                save_cpu_state(ctx, 1);
19592                gen_helper_ei(t0, cpu_env);
19593                gen_store_gpr(t0, rt);
19594            /* Stop translation as we may have switched the execution mode */
19595                ctx->base.is_jmp = DISAS_STOP;
19596                tcg_temp_free(t0);
19597            }
19598            break;
19599        case NM_RDPGPR:
19600            gen_load_srsgpr(rs, rt);
19601            break;
19602        case NM_WRPGPR:
19603            gen_store_srsgpr(rs, rt);
19604            break;
19605        case NM_WAIT:
19606            gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19607            break;
19608        case NM_DERET:
19609            gen_cp0(env, ctx, OPC_DERET, 0, 0);
19610            break;
19611        case NM_ERETX:
19612            gen_cp0(env, ctx, OPC_ERET, 0, 0);
19613            break;
19614#endif
19615        default:
19616            generate_exception_end(ctx, EXCP_RI);
19617            break;
19618        }
19619        break;
19620    case NM_POOL32AXF_7:
19621        {
19622            int32_t op1 = extract32(ctx->opcode, 9, 3);
19623            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19624        }
19625        break;
19626    default:
19627        generate_exception_end(ctx, EXCP_RI);
19628        break;
19629    }
19630}
19631
19632/* Immediate Value Compact Branches */
19633static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19634                                   int rt, int32_t imm, int32_t offset)
19635{
19636    TCGCond cond;
19637    int bcond_compute = 0;
19638    TCGv t0 = tcg_temp_new();
19639    TCGv t1 = tcg_temp_new();
19640
19641    gen_load_gpr(t0, rt);
19642    tcg_gen_movi_tl(t1, imm);
19643    ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19644
19645    /* Load needed operands and calculate btarget */
19646    switch (opc) {
19647    case NM_BEQIC:
19648        if (rt == 0 && imm == 0) {
19649            /* Unconditional branch */
19650        } else if (rt == 0 && imm != 0) {
19651            /* Treat as NOP */
19652            goto out;
19653        } else {
19654            bcond_compute = 1;
19655            cond = TCG_COND_EQ;
19656        }
19657        break;
19658    case NM_BBEQZC:
19659    case NM_BBNEZC:
19660        check_nms(ctx);
19661        if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19662            generate_exception_end(ctx, EXCP_RI);
19663            goto out;
19664        } else if (rt == 0 && opc == NM_BBEQZC) {
19665            /* Unconditional branch */
19666        } else if (rt == 0 && opc == NM_BBNEZC) {
19667            /* Treat as NOP */
19668            goto out;
19669        } else {
19670            tcg_gen_shri_tl(t0, t0, imm);
19671            tcg_gen_andi_tl(t0, t0, 1);
19672            tcg_gen_movi_tl(t1, 0);
19673            bcond_compute = 1;
19674            if (opc == NM_BBEQZC) {
19675                cond = TCG_COND_EQ;
19676            } else {
19677                cond = TCG_COND_NE;
19678            }
19679        }
19680        break;
19681    case NM_BNEIC:
19682        if (rt == 0 && imm == 0) {
19683            /* Treat as NOP */
19684            goto out;
19685        } else if (rt == 0 && imm != 0) {
19686            /* Unconditional branch */
19687        } else {
19688            bcond_compute = 1;
19689            cond = TCG_COND_NE;
19690        }
19691        break;
19692    case NM_BGEIC:
19693        if (rt == 0 && imm == 0) {
19694            /* Unconditional branch */
19695        } else  {
19696            bcond_compute = 1;
19697            cond = TCG_COND_GE;
19698        }
19699        break;
19700    case NM_BLTIC:
19701        bcond_compute = 1;
19702        cond = TCG_COND_LT;
19703        break;
19704    case NM_BGEIUC:
19705        if (rt == 0 && imm == 0) {
19706            /* Unconditional branch */
19707        } else  {
19708            bcond_compute = 1;
19709            cond = TCG_COND_GEU;
19710        }
19711        break;
19712    case NM_BLTIUC:
19713        bcond_compute = 1;
19714        cond = TCG_COND_LTU;
19715        break;
19716    default:
19717        MIPS_INVAL("Immediate Value Compact branch");
19718        generate_exception_end(ctx, EXCP_RI);
19719        goto out;
19720    }
19721
19722    /* branch completion */
19723    clear_branch_hflags(ctx);
19724    ctx->base.is_jmp = DISAS_NORETURN;
19725
19726    if (bcond_compute == 0) {
19727        /* Uncoditional compact branch */
19728        gen_goto_tb(ctx, 0, ctx->btarget);
19729    } else {
19730        /* Conditional compact branch */
19731        TCGLabel *fs = gen_new_label();
19732
19733        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19734
19735        gen_goto_tb(ctx, 1, ctx->btarget);
19736        gen_set_label(fs);
19737
19738        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19739    }
19740
19741out:
19742    tcg_temp_free(t0);
19743    tcg_temp_free(t1);
19744}
19745
19746/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19747static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19748                                                int rt)
19749{
19750    TCGv t0 = tcg_temp_new();
19751    TCGv t1 = tcg_temp_new();
19752
19753    /* load rs */
19754    gen_load_gpr(t0, rs);
19755
19756    /* link */
19757    if (rt != 0) {
19758        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19759    }
19760
19761    /* calculate btarget */
19762    tcg_gen_shli_tl(t0, t0, 1);
19763    tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19764    gen_op_addr_add(ctx, btarget, t1, t0);
19765
19766    /* branch completion */
19767    clear_branch_hflags(ctx);
19768    ctx->base.is_jmp = DISAS_NORETURN;
19769
19770    /* unconditional branch to register */
19771    tcg_gen_mov_tl(cpu_PC, btarget);
19772    tcg_gen_lookup_and_goto_ptr();
19773
19774    tcg_temp_free(t0);
19775    tcg_temp_free(t1);
19776}
19777
19778/* nanoMIPS Branches */
19779static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19780                                       int rs, int rt, int32_t offset)
19781{
19782    int bcond_compute = 0;
19783    TCGv t0 = tcg_temp_new();
19784    TCGv t1 = tcg_temp_new();
19785
19786    /* Load needed operands and calculate btarget */
19787    switch (opc) {
19788    /* compact branch */
19789    case OPC_BGEC:
19790    case OPC_BLTC:
19791        gen_load_gpr(t0, rs);
19792        gen_load_gpr(t1, rt);
19793        bcond_compute = 1;
19794        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19795        break;
19796    case OPC_BGEUC:
19797    case OPC_BLTUC:
19798        if (rs == 0 || rs == rt) {
19799            /* OPC_BLEZALC, OPC_BGEZALC */
19800            /* OPC_BGTZALC, OPC_BLTZALC */
19801            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19802        }
19803        gen_load_gpr(t0, rs);
19804        gen_load_gpr(t1, rt);
19805        bcond_compute = 1;
19806        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19807        break;
19808    case OPC_BC:
19809        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19810        break;
19811    case OPC_BEQZC:
19812        if (rs != 0) {
19813            /* OPC_BEQZC, OPC_BNEZC */
19814            gen_load_gpr(t0, rs);
19815            bcond_compute = 1;
19816            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19817        } else {
19818            /* OPC_JIC, OPC_JIALC */
19819            TCGv tbase = tcg_temp_new();
19820            TCGv toffset = tcg_temp_new();
19821
19822            gen_load_gpr(tbase, rt);
19823            tcg_gen_movi_tl(toffset, offset);
19824            gen_op_addr_add(ctx, btarget, tbase, toffset);
19825            tcg_temp_free(tbase);
19826            tcg_temp_free(toffset);
19827        }
19828        break;
19829    default:
19830        MIPS_INVAL("Compact branch/jump");
19831        generate_exception_end(ctx, EXCP_RI);
19832        goto out;
19833    }
19834
19835    if (bcond_compute == 0) {
19836        /* Uncoditional compact branch */
19837        switch (opc) {
19838        case OPC_BC:
19839            gen_goto_tb(ctx, 0, ctx->btarget);
19840            break;
19841        default:
19842            MIPS_INVAL("Compact branch/jump");
19843            generate_exception_end(ctx, EXCP_RI);
19844            goto out;
19845        }
19846    } else {
19847        /* Conditional compact branch */
19848        TCGLabel *fs = gen_new_label();
19849
19850        switch (opc) {
19851        case OPC_BGEUC:
19852            if (rs == 0 && rt != 0) {
19853                /* OPC_BLEZALC */
19854                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19855            } else if (rs != 0 && rt != 0 && rs == rt) {
19856                /* OPC_BGEZALC */
19857                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19858            } else {
19859                /* OPC_BGEUC */
19860                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19861            }
19862            break;
19863        case OPC_BLTUC:
19864            if (rs == 0 && rt != 0) {
19865                /* OPC_BGTZALC */
19866                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19867            } else if (rs != 0 && rt != 0 && rs == rt) {
19868                /* OPC_BLTZALC */
19869                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19870            } else {
19871                /* OPC_BLTUC */
19872                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19873            }
19874            break;
19875        case OPC_BGEC:
19876            if (rs == 0 && rt != 0) {
19877                /* OPC_BLEZC */
19878                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19879            } else if (rs != 0 && rt != 0 && rs == rt) {
19880                /* OPC_BGEZC */
19881                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19882            } else {
19883                /* OPC_BGEC */
19884                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19885            }
19886            break;
19887        case OPC_BLTC:
19888            if (rs == 0 && rt != 0) {
19889                /* OPC_BGTZC */
19890                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19891            } else if (rs != 0 && rt != 0 && rs == rt) {
19892                /* OPC_BLTZC */
19893                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19894            } else {
19895                /* OPC_BLTC */
19896                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19897            }
19898            break;
19899        case OPC_BEQZC:
19900            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19901            break;
19902        default:
19903            MIPS_INVAL("Compact conditional branch/jump");
19904            generate_exception_end(ctx, EXCP_RI);
19905            goto out;
19906        }
19907
19908        /* branch completion */
19909        clear_branch_hflags(ctx);
19910        ctx->base.is_jmp = DISAS_NORETURN;
19911
19912        /* Generating branch here as compact branches don't have delay slot */
19913        gen_goto_tb(ctx, 1, ctx->btarget);
19914        gen_set_label(fs);
19915
19916        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19917    }
19918
19919out:
19920    tcg_temp_free(t0);
19921    tcg_temp_free(t1);
19922}
19923
19924
19925/* nanoMIPS CP1 Branches */
19926static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19927                                   int32_t ft, int32_t offset)
19928{
19929    target_ulong btarget;
19930    TCGv_i64 t0 = tcg_temp_new_i64();
19931
19932    gen_load_fpr64(ctx, t0, ft);
19933    tcg_gen_andi_i64(t0, t0, 1);
19934
19935    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19936
19937    switch (op) {
19938    case NM_BC1EQZC:
19939        tcg_gen_xori_i64(t0, t0, 1);
19940        ctx->hflags |= MIPS_HFLAG_BC;
19941        break;
19942    case NM_BC1NEZC:
19943        /* t0 already set */
19944        ctx->hflags |= MIPS_HFLAG_BC;
19945        break;
19946    default:
19947        MIPS_INVAL("cp1 cond branch");
19948        generate_exception_end(ctx, EXCP_RI);
19949        goto out;
19950    }
19951
19952    tcg_gen_trunc_i64_tl(bcond, t0);
19953
19954    ctx->btarget = btarget;
19955
19956out:
19957    tcg_temp_free_i64(t0);
19958}
19959
19960
19961static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19962{
19963    TCGv t0, t1;
19964    t0 = tcg_temp_new();
19965    t1 = tcg_temp_new();
19966
19967    gen_load_gpr(t0, rs);
19968    gen_load_gpr(t1, rt);
19969
19970    if ((extract32(ctx->opcode, 6, 1)) == 1) {
19971        /* PP.LSXS instructions require shifting */
19972        switch (extract32(ctx->opcode, 7, 4)) {
19973        case NM_SHXS:
19974            check_nms(ctx);
19975        case NM_LHXS:
19976        case NM_LHUXS:
19977            tcg_gen_shli_tl(t0, t0, 1);
19978            break;
19979        case NM_SWXS:
19980            check_nms(ctx);
19981        case NM_LWXS:
19982        case NM_LWC1XS:
19983        case NM_SWC1XS:
19984            tcg_gen_shli_tl(t0, t0, 2);
19985            break;
19986        case NM_LDC1XS:
19987        case NM_SDC1XS:
19988            tcg_gen_shli_tl(t0, t0, 3);
19989            break;
19990        }
19991    }
19992    gen_op_addr_add(ctx, t0, t0, t1);
19993
19994    switch (extract32(ctx->opcode, 7, 4)) {
19995    case NM_LBX:
19996        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19997                           MO_SB);
19998        gen_store_gpr(t0, rd);
19999        break;
20000    case NM_LHX:
20001    /*case NM_LHXS:*/
20002        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20003                           MO_TESW);
20004        gen_store_gpr(t0, rd);
20005        break;
20006    case NM_LWX:
20007    /*case NM_LWXS:*/
20008        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20009                           MO_TESL);
20010        gen_store_gpr(t0, rd);
20011        break;
20012    case NM_LBUX:
20013        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20014                           MO_UB);
20015        gen_store_gpr(t0, rd);
20016        break;
20017    case NM_LHUX:
20018    /*case NM_LHUXS:*/
20019        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20020                           MO_TEUW);
20021        gen_store_gpr(t0, rd);
20022        break;
20023    case NM_SBX:
20024        check_nms(ctx);
20025        gen_load_gpr(t1, rd);
20026        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20027                           MO_8);
20028        break;
20029    case NM_SHX:
20030    /*case NM_SHXS:*/
20031        check_nms(ctx);
20032        gen_load_gpr(t1, rd);
20033        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20034                           MO_TEUW);
20035        break;
20036    case NM_SWX:
20037    /*case NM_SWXS:*/
20038        check_nms(ctx);
20039        gen_load_gpr(t1, rd);
20040        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20041                           MO_TEUL);
20042        break;
20043    case NM_LWC1X:
20044    /*case NM_LWC1XS:*/
20045    case NM_LDC1X:
20046    /*case NM_LDC1XS:*/
20047    case NM_SWC1X:
20048    /*case NM_SWC1XS:*/
20049    case NM_SDC1X:
20050    /*case NM_SDC1XS:*/
20051        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20052            check_cp1_enabled(ctx);
20053            switch (extract32(ctx->opcode, 7, 4)) {
20054            case NM_LWC1X:
20055            /*case NM_LWC1XS:*/
20056                gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20057                break;
20058            case NM_LDC1X:
20059            /*case NM_LDC1XS:*/
20060                gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20061                break;
20062            case NM_SWC1X:
20063            /*case NM_SWC1XS:*/
20064                gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20065                break;
20066            case NM_SDC1X:
20067            /*case NM_SDC1XS:*/
20068                gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20069                break;
20070            }
20071        } else {
20072            generate_exception_err(ctx, EXCP_CpU, 1);
20073        }
20074        break;
20075    default:
20076        generate_exception_end(ctx, EXCP_RI);
20077        break;
20078    }
20079
20080    tcg_temp_free(t0);
20081    tcg_temp_free(t1);
20082}
20083
20084static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20085{
20086    int rt, rs, rd;
20087
20088    rt = extract32(ctx->opcode, 21, 5);
20089    rs = extract32(ctx->opcode, 16, 5);
20090    rd = extract32(ctx->opcode, 11, 5);
20091
20092    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20093        generate_exception_end(ctx, EXCP_RI);
20094        return;
20095    }
20096    check_cp1_enabled(ctx);
20097    switch (extract32(ctx->opcode, 0, 3)) {
20098    case NM_POOL32F_0:
20099        switch (extract32(ctx->opcode, 3, 7)) {
20100        case NM_RINT_S:
20101            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20102            break;
20103        case NM_RINT_D:
20104            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20105            break;
20106        case NM_CLASS_S:
20107            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20108            break;
20109        case NM_CLASS_D:
20110            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20111            break;
20112        case NM_ADD_S:
20113            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20114            break;
20115        case NM_ADD_D:
20116            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20117            break;
20118        case NM_SUB_S:
20119            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20120            break;
20121        case NM_SUB_D:
20122            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20123            break;
20124        case NM_MUL_S:
20125            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20126            break;
20127        case NM_MUL_D:
20128            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20129            break;
20130        case NM_DIV_S:
20131            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20132            break;
20133        case NM_DIV_D:
20134            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20135            break;
20136        case NM_SELEQZ_S:
20137            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20138            break;
20139        case NM_SELEQZ_D:
20140            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20141            break;
20142        case NM_SELNEZ_S:
20143            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20144            break;
20145        case NM_SELNEZ_D:
20146            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20147            break;
20148        case NM_SEL_S:
20149            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20150            break;
20151        case NM_SEL_D:
20152            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20153            break;
20154        case NM_MADDF_S:
20155            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20156            break;
20157        case NM_MADDF_D:
20158            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20159            break;
20160        case NM_MSUBF_S:
20161            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20162            break;
20163        case NM_MSUBF_D:
20164            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20165            break;
20166        default:
20167            generate_exception_end(ctx, EXCP_RI);
20168            break;
20169        }
20170        break;
20171    case NM_POOL32F_3:
20172        switch (extract32(ctx->opcode, 3, 3)) {
20173        case NM_MIN_FMT:
20174            switch (extract32(ctx->opcode, 9, 1)) {
20175            case FMT_SDPS_S:
20176                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20177                break;
20178            case FMT_SDPS_D:
20179                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20180                break;
20181            }
20182            break;
20183        case NM_MAX_FMT:
20184            switch (extract32(ctx->opcode, 9, 1)) {
20185            case FMT_SDPS_S:
20186                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20187                break;
20188            case FMT_SDPS_D:
20189                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20190                break;
20191            }
20192            break;
20193        case NM_MINA_FMT:
20194            switch (extract32(ctx->opcode, 9, 1)) {
20195            case FMT_SDPS_S:
20196                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20197                break;
20198            case FMT_SDPS_D:
20199                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20200                break;
20201            }
20202            break;
20203        case NM_MAXA_FMT:
20204            switch (extract32(ctx->opcode, 9, 1)) {
20205            case FMT_SDPS_S:
20206                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20207                break;
20208            case FMT_SDPS_D:
20209                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20210                break;
20211            }
20212            break;
20213        case NM_POOL32FXF:
20214            switch (extract32(ctx->opcode, 6, 8)) {
20215            case NM_CFC1:
20216                gen_cp1(ctx, OPC_CFC1, rt, rs);
20217                break;
20218            case NM_CTC1:
20219                gen_cp1(ctx, OPC_CTC1, rt, rs);
20220                break;
20221            case NM_MFC1:
20222                gen_cp1(ctx, OPC_MFC1, rt, rs);
20223                break;
20224            case NM_MTC1:
20225                gen_cp1(ctx, OPC_MTC1, rt, rs);
20226                break;
20227            case NM_MFHC1:
20228                gen_cp1(ctx, OPC_MFHC1, rt, rs);
20229                break;
20230            case NM_MTHC1:
20231                gen_cp1(ctx, OPC_MTHC1, rt, rs);
20232                break;
20233            case NM_CVT_S_PL:
20234                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20235                break;
20236            case NM_CVT_S_PU:
20237                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20238                break;
20239            default:
20240                switch (extract32(ctx->opcode, 6, 9)) {
20241                case NM_CVT_L_S:
20242                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20243                    break;
20244                case NM_CVT_L_D:
20245                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20246                    break;
20247                case NM_CVT_W_S:
20248                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20249                    break;
20250                case NM_CVT_W_D:
20251                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20252                    break;
20253                case NM_RSQRT_S:
20254                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20255                    break;
20256                case NM_RSQRT_D:
20257                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20258                    break;
20259                case NM_SQRT_S:
20260                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20261                    break;
20262                case NM_SQRT_D:
20263                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20264                    break;
20265                case NM_RECIP_S:
20266                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20267                    break;
20268                case NM_RECIP_D:
20269                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20270                    break;
20271                case NM_FLOOR_L_S:
20272                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20273                    break;
20274                case NM_FLOOR_L_D:
20275                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20276                    break;
20277                case NM_FLOOR_W_S:
20278                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20279                    break;
20280                case NM_FLOOR_W_D:
20281                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20282                    break;
20283                case NM_CEIL_L_S:
20284                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20285                    break;
20286                case NM_CEIL_L_D:
20287                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20288                    break;
20289                case NM_CEIL_W_S:
20290                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20291                    break;
20292                case NM_CEIL_W_D:
20293                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20294                    break;
20295                case NM_TRUNC_L_S:
20296                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20297                    break;
20298                case NM_TRUNC_L_D:
20299                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20300                    break;
20301                case NM_TRUNC_W_S:
20302                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20303                    break;
20304                case NM_TRUNC_W_D:
20305                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20306                    break;
20307                case NM_ROUND_L_S:
20308                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20309                    break;
20310                case NM_ROUND_L_D:
20311                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20312                    break;
20313                case NM_ROUND_W_S:
20314                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20315                    break;
20316                case NM_ROUND_W_D:
20317                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20318                    break;
20319                case NM_MOV_S:
20320                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20321                    break;
20322                case NM_MOV_D:
20323                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20324                    break;
20325                case NM_ABS_S:
20326                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20327                    break;
20328                case NM_ABS_D:
20329                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20330                    break;
20331                case NM_NEG_S:
20332                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20333                    break;
20334                case NM_NEG_D:
20335                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20336                    break;
20337                case NM_CVT_D_S:
20338                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20339                    break;
20340                case NM_CVT_D_W:
20341                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20342                    break;
20343                case NM_CVT_D_L:
20344                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20345                    break;
20346                case NM_CVT_S_D:
20347                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20348                    break;
20349                case NM_CVT_S_W:
20350                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20351                    break;
20352                case NM_CVT_S_L:
20353                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20354                    break;
20355                default:
20356                    generate_exception_end(ctx, EXCP_RI);
20357                    break;
20358                }
20359                break;
20360            }
20361            break;
20362        }
20363        break;
20364    case NM_POOL32F_5:
20365        switch (extract32(ctx->opcode, 3, 3)) {
20366        case NM_CMP_CONDN_S:
20367            gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20368            break;
20369        case NM_CMP_CONDN_D:
20370            gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20371            break;
20372        default:
20373            generate_exception_end(ctx, EXCP_RI);
20374            break;
20375        }
20376        break;
20377    default:
20378        generate_exception_end(ctx, EXCP_RI);
20379        break;
20380    }
20381}
20382
20383static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20384                                       int rd, int rs, int rt)
20385{
20386    int ret = rd;
20387    TCGv t0 = tcg_temp_new();
20388    TCGv v1_t = tcg_temp_new();
20389    TCGv v2_t = tcg_temp_new();
20390
20391    gen_load_gpr(v1_t, rs);
20392    gen_load_gpr(v2_t, rt);
20393
20394    switch (opc) {
20395    case NM_CMP_EQ_PH:
20396        check_dsp(ctx);
20397        gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20398        break;
20399    case NM_CMP_LT_PH:
20400        check_dsp(ctx);
20401        gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20402        break;
20403    case NM_CMP_LE_PH:
20404        check_dsp(ctx);
20405        gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20406        break;
20407    case NM_CMPU_EQ_QB:
20408        check_dsp(ctx);
20409        gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20410        break;
20411    case NM_CMPU_LT_QB:
20412        check_dsp(ctx);
20413        gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20414        break;
20415    case NM_CMPU_LE_QB:
20416        check_dsp(ctx);
20417        gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20418        break;
20419    case NM_CMPGU_EQ_QB:
20420        check_dsp(ctx);
20421        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20422        gen_store_gpr(v1_t, ret);
20423        break;
20424    case NM_CMPGU_LT_QB:
20425        check_dsp(ctx);
20426        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20427        gen_store_gpr(v1_t, ret);
20428        break;
20429    case NM_CMPGU_LE_QB:
20430        check_dsp(ctx);
20431        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20432        gen_store_gpr(v1_t, ret);
20433        break;
20434    case NM_CMPGDU_EQ_QB:
20435        check_dsp_r2(ctx);
20436        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20437        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20438        gen_store_gpr(v1_t, ret);
20439        break;
20440    case NM_CMPGDU_LT_QB:
20441        check_dsp_r2(ctx);
20442        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20443        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20444        gen_store_gpr(v1_t, ret);
20445        break;
20446    case NM_CMPGDU_LE_QB:
20447        check_dsp_r2(ctx);
20448        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20449        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20450        gen_store_gpr(v1_t, ret);
20451        break;
20452    case NM_PACKRL_PH:
20453        check_dsp(ctx);
20454        gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20455        gen_store_gpr(v1_t, ret);
20456        break;
20457    case NM_PICK_QB:
20458        check_dsp(ctx);
20459        gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20460        gen_store_gpr(v1_t, ret);
20461        break;
20462    case NM_PICK_PH:
20463        check_dsp(ctx);
20464        gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20465        gen_store_gpr(v1_t, ret);
20466        break;
20467    case NM_ADDQ_S_W:
20468        check_dsp(ctx);
20469        gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20470        gen_store_gpr(v1_t, ret);
20471        break;
20472    case NM_SUBQ_S_W:
20473        check_dsp(ctx);
20474        gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20475        gen_store_gpr(v1_t, ret);
20476        break;
20477    case NM_ADDSC:
20478        check_dsp(ctx);
20479        gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20480        gen_store_gpr(v1_t, ret);
20481        break;
20482    case NM_ADDWC:
20483        check_dsp(ctx);
20484        gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20485        gen_store_gpr(v1_t, ret);
20486        break;
20487    case NM_ADDQ_S_PH:
20488        check_dsp(ctx);
20489        switch (extract32(ctx->opcode, 10, 1)) {
20490        case 0:
20491            /* ADDQ_PH */
20492            gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20493            gen_store_gpr(v1_t, ret);
20494            break;
20495        case 1:
20496            /* ADDQ_S_PH */
20497            gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20498            gen_store_gpr(v1_t, ret);
20499            break;
20500        }
20501        break;
20502    case NM_ADDQH_R_PH:
20503        check_dsp_r2(ctx);
20504        switch (extract32(ctx->opcode, 10, 1)) {
20505        case 0:
20506            /* ADDQH_PH */
20507            gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20508            gen_store_gpr(v1_t, ret);
20509            break;
20510        case 1:
20511            /* ADDQH_R_PH */
20512            gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20513            gen_store_gpr(v1_t, ret);
20514            break;
20515        }
20516        break;
20517    case NM_ADDQH_R_W:
20518        check_dsp_r2(ctx);
20519        switch (extract32(ctx->opcode, 10, 1)) {
20520        case 0:
20521            /* ADDQH_W */
20522            gen_helper_addqh_w(v1_t, v1_t, v2_t);
20523            gen_store_gpr(v1_t, ret);
20524            break;
20525        case 1:
20526            /* ADDQH_R_W */
20527            gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20528            gen_store_gpr(v1_t, ret);
20529            break;
20530        }
20531        break;
20532    case NM_ADDU_S_QB:
20533        check_dsp(ctx);
20534        switch (extract32(ctx->opcode, 10, 1)) {
20535        case 0:
20536            /* ADDU_QB */
20537            gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20538            gen_store_gpr(v1_t, ret);
20539            break;
20540        case 1:
20541            /* ADDU_S_QB */
20542            gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20543            gen_store_gpr(v1_t, ret);
20544            break;
20545        }
20546        break;
20547    case NM_ADDU_S_PH:
20548        check_dsp_r2(ctx);
20549        switch (extract32(ctx->opcode, 10, 1)) {
20550        case 0:
20551            /* ADDU_PH */
20552            gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20553            gen_store_gpr(v1_t, ret);
20554            break;
20555        case 1:
20556            /* ADDU_S_PH */
20557            gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20558            gen_store_gpr(v1_t, ret);
20559            break;
20560        }
20561        break;
20562    case NM_ADDUH_R_QB:
20563        check_dsp_r2(ctx);
20564        switch (extract32(ctx->opcode, 10, 1)) {
20565        case 0:
20566            /* ADDUH_QB */
20567            gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20568            gen_store_gpr(v1_t, ret);
20569            break;
20570        case 1:
20571            /* ADDUH_R_QB */
20572            gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20573            gen_store_gpr(v1_t, ret);
20574            break;
20575        }
20576        break;
20577    case NM_SHRAV_R_PH:
20578        check_dsp(ctx);
20579        switch (extract32(ctx->opcode, 10, 1)) {
20580        case 0:
20581            /* SHRAV_PH */
20582            gen_helper_shra_ph(v1_t, v1_t, v2_t);
20583            gen_store_gpr(v1_t, ret);
20584            break;
20585        case 1:
20586            /* SHRAV_R_PH */
20587            gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20588            gen_store_gpr(v1_t, ret);
20589            break;
20590        }
20591        break;
20592    case NM_SHRAV_R_QB:
20593        check_dsp_r2(ctx);
20594        switch (extract32(ctx->opcode, 10, 1)) {
20595        case 0:
20596            /* SHRAV_QB */
20597            gen_helper_shra_qb(v1_t, v1_t, v2_t);
20598            gen_store_gpr(v1_t, ret);
20599            break;
20600        case 1:
20601            /* SHRAV_R_QB */
20602            gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20603            gen_store_gpr(v1_t, ret);
20604            break;
20605        }
20606        break;
20607    case NM_SUBQ_S_PH:
20608        check_dsp(ctx);
20609        switch (extract32(ctx->opcode, 10, 1)) {
20610        case 0:
20611            /* SUBQ_PH */
20612            gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20613            gen_store_gpr(v1_t, ret);
20614            break;
20615        case 1:
20616            /* SUBQ_S_PH */
20617            gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20618            gen_store_gpr(v1_t, ret);
20619            break;
20620        }
20621        break;
20622    case NM_SUBQH_R_PH:
20623        check_dsp_r2(ctx);
20624        switch (extract32(ctx->opcode, 10, 1)) {
20625        case 0:
20626            /* SUBQH_PH */
20627            gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20628            gen_store_gpr(v1_t, ret);
20629            break;
20630        case 1:
20631            /* SUBQH_R_PH */
20632            gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20633            gen_store_gpr(v1_t, ret);
20634            break;
20635        }
20636        break;
20637    case NM_SUBQH_R_W:
20638        check_dsp_r2(ctx);
20639        switch (extract32(ctx->opcode, 10, 1)) {
20640        case 0:
20641            /* SUBQH_W */
20642            gen_helper_subqh_w(v1_t, v1_t, v2_t);
20643            gen_store_gpr(v1_t, ret);
20644            break;
20645        case 1:
20646            /* SUBQH_R_W */
20647            gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20648            gen_store_gpr(v1_t, ret);
20649            break;
20650        }
20651        break;
20652    case NM_SUBU_S_QB:
20653        check_dsp(ctx);
20654        switch (extract32(ctx->opcode, 10, 1)) {
20655        case 0:
20656            /* SUBU_QB */
20657            gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20658            gen_store_gpr(v1_t, ret);
20659            break;
20660        case 1:
20661            /* SUBU_S_QB */
20662            gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20663            gen_store_gpr(v1_t, ret);
20664            break;
20665        }
20666        break;
20667    case NM_SUBU_S_PH:
20668        check_dsp_r2(ctx);
20669        switch (extract32(ctx->opcode, 10, 1)) {
20670        case 0:
20671            /* SUBU_PH */
20672            gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20673            gen_store_gpr(v1_t, ret);
20674            break;
20675        case 1:
20676            /* SUBU_S_PH */
20677            gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20678            gen_store_gpr(v1_t, ret);
20679            break;
20680        }
20681        break;
20682    case NM_SUBUH_R_QB:
20683        check_dsp_r2(ctx);
20684        switch (extract32(ctx->opcode, 10, 1)) {
20685        case 0:
20686            /* SUBUH_QB */
20687            gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20688            gen_store_gpr(v1_t, ret);
20689            break;
20690        case 1:
20691            /* SUBUH_R_QB */
20692            gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20693            gen_store_gpr(v1_t, ret);
20694            break;
20695        }
20696        break;
20697    case NM_SHLLV_S_PH:
20698        check_dsp(ctx);
20699        switch (extract32(ctx->opcode, 10, 1)) {
20700        case 0:
20701            /* SHLLV_PH */
20702            gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20703            gen_store_gpr(v1_t, ret);
20704            break;
20705        case 1:
20706            /* SHLLV_S_PH */
20707            gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20708            gen_store_gpr(v1_t, ret);
20709            break;
20710        }
20711        break;
20712    case NM_PRECR_SRA_R_PH_W:
20713        check_dsp_r2(ctx);
20714        switch (extract32(ctx->opcode, 10, 1)) {
20715        case 0:
20716            /* PRECR_SRA_PH_W */
20717            {
20718                TCGv_i32 sa_t = tcg_const_i32(rd);
20719                gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20720                                          cpu_gpr[rt]);
20721                gen_store_gpr(v1_t, rt);
20722                tcg_temp_free_i32(sa_t);
20723            }
20724            break;
20725        case 1:
20726            /* PRECR_SRA_R_PH_W */
20727            {
20728                TCGv_i32 sa_t = tcg_const_i32(rd);
20729                gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20730                                            cpu_gpr[rt]);
20731                gen_store_gpr(v1_t, rt);
20732                tcg_temp_free_i32(sa_t);
20733            }
20734            break;
20735       }
20736        break;
20737    case NM_MULEU_S_PH_QBL:
20738        check_dsp(ctx);
20739        gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20740        gen_store_gpr(v1_t, ret);
20741        break;
20742    case NM_MULEU_S_PH_QBR:
20743        check_dsp(ctx);
20744        gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20745        gen_store_gpr(v1_t, ret);
20746        break;
20747    case NM_MULQ_RS_PH:
20748        check_dsp(ctx);
20749        gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20750        gen_store_gpr(v1_t, ret);
20751        break;
20752    case NM_MULQ_S_PH:
20753        check_dsp_r2(ctx);
20754        gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20755        gen_store_gpr(v1_t, ret);
20756        break;
20757    case NM_MULQ_RS_W:
20758        check_dsp_r2(ctx);
20759        gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20760        gen_store_gpr(v1_t, ret);
20761        break;
20762    case NM_MULQ_S_W:
20763        check_dsp_r2(ctx);
20764        gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20765        gen_store_gpr(v1_t, ret);
20766        break;
20767    case NM_APPEND:
20768        check_dsp_r2(ctx);
20769        gen_load_gpr(t0, rs);
20770        if (rd != 0) {
20771            tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20772        }
20773        tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20774        break;
20775    case NM_MODSUB:
20776        check_dsp(ctx);
20777        gen_helper_modsub(v1_t, v1_t, v2_t);
20778        gen_store_gpr(v1_t, ret);
20779        break;
20780    case NM_SHRAV_R_W:
20781        check_dsp(ctx);
20782        gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20783        gen_store_gpr(v1_t, ret);
20784        break;
20785    case NM_SHRLV_PH:
20786        check_dsp_r2(ctx);
20787        gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20788        gen_store_gpr(v1_t, ret);
20789        break;
20790    case NM_SHRLV_QB:
20791        check_dsp(ctx);
20792        gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20793        gen_store_gpr(v1_t, ret);
20794        break;
20795    case NM_SHLLV_QB:
20796        check_dsp(ctx);
20797        gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20798        gen_store_gpr(v1_t, ret);
20799        break;
20800    case NM_SHLLV_S_W:
20801        check_dsp(ctx);
20802        gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20803        gen_store_gpr(v1_t, ret);
20804        break;
20805    case NM_SHILO:
20806        check_dsp(ctx);
20807        {
20808            TCGv tv0 = tcg_temp_new();
20809            TCGv tv1 = tcg_temp_new();
20810            int16_t imm = extract32(ctx->opcode, 16, 7);
20811
20812            tcg_gen_movi_tl(tv0, rd >> 3);
20813            tcg_gen_movi_tl(tv1, imm);
20814            gen_helper_shilo(tv0, tv1, cpu_env);
20815        }
20816        break;
20817    case NM_MULEQ_S_W_PHL:
20818        check_dsp(ctx);
20819        gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20820        gen_store_gpr(v1_t, ret);
20821        break;
20822    case NM_MULEQ_S_W_PHR:
20823        check_dsp(ctx);
20824        gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20825        gen_store_gpr(v1_t, ret);
20826        break;
20827    case NM_MUL_S_PH:
20828        check_dsp_r2(ctx);
20829        switch (extract32(ctx->opcode, 10, 1)) {
20830        case 0:
20831            /* MUL_PH */
20832            gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20833            gen_store_gpr(v1_t, ret);
20834            break;
20835        case 1:
20836            /* MUL_S_PH */
20837            gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20838            gen_store_gpr(v1_t, ret);
20839            break;
20840        }
20841        break;
20842    case NM_PRECR_QB_PH:
20843        check_dsp_r2(ctx);
20844        gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20845        gen_store_gpr(v1_t, ret);
20846        break;
20847    case NM_PRECRQ_QB_PH:
20848        check_dsp(ctx);
20849        gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20850        gen_store_gpr(v1_t, ret);
20851        break;
20852    case NM_PRECRQ_PH_W:
20853        check_dsp(ctx);
20854        gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20855        gen_store_gpr(v1_t, ret);
20856        break;
20857    case NM_PRECRQ_RS_PH_W:
20858        check_dsp(ctx);
20859        gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20860        gen_store_gpr(v1_t, ret);
20861        break;
20862    case NM_PRECRQU_S_QB_PH:
20863        check_dsp(ctx);
20864        gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20865        gen_store_gpr(v1_t, ret);
20866        break;
20867    case NM_SHRA_R_W:
20868        check_dsp(ctx);
20869        tcg_gen_movi_tl(t0, rd);
20870        gen_helper_shra_r_w(v1_t, t0, v1_t);
20871        gen_store_gpr(v1_t, rt);
20872        break;
20873    case NM_SHRA_R_PH:
20874        check_dsp(ctx);
20875        tcg_gen_movi_tl(t0, rd >> 1);
20876        switch (extract32(ctx->opcode, 10, 1)) {
20877        case 0:
20878            /* SHRA_PH */
20879            gen_helper_shra_ph(v1_t, t0, v1_t);
20880            gen_store_gpr(v1_t, rt);
20881            break;
20882        case 1:
20883            /* SHRA_R_PH */
20884            gen_helper_shra_r_ph(v1_t, t0, v1_t);
20885            gen_store_gpr(v1_t, rt);
20886            break;
20887        }
20888        break;
20889    case NM_SHLL_S_PH:
20890        check_dsp(ctx);
20891        tcg_gen_movi_tl(t0, rd >> 1);
20892        switch (extract32(ctx->opcode, 10, 2)) {
20893        case 0:
20894            /* SHLL_PH */
20895            gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20896            gen_store_gpr(v1_t, rt);
20897            break;
20898        case 2:
20899            /* SHLL_S_PH */
20900            gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20901            gen_store_gpr(v1_t, rt);
20902            break;
20903        default:
20904            generate_exception_end(ctx, EXCP_RI);
20905            break;
20906        }
20907        break;
20908    case NM_SHLL_S_W:
20909        check_dsp(ctx);
20910        tcg_gen_movi_tl(t0, rd);
20911        gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20912        gen_store_gpr(v1_t, rt);
20913        break;
20914    case NM_REPL_PH:
20915        check_dsp(ctx);
20916        {
20917            int16_t imm;
20918            imm = sextract32(ctx->opcode, 11, 11);
20919            imm = (int16_t)(imm << 6) >> 6;
20920            if (rt != 0) {
20921                tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20922            }
20923        }
20924        break;
20925    default:
20926        generate_exception_end(ctx, EXCP_RI);
20927        break;
20928    }
20929}
20930
20931static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20932{
20933    uint16_t insn;
20934    uint32_t op;
20935    int rt, rs, rd;
20936    int offset;
20937    int imm;
20938
20939    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20940    ctx->opcode = (ctx->opcode << 16) | insn;
20941
20942    rt = extract32(ctx->opcode, 21, 5);
20943    rs = extract32(ctx->opcode, 16, 5);
20944    rd = extract32(ctx->opcode, 11, 5);
20945
20946    op = extract32(ctx->opcode, 26, 6);
20947    switch (op) {
20948    case NM_P_ADDIU:
20949        if (rt == 0) {
20950            /* P.RI */
20951            switch (extract32(ctx->opcode, 19, 2)) {
20952            case NM_SIGRIE:
20953            default:
20954                generate_exception_end(ctx, EXCP_RI);
20955                break;
20956            case NM_P_SYSCALL:
20957                if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20958                    generate_exception_end(ctx, EXCP_SYSCALL);
20959                } else {
20960                    generate_exception_end(ctx, EXCP_RI);
20961                }
20962                break;
20963            case NM_BREAK:
20964                generate_exception_end(ctx, EXCP_BREAK);
20965                break;
20966            case NM_SDBBP:
20967                if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20968                    gen_helper_do_semihosting(cpu_env);
20969                } else {
20970                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
20971                        generate_exception_end(ctx, EXCP_RI);
20972                    } else {
20973                        generate_exception_end(ctx, EXCP_DBp);
20974                    }
20975                }
20976                break;
20977            }
20978        } else {
20979            /* NM_ADDIU */
20980            imm = extract32(ctx->opcode, 0, 16);
20981            if (rs != 0) {
20982                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20983            } else {
20984                tcg_gen_movi_tl(cpu_gpr[rt], imm);
20985            }
20986            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20987        }
20988        break;
20989    case NM_ADDIUPC:
20990        if (rt != 0) {
20991            offset = sextract32(ctx->opcode, 0, 1) << 21 |
20992                     extract32(ctx->opcode, 1, 20) << 1;
20993            target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20994            tcg_gen_movi_tl(cpu_gpr[rt], addr);
20995        }
20996        break;
20997    case NM_POOL32A:
20998        switch (ctx->opcode & 0x07) {
20999        case NM_POOL32A0:
21000            gen_pool32a0_nanomips_insn(env, ctx);
21001            break;
21002        case NM_POOL32A5:
21003            {
21004                int32_t op1 = extract32(ctx->opcode, 3, 7);
21005                gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21006            }
21007            break;
21008        case NM_POOL32A7:
21009            switch (extract32(ctx->opcode, 3, 3)) {
21010            case NM_P_LSX:
21011                gen_p_lsx(ctx, rd, rs, rt);
21012                break;
21013            case NM_LSA:
21014                /* In nanoMIPS, the shift field directly encodes the shift
21015                 * amount, meaning that the supported shift values are in
21016                 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21017                gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21018                        extract32(ctx->opcode, 9, 2) - 1);
21019                break;
21020            case NM_EXTW:
21021                gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21022                break;
21023            case NM_POOL32AXF:
21024                gen_pool32axf_nanomips_insn(env, ctx);
21025                break;
21026            default:
21027                generate_exception_end(ctx, EXCP_RI);
21028                break;
21029            }
21030            break;
21031        default:
21032            generate_exception_end(ctx, EXCP_RI);
21033            break;
21034        }
21035        break;
21036    case NM_P_GP_W:
21037        switch (ctx->opcode & 0x03) {
21038        case NM_ADDIUGP_W:
21039            if (rt != 0) {
21040                offset = extract32(ctx->opcode, 0, 21);
21041                gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21042            }
21043            break;
21044        case NM_LWGP:
21045            gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21046            break;
21047        case NM_SWGP:
21048            gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21049            break;
21050        default:
21051            generate_exception_end(ctx, EXCP_RI);
21052            break;
21053        }
21054        break;
21055    case NM_P48I:
21056        {
21057            insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21058            target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21059            switch (extract32(ctx->opcode, 16, 5)) {
21060            case NM_LI48:
21061                check_nms(ctx);
21062                if (rt != 0) {
21063                    tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21064                }
21065                break;
21066            case NM_ADDIU48:
21067                check_nms(ctx);
21068                if (rt != 0) {
21069                    tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21070                    tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21071                }
21072                break;
21073            case NM_ADDIUGP48:
21074                check_nms(ctx);
21075                if (rt != 0) {
21076                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21077                }
21078                break;
21079            case NM_ADDIUPC48:
21080                check_nms(ctx);
21081                if (rt != 0) {
21082                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21083                                                addr_off);
21084
21085                    tcg_gen_movi_tl(cpu_gpr[rt], addr);
21086                }
21087                break;
21088            case NM_LWPC48:
21089                check_nms(ctx);
21090                if (rt != 0) {
21091                    TCGv t0;
21092                    t0 = tcg_temp_new();
21093
21094                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21095                                                addr_off);
21096
21097                    tcg_gen_movi_tl(t0, addr);
21098                    tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21099                    tcg_temp_free(t0);
21100                }
21101                break;
21102            case NM_SWPC48:
21103                check_nms(ctx);
21104                {
21105                    TCGv t0, t1;
21106                    t0 = tcg_temp_new();
21107                    t1 = tcg_temp_new();
21108
21109                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21110                                                addr_off);
21111
21112                    tcg_gen_movi_tl(t0, addr);
21113                    gen_load_gpr(t1, rt);
21114
21115                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21116
21117                    tcg_temp_free(t0);
21118                    tcg_temp_free(t1);
21119                }
21120                break;
21121            default:
21122                generate_exception_end(ctx, EXCP_RI);
21123                break;
21124            }
21125            return 6;
21126        }
21127    case NM_P_U12:
21128        switch (extract32(ctx->opcode, 12, 4)) {
21129        case NM_ORI:
21130            gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21131            break;
21132        case NM_XORI:
21133            gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21134            break;
21135        case NM_ANDI:
21136            gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21137            break;
21138        case NM_P_SR:
21139            switch (extract32(ctx->opcode, 20, 1)) {
21140            case NM_PP_SR:
21141                switch (ctx->opcode & 3) {
21142                case NM_SAVE:
21143                    gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21144                             extract32(ctx->opcode, 2, 1),
21145                             extract32(ctx->opcode, 3, 9) << 3);
21146                    break;
21147                case NM_RESTORE:
21148                case NM_RESTORE_JRC:
21149                    gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21150                                extract32(ctx->opcode, 2, 1),
21151                                extract32(ctx->opcode, 3, 9) << 3);
21152                    if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21153                        gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21154                    }
21155                    break;
21156                default:
21157                    generate_exception_end(ctx, EXCP_RI);
21158                    break;
21159                }
21160                break;
21161            case NM_P_SR_F:
21162                generate_exception_end(ctx, EXCP_RI);
21163                break;
21164            }
21165            break;
21166        case NM_SLTI:
21167            gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21168            break;
21169        case NM_SLTIU:
21170            gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21171            break;
21172        case NM_SEQI:
21173            {
21174                TCGv t0 = tcg_temp_new();
21175
21176                imm = extract32(ctx->opcode, 0, 12);
21177                gen_load_gpr(t0, rs);
21178                tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21179                gen_store_gpr(t0, rt);
21180
21181                tcg_temp_free(t0);
21182            }
21183            break;
21184        case NM_ADDIUNEG:
21185            imm = (int16_t) extract32(ctx->opcode, 0, 12);
21186            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21187            break;
21188        case NM_P_SHIFT:
21189            {
21190                int shift = extract32(ctx->opcode, 0, 5);
21191                switch (extract32(ctx->opcode, 5, 4)) {
21192                case NM_P_SLL:
21193                    if (rt == 0 && shift == 0) {
21194                        /* NOP */
21195                    } else if (rt == 0 && shift == 3) {
21196                        /* EHB - treat as NOP */
21197                    } else if (rt == 0 && shift == 5) {
21198                        /* PAUSE - treat as NOP */
21199                    } else if (rt == 0 && shift == 6) {
21200                        /* SYNC */
21201                        gen_sync(extract32(ctx->opcode, 16, 5));
21202                    } else {
21203                        /* SLL */
21204                        gen_shift_imm(ctx, OPC_SLL, rt, rs,
21205                                      extract32(ctx->opcode, 0, 5));
21206                    }
21207                    break;
21208                case NM_SRL:
21209                    gen_shift_imm(ctx, OPC_SRL, rt, rs,
21210                                  extract32(ctx->opcode, 0, 5));
21211                    break;
21212                case NM_SRA:
21213                    gen_shift_imm(ctx, OPC_SRA, rt, rs,
21214                                  extract32(ctx->opcode, 0, 5));
21215                    break;
21216                case NM_ROTR:
21217                    gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21218                                  extract32(ctx->opcode, 0, 5));
21219                    break;
21220                }
21221            }
21222            break;
21223        case NM_P_ROTX:
21224            check_nms(ctx);
21225            if (rt != 0) {
21226                TCGv t0 = tcg_temp_new();
21227                TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21228                TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21229                                                << 1);
21230                TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21231
21232                gen_load_gpr(t0, rs);
21233                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21234                tcg_temp_free(t0);
21235
21236                tcg_temp_free_i32(shift);
21237                tcg_temp_free_i32(shiftx);
21238                tcg_temp_free_i32(stripe);
21239            }
21240            break;
21241        case NM_P_INS:
21242            switch (((ctx->opcode >> 10) & 2) |
21243                    (extract32(ctx->opcode, 5, 1))) {
21244            case NM_INS:
21245                check_nms(ctx);
21246                gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21247                           extract32(ctx->opcode, 6, 5));
21248                break;
21249            default:
21250                generate_exception_end(ctx, EXCP_RI);
21251                break;
21252            }
21253            break;
21254        case NM_P_EXT:
21255            switch (((ctx->opcode >> 10) & 2) |
21256                    (extract32(ctx->opcode, 5, 1))) {
21257            case NM_EXT:
21258                check_nms(ctx);
21259                gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21260                           extract32(ctx->opcode, 6, 5));
21261                break;
21262            default:
21263                generate_exception_end(ctx, EXCP_RI);
21264                break;
21265            }
21266            break;
21267        default:
21268            generate_exception_end(ctx, EXCP_RI);
21269            break;
21270        }
21271        break;
21272    case NM_POOL32F:
21273        gen_pool32f_nanomips_insn(ctx);
21274        break;
21275    case NM_POOL32S:
21276        break;
21277    case NM_P_LUI:
21278        switch (extract32(ctx->opcode, 1, 1)) {
21279        case NM_LUI:
21280            if (rt != 0) {
21281                tcg_gen_movi_tl(cpu_gpr[rt],
21282                                sextract32(ctx->opcode, 0, 1) << 31 |
21283                                extract32(ctx->opcode, 2, 10) << 21 |
21284                                extract32(ctx->opcode, 12, 9) << 12);
21285            }
21286            break;
21287        case NM_ALUIPC:
21288            if (rt != 0) {
21289                offset = sextract32(ctx->opcode, 0, 1) << 31 |
21290                         extract32(ctx->opcode, 2, 10) << 21 |
21291                         extract32(ctx->opcode, 12, 9) << 12;
21292                target_long addr;
21293                addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21294                tcg_gen_movi_tl(cpu_gpr[rt], addr);
21295            }
21296            break;
21297        }
21298        break;
21299    case NM_P_GP_BH:
21300        {
21301            uint32_t u = extract32(ctx->opcode, 0, 18);
21302
21303            switch (extract32(ctx->opcode, 18, 3)) {
21304            case NM_LBGP:
21305                gen_ld(ctx, OPC_LB, rt, 28, u);
21306                break;
21307            case NM_SBGP:
21308                gen_st(ctx, OPC_SB, rt, 28, u);
21309                break;
21310            case NM_LBUGP:
21311                gen_ld(ctx, OPC_LBU, rt, 28, u);
21312                break;
21313            case NM_ADDIUGP_B:
21314                if (rt != 0) {
21315                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21316                }
21317                break;
21318            case NM_P_GP_LH:
21319                u &= ~1;
21320                switch (ctx->opcode & 1) {
21321                case NM_LHGP:
21322                    gen_ld(ctx, OPC_LH, rt, 28, u);
21323                    break;
21324                case NM_LHUGP:
21325                    gen_ld(ctx, OPC_LHU, rt, 28, u);
21326                    break;
21327                }
21328                break;
21329            case NM_P_GP_SH:
21330                u &= ~1;
21331                switch (ctx->opcode & 1) {
21332                case NM_SHGP:
21333                    gen_st(ctx, OPC_SH, rt, 28, u);
21334                    break;
21335                default:
21336                    generate_exception_end(ctx, EXCP_RI);
21337                    break;
21338                }
21339                break;
21340            case NM_P_GP_CP1:
21341                u &= ~0x3;
21342                switch (ctx->opcode & 0x3) {
21343                case NM_LWC1GP:
21344                    gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21345                    break;
21346                case NM_LDC1GP:
21347                    gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21348                    break;
21349                case NM_SWC1GP:
21350                    gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21351                    break;
21352                case NM_SDC1GP:
21353                    gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21354                    break;
21355                }
21356                break;
21357            default:
21358                generate_exception_end(ctx, EXCP_RI);
21359                break;
21360            }
21361        }
21362        break;
21363    case NM_P_LS_U12:
21364        {
21365            uint32_t u = extract32(ctx->opcode, 0, 12);
21366
21367            switch (extract32(ctx->opcode, 12, 4)) {
21368            case NM_P_PREFU12:
21369                if (rt == 31) {
21370                    /* SYNCI */
21371                    /* Break the TB to be able to sync copied instructions
21372                       immediately */
21373                    ctx->base.is_jmp = DISAS_STOP;
21374                } else {
21375                    /* PREF */
21376                    /* Treat as NOP. */
21377                }
21378                break;
21379            case NM_LB:
21380                gen_ld(ctx, OPC_LB, rt, rs, u);
21381                break;
21382            case NM_LH:
21383                gen_ld(ctx, OPC_LH, rt, rs, u);
21384                break;
21385            case NM_LW:
21386                gen_ld(ctx, OPC_LW, rt, rs, u);
21387                break;
21388            case NM_LBU:
21389                gen_ld(ctx, OPC_LBU, rt, rs, u);
21390                break;
21391            case NM_LHU:
21392                gen_ld(ctx, OPC_LHU, rt, rs, u);
21393                break;
21394            case NM_SB:
21395                gen_st(ctx, OPC_SB, rt, rs, u);
21396                break;
21397            case NM_SH:
21398                gen_st(ctx, OPC_SH, rt, rs, u);
21399                break;
21400            case NM_SW:
21401                gen_st(ctx, OPC_SW, rt, rs, u);
21402                break;
21403            case NM_LWC1:
21404                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21405                break;
21406            case NM_LDC1:
21407                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21408                break;
21409            case NM_SWC1:
21410                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21411                break;
21412            case NM_SDC1:
21413                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21414                break;
21415            default:
21416                generate_exception_end(ctx, EXCP_RI);
21417                break;
21418            }
21419        }
21420        break;
21421    case NM_P_LS_S9:
21422        {
21423            int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21424                        extract32(ctx->opcode, 0, 8);
21425
21426            switch (extract32(ctx->opcode, 8, 3)) {
21427            case NM_P_LS_S0:
21428                switch (extract32(ctx->opcode, 11, 4)) {
21429                case NM_LBS9:
21430                    gen_ld(ctx, OPC_LB, rt, rs, s);
21431                    break;
21432                case NM_LHS9:
21433                    gen_ld(ctx, OPC_LH, rt, rs, s);
21434                    break;
21435                case NM_LWS9:
21436                    gen_ld(ctx, OPC_LW, rt, rs, s);
21437                    break;
21438                case NM_LBUS9:
21439                    gen_ld(ctx, OPC_LBU, rt, rs, s);
21440                    break;
21441                case NM_LHUS9:
21442                    gen_ld(ctx, OPC_LHU, rt, rs, s);
21443                    break;
21444                case NM_SBS9:
21445                    gen_st(ctx, OPC_SB, rt, rs, s);
21446                    break;
21447                case NM_SHS9:
21448                    gen_st(ctx, OPC_SH, rt, rs, s);
21449                    break;
21450                case NM_SWS9:
21451                    gen_st(ctx, OPC_SW, rt, rs, s);
21452                    break;
21453                case NM_LWC1S9:
21454                    gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21455                    break;
21456                case NM_LDC1S9:
21457                    gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21458                    break;
21459                case NM_SWC1S9:
21460                    gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21461                    break;
21462                case NM_SDC1S9:
21463                    gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21464                    break;
21465                case NM_P_PREFS9:
21466                    if (rt == 31) {
21467                        /* SYNCI */
21468                        /* Break the TB to be able to sync copied instructions
21469                           immediately */
21470                        ctx->base.is_jmp = DISAS_STOP;
21471                    } else {
21472                        /* PREF */
21473                        /* Treat as NOP. */
21474                    }
21475                    break;
21476                default:
21477                    generate_exception_end(ctx, EXCP_RI);
21478                    break;
21479                }
21480                break;
21481            case NM_P_LS_S1:
21482                switch (extract32(ctx->opcode, 11, 4)) {
21483                case NM_UALH:
21484                case NM_UASH:
21485                    check_nms(ctx);
21486                    {
21487                        TCGv t0 = tcg_temp_new();
21488                        TCGv t1 = tcg_temp_new();
21489
21490                        gen_base_offset_addr(ctx, t0, rs, s);
21491
21492                        switch (extract32(ctx->opcode, 11, 4)) {
21493                        case NM_UALH:
21494                            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21495                                               MO_UNALN);
21496                            gen_store_gpr(t0, rt);
21497                            break;
21498                        case NM_UASH:
21499                            gen_load_gpr(t1, rt);
21500                            tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21501                                               MO_UNALN);
21502                            break;
21503                        }
21504                        tcg_temp_free(t0);
21505                        tcg_temp_free(t1);
21506                    }
21507                    break;
21508                case NM_P_LL:
21509                    switch (ctx->opcode & 0x03) {
21510                    case NM_LL:
21511                        gen_ld(ctx, OPC_LL, rt, rs, s);
21512                        break;
21513                    case NM_LLWP:
21514                        check_xnp(ctx);
21515                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21516                        break;
21517                    }
21518                    break;
21519                case NM_P_SC:
21520                    switch (ctx->opcode & 0x03) {
21521                    case NM_SC:
21522                        gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21523                        break;
21524                    case NM_SCWP:
21525                        check_xnp(ctx);
21526                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21527                                 false);
21528                        break;
21529                    }
21530                    break;
21531                case NM_CACHE:
21532                    check_cp0_enabled(ctx);
21533                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21534                        gen_cache_operation(ctx, rt, rs, s);
21535                    }
21536                    break;
21537                }
21538                break;
21539            case NM_P_LS_E0:
21540                switch (extract32(ctx->opcode, 11, 4)) {
21541                case NM_LBE:
21542                    check_eva(ctx);
21543                    check_cp0_enabled(ctx);
21544                    gen_ld(ctx, OPC_LBE, rt, rs, s);
21545                    break;
21546                case NM_SBE:
21547                    check_eva(ctx);
21548                    check_cp0_enabled(ctx);
21549                    gen_st(ctx, OPC_SBE, rt, rs, s);
21550                    break;
21551                case NM_LBUE:
21552                    check_eva(ctx);
21553                    check_cp0_enabled(ctx);
21554                    gen_ld(ctx, OPC_LBUE, rt, rs, s);
21555                    break;
21556                case NM_P_PREFE:
21557                    if (rt == 31) {
21558                        /* case NM_SYNCIE */
21559                        check_eva(ctx);
21560                        check_cp0_enabled(ctx);
21561                        /* Break the TB to be able to sync copied instructions
21562                           immediately */
21563                        ctx->base.is_jmp = DISAS_STOP;
21564                    } else {
21565                        /* case NM_PREFE */
21566                        check_eva(ctx);
21567                        check_cp0_enabled(ctx);
21568                        /* Treat as NOP. */
21569                    }
21570                    break;
21571                case NM_LHE:
21572                    check_eva(ctx);
21573                    check_cp0_enabled(ctx);
21574                    gen_ld(ctx, OPC_LHE, rt, rs, s);
21575                    break;
21576                case NM_SHE:
21577                    check_eva(ctx);
21578                    check_cp0_enabled(ctx);
21579                    gen_st(ctx, OPC_SHE, rt, rs, s);
21580                    break;
21581                case NM_LHUE:
21582                    check_eva(ctx);
21583                    check_cp0_enabled(ctx);
21584                    gen_ld(ctx, OPC_LHUE, rt, rs, s);
21585                    break;
21586                case NM_CACHEE:
21587                    check_nms_dl_il_sl_tl_l2c(ctx);
21588                    gen_cache_operation(ctx, rt, rs, s);
21589                    break;
21590                case NM_LWE:
21591                    check_eva(ctx);
21592                    check_cp0_enabled(ctx);
21593                    gen_ld(ctx, OPC_LWE, rt, rs, s);
21594                    break;
21595                case NM_SWE:
21596                    check_eva(ctx);
21597                    check_cp0_enabled(ctx);
21598                    gen_st(ctx, OPC_SWE, rt, rs, s);
21599                    break;
21600                case NM_P_LLE:
21601                    switch (extract32(ctx->opcode, 2, 2)) {
21602                    case NM_LLE:
21603                        check_xnp(ctx);
21604                        check_eva(ctx);
21605                        check_cp0_enabled(ctx);
21606                        gen_ld(ctx, OPC_LLE, rt, rs, s);
21607                        break;
21608                    case NM_LLWPE:
21609                        check_xnp(ctx);
21610                        check_eva(ctx);
21611                        check_cp0_enabled(ctx);
21612                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21613                        break;
21614                    default:
21615                        generate_exception_end(ctx, EXCP_RI);
21616                        break;
21617                    }
21618                    break;
21619                case NM_P_SCE:
21620                    switch (extract32(ctx->opcode, 2, 2)) {
21621                    case NM_SCE:
21622                        check_xnp(ctx);
21623                        check_eva(ctx);
21624                        check_cp0_enabled(ctx);
21625                        gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21626                        break;
21627                    case NM_SCWPE:
21628                        check_xnp(ctx);
21629                        check_eva(ctx);
21630                        check_cp0_enabled(ctx);
21631                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21632                                 true);
21633                        break;
21634                    default:
21635                        generate_exception_end(ctx, EXCP_RI);
21636                        break;
21637                    }
21638                    break;
21639                }
21640                break;
21641            case NM_P_LS_WM:
21642            case NM_P_LS_UAWM:
21643                check_nms(ctx);
21644                {
21645                    int count = extract32(ctx->opcode, 12, 3);
21646                    int counter = 0;
21647
21648                    offset = sextract32(ctx->opcode, 15, 1) << 8 |
21649                             extract32(ctx->opcode, 0, 8);
21650                    TCGv va = tcg_temp_new();
21651                    TCGv t1 = tcg_temp_new();
21652                    TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21653                                      NM_P_LS_UAWM ? MO_UNALN : 0;
21654
21655                    count = (count == 0) ? 8 : count;
21656                    while (counter != count) {
21657                        int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21658                        int this_offset = offset + (counter << 2);
21659
21660                        gen_base_offset_addr(ctx, va, rs, this_offset);
21661
21662                        switch (extract32(ctx->opcode, 11, 1)) {
21663                        case NM_LWM:
21664                            tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21665                                               memop | MO_TESL);
21666                            gen_store_gpr(t1, this_rt);
21667                            if ((this_rt == rs) &&
21668                                (counter != (count - 1))) {
21669                                /* UNPREDICTABLE */
21670                            }
21671                            break;
21672                        case NM_SWM:
21673                            this_rt = (rt == 0) ? 0 : this_rt;
21674                            gen_load_gpr(t1, this_rt);
21675                            tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21676                                               memop | MO_TEUL);
21677                            break;
21678                        }
21679                        counter++;
21680                    }
21681                    tcg_temp_free(va);
21682                    tcg_temp_free(t1);
21683                }
21684                break;
21685            default:
21686                generate_exception_end(ctx, EXCP_RI);
21687                break;
21688            }
21689        }
21690        break;
21691    case NM_MOVE_BALC:
21692        check_nms(ctx);
21693        {
21694            TCGv t0 = tcg_temp_new();
21695            int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21696                        extract32(ctx->opcode, 1, 20) << 1;
21697            rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21698            rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21699                            extract32(ctx->opcode, 21, 3));
21700            gen_load_gpr(t0, rt);
21701            tcg_gen_mov_tl(cpu_gpr[rd], t0);
21702            gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21703            tcg_temp_free(t0);
21704        }
21705        break;
21706    case NM_P_BAL:
21707        {
21708            int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21709                        extract32(ctx->opcode, 1, 24) << 1;
21710
21711            if ((extract32(ctx->opcode, 25, 1)) == 0) {
21712                /* BC */
21713                gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21714            } else {
21715                /* BALC */
21716                gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21717            }
21718        }
21719        break;
21720    case NM_P_J:
21721        switch (extract32(ctx->opcode, 12, 4)) {
21722        case NM_JALRC:
21723        case NM_JALRC_HB:
21724            gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21725            break;
21726        case NM_P_BALRSC:
21727            gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21728            break;
21729        default:
21730            generate_exception_end(ctx, EXCP_RI);
21731            break;
21732        }
21733        break;
21734    case NM_P_BR1:
21735        {
21736            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21737                        extract32(ctx->opcode, 1, 13) << 1;
21738            switch (extract32(ctx->opcode, 14, 2)) {
21739            case NM_BEQC:
21740                check_nms(ctx);
21741                gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21742                break;
21743            case NM_P_BR3A:
21744                s = sextract32(ctx->opcode, 0, 1) << 14 |
21745                    extract32(ctx->opcode, 1, 13) << 1;
21746                check_cp1_enabled(ctx);
21747                switch (extract32(ctx->opcode, 16, 5)) {
21748                case NM_BC1EQZC:
21749                    gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21750                    break;
21751                case NM_BC1NEZC:
21752                    gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21753                    break;
21754                case NM_BPOSGE32C:
21755                    check_dsp_r3(ctx);
21756                    {
21757                        int32_t imm = extract32(ctx->opcode, 1, 13) |
21758                                      extract32(ctx->opcode, 0, 1) << 13;
21759
21760                        gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21761                                              imm);
21762                    }
21763                    break;
21764                default:
21765                    generate_exception_end(ctx, EXCP_RI);
21766                    break;
21767                }
21768                break;
21769            case NM_BGEC:
21770                if (rs == rt) {
21771                    gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21772                } else {
21773                    gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21774                }
21775                break;
21776            case NM_BGEUC:
21777                if (rs == rt || rt == 0) {
21778                    gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21779                } else if (rs == 0) {
21780                    gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21781                } else {
21782                    gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21783                }
21784                break;
21785            }
21786        }
21787        break;
21788    case NM_P_BR2:
21789        {
21790            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21791                        extract32(ctx->opcode, 1, 13) << 1;
21792            switch (extract32(ctx->opcode, 14, 2)) {
21793            case NM_BNEC:
21794                check_nms(ctx);
21795                gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21796                break;
21797            case NM_BLTC:
21798                if (rs != 0 && rt != 0 && rs == rt) {
21799                    /* NOP */
21800                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21801                } else {
21802                    gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21803                }
21804                break;
21805            case NM_BLTUC:
21806                if (rs == 0 || rs == rt) {
21807                    /* NOP */
21808                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21809                } else {
21810                    gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21811                }
21812                break;
21813            default:
21814                generate_exception_end(ctx, EXCP_RI);
21815                break;
21816            }
21817        }
21818        break;
21819    case NM_P_BRI:
21820        {
21821            int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21822                        extract32(ctx->opcode, 1, 10) << 1;
21823            uint32_t u = extract32(ctx->opcode, 11, 7);
21824
21825            gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21826                                   rt, u, s);
21827        }
21828        break;
21829    default:
21830        generate_exception_end(ctx, EXCP_RI);
21831        break;
21832    }
21833    return 4;
21834}
21835
21836static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21837{
21838    uint32_t op;
21839    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
21840    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
21841    int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
21842    int offset;
21843    int imm;
21844
21845    /* make sure instructions are on a halfword boundary */
21846    if (ctx->base.pc_next & 0x1) {
21847        TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21848        tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21849        tcg_temp_free(tmp);
21850        generate_exception_end(ctx, EXCP_AdEL);
21851        return 2;
21852    }
21853
21854    op = extract32(ctx->opcode, 10, 6);
21855    switch (op) {
21856    case NM_P16_MV:
21857        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21858        if (rt != 0) {
21859            /* MOVE */
21860            rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21861            gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21862        } else {
21863            /* P16.RI */
21864            switch (extract32(ctx->opcode, 3, 2)) {
21865            case NM_P16_SYSCALL:
21866                if (extract32(ctx->opcode, 2, 1) == 0) {
21867                    generate_exception_end(ctx, EXCP_SYSCALL);
21868                } else {
21869                    generate_exception_end(ctx, EXCP_RI);
21870                }
21871                break;
21872            case NM_BREAK16:
21873                generate_exception_end(ctx, EXCP_BREAK);
21874                break;
21875            case NM_SDBBP16:
21876                if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21877                    gen_helper_do_semihosting(cpu_env);
21878                } else {
21879                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
21880                        generate_exception_end(ctx, EXCP_RI);
21881                    } else {
21882                        generate_exception_end(ctx, EXCP_DBp);
21883                    }
21884                }
21885                break;
21886            default:
21887                generate_exception_end(ctx, EXCP_RI);
21888                break;
21889            }
21890        }
21891        break;
21892    case NM_P16_SHIFT:
21893        {
21894            int shift = extract32(ctx->opcode, 0, 3);
21895            uint32_t opc = 0;
21896            shift = (shift == 0) ? 8 : shift;
21897
21898            switch (extract32(ctx->opcode, 3, 1)) {
21899            case NM_SLL16:
21900                opc = OPC_SLL;
21901                break;
21902            case NM_SRL16:
21903                opc = OPC_SRL;
21904                break;
21905            }
21906            gen_shift_imm(ctx, opc, rt, rs, shift);
21907        }
21908        break;
21909    case NM_P16C:
21910        switch (ctx->opcode & 1) {
21911        case NM_POOL16C_0:
21912            gen_pool16c_nanomips_insn(ctx);
21913            break;
21914        case NM_LWXS16:
21915            gen_ldxs(ctx, rt, rs, rd);
21916            break;
21917        }
21918        break;
21919    case NM_P16_A1:
21920        switch (extract32(ctx->opcode, 6, 1)) {
21921        case NM_ADDIUR1SP:
21922            imm = extract32(ctx->opcode, 0, 6) << 2;
21923            gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21924            break;
21925        default:
21926            generate_exception_end(ctx, EXCP_RI);
21927            break;
21928        }
21929        break;
21930    case NM_P16_A2:
21931        switch (extract32(ctx->opcode, 3, 1)) {
21932        case NM_ADDIUR2:
21933            imm = extract32(ctx->opcode, 0, 3) << 2;
21934            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21935            break;
21936        case NM_P_ADDIURS5:
21937            rt = extract32(ctx->opcode, 5, 5);
21938            if (rt != 0) {
21939                /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21940                imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21941                      (extract32(ctx->opcode, 0, 3));
21942                gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21943            }
21944            break;
21945        }
21946        break;
21947    case NM_P16_ADDU:
21948        switch (ctx->opcode & 0x1) {
21949        case NM_ADDU16:
21950            gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21951            break;
21952        case NM_SUBU16:
21953            gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21954            break;
21955        }
21956        break;
21957    case NM_P16_4X4:
21958        rt = (extract32(ctx->opcode, 9, 1) << 3) |
21959              extract32(ctx->opcode, 5, 3);
21960        rs = (extract32(ctx->opcode, 4, 1) << 3) |
21961              extract32(ctx->opcode, 0, 3);
21962        rt = decode_gpr_gpr4(rt);
21963        rs = decode_gpr_gpr4(rs);
21964        switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21965                (extract32(ctx->opcode, 3, 1))) {
21966        case NM_ADDU4X4:
21967            check_nms(ctx);
21968            gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21969            break;
21970        case NM_MUL4X4:
21971            check_nms(ctx);
21972            gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21973            break;
21974        default:
21975            generate_exception_end(ctx, EXCP_RI);
21976            break;
21977        }
21978        break;
21979    case NM_LI16:
21980        {
21981            int imm = extract32(ctx->opcode, 0, 7);
21982            imm = (imm == 0x7f ? -1 : imm);
21983            if (rt != 0) {
21984                tcg_gen_movi_tl(cpu_gpr[rt], imm);
21985            }
21986        }
21987        break;
21988    case NM_ANDI16:
21989        {
21990            uint32_t u = extract32(ctx->opcode, 0, 4);
21991            u = (u == 12) ? 0xff :
21992                (u == 13) ? 0xffff : u;
21993            gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21994        }
21995        break;
21996    case NM_P16_LB:
21997        offset = extract32(ctx->opcode, 0, 2);
21998        switch (extract32(ctx->opcode, 2, 2)) {
21999        case NM_LB16:
22000            gen_ld(ctx, OPC_LB, rt, rs, offset);
22001            break;
22002        case NM_SB16:
22003            rt = decode_gpr_gpr3_src_store(
22004                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22005            gen_st(ctx, OPC_SB, rt, rs, offset);
22006            break;
22007        case NM_LBU16:
22008            gen_ld(ctx, OPC_LBU, rt, rs, offset);
22009            break;
22010        default:
22011            generate_exception_end(ctx, EXCP_RI);
22012            break;
22013        }
22014        break;
22015    case NM_P16_LH:
22016        offset = extract32(ctx->opcode, 1, 2) << 1;
22017        switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22018        case NM_LH16:
22019            gen_ld(ctx, OPC_LH, rt, rs, offset);
22020            break;
22021        case NM_SH16:
22022            rt = decode_gpr_gpr3_src_store(
22023                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
22024            gen_st(ctx, OPC_SH, rt, rs, offset);
22025            break;
22026        case NM_LHU16:
22027            gen_ld(ctx, OPC_LHU, rt, rs, offset);
22028            break;
22029        default:
22030            generate_exception_end(ctx, EXCP_RI);
22031            break;
22032        }
22033        break;
22034    case NM_LW16:
22035        offset = extract32(ctx->opcode, 0, 4) << 2;
22036        gen_ld(ctx, OPC_LW, rt, rs, offset);
22037        break;
22038    case NM_LWSP16:
22039        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22040        offset = extract32(ctx->opcode, 0, 5) << 2;
22041        gen_ld(ctx, OPC_LW, rt, 29, offset);
22042        break;
22043    case NM_LW4X4:
22044        check_nms(ctx);
22045        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22046             extract32(ctx->opcode, 5, 3);
22047        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22048             extract32(ctx->opcode, 0, 3);
22049        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22050                 (extract32(ctx->opcode, 8, 1) << 2);
22051        rt = decode_gpr_gpr4(rt);
22052        rs = decode_gpr_gpr4(rs);
22053        gen_ld(ctx, OPC_LW, rt, rs, offset);
22054        break;
22055    case NM_SW4X4:
22056        check_nms(ctx);
22057        rt = (extract32(ctx->opcode, 9, 1) << 3) |
22058             extract32(ctx->opcode, 5, 3);
22059        rs = (extract32(ctx->opcode, 4, 1) << 3) |
22060             extract32(ctx->opcode, 0, 3);
22061        offset = (extract32(ctx->opcode, 3, 1) << 3) |
22062                 (extract32(ctx->opcode, 8, 1) << 2);
22063        rt = decode_gpr_gpr4_zero(rt);
22064        rs = decode_gpr_gpr4(rs);
22065        gen_st(ctx, OPC_SW, rt, rs, offset);
22066        break;
22067    case NM_LWGP16:
22068        offset = extract32(ctx->opcode, 0, 7) << 2;
22069        gen_ld(ctx, OPC_LW, rt, 28, offset);
22070        break;
22071    case NM_SWSP16:
22072        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22073        offset = extract32(ctx->opcode, 0, 5) << 2;
22074        gen_st(ctx, OPC_SW, rt, 29, offset);
22075        break;
22076    case NM_SW16:
22077        rt = decode_gpr_gpr3_src_store(
22078                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22079        rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22080        offset = extract32(ctx->opcode, 0, 4) << 2;
22081        gen_st(ctx, OPC_SW, rt, rs, offset);
22082        break;
22083    case NM_SWGP16:
22084        rt = decode_gpr_gpr3_src_store(
22085                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22086        offset = extract32(ctx->opcode, 0, 7) << 2;
22087        gen_st(ctx, OPC_SW, rt, 28, offset);
22088        break;
22089    case NM_BC16:
22090        gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22091                           (sextract32(ctx->opcode, 0, 1) << 10) |
22092                           (extract32(ctx->opcode, 1, 9) << 1));
22093        break;
22094    case NM_BALC16:
22095        gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22096                           (sextract32(ctx->opcode, 0, 1) << 10) |
22097                           (extract32(ctx->opcode, 1, 9) << 1));
22098        break;
22099    case NM_BEQZC16:
22100        gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22101                           (sextract32(ctx->opcode, 0, 1) << 7) |
22102                           (extract32(ctx->opcode, 1, 6) << 1));
22103        break;
22104    case NM_BNEZC16:
22105        gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22106                           (sextract32(ctx->opcode, 0, 1) << 7) |
22107                           (extract32(ctx->opcode, 1, 6) << 1));
22108        break;
22109    case NM_P16_BR:
22110        switch (ctx->opcode & 0xf) {
22111        case 0:
22112            /* P16.JRC */
22113            switch (extract32(ctx->opcode, 4, 1)) {
22114            case NM_JRC:
22115                gen_compute_branch_nm(ctx, OPC_JR, 2,
22116                                   extract32(ctx->opcode, 5, 5), 0, 0);
22117                break;
22118            case NM_JALRC16:
22119                gen_compute_branch_nm(ctx, OPC_JALR, 2,
22120                                   extract32(ctx->opcode, 5, 5), 31, 0);
22121                break;
22122            }
22123            break;
22124        default:
22125            {
22126                /* P16.BRI */
22127                uint32_t opc = extract32(ctx->opcode, 4, 3) <
22128                               extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22129                gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22130                                   extract32(ctx->opcode, 0, 4) << 1);
22131            }
22132            break;
22133        }
22134        break;
22135    case NM_P16_SR:
22136        {
22137            int count = extract32(ctx->opcode, 0, 4);
22138            int u = extract32(ctx->opcode, 4, 4) << 4;
22139
22140            rt = 30 + extract32(ctx->opcode, 9, 1);
22141            switch (extract32(ctx->opcode, 8, 1)) {
22142            case NM_SAVE16:
22143                gen_save(ctx, rt, count, 0, u);
22144                break;
22145            case NM_RESTORE_JRC16:
22146                gen_restore(ctx, rt, count, 0, u);
22147                gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22148                break;
22149            }
22150        }
22151        break;
22152    case NM_MOVEP:
22153    case NM_MOVEPREV:
22154        check_nms(ctx);
22155        {
22156            static const int gpr2reg1[] = {4, 5, 6, 7};
22157            static const int gpr2reg2[] = {5, 6, 7, 8};
22158            int re;
22159            int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22160                      extract32(ctx->opcode, 8, 1);
22161            int r1 = gpr2reg1[rd2];
22162            int r2 = gpr2reg2[rd2];
22163            int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22164                     extract32(ctx->opcode, 0, 3);
22165            int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22166                     extract32(ctx->opcode, 5, 3);
22167            TCGv t0 = tcg_temp_new();
22168            TCGv t1 = tcg_temp_new();
22169            if (op == NM_MOVEP) {
22170                rd = r1;
22171                re = r2;
22172                rs = decode_gpr_gpr4_zero(r3);
22173                rt = decode_gpr_gpr4_zero(r4);
22174            } else {
22175                rd = decode_gpr_gpr4(r3);
22176                re = decode_gpr_gpr4(r4);
22177                rs = r1;
22178                rt = r2;
22179            }
22180            gen_load_gpr(t0, rs);
22181            gen_load_gpr(t1, rt);
22182            tcg_gen_mov_tl(cpu_gpr[rd], t0);
22183            tcg_gen_mov_tl(cpu_gpr[re], t1);
22184            tcg_temp_free(t0);
22185            tcg_temp_free(t1);
22186        }
22187        break;
22188    default:
22189        return decode_nanomips_32_48_opc(env, ctx);
22190    }
22191
22192    return 2;
22193}
22194
22195
22196/* SmartMIPS extension to MIPS32 */
22197
22198#if defined(TARGET_MIPS64)
22199
22200/* MDMX extension to MIPS64 */
22201
22202#endif
22203
22204/* MIPSDSP functions. */
22205static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22206                           int rd, int base, int offset)
22207{
22208    TCGv t0;
22209
22210    check_dsp(ctx);
22211    t0 = tcg_temp_new();
22212
22213    if (base == 0) {
22214        gen_load_gpr(t0, offset);
22215    } else if (offset == 0) {
22216        gen_load_gpr(t0, base);
22217    } else {
22218        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22219    }
22220
22221    switch (opc) {
22222    case OPC_LBUX:
22223        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22224        gen_store_gpr(t0, rd);
22225        break;
22226    case OPC_LHX:
22227        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22228        gen_store_gpr(t0, rd);
22229        break;
22230    case OPC_LWX:
22231        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22232        gen_store_gpr(t0, rd);
22233        break;
22234#if defined(TARGET_MIPS64)
22235    case OPC_LDX:
22236        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22237        gen_store_gpr(t0, rd);
22238        break;
22239#endif
22240    }
22241    tcg_temp_free(t0);
22242}
22243
22244static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22245                              int ret, int v1, int v2)
22246{
22247    TCGv v1_t;
22248    TCGv v2_t;
22249
22250    if (ret == 0) {
22251        /* Treat as NOP. */
22252        return;
22253    }
22254
22255    v1_t = tcg_temp_new();
22256    v2_t = tcg_temp_new();
22257
22258    gen_load_gpr(v1_t, v1);
22259    gen_load_gpr(v2_t, v2);
22260
22261    switch (op1) {
22262    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22263    case OPC_MULT_G_2E:
22264        check_dsp_r2(ctx);
22265        switch (op2) {
22266        case OPC_ADDUH_QB:
22267            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22268            break;
22269        case OPC_ADDUH_R_QB:
22270            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22271            break;
22272        case OPC_ADDQH_PH:
22273            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22274            break;
22275        case OPC_ADDQH_R_PH:
22276            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22277            break;
22278        case OPC_ADDQH_W:
22279            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22280            break;
22281        case OPC_ADDQH_R_W:
22282            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22283            break;
22284        case OPC_SUBUH_QB:
22285            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22286            break;
22287        case OPC_SUBUH_R_QB:
22288            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22289            break;
22290        case OPC_SUBQH_PH:
22291            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22292            break;
22293        case OPC_SUBQH_R_PH:
22294            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22295            break;
22296        case OPC_SUBQH_W:
22297            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22298            break;
22299        case OPC_SUBQH_R_W:
22300            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22301            break;
22302        }
22303        break;
22304    case OPC_ABSQ_S_PH_DSP:
22305        switch (op2) {
22306        case OPC_ABSQ_S_QB:
22307            check_dsp_r2(ctx);
22308            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22309            break;
22310        case OPC_ABSQ_S_PH:
22311            check_dsp(ctx);
22312            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22313            break;
22314        case OPC_ABSQ_S_W:
22315            check_dsp(ctx);
22316            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22317            break;
22318        case OPC_PRECEQ_W_PHL:
22319            check_dsp(ctx);
22320            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22321            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22322            break;
22323        case OPC_PRECEQ_W_PHR:
22324            check_dsp(ctx);
22325            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22326            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22327            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22328            break;
22329        case OPC_PRECEQU_PH_QBL:
22330            check_dsp(ctx);
22331            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22332            break;
22333        case OPC_PRECEQU_PH_QBR:
22334            check_dsp(ctx);
22335            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22336            break;
22337        case OPC_PRECEQU_PH_QBLA:
22338            check_dsp(ctx);
22339            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22340            break;
22341        case OPC_PRECEQU_PH_QBRA:
22342            check_dsp(ctx);
22343            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22344            break;
22345        case OPC_PRECEU_PH_QBL:
22346            check_dsp(ctx);
22347            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22348            break;
22349        case OPC_PRECEU_PH_QBR:
22350            check_dsp(ctx);
22351            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22352            break;
22353        case OPC_PRECEU_PH_QBLA:
22354            check_dsp(ctx);
22355            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22356            break;
22357        case OPC_PRECEU_PH_QBRA:
22358            check_dsp(ctx);
22359            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22360            break;
22361        }
22362        break;
22363    case OPC_ADDU_QB_DSP:
22364        switch (op2) {
22365        case OPC_ADDQ_PH:
22366            check_dsp(ctx);
22367            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22368            break;
22369        case OPC_ADDQ_S_PH:
22370            check_dsp(ctx);
22371            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22372            break;
22373        case OPC_ADDQ_S_W:
22374            check_dsp(ctx);
22375            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22376            break;
22377        case OPC_ADDU_QB:
22378            check_dsp(ctx);
22379            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22380            break;
22381        case OPC_ADDU_S_QB:
22382            check_dsp(ctx);
22383            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22384            break;
22385        case OPC_ADDU_PH:
22386            check_dsp_r2(ctx);
22387            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22388            break;
22389        case OPC_ADDU_S_PH:
22390            check_dsp_r2(ctx);
22391            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22392            break;
22393        case OPC_SUBQ_PH:
22394            check_dsp(ctx);
22395            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22396            break;
22397        case OPC_SUBQ_S_PH:
22398            check_dsp(ctx);
22399            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22400            break;
22401        case OPC_SUBQ_S_W:
22402            check_dsp(ctx);
22403            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22404            break;
22405        case OPC_SUBU_QB:
22406            check_dsp(ctx);
22407            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22408            break;
22409        case OPC_SUBU_S_QB:
22410            check_dsp(ctx);
22411            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22412            break;
22413        case OPC_SUBU_PH:
22414            check_dsp_r2(ctx);
22415            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22416            break;
22417        case OPC_SUBU_S_PH:
22418            check_dsp_r2(ctx);
22419            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22420            break;
22421        case OPC_ADDSC:
22422            check_dsp(ctx);
22423            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22424            break;
22425        case OPC_ADDWC:
22426            check_dsp(ctx);
22427            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22428            break;
22429        case OPC_MODSUB:
22430            check_dsp(ctx);
22431            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22432            break;
22433        case OPC_RADDU_W_QB:
22434            check_dsp(ctx);
22435            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22436            break;
22437        }
22438        break;
22439    case OPC_CMPU_EQ_QB_DSP:
22440        switch (op2) {
22441        case OPC_PRECR_QB_PH:
22442            check_dsp_r2(ctx);
22443            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22444            break;
22445        case OPC_PRECRQ_QB_PH:
22446            check_dsp(ctx);
22447            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22448            break;
22449        case OPC_PRECR_SRA_PH_W:
22450            check_dsp_r2(ctx);
22451            {
22452                TCGv_i32 sa_t = tcg_const_i32(v2);
22453                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22454                                          cpu_gpr[ret]);
22455                tcg_temp_free_i32(sa_t);
22456                break;
22457            }
22458        case OPC_PRECR_SRA_R_PH_W:
22459            check_dsp_r2(ctx);
22460            {
22461                TCGv_i32 sa_t = tcg_const_i32(v2);
22462                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22463                                            cpu_gpr[ret]);
22464                tcg_temp_free_i32(sa_t);
22465                break;
22466            }
22467        case OPC_PRECRQ_PH_W:
22468            check_dsp(ctx);
22469            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22470            break;
22471        case OPC_PRECRQ_RS_PH_W:
22472            check_dsp(ctx);
22473            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22474            break;
22475        case OPC_PRECRQU_S_QB_PH:
22476            check_dsp(ctx);
22477            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22478            break;
22479        }
22480        break;
22481#ifdef TARGET_MIPS64
22482    case OPC_ABSQ_S_QH_DSP:
22483        switch (op2) {
22484        case OPC_PRECEQ_L_PWL:
22485            check_dsp(ctx);
22486            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22487            break;
22488        case OPC_PRECEQ_L_PWR:
22489            check_dsp(ctx);
22490            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22491            break;
22492        case OPC_PRECEQ_PW_QHL:
22493            check_dsp(ctx);
22494            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22495            break;
22496        case OPC_PRECEQ_PW_QHR:
22497            check_dsp(ctx);
22498            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22499            break;
22500        case OPC_PRECEQ_PW_QHLA:
22501            check_dsp(ctx);
22502            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22503            break;
22504        case OPC_PRECEQ_PW_QHRA:
22505            check_dsp(ctx);
22506            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22507            break;
22508        case OPC_PRECEQU_QH_OBL:
22509            check_dsp(ctx);
22510            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22511            break;
22512        case OPC_PRECEQU_QH_OBR:
22513            check_dsp(ctx);
22514            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22515            break;
22516        case OPC_PRECEQU_QH_OBLA:
22517            check_dsp(ctx);
22518            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22519            break;
22520        case OPC_PRECEQU_QH_OBRA:
22521            check_dsp(ctx);
22522            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22523            break;
22524        case OPC_PRECEU_QH_OBL:
22525            check_dsp(ctx);
22526            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22527            break;
22528        case OPC_PRECEU_QH_OBR:
22529            check_dsp(ctx);
22530            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22531            break;
22532        case OPC_PRECEU_QH_OBLA:
22533            check_dsp(ctx);
22534            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22535            break;
22536        case OPC_PRECEU_QH_OBRA:
22537            check_dsp(ctx);
22538            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22539            break;
22540        case OPC_ABSQ_S_OB:
22541            check_dsp_r2(ctx);
22542            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22543            break;
22544        case OPC_ABSQ_S_PW:
22545            check_dsp(ctx);
22546            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22547            break;
22548        case OPC_ABSQ_S_QH:
22549            check_dsp(ctx);
22550            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22551            break;
22552        }
22553        break;
22554    case OPC_ADDU_OB_DSP:
22555        switch (op2) {
22556        case OPC_RADDU_L_OB:
22557            check_dsp(ctx);
22558            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22559            break;
22560        case OPC_SUBQ_PW:
22561            check_dsp(ctx);
22562            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22563            break;
22564        case OPC_SUBQ_S_PW:
22565            check_dsp(ctx);
22566            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22567            break;
22568        case OPC_SUBQ_QH:
22569            check_dsp(ctx);
22570            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22571            break;
22572        case OPC_SUBQ_S_QH:
22573            check_dsp(ctx);
22574            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22575            break;
22576        case OPC_SUBU_OB:
22577            check_dsp(ctx);
22578            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22579            break;
22580        case OPC_SUBU_S_OB:
22581            check_dsp(ctx);
22582            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22583            break;
22584        case OPC_SUBU_QH:
22585            check_dsp_r2(ctx);
22586            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22587            break;
22588        case OPC_SUBU_S_QH:
22589            check_dsp_r2(ctx);
22590            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22591            break;
22592        case OPC_SUBUH_OB:
22593            check_dsp_r2(ctx);
22594            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22595            break;
22596        case OPC_SUBUH_R_OB:
22597            check_dsp_r2(ctx);
22598            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22599            break;
22600        case OPC_ADDQ_PW:
22601            check_dsp(ctx);
22602            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22603            break;
22604        case OPC_ADDQ_S_PW:
22605            check_dsp(ctx);
22606            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22607            break;
22608        case OPC_ADDQ_QH:
22609            check_dsp(ctx);
22610            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22611            break;
22612        case OPC_ADDQ_S_QH:
22613            check_dsp(ctx);
22614            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22615            break;
22616        case OPC_ADDU_OB:
22617            check_dsp(ctx);
22618            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22619            break;
22620        case OPC_ADDU_S_OB:
22621            check_dsp(ctx);
22622            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22623            break;
22624        case OPC_ADDU_QH:
22625            check_dsp_r2(ctx);
22626            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22627            break;
22628        case OPC_ADDU_S_QH:
22629            check_dsp_r2(ctx);
22630            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22631            break;
22632        case OPC_ADDUH_OB:
22633            check_dsp_r2(ctx);
22634            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22635            break;
22636        case OPC_ADDUH_R_OB:
22637            check_dsp_r2(ctx);
22638            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22639            break;
22640        }
22641        break;
22642    case OPC_CMPU_EQ_OB_DSP:
22643        switch (op2) {
22644        case OPC_PRECR_OB_QH:
22645            check_dsp_r2(ctx);
22646            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22647            break;
22648        case OPC_PRECR_SRA_QH_PW:
22649            check_dsp_r2(ctx);
22650            {
22651                TCGv_i32 ret_t = tcg_const_i32(ret);
22652                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22653                tcg_temp_free_i32(ret_t);
22654                break;
22655            }
22656        case OPC_PRECR_SRA_R_QH_PW:
22657            check_dsp_r2(ctx);
22658            {
22659                TCGv_i32 sa_v = tcg_const_i32(ret);
22660                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22661                tcg_temp_free_i32(sa_v);
22662                break;
22663            }
22664        case OPC_PRECRQ_OB_QH:
22665            check_dsp(ctx);
22666            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22667            break;
22668        case OPC_PRECRQ_PW_L:
22669            check_dsp(ctx);
22670            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22671            break;
22672        case OPC_PRECRQ_QH_PW:
22673            check_dsp(ctx);
22674            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22675            break;
22676        case OPC_PRECRQ_RS_QH_PW:
22677            check_dsp(ctx);
22678            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22679            break;
22680        case OPC_PRECRQU_S_OB_QH:
22681            check_dsp(ctx);
22682            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22683            break;
22684        }
22685        break;
22686#endif
22687    }
22688
22689    tcg_temp_free(v1_t);
22690    tcg_temp_free(v2_t);
22691}
22692
22693static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22694                              int ret, int v1, int v2)
22695{
22696    uint32_t op2;
22697    TCGv t0;
22698    TCGv v1_t;
22699    TCGv v2_t;
22700
22701    if (ret == 0) {
22702        /* Treat as NOP. */
22703        return;
22704    }
22705
22706    t0 = tcg_temp_new();
22707    v1_t = tcg_temp_new();
22708    v2_t = tcg_temp_new();
22709
22710    tcg_gen_movi_tl(t0, v1);
22711    gen_load_gpr(v1_t, v1);
22712    gen_load_gpr(v2_t, v2);
22713
22714    switch (opc) {
22715    case OPC_SHLL_QB_DSP:
22716        {
22717            op2 = MASK_SHLL_QB(ctx->opcode);
22718            switch (op2) {
22719            case OPC_SHLL_QB:
22720                check_dsp(ctx);
22721                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22722                break;
22723            case OPC_SHLLV_QB:
22724                check_dsp(ctx);
22725                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22726                break;
22727            case OPC_SHLL_PH:
22728                check_dsp(ctx);
22729                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22730                break;
22731            case OPC_SHLLV_PH:
22732                check_dsp(ctx);
22733                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22734                break;
22735            case OPC_SHLL_S_PH:
22736                check_dsp(ctx);
22737                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22738                break;
22739            case OPC_SHLLV_S_PH:
22740                check_dsp(ctx);
22741                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22742                break;
22743            case OPC_SHLL_S_W:
22744                check_dsp(ctx);
22745                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22746                break;
22747            case OPC_SHLLV_S_W:
22748                check_dsp(ctx);
22749                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22750                break;
22751            case OPC_SHRL_QB:
22752                check_dsp(ctx);
22753                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22754                break;
22755            case OPC_SHRLV_QB:
22756                check_dsp(ctx);
22757                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22758                break;
22759            case OPC_SHRL_PH:
22760                check_dsp_r2(ctx);
22761                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22762                break;
22763            case OPC_SHRLV_PH:
22764                check_dsp_r2(ctx);
22765                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22766                break;
22767            case OPC_SHRA_QB:
22768                check_dsp_r2(ctx);
22769                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22770                break;
22771            case OPC_SHRA_R_QB:
22772                check_dsp_r2(ctx);
22773                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22774                break;
22775            case OPC_SHRAV_QB:
22776                check_dsp_r2(ctx);
22777                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22778                break;
22779            case OPC_SHRAV_R_QB:
22780                check_dsp_r2(ctx);
22781                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22782                break;
22783            case OPC_SHRA_PH:
22784                check_dsp(ctx);
22785                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22786                break;
22787            case OPC_SHRA_R_PH:
22788                check_dsp(ctx);
22789                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22790                break;
22791            case OPC_SHRAV_PH:
22792                check_dsp(ctx);
22793                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22794                break;
22795            case OPC_SHRAV_R_PH:
22796                check_dsp(ctx);
22797                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22798                break;
22799            case OPC_SHRA_R_W:
22800                check_dsp(ctx);
22801                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22802                break;
22803            case OPC_SHRAV_R_W:
22804                check_dsp(ctx);
22805                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22806                break;
22807            default:            /* Invalid */
22808                MIPS_INVAL("MASK SHLL.QB");
22809                generate_exception_end(ctx, EXCP_RI);
22810                break;
22811            }
22812            break;
22813        }
22814#ifdef TARGET_MIPS64
22815    case OPC_SHLL_OB_DSP:
22816        op2 = MASK_SHLL_OB(ctx->opcode);
22817        switch (op2) {
22818        case OPC_SHLL_PW:
22819            check_dsp(ctx);
22820            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22821            break;
22822        case OPC_SHLLV_PW:
22823            check_dsp(ctx);
22824            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22825            break;
22826        case OPC_SHLL_S_PW:
22827            check_dsp(ctx);
22828            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22829            break;
22830        case OPC_SHLLV_S_PW:
22831            check_dsp(ctx);
22832            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22833            break;
22834        case OPC_SHLL_OB:
22835            check_dsp(ctx);
22836            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22837            break;
22838        case OPC_SHLLV_OB:
22839            check_dsp(ctx);
22840            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22841            break;
22842        case OPC_SHLL_QH:
22843            check_dsp(ctx);
22844            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22845            break;
22846        case OPC_SHLLV_QH:
22847            check_dsp(ctx);
22848            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22849            break;
22850        case OPC_SHLL_S_QH:
22851            check_dsp(ctx);
22852            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22853            break;
22854        case OPC_SHLLV_S_QH:
22855            check_dsp(ctx);
22856            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22857            break;
22858        case OPC_SHRA_OB:
22859            check_dsp_r2(ctx);
22860            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22861            break;
22862        case OPC_SHRAV_OB:
22863            check_dsp_r2(ctx);
22864            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22865            break;
22866        case OPC_SHRA_R_OB:
22867            check_dsp_r2(ctx);
22868            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22869            break;
22870        case OPC_SHRAV_R_OB:
22871            check_dsp_r2(ctx);
22872            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22873            break;
22874        case OPC_SHRA_PW:
22875            check_dsp(ctx);
22876            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22877            break;
22878        case OPC_SHRAV_PW:
22879            check_dsp(ctx);
22880            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22881            break;
22882        case OPC_SHRA_R_PW:
22883            check_dsp(ctx);
22884            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22885            break;
22886        case OPC_SHRAV_R_PW:
22887            check_dsp(ctx);
22888            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22889            break;
22890        case OPC_SHRA_QH:
22891            check_dsp(ctx);
22892            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22893            break;
22894        case OPC_SHRAV_QH:
22895            check_dsp(ctx);
22896            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22897            break;
22898        case OPC_SHRA_R_QH:
22899            check_dsp(ctx);
22900            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22901            break;
22902        case OPC_SHRAV_R_QH:
22903            check_dsp(ctx);
22904            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22905            break;
22906        case OPC_SHRL_OB:
22907            check_dsp(ctx);
22908            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22909            break;
22910        case OPC_SHRLV_OB:
22911            check_dsp(ctx);
22912            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22913            break;
22914        case OPC_SHRL_QH:
22915            check_dsp_r2(ctx);
22916            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22917            break;
22918        case OPC_SHRLV_QH:
22919            check_dsp_r2(ctx);
22920            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22921            break;
22922        default:            /* Invalid */
22923            MIPS_INVAL("MASK SHLL.OB");
22924            generate_exception_end(ctx, EXCP_RI);
22925            break;
22926        }
22927        break;
22928#endif
22929    }
22930
22931    tcg_temp_free(t0);
22932    tcg_temp_free(v1_t);
22933    tcg_temp_free(v2_t);
22934}
22935
22936static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22937                                 int ret, int v1, int v2, int check_ret)
22938{
22939    TCGv_i32 t0;
22940    TCGv v1_t;
22941    TCGv v2_t;
22942
22943    if ((ret == 0) && (check_ret == 1)) {
22944        /* Treat as NOP. */
22945        return;
22946    }
22947
22948    t0 = tcg_temp_new_i32();
22949    v1_t = tcg_temp_new();
22950    v2_t = tcg_temp_new();
22951
22952    tcg_gen_movi_i32(t0, ret);
22953    gen_load_gpr(v1_t, v1);
22954    gen_load_gpr(v2_t, v2);
22955
22956    switch (op1) {
22957    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22958     * the same mask and op1. */
22959    case OPC_MULT_G_2E:
22960        check_dsp_r2(ctx);
22961        switch (op2) {
22962        case  OPC_MUL_PH:
22963            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22964            break;
22965        case  OPC_MUL_S_PH:
22966            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22967            break;
22968        case OPC_MULQ_S_W:
22969            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22970            break;
22971        case OPC_MULQ_RS_W:
22972            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22973            break;
22974        }
22975        break;
22976    case OPC_DPA_W_PH_DSP:
22977        switch (op2) {
22978        case OPC_DPAU_H_QBL:
22979            check_dsp(ctx);
22980            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22981            break;
22982        case OPC_DPAU_H_QBR:
22983            check_dsp(ctx);
22984            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22985            break;
22986        case OPC_DPSU_H_QBL:
22987            check_dsp(ctx);
22988            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22989            break;
22990        case OPC_DPSU_H_QBR:
22991            check_dsp(ctx);
22992            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22993            break;
22994        case OPC_DPA_W_PH:
22995            check_dsp_r2(ctx);
22996            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22997            break;
22998        case OPC_DPAX_W_PH:
22999            check_dsp_r2(ctx);
23000            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23001            break;
23002        case OPC_DPAQ_S_W_PH:
23003            check_dsp(ctx);
23004            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23005            break;
23006        case OPC_DPAQX_S_W_PH:
23007            check_dsp_r2(ctx);
23008            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23009            break;
23010        case OPC_DPAQX_SA_W_PH:
23011            check_dsp_r2(ctx);
23012            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23013            break;
23014        case OPC_DPS_W_PH:
23015            check_dsp_r2(ctx);
23016            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23017            break;
23018        case OPC_DPSX_W_PH:
23019            check_dsp_r2(ctx);
23020            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23021            break;
23022        case OPC_DPSQ_S_W_PH:
23023            check_dsp(ctx);
23024            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23025            break;
23026        case OPC_DPSQX_S_W_PH:
23027            check_dsp_r2(ctx);
23028            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23029            break;
23030        case OPC_DPSQX_SA_W_PH:
23031            check_dsp_r2(ctx);
23032            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23033            break;
23034        case OPC_MULSAQ_S_W_PH:
23035            check_dsp(ctx);
23036            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23037            break;
23038        case OPC_DPAQ_SA_L_W:
23039            check_dsp(ctx);
23040            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23041            break;
23042        case OPC_DPSQ_SA_L_W:
23043            check_dsp(ctx);
23044            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23045            break;
23046        case OPC_MAQ_S_W_PHL:
23047            check_dsp(ctx);
23048            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23049            break;
23050        case OPC_MAQ_S_W_PHR:
23051            check_dsp(ctx);
23052            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23053            break;
23054        case OPC_MAQ_SA_W_PHL:
23055            check_dsp(ctx);
23056            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23057            break;
23058        case OPC_MAQ_SA_W_PHR:
23059            check_dsp(ctx);
23060            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23061            break;
23062        case OPC_MULSA_W_PH:
23063            check_dsp_r2(ctx);
23064            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23065            break;
23066        }
23067        break;
23068#ifdef TARGET_MIPS64
23069    case OPC_DPAQ_W_QH_DSP:
23070        {
23071            int ac = ret & 0x03;
23072            tcg_gen_movi_i32(t0, ac);
23073
23074            switch (op2) {
23075            case OPC_DMADD:
23076                check_dsp(ctx);
23077                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23078                break;
23079            case OPC_DMADDU:
23080                check_dsp(ctx);
23081                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23082                break;
23083            case OPC_DMSUB:
23084                check_dsp(ctx);
23085                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23086                break;
23087            case OPC_DMSUBU:
23088                check_dsp(ctx);
23089                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23090                break;
23091            case OPC_DPA_W_QH:
23092                check_dsp_r2(ctx);
23093                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23094                break;
23095            case OPC_DPAQ_S_W_QH:
23096                check_dsp(ctx);
23097                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23098                break;
23099            case OPC_DPAQ_SA_L_PW:
23100                check_dsp(ctx);
23101                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23102                break;
23103            case OPC_DPAU_H_OBL:
23104                check_dsp(ctx);
23105                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23106                break;
23107            case OPC_DPAU_H_OBR:
23108                check_dsp(ctx);
23109                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23110                break;
23111            case OPC_DPS_W_QH:
23112                check_dsp_r2(ctx);
23113                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23114                break;
23115            case OPC_DPSQ_S_W_QH:
23116                check_dsp(ctx);
23117                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23118                break;
23119            case OPC_DPSQ_SA_L_PW:
23120                check_dsp(ctx);
23121                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23122                break;
23123            case OPC_DPSU_H_OBL:
23124                check_dsp(ctx);
23125                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23126                break;
23127            case OPC_DPSU_H_OBR:
23128                check_dsp(ctx);
23129                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23130                break;
23131            case OPC_MAQ_S_L_PWL:
23132                check_dsp(ctx);
23133                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23134                break;
23135            case OPC_MAQ_S_L_PWR:
23136                check_dsp(ctx);
23137                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23138                break;
23139            case OPC_MAQ_S_W_QHLL:
23140                check_dsp(ctx);
23141                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23142                break;
23143            case OPC_MAQ_SA_W_QHLL:
23144                check_dsp(ctx);
23145                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23146                break;
23147            case OPC_MAQ_S_W_QHLR:
23148                check_dsp(ctx);
23149                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23150                break;
23151            case OPC_MAQ_SA_W_QHLR:
23152                check_dsp(ctx);
23153                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23154                break;
23155            case OPC_MAQ_S_W_QHRL:
23156                check_dsp(ctx);
23157                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23158                break;
23159            case OPC_MAQ_SA_W_QHRL:
23160                check_dsp(ctx);
23161                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23162                break;
23163            case OPC_MAQ_S_W_QHRR:
23164                check_dsp(ctx);
23165                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23166                break;
23167            case OPC_MAQ_SA_W_QHRR:
23168                check_dsp(ctx);
23169                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23170                break;
23171            case OPC_MULSAQ_S_L_PW:
23172                check_dsp(ctx);
23173                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23174                break;
23175            case OPC_MULSAQ_S_W_QH:
23176                check_dsp(ctx);
23177                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23178                break;
23179            }
23180        }
23181        break;
23182#endif
23183    case OPC_ADDU_QB_DSP:
23184        switch (op2) {
23185        case OPC_MULEU_S_PH_QBL:
23186            check_dsp(ctx);
23187            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23188            break;
23189        case OPC_MULEU_S_PH_QBR:
23190            check_dsp(ctx);
23191            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23192            break;
23193        case OPC_MULQ_RS_PH:
23194            check_dsp(ctx);
23195            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23196            break;
23197        case OPC_MULEQ_S_W_PHL:
23198            check_dsp(ctx);
23199            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23200            break;
23201        case OPC_MULEQ_S_W_PHR:
23202            check_dsp(ctx);
23203            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23204            break;
23205        case OPC_MULQ_S_PH:
23206            check_dsp_r2(ctx);
23207            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23208            break;
23209        }
23210        break;
23211#ifdef TARGET_MIPS64
23212    case OPC_ADDU_OB_DSP:
23213        switch (op2) {
23214        case OPC_MULEQ_S_PW_QHL:
23215            check_dsp(ctx);
23216            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23217            break;
23218        case OPC_MULEQ_S_PW_QHR:
23219            check_dsp(ctx);
23220            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23221            break;
23222        case OPC_MULEU_S_QH_OBL:
23223            check_dsp(ctx);
23224            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23225            break;
23226        case OPC_MULEU_S_QH_OBR:
23227            check_dsp(ctx);
23228            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23229            break;
23230        case OPC_MULQ_RS_QH:
23231            check_dsp(ctx);
23232            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23233            break;
23234        }
23235        break;
23236#endif
23237    }
23238
23239    tcg_temp_free_i32(t0);
23240    tcg_temp_free(v1_t);
23241    tcg_temp_free(v2_t);
23242}
23243
23244static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23245                                int ret, int val)
23246{
23247    int16_t imm;
23248    TCGv t0;
23249    TCGv val_t;
23250
23251    if (ret == 0) {
23252        /* Treat as NOP. */
23253        return;
23254    }
23255
23256    t0 = tcg_temp_new();
23257    val_t = tcg_temp_new();
23258    gen_load_gpr(val_t, val);
23259
23260    switch (op1) {
23261    case OPC_ABSQ_S_PH_DSP:
23262        switch (op2) {
23263        case OPC_BITREV:
23264            check_dsp(ctx);
23265            gen_helper_bitrev(cpu_gpr[ret], val_t);
23266            break;
23267        case OPC_REPL_QB:
23268            check_dsp(ctx);
23269            {
23270                target_long result;
23271                imm = (ctx->opcode >> 16) & 0xFF;
23272                result = (uint32_t)imm << 24 |
23273                         (uint32_t)imm << 16 |
23274                         (uint32_t)imm << 8  |
23275                         (uint32_t)imm;
23276                result = (int32_t)result;
23277                tcg_gen_movi_tl(cpu_gpr[ret], result);
23278            }
23279            break;
23280        case OPC_REPLV_QB:
23281            check_dsp(ctx);
23282            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23283            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23284            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23285            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23286            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23287            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23288            break;
23289        case OPC_REPL_PH:
23290            check_dsp(ctx);
23291            {
23292                imm = (ctx->opcode >> 16) & 0x03FF;
23293                imm = (int16_t)(imm << 6) >> 6;
23294                tcg_gen_movi_tl(cpu_gpr[ret], \
23295                                (target_long)((int32_t)imm << 16 | \
23296                                (uint16_t)imm));
23297            }
23298            break;
23299        case OPC_REPLV_PH:
23300            check_dsp(ctx);
23301            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23302            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23303            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23304            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23305            break;
23306        }
23307        break;
23308#ifdef TARGET_MIPS64
23309    case OPC_ABSQ_S_QH_DSP:
23310        switch (op2) {
23311        case OPC_REPL_OB:
23312            check_dsp(ctx);
23313            {
23314                target_long temp;
23315
23316                imm = (ctx->opcode >> 16) & 0xFF;
23317                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23318                temp = (temp << 16) | temp;
23319                temp = (temp << 32) | temp;
23320                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23321                break;
23322            }
23323        case OPC_REPL_PW:
23324            check_dsp(ctx);
23325            {
23326                target_long temp;
23327
23328                imm = (ctx->opcode >> 16) & 0x03FF;
23329                imm = (int16_t)(imm << 6) >> 6;
23330                temp = ((target_long)imm << 32) \
23331                       | ((target_long)imm & 0xFFFFFFFF);
23332                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23333                break;
23334            }
23335        case OPC_REPL_QH:
23336            check_dsp(ctx);
23337            {
23338                target_long temp;
23339
23340                imm = (ctx->opcode >> 16) & 0x03FF;
23341                imm = (int16_t)(imm << 6) >> 6;
23342
23343                temp = ((uint64_t)(uint16_t)imm << 48) |
23344                       ((uint64_t)(uint16_t)imm << 32) |
23345                       ((uint64_t)(uint16_t)imm << 16) |
23346                       (uint64_t)(uint16_t)imm;
23347                tcg_gen_movi_tl(cpu_gpr[ret], temp);
23348                break;
23349            }
23350        case OPC_REPLV_OB:
23351            check_dsp(ctx);
23352            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23353            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23354            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23355            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23356            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23357            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23358            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23359            break;
23360        case OPC_REPLV_PW:
23361            check_dsp(ctx);
23362            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23363            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23364            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23365            break;
23366        case OPC_REPLV_QH:
23367            check_dsp(ctx);
23368            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23369            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23370            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23371            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23372            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23373            break;
23374        }
23375        break;
23376#endif
23377    }
23378    tcg_temp_free(t0);
23379    tcg_temp_free(val_t);
23380}
23381
23382static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23383                                     uint32_t op1, uint32_t op2,
23384                                     int ret, int v1, int v2, int check_ret)
23385{
23386    TCGv t1;
23387    TCGv v1_t;
23388    TCGv v2_t;
23389
23390    if ((ret == 0) && (check_ret == 1)) {
23391        /* Treat as NOP. */
23392        return;
23393    }
23394
23395    t1 = tcg_temp_new();
23396    v1_t = tcg_temp_new();
23397    v2_t = tcg_temp_new();
23398
23399    gen_load_gpr(v1_t, v1);
23400    gen_load_gpr(v2_t, v2);
23401
23402    switch (op1) {
23403    case OPC_CMPU_EQ_QB_DSP:
23404        switch (op2) {
23405        case OPC_CMPU_EQ_QB:
23406            check_dsp(ctx);
23407            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23408            break;
23409        case OPC_CMPU_LT_QB:
23410            check_dsp(ctx);
23411            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23412            break;
23413        case OPC_CMPU_LE_QB:
23414            check_dsp(ctx);
23415            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23416            break;
23417        case OPC_CMPGU_EQ_QB:
23418            check_dsp(ctx);
23419            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23420            break;
23421        case OPC_CMPGU_LT_QB:
23422            check_dsp(ctx);
23423            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23424            break;
23425        case OPC_CMPGU_LE_QB:
23426            check_dsp(ctx);
23427            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23428            break;
23429        case OPC_CMPGDU_EQ_QB:
23430            check_dsp_r2(ctx);
23431            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23432            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23433            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23434            tcg_gen_shli_tl(t1, t1, 24);
23435            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23436            break;
23437        case OPC_CMPGDU_LT_QB:
23438            check_dsp_r2(ctx);
23439            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23440            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23441            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23442            tcg_gen_shli_tl(t1, t1, 24);
23443            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23444            break;
23445        case OPC_CMPGDU_LE_QB:
23446            check_dsp_r2(ctx);
23447            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23448            tcg_gen_mov_tl(cpu_gpr[ret], t1);
23449            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23450            tcg_gen_shli_tl(t1, t1, 24);
23451            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23452            break;
23453        case OPC_CMP_EQ_PH:
23454            check_dsp(ctx);
23455            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23456            break;
23457        case OPC_CMP_LT_PH:
23458            check_dsp(ctx);
23459            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23460            break;
23461        case OPC_CMP_LE_PH:
23462            check_dsp(ctx);
23463            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23464            break;
23465        case OPC_PICK_QB:
23466            check_dsp(ctx);
23467            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23468            break;
23469        case OPC_PICK_PH:
23470            check_dsp(ctx);
23471            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23472            break;
23473        case OPC_PACKRL_PH:
23474            check_dsp(ctx);
23475            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23476            break;
23477        }
23478        break;
23479#ifdef TARGET_MIPS64
23480    case OPC_CMPU_EQ_OB_DSP:
23481        switch (op2) {
23482        case OPC_CMP_EQ_PW:
23483            check_dsp(ctx);
23484            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23485            break;
23486        case OPC_CMP_LT_PW:
23487            check_dsp(ctx);
23488            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23489            break;
23490        case OPC_CMP_LE_PW:
23491            check_dsp(ctx);
23492            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23493            break;
23494        case OPC_CMP_EQ_QH:
23495            check_dsp(ctx);
23496            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23497            break;
23498        case OPC_CMP_LT_QH:
23499            check_dsp(ctx);
23500            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23501            break;
23502        case OPC_CMP_LE_QH:
23503            check_dsp(ctx);
23504            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23505            break;
23506        case OPC_CMPGDU_EQ_OB:
23507            check_dsp_r2(ctx);
23508            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23509            break;
23510        case OPC_CMPGDU_LT_OB:
23511            check_dsp_r2(ctx);
23512            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23513            break;
23514        case OPC_CMPGDU_LE_OB:
23515            check_dsp_r2(ctx);
23516            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23517            break;
23518        case OPC_CMPGU_EQ_OB:
23519            check_dsp(ctx);
23520            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23521            break;
23522        case OPC_CMPGU_LT_OB:
23523            check_dsp(ctx);
23524            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23525            break;
23526        case OPC_CMPGU_LE_OB:
23527            check_dsp(ctx);
23528            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23529            break;
23530        case OPC_CMPU_EQ_OB:
23531            check_dsp(ctx);
23532            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23533            break;
23534        case OPC_CMPU_LT_OB:
23535            check_dsp(ctx);
23536            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23537            break;
23538        case OPC_CMPU_LE_OB:
23539            check_dsp(ctx);
23540            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23541            break;
23542        case OPC_PACKRL_PW:
23543            check_dsp(ctx);
23544            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23545            break;
23546        case OPC_PICK_OB:
23547            check_dsp(ctx);
23548            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23549            break;
23550        case OPC_PICK_PW:
23551            check_dsp(ctx);
23552            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23553            break;
23554        case OPC_PICK_QH:
23555            check_dsp(ctx);
23556            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23557            break;
23558        }
23559        break;
23560#endif
23561    }
23562
23563    tcg_temp_free(t1);
23564    tcg_temp_free(v1_t);
23565    tcg_temp_free(v2_t);
23566}
23567
23568static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23569                               uint32_t op1, int rt, int rs, int sa)
23570{
23571    TCGv t0;
23572
23573    check_dsp_r2(ctx);
23574
23575    if (rt == 0) {
23576        /* Treat as NOP. */
23577        return;
23578    }
23579
23580    t0 = tcg_temp_new();
23581    gen_load_gpr(t0, rs);
23582
23583    switch (op1) {
23584    case OPC_APPEND_DSP:
23585        switch (MASK_APPEND(ctx->opcode)) {
23586        case OPC_APPEND:
23587            if (sa != 0) {
23588                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23589            }
23590            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23591            break;
23592        case OPC_PREPEND:
23593            if (sa != 0) {
23594                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23595                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23596                tcg_gen_shli_tl(t0, t0, 32 - sa);
23597                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23598            }
23599            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23600            break;
23601        case OPC_BALIGN:
23602            sa &= 3;
23603            if (sa != 0 && sa != 2) {
23604                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23605                tcg_gen_ext32u_tl(t0, t0);
23606                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23607                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23608            }
23609            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23610            break;
23611        default:            /* Invalid */
23612            MIPS_INVAL("MASK APPEND");
23613            generate_exception_end(ctx, EXCP_RI);
23614            break;
23615        }
23616        break;
23617#ifdef TARGET_MIPS64
23618    case OPC_DAPPEND_DSP:
23619        switch (MASK_DAPPEND(ctx->opcode)) {
23620        case OPC_DAPPEND:
23621            if (sa != 0) {
23622                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23623            }
23624            break;
23625        case OPC_PREPENDD:
23626            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23627            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23628            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23629            break;
23630        case OPC_PREPENDW:
23631            if (sa != 0) {
23632                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23633                tcg_gen_shli_tl(t0, t0, 64 - sa);
23634                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23635            }
23636            break;
23637        case OPC_DBALIGN:
23638            sa &= 7;
23639            if (sa != 0 && sa != 2 && sa != 4) {
23640                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23641                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23642                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23643            }
23644            break;
23645        default:            /* Invalid */
23646            MIPS_INVAL("MASK DAPPEND");
23647            generate_exception_end(ctx, EXCP_RI);
23648            break;
23649        }
23650        break;
23651#endif
23652    }
23653    tcg_temp_free(t0);
23654}
23655
23656static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23657                                int ret, int v1, int v2, int check_ret)
23658
23659{
23660    TCGv t0;
23661    TCGv t1;
23662    TCGv v1_t;
23663    TCGv v2_t;
23664    int16_t imm;
23665
23666    if ((ret == 0) && (check_ret == 1)) {
23667        /* Treat as NOP. */
23668        return;
23669    }
23670
23671    t0 = tcg_temp_new();
23672    t1 = tcg_temp_new();
23673    v1_t = tcg_temp_new();
23674    v2_t = tcg_temp_new();
23675
23676    gen_load_gpr(v1_t, v1);
23677    gen_load_gpr(v2_t, v2);
23678
23679    switch (op1) {
23680    case OPC_EXTR_W_DSP:
23681        check_dsp(ctx);
23682        switch (op2) {
23683        case OPC_EXTR_W:
23684            tcg_gen_movi_tl(t0, v2);
23685            tcg_gen_movi_tl(t1, v1);
23686            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23687            break;
23688        case OPC_EXTR_R_W:
23689            tcg_gen_movi_tl(t0, v2);
23690            tcg_gen_movi_tl(t1, v1);
23691            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23692            break;
23693        case OPC_EXTR_RS_W:
23694            tcg_gen_movi_tl(t0, v2);
23695            tcg_gen_movi_tl(t1, v1);
23696            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23697            break;
23698        case OPC_EXTR_S_H:
23699            tcg_gen_movi_tl(t0, v2);
23700            tcg_gen_movi_tl(t1, v1);
23701            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23702            break;
23703        case OPC_EXTRV_S_H:
23704            tcg_gen_movi_tl(t0, v2);
23705            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23706            break;
23707        case OPC_EXTRV_W:
23708            tcg_gen_movi_tl(t0, v2);
23709            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23710            break;
23711        case OPC_EXTRV_R_W:
23712            tcg_gen_movi_tl(t0, v2);
23713            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23714            break;
23715        case OPC_EXTRV_RS_W:
23716            tcg_gen_movi_tl(t0, v2);
23717            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23718            break;
23719        case OPC_EXTP:
23720            tcg_gen_movi_tl(t0, v2);
23721            tcg_gen_movi_tl(t1, v1);
23722            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23723            break;
23724        case OPC_EXTPV:
23725            tcg_gen_movi_tl(t0, v2);
23726            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23727            break;
23728        case OPC_EXTPDP:
23729            tcg_gen_movi_tl(t0, v2);
23730            tcg_gen_movi_tl(t1, v1);
23731            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23732            break;
23733        case OPC_EXTPDPV:
23734            tcg_gen_movi_tl(t0, v2);
23735            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23736            break;
23737        case OPC_SHILO:
23738            imm = (ctx->opcode >> 20) & 0x3F;
23739            tcg_gen_movi_tl(t0, ret);
23740            tcg_gen_movi_tl(t1, imm);
23741            gen_helper_shilo(t0, t1, cpu_env);
23742            break;
23743        case OPC_SHILOV:
23744            tcg_gen_movi_tl(t0, ret);
23745            gen_helper_shilo(t0, v1_t, cpu_env);
23746            break;
23747        case OPC_MTHLIP:
23748            tcg_gen_movi_tl(t0, ret);
23749            gen_helper_mthlip(t0, v1_t, cpu_env);
23750            break;
23751        case OPC_WRDSP:
23752            imm = (ctx->opcode >> 11) & 0x3FF;
23753            tcg_gen_movi_tl(t0, imm);
23754            gen_helper_wrdsp(v1_t, t0, cpu_env);
23755            break;
23756        case OPC_RDDSP:
23757            imm = (ctx->opcode >> 16) & 0x03FF;
23758            tcg_gen_movi_tl(t0, imm);
23759            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23760            break;
23761        }
23762        break;
23763#ifdef TARGET_MIPS64
23764    case OPC_DEXTR_W_DSP:
23765        check_dsp(ctx);
23766        switch (op2) {
23767        case OPC_DMTHLIP:
23768            tcg_gen_movi_tl(t0, ret);
23769            gen_helper_dmthlip(v1_t, t0, cpu_env);
23770            break;
23771        case OPC_DSHILO:
23772            {
23773                int shift = (ctx->opcode >> 19) & 0x7F;
23774                int ac = (ctx->opcode >> 11) & 0x03;
23775                tcg_gen_movi_tl(t0, shift);
23776                tcg_gen_movi_tl(t1, ac);
23777                gen_helper_dshilo(t0, t1, cpu_env);
23778                break;
23779            }
23780        case OPC_DSHILOV:
23781            {
23782                int ac = (ctx->opcode >> 11) & 0x03;
23783                tcg_gen_movi_tl(t0, ac);
23784                gen_helper_dshilo(v1_t, t0, cpu_env);
23785                break;
23786            }
23787        case OPC_DEXTP:
23788            tcg_gen_movi_tl(t0, v2);
23789            tcg_gen_movi_tl(t1, v1);
23790
23791            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23792            break;
23793        case OPC_DEXTPV:
23794            tcg_gen_movi_tl(t0, v2);
23795            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23796            break;
23797        case OPC_DEXTPDP:
23798            tcg_gen_movi_tl(t0, v2);
23799            tcg_gen_movi_tl(t1, v1);
23800            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23801            break;
23802        case OPC_DEXTPDPV:
23803            tcg_gen_movi_tl(t0, v2);
23804            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23805            break;
23806        case OPC_DEXTR_L:
23807            tcg_gen_movi_tl(t0, v2);
23808            tcg_gen_movi_tl(t1, v1);
23809            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23810            break;
23811        case OPC_DEXTR_R_L:
23812            tcg_gen_movi_tl(t0, v2);
23813            tcg_gen_movi_tl(t1, v1);
23814            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23815            break;
23816        case OPC_DEXTR_RS_L:
23817            tcg_gen_movi_tl(t0, v2);
23818            tcg_gen_movi_tl(t1, v1);
23819            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23820            break;
23821        case OPC_DEXTR_W:
23822            tcg_gen_movi_tl(t0, v2);
23823            tcg_gen_movi_tl(t1, v1);
23824            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23825            break;
23826        case OPC_DEXTR_R_W:
23827            tcg_gen_movi_tl(t0, v2);
23828            tcg_gen_movi_tl(t1, v1);
23829            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23830            break;
23831        case OPC_DEXTR_RS_W:
23832            tcg_gen_movi_tl(t0, v2);
23833            tcg_gen_movi_tl(t1, v1);
23834            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23835            break;
23836        case OPC_DEXTR_S_H:
23837            tcg_gen_movi_tl(t0, v2);
23838            tcg_gen_movi_tl(t1, v1);
23839            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23840            break;
23841        case OPC_DEXTRV_S_H:
23842            tcg_gen_movi_tl(t0, v2);
23843            tcg_gen_movi_tl(t1, v1);
23844            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23845            break;
23846        case OPC_DEXTRV_L:
23847            tcg_gen_movi_tl(t0, v2);
23848            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23849            break;
23850        case OPC_DEXTRV_R_L:
23851            tcg_gen_movi_tl(t0, v2);
23852            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23853            break;
23854        case OPC_DEXTRV_RS_L:
23855            tcg_gen_movi_tl(t0, v2);
23856            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23857            break;
23858        case OPC_DEXTRV_W:
23859            tcg_gen_movi_tl(t0, v2);
23860            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23861            break;
23862        case OPC_DEXTRV_R_W:
23863            tcg_gen_movi_tl(t0, v2);
23864            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23865            break;
23866        case OPC_DEXTRV_RS_W:
23867            tcg_gen_movi_tl(t0, v2);
23868            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23869            break;
23870        }
23871        break;
23872#endif
23873    }
23874
23875    tcg_temp_free(t0);
23876    tcg_temp_free(t1);
23877    tcg_temp_free(v1_t);
23878    tcg_temp_free(v2_t);
23879}
23880
23881/* End MIPSDSP functions. */
23882
23883static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23884{
23885    int rs, rt, rd, sa;
23886    uint32_t op1, op2;
23887
23888    rs = (ctx->opcode >> 21) & 0x1f;
23889    rt = (ctx->opcode >> 16) & 0x1f;
23890    rd = (ctx->opcode >> 11) & 0x1f;
23891    sa = (ctx->opcode >> 6) & 0x1f;
23892
23893    op1 = MASK_SPECIAL(ctx->opcode);
23894    switch (op1) {
23895    case OPC_LSA:
23896        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23897        break;
23898    case OPC_MULT:
23899    case OPC_MULTU:
23900    case OPC_DIV:
23901    case OPC_DIVU:
23902        op2 = MASK_R6_MULDIV(ctx->opcode);
23903        switch (op2) {
23904        case R6_OPC_MUL:
23905        case R6_OPC_MUH:
23906        case R6_OPC_MULU:
23907        case R6_OPC_MUHU:
23908        case R6_OPC_DIV:
23909        case R6_OPC_MOD:
23910        case R6_OPC_DIVU:
23911        case R6_OPC_MODU:
23912            gen_r6_muldiv(ctx, op2, rd, rs, rt);
23913            break;
23914        default:
23915            MIPS_INVAL("special_r6 muldiv");
23916            generate_exception_end(ctx, EXCP_RI);
23917            break;
23918        }
23919        break;
23920    case OPC_SELEQZ:
23921    case OPC_SELNEZ:
23922        gen_cond_move(ctx, op1, rd, rs, rt);
23923        break;
23924    case R6_OPC_CLO:
23925    case R6_OPC_CLZ:
23926        if (rt == 0 && sa == 1) {
23927            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23928               We need additionally to check other fields */
23929            gen_cl(ctx, op1, rd, rs);
23930        } else {
23931            generate_exception_end(ctx, EXCP_RI);
23932        }
23933        break;
23934    case R6_OPC_SDBBP:
23935        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23936            gen_helper_do_semihosting(cpu_env);
23937        } else {
23938            if (ctx->hflags & MIPS_HFLAG_SBRI) {
23939                generate_exception_end(ctx, EXCP_RI);
23940            } else {
23941                generate_exception_end(ctx, EXCP_DBp);
23942            }
23943        }
23944        break;
23945#if defined(TARGET_MIPS64)
23946    case OPC_DLSA:
23947        check_mips_64(ctx);
23948        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23949        break;
23950    case R6_OPC_DCLO:
23951    case R6_OPC_DCLZ:
23952        if (rt == 0 && sa == 1) {
23953            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23954               We need additionally to check other fields */
23955            check_mips_64(ctx);
23956            gen_cl(ctx, op1, rd, rs);
23957        } else {
23958            generate_exception_end(ctx, EXCP_RI);
23959        }
23960        break;
23961    case OPC_DMULT:
23962    case OPC_DMULTU:
23963    case OPC_DDIV:
23964    case OPC_DDIVU:
23965
23966        op2 = MASK_R6_MULDIV(ctx->opcode);
23967        switch (op2) {
23968        case R6_OPC_DMUL:
23969        case R6_OPC_DMUH:
23970        case R6_OPC_DMULU:
23971        case R6_OPC_DMUHU:
23972        case R6_OPC_DDIV:
23973        case R6_OPC_DMOD:
23974        case R6_OPC_DDIVU:
23975        case R6_OPC_DMODU:
23976            check_mips_64(ctx);
23977            gen_r6_muldiv(ctx, op2, rd, rs, rt);
23978            break;
23979        default:
23980            MIPS_INVAL("special_r6 muldiv");
23981            generate_exception_end(ctx, EXCP_RI);
23982            break;
23983        }
23984        break;
23985#endif
23986    default:            /* Invalid */
23987        MIPS_INVAL("special_r6");
23988        generate_exception_end(ctx, EXCP_RI);
23989        break;
23990    }
23991}
23992
23993static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23994{
23995    int rs = extract32(ctx->opcode, 21, 5);
23996    int rt = extract32(ctx->opcode, 16, 5);
23997    int rd = extract32(ctx->opcode, 11, 5);
23998    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
23999
24000    switch (op1) {
24001    case OPC_MOVN:         /* Conditional move */
24002    case OPC_MOVZ:
24003        gen_cond_move(ctx, op1, rd, rs, rt);
24004        break;
24005    case OPC_MFHI:          /* Move from HI/LO */
24006    case OPC_MFLO:
24007        gen_HILO(ctx, op1, 0, rd);
24008        break;
24009    case OPC_MTHI:
24010    case OPC_MTLO:          /* Move to HI/LO */
24011        gen_HILO(ctx, op1, 0, rs);
24012        break;
24013    case OPC_MULT:
24014    case OPC_MULTU:
24015        gen_mul_txx9(ctx, op1, rd, rs, rt);
24016        break;
24017    case OPC_DIV:
24018    case OPC_DIVU:
24019        gen_muldiv(ctx, op1, 0, rs, rt);
24020        break;
24021#if defined(TARGET_MIPS64)
24022    case OPC_DMULT:
24023    case OPC_DMULTU:
24024    case OPC_DDIV:
24025    case OPC_DDIVU:
24026        check_insn_opc_user_only(ctx, INSN_R5900);
24027        gen_muldiv(ctx, op1, 0, rs, rt);
24028        break;
24029#endif
24030    case OPC_JR:
24031        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24032        break;
24033    default:            /* Invalid */
24034        MIPS_INVAL("special_tx79");
24035        generate_exception_end(ctx, EXCP_RI);
24036        break;
24037    }
24038}
24039
24040static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24041{
24042    int rs, rt, rd, sa;
24043    uint32_t op1;
24044
24045    rs = (ctx->opcode >> 21) & 0x1f;
24046    rt = (ctx->opcode >> 16) & 0x1f;
24047    rd = (ctx->opcode >> 11) & 0x1f;
24048    sa = (ctx->opcode >> 6) & 0x1f;
24049
24050    op1 = MASK_SPECIAL(ctx->opcode);
24051    switch (op1) {
24052    case OPC_MOVN:         /* Conditional move */
24053    case OPC_MOVZ:
24054        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24055                   INSN_LOONGSON2E | INSN_LOONGSON2F);
24056        gen_cond_move(ctx, op1, rd, rs, rt);
24057        break;
24058    case OPC_MFHI:          /* Move from HI/LO */
24059    case OPC_MFLO:
24060        gen_HILO(ctx, op1, rs & 3, rd);
24061        break;
24062    case OPC_MTHI:
24063    case OPC_MTLO:          /* Move to HI/LO */
24064        gen_HILO(ctx, op1, rd & 3, rs);
24065        break;
24066    case OPC_MOVCI:
24067        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24068        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24069            check_cp1_enabled(ctx);
24070            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24071                      (ctx->opcode >> 16) & 1);
24072        } else {
24073            generate_exception_err(ctx, EXCP_CpU, 1);
24074        }
24075        break;
24076    case OPC_MULT:
24077    case OPC_MULTU:
24078        if (sa) {
24079            check_insn(ctx, INSN_VR54XX);
24080            op1 = MASK_MUL_VR54XX(ctx->opcode);
24081            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24082        } else {
24083            gen_muldiv(ctx, op1, rd & 3, rs, rt);
24084        }
24085        break;
24086    case OPC_DIV:
24087    case OPC_DIVU:
24088        gen_muldiv(ctx, op1, 0, rs, rt);
24089        break;
24090#if defined(TARGET_MIPS64)
24091    case OPC_DMULT:
24092    case OPC_DMULTU:
24093    case OPC_DDIV:
24094    case OPC_DDIVU:
24095        check_insn(ctx, ISA_MIPS3);
24096        check_mips_64(ctx);
24097        gen_muldiv(ctx, op1, 0, rs, rt);
24098        break;
24099#endif
24100    case OPC_JR:
24101        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24102        break;
24103    case OPC_SPIM:
24104#ifdef MIPS_STRICT_STANDARD
24105        MIPS_INVAL("SPIM");
24106        generate_exception_end(ctx, EXCP_RI);
24107#else
24108        /* Implemented as RI exception for now. */
24109        MIPS_INVAL("spim (unofficial)");
24110        generate_exception_end(ctx, EXCP_RI);
24111#endif
24112        break;
24113    default:            /* Invalid */
24114        MIPS_INVAL("special_legacy");
24115        generate_exception_end(ctx, EXCP_RI);
24116        break;
24117    }
24118}
24119
24120static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24121{
24122    int rs, rt, rd, sa;
24123    uint32_t op1;
24124
24125    rs = (ctx->opcode >> 21) & 0x1f;
24126    rt = (ctx->opcode >> 16) & 0x1f;
24127    rd = (ctx->opcode >> 11) & 0x1f;
24128    sa = (ctx->opcode >> 6) & 0x1f;
24129
24130    op1 = MASK_SPECIAL(ctx->opcode);
24131    switch (op1) {
24132    case OPC_SLL:          /* Shift with immediate */
24133        if (sa == 5 && rd == 0 &&
24134            rs == 0 && rt == 0) { /* PAUSE */
24135            if ((ctx->insn_flags & ISA_MIPS32R6) &&
24136                (ctx->hflags & MIPS_HFLAG_BMASK)) {
24137                generate_exception_end(ctx, EXCP_RI);
24138                break;
24139            }
24140        }
24141        /* Fallthrough */
24142    case OPC_SRA:
24143        gen_shift_imm(ctx, op1, rd, rt, sa);
24144        break;
24145    case OPC_SRL:
24146        switch ((ctx->opcode >> 21) & 0x1f) {
24147        case 1:
24148            /* rotr is decoded as srl on non-R2 CPUs */
24149            if (ctx->insn_flags & ISA_MIPS32R2) {
24150                op1 = OPC_ROTR;
24151            }
24152            /* Fallthrough */
24153        case 0:
24154            gen_shift_imm(ctx, op1, rd, rt, sa);
24155            break;
24156        default:
24157            generate_exception_end(ctx, EXCP_RI);
24158            break;
24159        }
24160        break;
24161    case OPC_ADD:
24162    case OPC_ADDU:
24163    case OPC_SUB:
24164    case OPC_SUBU:
24165        gen_arith(ctx, op1, rd, rs, rt);
24166        break;
24167    case OPC_SLLV:         /* Shifts */
24168    case OPC_SRAV:
24169        gen_shift(ctx, op1, rd, rs, rt);
24170        break;
24171    case OPC_SRLV:
24172        switch ((ctx->opcode >> 6) & 0x1f) {
24173        case 1:
24174            /* rotrv is decoded as srlv on non-R2 CPUs */
24175            if (ctx->insn_flags & ISA_MIPS32R2) {
24176                op1 = OPC_ROTRV;
24177            }
24178            /* Fallthrough */
24179        case 0:
24180            gen_shift(ctx, op1, rd, rs, rt);
24181            break;
24182        default:
24183            generate_exception_end(ctx, EXCP_RI);
24184            break;
24185        }
24186        break;
24187    case OPC_SLT:          /* Set on less than */
24188    case OPC_SLTU:
24189        gen_slt(ctx, op1, rd, rs, rt);
24190        break;
24191    case OPC_AND:          /* Logic*/
24192    case OPC_OR:
24193    case OPC_NOR:
24194    case OPC_XOR:
24195        gen_logic(ctx, op1, rd, rs, rt);
24196        break;
24197    case OPC_JALR:
24198        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24199        break;
24200    case OPC_TGE: /* Traps */
24201    case OPC_TGEU:
24202    case OPC_TLT:
24203    case OPC_TLTU:
24204    case OPC_TEQ:
24205    case OPC_TNE:
24206        check_insn(ctx, ISA_MIPS2);
24207        gen_trap(ctx, op1, rs, rt, -1);
24208        break;
24209    case OPC_LSA: /* OPC_PMON */
24210        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24211            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24212            decode_opc_special_r6(env, ctx);
24213        } else {
24214            /* Pmon entry point, also R4010 selsl */
24215#ifdef MIPS_STRICT_STANDARD
24216            MIPS_INVAL("PMON / selsl");
24217            generate_exception_end(ctx, EXCP_RI);
24218#else
24219            gen_helper_0e0i(pmon, sa);
24220#endif
24221        }
24222        break;
24223    case OPC_SYSCALL:
24224        generate_exception_end(ctx, EXCP_SYSCALL);
24225        break;
24226    case OPC_BREAK:
24227        generate_exception_end(ctx, EXCP_BREAK);
24228        break;
24229    case OPC_SYNC:
24230        check_insn(ctx, ISA_MIPS2);
24231        gen_sync(extract32(ctx->opcode, 6, 5));
24232        break;
24233
24234#if defined(TARGET_MIPS64)
24235        /* MIPS64 specific opcodes */
24236    case OPC_DSLL:
24237    case OPC_DSRA:
24238    case OPC_DSLL32:
24239    case OPC_DSRA32:
24240        check_insn(ctx, ISA_MIPS3);
24241        check_mips_64(ctx);
24242        gen_shift_imm(ctx, op1, rd, rt, sa);
24243        break;
24244    case OPC_DSRL:
24245        switch ((ctx->opcode >> 21) & 0x1f) {
24246        case 1:
24247            /* drotr is decoded as dsrl on non-R2 CPUs */
24248            if (ctx->insn_flags & ISA_MIPS32R2) {
24249                op1 = OPC_DROTR;
24250            }
24251            /* Fallthrough */
24252        case 0:
24253            check_insn(ctx, ISA_MIPS3);
24254            check_mips_64(ctx);
24255            gen_shift_imm(ctx, op1, rd, rt, sa);
24256            break;
24257        default:
24258            generate_exception_end(ctx, EXCP_RI);
24259            break;
24260        }
24261        break;
24262    case OPC_DSRL32:
24263        switch ((ctx->opcode >> 21) & 0x1f) {
24264        case 1:
24265            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24266            if (ctx->insn_flags & ISA_MIPS32R2) {
24267                op1 = OPC_DROTR32;
24268            }
24269            /* Fallthrough */
24270        case 0:
24271            check_insn(ctx, ISA_MIPS3);
24272            check_mips_64(ctx);
24273            gen_shift_imm(ctx, op1, rd, rt, sa);
24274            break;
24275        default:
24276            generate_exception_end(ctx, EXCP_RI);
24277            break;
24278        }
24279        break;
24280    case OPC_DADD:
24281    case OPC_DADDU:
24282    case OPC_DSUB:
24283    case OPC_DSUBU:
24284        check_insn(ctx, ISA_MIPS3);
24285        check_mips_64(ctx);
24286        gen_arith(ctx, op1, rd, rs, rt);
24287        break;
24288    case OPC_DSLLV:
24289    case OPC_DSRAV:
24290        check_insn(ctx, ISA_MIPS3);
24291        check_mips_64(ctx);
24292        gen_shift(ctx, op1, rd, rs, rt);
24293        break;
24294    case OPC_DSRLV:
24295        switch ((ctx->opcode >> 6) & 0x1f) {
24296        case 1:
24297            /* drotrv is decoded as dsrlv on non-R2 CPUs */
24298            if (ctx->insn_flags & ISA_MIPS32R2) {
24299                op1 = OPC_DROTRV;
24300            }
24301            /* Fallthrough */
24302        case 0:
24303            check_insn(ctx, ISA_MIPS3);
24304            check_mips_64(ctx);
24305            gen_shift(ctx, op1, rd, rs, rt);
24306            break;
24307        default:
24308            generate_exception_end(ctx, EXCP_RI);
24309            break;
24310        }
24311        break;
24312    case OPC_DLSA:
24313        if ((ctx->insn_flags & ISA_MIPS32R6) ||
24314            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24315            decode_opc_special_r6(env, ctx);
24316        }
24317        break;
24318#endif
24319    default:
24320        if (ctx->insn_flags & ISA_MIPS32R6) {
24321            decode_opc_special_r6(env, ctx);
24322        } else if (ctx->insn_flags & INSN_R5900) {
24323            decode_opc_special_tx79(env, ctx);
24324        } else {
24325            decode_opc_special_legacy(env, ctx);
24326        }
24327    }
24328}
24329
24330
24331#if defined(TARGET_MIPS64)
24332
24333/*
24334 *
24335 *           MMI (MultiMedia Interface) ASE instructions
24336 *           ===========================================
24337 */
24338
24339/*
24340 *          MMI instructions category: data communication
24341 *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24342 *
24343 *   PCPYH    PEXCH    PEXTLB   PINTH    PPACB    PEXT5    PREVH
24344 *   PCPYLD   PEXCW    PEXTLH   PINTEH   PPACH    PPAC5    PROT3W
24345 *   PCPYUD   PEXEH    PEXTLW            PPACW
24346 *            PEXEW    PEXTUB
24347 *                     PEXTUH
24348 *                     PEXTUW
24349 */
24350
24351#endif
24352
24353
24354#if !defined(TARGET_MIPS64)
24355
24356/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24357#define MXU_APTN1_A    0
24358#define MXU_APTN1_S    1
24359
24360/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24361#define MXU_APTN2_AA    0
24362#define MXU_APTN2_AS    1
24363#define MXU_APTN2_SA    2
24364#define MXU_APTN2_SS    3
24365
24366/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24367#define MXU_EPTN2_AA    0
24368#define MXU_EPTN2_AS    1
24369#define MXU_EPTN2_SA    2
24370#define MXU_EPTN2_SS    3
24371
24372/* MXU operand getting pattern 'optn2' */
24373#define MXU_OPTN2_PTN0  0
24374#define MXU_OPTN2_PTN1  1
24375#define MXU_OPTN2_PTN2  2
24376#define MXU_OPTN2_PTN3  3
24377/* alternative naming scheme for 'optn2' */
24378#define MXU_OPTN2_WW    0
24379#define MXU_OPTN2_LW    1
24380#define MXU_OPTN2_HW    2
24381#define MXU_OPTN2_XW    3
24382
24383/* MXU operand getting pattern 'optn3' */
24384#define MXU_OPTN3_PTN0  0
24385#define MXU_OPTN3_PTN1  1
24386#define MXU_OPTN3_PTN2  2
24387#define MXU_OPTN3_PTN3  3
24388#define MXU_OPTN3_PTN4  4
24389#define MXU_OPTN3_PTN5  5
24390#define MXU_OPTN3_PTN6  6
24391#define MXU_OPTN3_PTN7  7
24392
24393
24394/*
24395 * S32I2M XRa, rb - Register move from GRF to XRF
24396 */
24397static void gen_mxu_s32i2m(DisasContext *ctx)
24398{
24399    TCGv t0;
24400    uint32_t XRa, Rb;
24401
24402    t0 = tcg_temp_new();
24403
24404    XRa = extract32(ctx->opcode, 6, 5);
24405    Rb = extract32(ctx->opcode, 16, 5);
24406
24407    gen_load_gpr(t0, Rb);
24408    if (XRa <= 15) {
24409        gen_store_mxu_gpr(t0, XRa);
24410    } else if (XRa == 16) {
24411        gen_store_mxu_cr(t0);
24412    }
24413
24414    tcg_temp_free(t0);
24415}
24416
24417/*
24418 * S32M2I XRa, rb - Register move from XRF to GRF
24419 */
24420static void gen_mxu_s32m2i(DisasContext *ctx)
24421{
24422    TCGv t0;
24423    uint32_t XRa, Rb;
24424
24425    t0 = tcg_temp_new();
24426
24427    XRa = extract32(ctx->opcode, 6, 5);
24428    Rb = extract32(ctx->opcode, 16, 5);
24429
24430    if (XRa <= 15) {
24431        gen_load_mxu_gpr(t0, XRa);
24432    } else if (XRa == 16) {
24433        gen_load_mxu_cr(t0);
24434    }
24435
24436    gen_store_gpr(t0, Rb);
24437
24438    tcg_temp_free(t0);
24439}
24440
24441/*
24442 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24443 */
24444static void gen_mxu_s8ldd(DisasContext *ctx)
24445{
24446    TCGv t0, t1;
24447    uint32_t XRa, Rb, s8, optn3;
24448
24449    t0 = tcg_temp_new();
24450    t1 = tcg_temp_new();
24451
24452    XRa = extract32(ctx->opcode, 6, 4);
24453    s8 = extract32(ctx->opcode, 10, 8);
24454    optn3 = extract32(ctx->opcode, 18, 3);
24455    Rb = extract32(ctx->opcode, 21, 5);
24456
24457    gen_load_gpr(t0, Rb);
24458    tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24459
24460    switch (optn3) {
24461    /* XRa[7:0] = tmp8 */
24462    case MXU_OPTN3_PTN0:
24463        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24464        gen_load_mxu_gpr(t0, XRa);
24465        tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24466        break;
24467    /* XRa[15:8] = tmp8 */
24468    case MXU_OPTN3_PTN1:
24469        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24470        gen_load_mxu_gpr(t0, XRa);
24471        tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24472        break;
24473    /* XRa[23:16] = tmp8 */
24474    case MXU_OPTN3_PTN2:
24475        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24476        gen_load_mxu_gpr(t0, XRa);
24477        tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24478        break;
24479    /* XRa[31:24] = tmp8 */
24480    case MXU_OPTN3_PTN3:
24481        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24482        gen_load_mxu_gpr(t0, XRa);
24483        tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24484        break;
24485    /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24486    case MXU_OPTN3_PTN4:
24487        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24488        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24489        break;
24490    /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24491    case MXU_OPTN3_PTN5:
24492        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24493        tcg_gen_shli_tl(t1, t1, 8);
24494        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24495        break;
24496    /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24497    case MXU_OPTN3_PTN6:
24498        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24499        tcg_gen_mov_tl(t0, t1);
24500        tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24501        tcg_gen_shli_tl(t1, t1, 16);
24502        tcg_gen_or_tl(t0, t0, t1);
24503        break;
24504    /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24505    case MXU_OPTN3_PTN7:
24506        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24507        tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24508        tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24509        break;
24510    }
24511
24512    gen_store_mxu_gpr(t0, XRa);
24513
24514    tcg_temp_free(t0);
24515    tcg_temp_free(t1);
24516}
24517
24518/*
24519 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24520 */
24521static void gen_mxu_d16mul(DisasContext *ctx)
24522{
24523    TCGv t0, t1, t2, t3;
24524    uint32_t XRa, XRb, XRc, XRd, optn2;
24525
24526    t0 = tcg_temp_new();
24527    t1 = tcg_temp_new();
24528    t2 = tcg_temp_new();
24529    t3 = tcg_temp_new();
24530
24531    XRa = extract32(ctx->opcode, 6, 4);
24532    XRb = extract32(ctx->opcode, 10, 4);
24533    XRc = extract32(ctx->opcode, 14, 4);
24534    XRd = extract32(ctx->opcode, 18, 4);
24535    optn2 = extract32(ctx->opcode, 22, 2);
24536
24537    gen_load_mxu_gpr(t1, XRb);
24538    tcg_gen_sextract_tl(t0, t1, 0, 16);
24539    tcg_gen_sextract_tl(t1, t1, 16, 16);
24540    gen_load_mxu_gpr(t3, XRc);
24541    tcg_gen_sextract_tl(t2, t3, 0, 16);
24542    tcg_gen_sextract_tl(t3, t3, 16, 16);
24543
24544    switch (optn2) {
24545    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24546        tcg_gen_mul_tl(t3, t1, t3);
24547        tcg_gen_mul_tl(t2, t0, t2);
24548        break;
24549    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24550        tcg_gen_mul_tl(t3, t0, t3);
24551        tcg_gen_mul_tl(t2, t0, t2);
24552        break;
24553    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24554        tcg_gen_mul_tl(t3, t1, t3);
24555        tcg_gen_mul_tl(t2, t1, t2);
24556        break;
24557    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24558        tcg_gen_mul_tl(t3, t0, t3);
24559        tcg_gen_mul_tl(t2, t1, t2);
24560        break;
24561    }
24562    gen_store_mxu_gpr(t3, XRa);
24563    gen_store_mxu_gpr(t2, XRd);
24564
24565    tcg_temp_free(t0);
24566    tcg_temp_free(t1);
24567    tcg_temp_free(t2);
24568    tcg_temp_free(t3);
24569}
24570
24571/*
24572 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24573 *                                           and accumulate
24574 */
24575static void gen_mxu_d16mac(DisasContext *ctx)
24576{
24577    TCGv t0, t1, t2, t3;
24578    uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24579
24580    t0 = tcg_temp_new();
24581    t1 = tcg_temp_new();
24582    t2 = tcg_temp_new();
24583    t3 = tcg_temp_new();
24584
24585    XRa = extract32(ctx->opcode, 6, 4);
24586    XRb = extract32(ctx->opcode, 10, 4);
24587    XRc = extract32(ctx->opcode, 14, 4);
24588    XRd = extract32(ctx->opcode, 18, 4);
24589    optn2 = extract32(ctx->opcode, 22, 2);
24590    aptn2 = extract32(ctx->opcode, 24, 2);
24591
24592    gen_load_mxu_gpr(t1, XRb);
24593    tcg_gen_sextract_tl(t0, t1, 0, 16);
24594    tcg_gen_sextract_tl(t1, t1, 16, 16);
24595
24596    gen_load_mxu_gpr(t3, XRc);
24597    tcg_gen_sextract_tl(t2, t3, 0, 16);
24598    tcg_gen_sextract_tl(t3, t3, 16, 16);
24599
24600    switch (optn2) {
24601    case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24602        tcg_gen_mul_tl(t3, t1, t3);
24603        tcg_gen_mul_tl(t2, t0, t2);
24604        break;
24605    case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24606        tcg_gen_mul_tl(t3, t0, t3);
24607        tcg_gen_mul_tl(t2, t0, t2);
24608        break;
24609    case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24610        tcg_gen_mul_tl(t3, t1, t3);
24611        tcg_gen_mul_tl(t2, t1, t2);
24612        break;
24613    case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24614        tcg_gen_mul_tl(t3, t0, t3);
24615        tcg_gen_mul_tl(t2, t1, t2);
24616        break;
24617    }
24618    gen_load_mxu_gpr(t0, XRa);
24619    gen_load_mxu_gpr(t1, XRd);
24620
24621    switch (aptn2) {
24622    case MXU_APTN2_AA:
24623        tcg_gen_add_tl(t3, t0, t3);
24624        tcg_gen_add_tl(t2, t1, t2);
24625        break;
24626    case MXU_APTN2_AS:
24627        tcg_gen_add_tl(t3, t0, t3);
24628        tcg_gen_sub_tl(t2, t1, t2);
24629        break;
24630    case MXU_APTN2_SA:
24631        tcg_gen_sub_tl(t3, t0, t3);
24632        tcg_gen_add_tl(t2, t1, t2);
24633        break;
24634    case MXU_APTN2_SS:
24635        tcg_gen_sub_tl(t3, t0, t3);
24636        tcg_gen_sub_tl(t2, t1, t2);
24637        break;
24638    }
24639    gen_store_mxu_gpr(t3, XRa);
24640    gen_store_mxu_gpr(t2, XRd);
24641
24642    tcg_temp_free(t0);
24643    tcg_temp_free(t1);
24644    tcg_temp_free(t2);
24645    tcg_temp_free(t3);
24646}
24647
24648/*
24649 * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24650 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24651 */
24652static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24653{
24654    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24655    uint32_t XRa, XRb, XRc, XRd, sel;
24656
24657    t0 = tcg_temp_new();
24658    t1 = tcg_temp_new();
24659    t2 = tcg_temp_new();
24660    t3 = tcg_temp_new();
24661    t4 = tcg_temp_new();
24662    t5 = tcg_temp_new();
24663    t6 = tcg_temp_new();
24664    t7 = tcg_temp_new();
24665
24666    XRa = extract32(ctx->opcode, 6, 4);
24667    XRb = extract32(ctx->opcode, 10, 4);
24668    XRc = extract32(ctx->opcode, 14, 4);
24669    XRd = extract32(ctx->opcode, 18, 4);
24670    sel = extract32(ctx->opcode, 22, 2);
24671
24672    gen_load_mxu_gpr(t3, XRb);
24673    gen_load_mxu_gpr(t7, XRc);
24674
24675    if (sel == 0x2) {
24676        /* Q8MULSU */
24677        tcg_gen_ext8s_tl(t0, t3);
24678        tcg_gen_shri_tl(t3, t3, 8);
24679        tcg_gen_ext8s_tl(t1, t3);
24680        tcg_gen_shri_tl(t3, t3, 8);
24681        tcg_gen_ext8s_tl(t2, t3);
24682        tcg_gen_shri_tl(t3, t3, 8);
24683        tcg_gen_ext8s_tl(t3, t3);
24684    } else {
24685        /* Q8MUL */
24686        tcg_gen_ext8u_tl(t0, t3);
24687        tcg_gen_shri_tl(t3, t3, 8);
24688        tcg_gen_ext8u_tl(t1, t3);
24689        tcg_gen_shri_tl(t3, t3, 8);
24690        tcg_gen_ext8u_tl(t2, t3);
24691        tcg_gen_shri_tl(t3, t3, 8);
24692        tcg_gen_ext8u_tl(t3, t3);
24693    }
24694
24695    tcg_gen_ext8u_tl(t4, t7);
24696    tcg_gen_shri_tl(t7, t7, 8);
24697    tcg_gen_ext8u_tl(t5, t7);
24698    tcg_gen_shri_tl(t7, t7, 8);
24699    tcg_gen_ext8u_tl(t6, t7);
24700    tcg_gen_shri_tl(t7, t7, 8);
24701    tcg_gen_ext8u_tl(t7, t7);
24702
24703    tcg_gen_mul_tl(t0, t0, t4);
24704    tcg_gen_mul_tl(t1, t1, t5);
24705    tcg_gen_mul_tl(t2, t2, t6);
24706    tcg_gen_mul_tl(t3, t3, t7);
24707
24708    tcg_gen_andi_tl(t0, t0, 0xFFFF);
24709    tcg_gen_andi_tl(t1, t1, 0xFFFF);
24710    tcg_gen_andi_tl(t2, t2, 0xFFFF);
24711    tcg_gen_andi_tl(t3, t3, 0xFFFF);
24712
24713    tcg_gen_shli_tl(t1, t1, 16);
24714    tcg_gen_shli_tl(t3, t3, 16);
24715
24716    tcg_gen_or_tl(t0, t0, t1);
24717    tcg_gen_or_tl(t1, t2, t3);
24718
24719    gen_store_mxu_gpr(t0, XRd);
24720    gen_store_mxu_gpr(t1, XRa);
24721
24722    tcg_temp_free(t0);
24723    tcg_temp_free(t1);
24724    tcg_temp_free(t2);
24725    tcg_temp_free(t3);
24726    tcg_temp_free(t4);
24727    tcg_temp_free(t5);
24728    tcg_temp_free(t6);
24729    tcg_temp_free(t7);
24730}
24731
24732/*
24733 * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
24734 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24735 */
24736static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24737{
24738    TCGv t0, t1;
24739    uint32_t XRa, Rb, s12, sel;
24740
24741    t0 = tcg_temp_new();
24742    t1 = tcg_temp_new();
24743
24744    XRa = extract32(ctx->opcode, 6, 4);
24745    s12 = extract32(ctx->opcode, 10, 10);
24746    sel = extract32(ctx->opcode, 20, 1);
24747    Rb = extract32(ctx->opcode, 21, 5);
24748
24749    gen_load_gpr(t0, Rb);
24750
24751    tcg_gen_movi_tl(t1, s12);
24752    tcg_gen_shli_tl(t1, t1, 2);
24753    if (s12 & 0x200) {
24754        tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24755    }
24756    tcg_gen_add_tl(t1, t0, t1);
24757    tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24758
24759    if (sel == 1) {
24760        /* S32LDDR */
24761        tcg_gen_bswap32_tl(t1, t1);
24762    }
24763    gen_store_mxu_gpr(t1, XRa);
24764
24765    tcg_temp_free(t0);
24766    tcg_temp_free(t1);
24767}
24768
24769
24770/*
24771 *                 MXU instruction category: logic
24772 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24773 *
24774 *               S32NOR    S32AND    S32OR    S32XOR
24775 */
24776
24777/*
24778 *  S32NOR XRa, XRb, XRc
24779 *    Update XRa with the result of logical bitwise 'nor' operation
24780 *    applied to the content of XRb and XRc.
24781 *
24782 *   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
24783 *  +-----------+---------+-----+-------+-------+-------+-----------+
24784 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24785 *  +-----------+---------+-----+-------+-------+-------+-----------+
24786 */
24787static void gen_mxu_S32NOR(DisasContext *ctx)
24788{
24789    uint32_t pad, XRc, XRb, XRa;
24790
24791    pad = extract32(ctx->opcode, 21, 5);
24792    XRc = extract32(ctx->opcode, 14, 4);
24793    XRb = extract32(ctx->opcode, 10, 4);
24794    XRa = extract32(ctx->opcode,  6, 4);
24795
24796    if (unlikely(pad != 0)) {
24797        /* opcode padding incorrect -> do nothing */
24798    } else if (unlikely(XRa == 0)) {
24799        /* destination is zero register -> do nothing */
24800    } else if (unlikely((XRb == 0) && (XRc == 0))) {
24801        /* both operands zero registers -> just set destination to all 1s */
24802        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24803    } else if (unlikely(XRb == 0)) {
24804        /* XRb zero register -> just set destination to the negation of XRc */
24805        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24806    } else if (unlikely(XRc == 0)) {
24807        /* XRa zero register -> just set destination to the negation of XRb */
24808        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24809    } else if (unlikely(XRb == XRc)) {
24810        /* both operands same -> just set destination to the negation of XRb */
24811        tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24812    } else {
24813        /* the most general case */
24814        tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24815    }
24816}
24817
24818/*
24819 *  S32AND XRa, XRb, XRc
24820 *    Update XRa with the result of logical bitwise 'and' operation
24821 *    applied to the content of XRb and XRc.
24822 *
24823 *   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
24824 *  +-----------+---------+-----+-------+-------+-------+-----------+
24825 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24826 *  +-----------+---------+-----+-------+-------+-------+-----------+
24827 */
24828static void gen_mxu_S32AND(DisasContext *ctx)
24829{
24830    uint32_t pad, XRc, XRb, XRa;
24831
24832    pad = extract32(ctx->opcode, 21, 5);
24833    XRc = extract32(ctx->opcode, 14, 4);
24834    XRb = extract32(ctx->opcode, 10, 4);
24835    XRa = extract32(ctx->opcode,  6, 4);
24836
24837    if (unlikely(pad != 0)) {
24838        /* opcode padding incorrect -> do nothing */
24839    } else if (unlikely(XRa == 0)) {
24840        /* destination is zero register -> do nothing */
24841    } else if (unlikely((XRb == 0) || (XRc == 0))) {
24842        /* one of operands zero register -> just set destination to all 0s */
24843        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24844    } else if (unlikely(XRb == XRc)) {
24845        /* both operands same -> just set destination to one of them */
24846        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24847    } else {
24848        /* the most general case */
24849        tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24850    }
24851}
24852
24853/*
24854 *  S32OR XRa, XRb, XRc
24855 *    Update XRa with the result of logical bitwise 'or' operation
24856 *    applied to the content of XRb and XRc.
24857 *
24858 *   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
24859 *  +-----------+---------+-----+-------+-------+-------+-----------+
24860 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24861 *  +-----------+---------+-----+-------+-------+-------+-----------+
24862 */
24863static void gen_mxu_S32OR(DisasContext *ctx)
24864{
24865    uint32_t pad, XRc, XRb, XRa;
24866
24867    pad = extract32(ctx->opcode, 21, 5);
24868    XRc = extract32(ctx->opcode, 14, 4);
24869    XRb = extract32(ctx->opcode, 10, 4);
24870    XRa = extract32(ctx->opcode,  6, 4);
24871
24872    if (unlikely(pad != 0)) {
24873        /* opcode padding incorrect -> do nothing */
24874    } else if (unlikely(XRa == 0)) {
24875        /* destination is zero register -> do nothing */
24876    } else if (unlikely((XRb == 0) && (XRc == 0))) {
24877        /* both operands zero registers -> just set destination to all 0s */
24878        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24879    } else if (unlikely(XRb == 0)) {
24880        /* XRb zero register -> just set destination to the content of XRc */
24881        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24882    } else if (unlikely(XRc == 0)) {
24883        /* XRc zero register -> just set destination to the content of XRb */
24884        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24885    } else if (unlikely(XRb == XRc)) {
24886        /* both operands same -> just set destination to one of them */
24887        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24888    } else {
24889        /* the most general case */
24890        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24891    }
24892}
24893
24894/*
24895 *  S32XOR XRa, XRb, XRc
24896 *    Update XRa with the result of logical bitwise 'xor' operation
24897 *    applied to the content of XRb and XRc.
24898 *
24899 *   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
24900 *  +-----------+---------+-----+-------+-------+-------+-----------+
24901 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24902 *  +-----------+---------+-----+-------+-------+-------+-----------+
24903 */
24904static void gen_mxu_S32XOR(DisasContext *ctx)
24905{
24906    uint32_t pad, XRc, XRb, XRa;
24907
24908    pad = extract32(ctx->opcode, 21, 5);
24909    XRc = extract32(ctx->opcode, 14, 4);
24910    XRb = extract32(ctx->opcode, 10, 4);
24911    XRa = extract32(ctx->opcode,  6, 4);
24912
24913    if (unlikely(pad != 0)) {
24914        /* opcode padding incorrect -> do nothing */
24915    } else if (unlikely(XRa == 0)) {
24916        /* destination is zero register -> do nothing */
24917    } else if (unlikely((XRb == 0) && (XRc == 0))) {
24918        /* both operands zero registers -> just set destination to all 0s */
24919        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24920    } else if (unlikely(XRb == 0)) {
24921        /* XRb zero register -> just set destination to the content of XRc */
24922        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24923    } else if (unlikely(XRc == 0)) {
24924        /* XRc zero register -> just set destination to the content of XRb */
24925        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24926    } else if (unlikely(XRb == XRc)) {
24927        /* both operands same -> just set destination to all 0s */
24928        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24929    } else {
24930        /* the most general case */
24931        tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24932    }
24933}
24934
24935
24936/*
24937 *                   MXU instruction category max/min
24938 *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24939 *
24940 *                     S32MAX     D16MAX     Q8MAX
24941 *                     S32MIN     D16MIN     Q8MIN
24942 */
24943
24944/*
24945 *  S32MAX XRa, XRb, XRc
24946 *    Update XRa with the maximum of signed 32-bit integers contained
24947 *    in XRb and XRc.
24948 *
24949 *  S32MIN XRa, XRb, XRc
24950 *    Update XRa with the minimum of signed 32-bit integers contained
24951 *    in XRb and XRc.
24952 *
24953 *   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
24954 *  +-----------+---------+-----+-------+-------+-------+-----------+
24955 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
24956 *  +-----------+---------+-----+-------+-------+-------+-----------+
24957 */
24958static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
24959{
24960    uint32_t pad, opc, XRc, XRb, XRa;
24961
24962    pad = extract32(ctx->opcode, 21, 5);
24963    opc = extract32(ctx->opcode, 18, 3);
24964    XRc = extract32(ctx->opcode, 14, 4);
24965    XRb = extract32(ctx->opcode, 10, 4);
24966    XRa = extract32(ctx->opcode,  6, 4);
24967
24968    if (unlikely(pad != 0)) {
24969        /* opcode padding incorrect -> do nothing */
24970    } else if (unlikely(XRa == 0)) {
24971        /* destination is zero register -> do nothing */
24972    } else if (unlikely((XRb == 0) && (XRc == 0))) {
24973        /* both operands zero registers -> just set destination to zero */
24974        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24975    } else if (unlikely((XRb == 0) || (XRc == 0))) {
24976        /* exactly one operand is zero register - find which one is not...*/
24977        uint32_t XRx = XRb ? XRb : XRc;
24978        /* ...and do max/min operation with one operand 0 */
24979        if (opc == OPC_MXU_S32MAX) {
24980            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24981        } else {
24982            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24983        }
24984    } else if (unlikely(XRb == XRc)) {
24985        /* both operands same -> just set destination to one of them */
24986        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24987    } else {
24988        /* the most general case */
24989        if (opc == OPC_MXU_S32MAX) {
24990            tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24991                                               mxu_gpr[XRc - 1]);
24992        } else {
24993            tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24994                                               mxu_gpr[XRc - 1]);
24995        }
24996    }
24997}
24998
24999/*
25000 *  D16MAX
25001 *    Update XRa with the 16-bit-wise maximums of signed integers
25002 *    contained in XRb and XRc.
25003 *
25004 *  D16MIN
25005 *    Update XRa with the 16-bit-wise minimums of signed integers
25006 *    contained in XRb and XRc.
25007 *
25008 *   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
25009 *  +-----------+---------+-----+-------+-------+-------+-----------+
25010 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25011 *  +-----------+---------+-----+-------+-------+-------+-----------+
25012 */
25013static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25014{
25015    uint32_t pad, opc, XRc, XRb, XRa;
25016
25017    pad = extract32(ctx->opcode, 21, 5);
25018    opc = extract32(ctx->opcode, 18, 3);
25019    XRc = extract32(ctx->opcode, 14, 4);
25020    XRb = extract32(ctx->opcode, 10, 4);
25021    XRa = extract32(ctx->opcode,  6, 4);
25022
25023    if (unlikely(pad != 0)) {
25024        /* opcode padding incorrect -> do nothing */
25025    } else if (unlikely(XRc == 0)) {
25026        /* destination is zero register -> do nothing */
25027    } else if (unlikely((XRb == 0) && (XRa == 0))) {
25028        /* both operands zero registers -> just set destination to zero */
25029        tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25030    } else if (unlikely((XRb == 0) || (XRa == 0))) {
25031        /* exactly one operand is zero register - find which one is not...*/
25032        uint32_t XRx = XRb ? XRb : XRc;
25033        /* ...and do half-word-wise max/min with one operand 0 */
25034        TCGv_i32 t0 = tcg_temp_new();
25035        TCGv_i32 t1 = tcg_const_i32(0);
25036
25037        /* the left half-word first */
25038        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25039        if (opc == OPC_MXU_D16MAX) {
25040            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25041        } else {
25042            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25043        }
25044
25045        /* the right half-word */
25046        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25047        /* move half-words to the leftmost position */
25048        tcg_gen_shli_i32(t0, t0, 16);
25049        /* t0 will be max/min of t0 and t1 */
25050        if (opc == OPC_MXU_D16MAX) {
25051            tcg_gen_smax_i32(t0, t0, t1);
25052        } else {
25053            tcg_gen_smin_i32(t0, t0, t1);
25054        }
25055        /* return resulting half-words to its original position */
25056        tcg_gen_shri_i32(t0, t0, 16);
25057        /* finaly update the destination */
25058        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25059
25060        tcg_temp_free(t1);
25061        tcg_temp_free(t0);
25062    } else if (unlikely(XRb == XRc)) {
25063        /* both operands same -> just set destination to one of them */
25064        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25065    } else {
25066        /* the most general case */
25067        TCGv_i32 t0 = tcg_temp_new();
25068        TCGv_i32 t1 = tcg_temp_new();
25069
25070        /* the left half-word first */
25071        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25072        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25073        if (opc == OPC_MXU_D16MAX) {
25074            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25075        } else {
25076            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25077        }
25078
25079        /* the right half-word */
25080        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25081        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25082        /* move half-words to the leftmost position */
25083        tcg_gen_shli_i32(t0, t0, 16);
25084        tcg_gen_shli_i32(t1, t1, 16);
25085        /* t0 will be max/min of t0 and t1 */
25086        if (opc == OPC_MXU_D16MAX) {
25087            tcg_gen_smax_i32(t0, t0, t1);
25088        } else {
25089            tcg_gen_smin_i32(t0, t0, t1);
25090        }
25091        /* return resulting half-words to its original position */
25092        tcg_gen_shri_i32(t0, t0, 16);
25093        /* finaly update the destination */
25094        tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25095
25096        tcg_temp_free(t1);
25097        tcg_temp_free(t0);
25098    }
25099}
25100
25101/*
25102 *  Q8MAX
25103 *    Update XRa with the 8-bit-wise maximums of signed integers
25104 *    contained in XRb and XRc.
25105 *
25106 *  Q8MIN
25107 *    Update XRa with the 8-bit-wise minimums of signed integers
25108 *    contained in XRb and XRc.
25109 *
25110 *   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
25111 *  +-----------+---------+-----+-------+-------+-------+-----------+
25112 *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25113 *  +-----------+---------+-----+-------+-------+-------+-----------+
25114 */
25115static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25116{
25117    uint32_t pad, opc, XRc, XRb, XRa;
25118
25119    pad = extract32(ctx->opcode, 21, 5);
25120    opc = extract32(ctx->opcode, 18, 3);
25121    XRc = extract32(ctx->opcode, 14, 4);
25122    XRb = extract32(ctx->opcode, 10, 4);
25123    XRa = extract32(ctx->opcode,  6, 4);
25124
25125    if (unlikely(pad != 0)) {
25126        /* opcode padding incorrect -> do nothing */
25127    } else if (unlikely(XRa == 0)) {
25128        /* destination is zero register -> do nothing */
25129    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25130        /* both operands zero registers -> just set destination to zero */
25131        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25132    } else if (unlikely((XRb == 0) || (XRc == 0))) {
25133        /* exactly one operand is zero register - make it be the first...*/
25134        uint32_t XRx = XRb ? XRb : XRc;
25135        /* ...and do byte-wise max/min with one operand 0 */
25136        TCGv_i32 t0 = tcg_temp_new();
25137        TCGv_i32 t1 = tcg_const_i32(0);
25138        int32_t i;
25139
25140        /* the leftmost byte (byte 3) first */
25141        tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25142        if (opc == OPC_MXU_Q8MAX) {
25143            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25144        } else {
25145            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25146        }
25147
25148        /* bytes 2, 1, 0 */
25149        for (i = 2; i >= 0; i--) {
25150            /* extract the byte */
25151            tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25152            /* move the byte to the leftmost position */
25153            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25154            /* t0 will be max/min of t0 and t1 */
25155            if (opc == OPC_MXU_Q8MAX) {
25156                tcg_gen_smax_i32(t0, t0, t1);
25157            } else {
25158                tcg_gen_smin_i32(t0, t0, t1);
25159            }
25160            /* return resulting byte to its original position */
25161            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25162            /* finaly update the destination */
25163            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25164        }
25165
25166        tcg_temp_free(t1);
25167        tcg_temp_free(t0);
25168    } else if (unlikely(XRb == XRc)) {
25169        /* both operands same -> just set destination to one of them */
25170        tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25171    } else {
25172        /* the most general case */
25173        TCGv_i32 t0 = tcg_temp_new();
25174        TCGv_i32 t1 = tcg_temp_new();
25175        int32_t i;
25176
25177        /* the leftmost bytes (bytes 3) first */
25178        tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25179        tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25180        if (opc == OPC_MXU_Q8MAX) {
25181            tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25182        } else {
25183            tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25184        }
25185
25186        /* bytes 2, 1, 0 */
25187        for (i = 2; i >= 0; i--) {
25188            /* extract corresponding bytes */
25189            tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25190            tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25191            /* move the bytes to the leftmost position */
25192            tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25193            tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25194            /* t0 will be max/min of t0 and t1 */
25195            if (opc == OPC_MXU_Q8MAX) {
25196                tcg_gen_smax_i32(t0, t0, t1);
25197            } else {
25198                tcg_gen_smin_i32(t0, t0, t1);
25199            }
25200            /* return resulting byte to its original position */
25201            tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25202            /* finaly update the destination */
25203            tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25204        }
25205
25206        tcg_temp_free(t1);
25207        tcg_temp_free(t0);
25208    }
25209}
25210
25211
25212/*
25213 *                 MXU instruction category: align
25214 *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25215 *
25216 *                       S32ALN     S32ALNI
25217 */
25218
25219/*
25220 *  S32ALNI XRc, XRb, XRa, optn3
25221 *    Arrange bytes from XRb and XRc according to one of five sets of
25222 *    rules determined by optn3, and place the result in XRa.
25223 *
25224 *   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
25225 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25226 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25227 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25228 *
25229 */
25230static void gen_mxu_S32ALNI(DisasContext *ctx)
25231{
25232    uint32_t optn3, pad, XRc, XRb, XRa;
25233
25234    optn3 = extract32(ctx->opcode,  23, 3);
25235    pad   = extract32(ctx->opcode,  21, 2);
25236    XRc   = extract32(ctx->opcode, 14, 4);
25237    XRb   = extract32(ctx->opcode, 10, 4);
25238    XRa   = extract32(ctx->opcode,  6, 4);
25239
25240    if (unlikely(pad != 0)) {
25241        /* opcode padding incorrect -> do nothing */
25242    } else if (unlikely(XRa == 0)) {
25243        /* destination is zero register -> do nothing */
25244    } else if (unlikely((XRb == 0) && (XRc == 0))) {
25245        /* both operands zero registers -> just set destination to all 0s */
25246        tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25247    } else if (unlikely(XRb == 0)) {
25248        /* XRb zero register -> just appropriatelly shift XRc into XRa */
25249        switch (optn3) {
25250        case MXU_OPTN3_PTN0:
25251            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25252            break;
25253        case MXU_OPTN3_PTN1:
25254        case MXU_OPTN3_PTN2:
25255        case MXU_OPTN3_PTN3:
25256            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25257                             8 * (4 - optn3));
25258            break;
25259        case MXU_OPTN3_PTN4:
25260            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25261            break;
25262        }
25263    } else if (unlikely(XRc == 0)) {
25264        /* XRc zero register -> just appropriatelly shift XRb into XRa */
25265        switch (optn3) {
25266        case MXU_OPTN3_PTN0:
25267            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25268            break;
25269        case MXU_OPTN3_PTN1:
25270        case MXU_OPTN3_PTN2:
25271        case MXU_OPTN3_PTN3:
25272            tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25273            break;
25274        case MXU_OPTN3_PTN4:
25275            tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25276            break;
25277        }
25278    } else if (unlikely(XRb == XRc)) {
25279        /* both operands same -> just rotation or moving from any of them */
25280        switch (optn3) {
25281        case MXU_OPTN3_PTN0:
25282        case MXU_OPTN3_PTN4:
25283            tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25284            break;
25285        case MXU_OPTN3_PTN1:
25286        case MXU_OPTN3_PTN2:
25287        case MXU_OPTN3_PTN3:
25288            tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25289            break;
25290        }
25291    } else {
25292        /* the most general case */
25293        switch (optn3) {
25294        case MXU_OPTN3_PTN0:
25295            {
25296                /*                                         */
25297                /*         XRb                XRc          */
25298                /*  +---------------+                      */
25299                /*  | A   B   C   D |    E   F   G   H     */
25300                /*  +-------+-------+                      */
25301                /*          |                              */
25302                /*         XRa                             */
25303                /*                                         */
25304
25305                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25306            }
25307            break;
25308        case MXU_OPTN3_PTN1:
25309            {
25310                /*                                         */
25311                /*         XRb                 XRc         */
25312                /*      +-------------------+              */
25313                /*    A | B   C   D       E | F   G   H    */
25314                /*      +---------+---------+              */
25315                /*                |                        */
25316                /*               XRa                       */
25317                /*                                         */
25318
25319                TCGv_i32 t0 = tcg_temp_new();
25320                TCGv_i32 t1 = tcg_temp_new();
25321
25322                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25323                tcg_gen_shli_i32(t0, t0, 8);
25324
25325                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25326                tcg_gen_shri_i32(t1, t1, 24);
25327
25328                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25329
25330                tcg_temp_free(t1);
25331                tcg_temp_free(t0);
25332            }
25333            break;
25334        case MXU_OPTN3_PTN2:
25335            {
25336                /*                                         */
25337                /*         XRb                 XRc         */
25338                /*          +-------------------+          */
25339                /*    A   B | C   D       E   F | G   H    */
25340                /*          +---------+---------+          */
25341                /*                    |                    */
25342                /*                   XRa                   */
25343                /*                                         */
25344
25345                TCGv_i32 t0 = tcg_temp_new();
25346                TCGv_i32 t1 = tcg_temp_new();
25347
25348                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25349                tcg_gen_shli_i32(t0, t0, 16);
25350
25351                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25352                tcg_gen_shri_i32(t1, t1, 16);
25353
25354                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25355
25356                tcg_temp_free(t1);
25357                tcg_temp_free(t0);
25358            }
25359            break;
25360        case MXU_OPTN3_PTN3:
25361            {
25362                /*                                         */
25363                /*         XRb                 XRc         */
25364                /*              +-------------------+      */
25365                /*    A   B   C | D       E   F   G | H    */
25366                /*              +---------+---------+      */
25367                /*                        |                */
25368                /*                       XRa               */
25369                /*                                         */
25370
25371                TCGv_i32 t0 = tcg_temp_new();
25372                TCGv_i32 t1 = tcg_temp_new();
25373
25374                tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25375                tcg_gen_shli_i32(t0, t0, 24);
25376
25377                tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25378                tcg_gen_shri_i32(t1, t1, 8);
25379
25380                tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25381
25382                tcg_temp_free(t1);
25383                tcg_temp_free(t0);
25384            }
25385            break;
25386        case MXU_OPTN3_PTN4:
25387            {
25388                /*                                         */
25389                /*         XRb                 XRc         */
25390                /*                     +---------------+   */
25391                /*    A   B   C   D    | E   F   G   H |   */
25392                /*                     +-------+-------+   */
25393                /*                             |           */
25394                /*                            XRa          */
25395                /*                                         */
25396
25397                tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25398            }
25399            break;
25400        }
25401    }
25402}
25403
25404
25405/*
25406 * Decoding engine for MXU
25407 * =======================
25408 */
25409
25410/*
25411 *
25412 * Decode MXU pool00
25413 *
25414 *   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
25415 *  +-----------+---------+-----+-------+-------+-------+-----------+
25416 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25417 *  +-----------+---------+-----+-------+-------+-------+-----------+
25418 *
25419 */
25420static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25421{
25422    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25423
25424    switch (opcode) {
25425    case OPC_MXU_S32MAX:
25426    case OPC_MXU_S32MIN:
25427        gen_mxu_S32MAX_S32MIN(ctx);
25428        break;
25429    case OPC_MXU_D16MAX:
25430    case OPC_MXU_D16MIN:
25431        gen_mxu_D16MAX_D16MIN(ctx);
25432        break;
25433    case OPC_MXU_Q8MAX:
25434    case OPC_MXU_Q8MIN:
25435        gen_mxu_Q8MAX_Q8MIN(ctx);
25436        break;
25437    case OPC_MXU_Q8SLT:
25438        /* TODO: Implement emulation of Q8SLT instruction. */
25439        MIPS_INVAL("OPC_MXU_Q8SLT");
25440        generate_exception_end(ctx, EXCP_RI);
25441        break;
25442    case OPC_MXU_Q8SLTU:
25443        /* TODO: Implement emulation of Q8SLTU instruction. */
25444        MIPS_INVAL("OPC_MXU_Q8SLTU");
25445        generate_exception_end(ctx, EXCP_RI);
25446        break;
25447    default:
25448        MIPS_INVAL("decode_opc_mxu");
25449        generate_exception_end(ctx, EXCP_RI);
25450        break;
25451    }
25452}
25453
25454/*
25455 *
25456 * Decode MXU pool01
25457 *
25458 *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25459 *   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
25460 *  +-----------+---------+-----+-------+-------+-------+-----------+
25461 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25462 *  +-----------+---------+-----+-------+-------+-------+-----------+
25463 *
25464 *  Q8ADD:
25465 *   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
25466 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25467 *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25468 *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25469 *
25470 */
25471static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25472{
25473    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25474
25475    switch (opcode) {
25476    case OPC_MXU_S32SLT:
25477        /* TODO: Implement emulation of S32SLT instruction. */
25478        MIPS_INVAL("OPC_MXU_S32SLT");
25479        generate_exception_end(ctx, EXCP_RI);
25480        break;
25481    case OPC_MXU_D16SLT:
25482        /* TODO: Implement emulation of D16SLT instruction. */
25483        MIPS_INVAL("OPC_MXU_D16SLT");
25484        generate_exception_end(ctx, EXCP_RI);
25485        break;
25486    case OPC_MXU_D16AVG:
25487        /* TODO: Implement emulation of D16AVG instruction. */
25488        MIPS_INVAL("OPC_MXU_D16AVG");
25489        generate_exception_end(ctx, EXCP_RI);
25490        break;
25491    case OPC_MXU_D16AVGR:
25492        /* TODO: Implement emulation of D16AVGR instruction. */
25493        MIPS_INVAL("OPC_MXU_D16AVGR");
25494        generate_exception_end(ctx, EXCP_RI);
25495        break;
25496    case OPC_MXU_Q8AVG:
25497        /* TODO: Implement emulation of Q8AVG instruction. */
25498        MIPS_INVAL("OPC_MXU_Q8AVG");
25499        generate_exception_end(ctx, EXCP_RI);
25500        break;
25501    case OPC_MXU_Q8AVGR:
25502        /* TODO: Implement emulation of Q8AVGR instruction. */
25503        MIPS_INVAL("OPC_MXU_Q8AVGR");
25504        generate_exception_end(ctx, EXCP_RI);
25505        break;
25506    case OPC_MXU_Q8ADD:
25507        /* TODO: Implement emulation of Q8ADD instruction. */
25508        MIPS_INVAL("OPC_MXU_Q8ADD");
25509        generate_exception_end(ctx, EXCP_RI);
25510        break;
25511    default:
25512        MIPS_INVAL("decode_opc_mxu");
25513        generate_exception_end(ctx, EXCP_RI);
25514        break;
25515    }
25516}
25517
25518/*
25519 *
25520 * Decode MXU pool02
25521 *
25522 *   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
25523 *  +-----------+---------+-----+-------+-------+-------+-----------+
25524 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
25525 *  +-----------+---------+-----+-------+-------+-------+-----------+
25526 *
25527 */
25528static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25529{
25530    uint32_t opcode = extract32(ctx->opcode, 18, 3);
25531
25532    switch (opcode) {
25533    case OPC_MXU_S32CPS:
25534        /* TODO: Implement emulation of S32CPS instruction. */
25535        MIPS_INVAL("OPC_MXU_S32CPS");
25536        generate_exception_end(ctx, EXCP_RI);
25537        break;
25538    case OPC_MXU_D16CPS:
25539        /* TODO: Implement emulation of D16CPS instruction. */
25540        MIPS_INVAL("OPC_MXU_D16CPS");
25541        generate_exception_end(ctx, EXCP_RI);
25542        break;
25543    case OPC_MXU_Q8ABD:
25544        /* TODO: Implement emulation of Q8ABD instruction. */
25545        MIPS_INVAL("OPC_MXU_Q8ABD");
25546        generate_exception_end(ctx, EXCP_RI);
25547        break;
25548    case OPC_MXU_Q16SAT:
25549        /* TODO: Implement emulation of Q16SAT instruction. */
25550        MIPS_INVAL("OPC_MXU_Q16SAT");
25551        generate_exception_end(ctx, EXCP_RI);
25552        break;
25553    default:
25554        MIPS_INVAL("decode_opc_mxu");
25555        generate_exception_end(ctx, EXCP_RI);
25556        break;
25557    }
25558}
25559
25560/*
25561 *
25562 * Decode MXU pool03
25563 *
25564 *  D16MULF:
25565 *   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
25566 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25567 *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
25568 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25569 *
25570 *  D16MULE:
25571 *   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
25572 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25573 *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
25574 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25575 *
25576 */
25577static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25578{
25579    uint32_t opcode = extract32(ctx->opcode, 24, 2);
25580
25581    switch (opcode) {
25582    case OPC_MXU_D16MULF:
25583        /* TODO: Implement emulation of D16MULF instruction. */
25584        MIPS_INVAL("OPC_MXU_D16MULF");
25585        generate_exception_end(ctx, EXCP_RI);
25586        break;
25587    case OPC_MXU_D16MULE:
25588        /* TODO: Implement emulation of D16MULE instruction. */
25589        MIPS_INVAL("OPC_MXU_D16MULE");
25590        generate_exception_end(ctx, EXCP_RI);
25591        break;
25592    default:
25593        MIPS_INVAL("decode_opc_mxu");
25594        generate_exception_end(ctx, EXCP_RI);
25595        break;
25596    }
25597}
25598
25599/*
25600 *
25601 * Decode MXU pool04
25602 *
25603 *   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
25604 *  +-----------+---------+-+-------------------+-------+-----------+
25605 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
25606 *  +-----------+---------+-+-------------------+-------+-----------+
25607 *
25608 */
25609static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25610{
25611    uint32_t opcode = extract32(ctx->opcode, 20, 1);
25612
25613    switch (opcode) {
25614    case OPC_MXU_S32LDD:
25615    case OPC_MXU_S32LDDR:
25616        gen_mxu_s32ldd_s32lddr(ctx);
25617        break;
25618    default:
25619        MIPS_INVAL("decode_opc_mxu");
25620        generate_exception_end(ctx, EXCP_RI);
25621        break;
25622    }
25623}
25624
25625/*
25626 *
25627 * Decode MXU pool05
25628 *
25629 *   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
25630 *  +-----------+---------+-+-------------------+-------+-----------+
25631 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
25632 *  +-----------+---------+-+-------------------+-------+-----------+
25633 *
25634 */
25635static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25636{
25637    uint32_t opcode = extract32(ctx->opcode, 20, 1);
25638
25639    switch (opcode) {
25640    case OPC_MXU_S32STD:
25641        /* TODO: Implement emulation of S32STD instruction. */
25642        MIPS_INVAL("OPC_MXU_S32STD");
25643        generate_exception_end(ctx, EXCP_RI);
25644        break;
25645    case OPC_MXU_S32STDR:
25646        /* TODO: Implement emulation of S32STDR instruction. */
25647        MIPS_INVAL("OPC_MXU_S32STDR");
25648        generate_exception_end(ctx, EXCP_RI);
25649        break;
25650    default:
25651        MIPS_INVAL("decode_opc_mxu");
25652        generate_exception_end(ctx, EXCP_RI);
25653        break;
25654    }
25655}
25656
25657/*
25658 *
25659 * Decode MXU pool06
25660 *
25661 *   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
25662 *  +-----------+---------+---------+---+-------+-------+-----------+
25663 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
25664 *  +-----------+---------+---------+---+-------+-------+-----------+
25665 *
25666 */
25667static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25668{
25669    uint32_t opcode = extract32(ctx->opcode, 10, 4);
25670
25671    switch (opcode) {
25672    case OPC_MXU_S32LDDV:
25673        /* TODO: Implement emulation of S32LDDV instruction. */
25674        MIPS_INVAL("OPC_MXU_S32LDDV");
25675        generate_exception_end(ctx, EXCP_RI);
25676        break;
25677    case OPC_MXU_S32LDDVR:
25678        /* TODO: Implement emulation of S32LDDVR instruction. */
25679        MIPS_INVAL("OPC_MXU_S32LDDVR");
25680        generate_exception_end(ctx, EXCP_RI);
25681        break;
25682    default:
25683        MIPS_INVAL("decode_opc_mxu");
25684        generate_exception_end(ctx, EXCP_RI);
25685        break;
25686    }
25687}
25688
25689/*
25690 *
25691 * Decode MXU pool07
25692 *
25693 *   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
25694 *  +-----------+---------+---------+---+-------+-------+-----------+
25695 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
25696 *  +-----------+---------+---------+---+-------+-------+-----------+
25697 *
25698 */
25699static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25700{
25701    uint32_t opcode = extract32(ctx->opcode, 10, 4);
25702
25703    switch (opcode) {
25704    case OPC_MXU_S32STDV:
25705        /* TODO: Implement emulation of S32TDV instruction. */
25706        MIPS_INVAL("OPC_MXU_S32TDV");
25707        generate_exception_end(ctx, EXCP_RI);
25708        break;
25709    case OPC_MXU_S32STDVR:
25710        /* TODO: Implement emulation of S32TDVR instruction. */
25711        MIPS_INVAL("OPC_MXU_S32TDVR");
25712        generate_exception_end(ctx, EXCP_RI);
25713        break;
25714    default:
25715        MIPS_INVAL("decode_opc_mxu");
25716        generate_exception_end(ctx, EXCP_RI);
25717        break;
25718    }
25719}
25720
25721/*
25722 *
25723 * Decode MXU pool08
25724 *
25725 *   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
25726 *  +-----------+---------+-+-------------------+-------+-----------+
25727 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
25728 *  +-----------+---------+-+-------------------+-------+-----------+
25729 *
25730*/
25731static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25732{
25733    uint32_t opcode = extract32(ctx->opcode, 20, 1);
25734
25735    switch (opcode) {
25736    case OPC_MXU_S32LDI:
25737        /* TODO: Implement emulation of S32LDI instruction. */
25738        MIPS_INVAL("OPC_MXU_S32LDI");
25739        generate_exception_end(ctx, EXCP_RI);
25740        break;
25741    case OPC_MXU_S32LDIR:
25742        /* TODO: Implement emulation of S32LDIR instruction. */
25743        MIPS_INVAL("OPC_MXU_S32LDIR");
25744        generate_exception_end(ctx, EXCP_RI);
25745        break;
25746    default:
25747        MIPS_INVAL("decode_opc_mxu");
25748        generate_exception_end(ctx, EXCP_RI);
25749        break;
25750    }
25751}
25752
25753/*
25754 *
25755 * Decode MXU pool09
25756 *
25757 *   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
25758 *  +-----------+---------+-+-------------------+-------+-----------+
25759 *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
25760 *  +-----------+---------+-+-------------------+-------+-----------+
25761 *
25762 */
25763static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25764{
25765    uint32_t opcode = extract32(ctx->opcode, 5, 0);
25766
25767    switch (opcode) {
25768    case OPC_MXU_S32SDI:
25769        /* TODO: Implement emulation of S32SDI instruction. */
25770        MIPS_INVAL("OPC_MXU_S32SDI");
25771        generate_exception_end(ctx, EXCP_RI);
25772        break;
25773    case OPC_MXU_S32SDIR:
25774        /* TODO: Implement emulation of S32SDIR instruction. */
25775        MIPS_INVAL("OPC_MXU_S32SDIR");
25776        generate_exception_end(ctx, EXCP_RI);
25777        break;
25778    default:
25779        MIPS_INVAL("decode_opc_mxu");
25780        generate_exception_end(ctx, EXCP_RI);
25781        break;
25782    }
25783}
25784
25785/*
25786 *
25787 * Decode MXU pool10
25788 *
25789 *   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
25790 *  +-----------+---------+---------+---+-------+-------+-----------+
25791 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
25792 *  +-----------+---------+---------+---+-------+-------+-----------+
25793 *
25794 */
25795static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25796{
25797    uint32_t opcode = extract32(ctx->opcode, 5, 0);
25798
25799    switch (opcode) {
25800    case OPC_MXU_S32LDIV:
25801        /* TODO: Implement emulation of S32LDIV instruction. */
25802        MIPS_INVAL("OPC_MXU_S32LDIV");
25803        generate_exception_end(ctx, EXCP_RI);
25804        break;
25805    case OPC_MXU_S32LDIVR:
25806        /* TODO: Implement emulation of S32LDIVR instruction. */
25807        MIPS_INVAL("OPC_MXU_S32LDIVR");
25808        generate_exception_end(ctx, EXCP_RI);
25809        break;
25810    default:
25811        MIPS_INVAL("decode_opc_mxu");
25812        generate_exception_end(ctx, EXCP_RI);
25813        break;
25814    }
25815}
25816
25817/*
25818 *
25819 * Decode MXU pool11
25820 *
25821 *   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
25822 *  +-----------+---------+---------+---+-------+-------+-----------+
25823 *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
25824 *  +-----------+---------+---------+---+-------+-------+-----------+
25825 *
25826 */
25827static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25828{
25829    uint32_t opcode = extract32(ctx->opcode, 10, 4);
25830
25831    switch (opcode) {
25832    case OPC_MXU_S32SDIV:
25833        /* TODO: Implement emulation of S32SDIV instruction. */
25834        MIPS_INVAL("OPC_MXU_S32SDIV");
25835        generate_exception_end(ctx, EXCP_RI);
25836        break;
25837    case OPC_MXU_S32SDIVR:
25838        /* TODO: Implement emulation of S32SDIVR instruction. */
25839        MIPS_INVAL("OPC_MXU_S32SDIVR");
25840        generate_exception_end(ctx, EXCP_RI);
25841        break;
25842    default:
25843        MIPS_INVAL("decode_opc_mxu");
25844        generate_exception_end(ctx, EXCP_RI);
25845        break;
25846    }
25847}
25848
25849/*
25850 *
25851 * Decode MXU pool12
25852 *
25853 *   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
25854 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25855 *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
25856 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25857 *
25858 */
25859static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25860{
25861    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25862
25863    switch (opcode) {
25864    case OPC_MXU_D32ACC:
25865        /* TODO: Implement emulation of D32ACC instruction. */
25866        MIPS_INVAL("OPC_MXU_D32ACC");
25867        generate_exception_end(ctx, EXCP_RI);
25868        break;
25869    case OPC_MXU_D32ACCM:
25870        /* TODO: Implement emulation of D32ACCM instruction. */
25871        MIPS_INVAL("OPC_MXU_D32ACCM");
25872        generate_exception_end(ctx, EXCP_RI);
25873        break;
25874    case OPC_MXU_D32ASUM:
25875        /* TODO: Implement emulation of D32ASUM instruction. */
25876        MIPS_INVAL("OPC_MXU_D32ASUM");
25877        generate_exception_end(ctx, EXCP_RI);
25878        break;
25879    default:
25880        MIPS_INVAL("decode_opc_mxu");
25881        generate_exception_end(ctx, EXCP_RI);
25882        break;
25883    }
25884}
25885
25886/*
25887 *
25888 * Decode MXU pool13
25889 *
25890 *   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
25891 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25892 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
25893 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25894 *
25895 */
25896static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25897{
25898    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25899
25900    switch (opcode) {
25901    case OPC_MXU_Q16ACC:
25902        /* TODO: Implement emulation of Q16ACC instruction. */
25903        MIPS_INVAL("OPC_MXU_Q16ACC");
25904        generate_exception_end(ctx, EXCP_RI);
25905        break;
25906    case OPC_MXU_Q16ACCM:
25907        /* TODO: Implement emulation of Q16ACCM instruction. */
25908        MIPS_INVAL("OPC_MXU_Q16ACCM");
25909        generate_exception_end(ctx, EXCP_RI);
25910        break;
25911    case OPC_MXU_Q16ASUM:
25912        /* TODO: Implement emulation of Q16ASUM instruction. */
25913        MIPS_INVAL("OPC_MXU_Q16ASUM");
25914        generate_exception_end(ctx, EXCP_RI);
25915        break;
25916    default:
25917        MIPS_INVAL("decode_opc_mxu");
25918        generate_exception_end(ctx, EXCP_RI);
25919        break;
25920    }
25921}
25922
25923/*
25924 *
25925 * Decode MXU pool14
25926 *
25927 *  Q8ADDE, Q8ACCE:
25928 *   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
25929 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25930 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
25931 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25932 *
25933 *  D8SUM, D8SUMC:
25934 *   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
25935 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25936 *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
25937 *  +-----------+---+---+-------+-------+-------+-------+-----------+
25938 *
25939 */
25940static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25941{
25942    uint32_t opcode = extract32(ctx->opcode, 22, 2);
25943
25944    switch (opcode) {
25945    case OPC_MXU_Q8ADDE:
25946        /* TODO: Implement emulation of Q8ADDE instruction. */
25947        MIPS_INVAL("OPC_MXU_Q8ADDE");
25948        generate_exception_end(ctx, EXCP_RI);
25949        break;
25950    case OPC_MXU_D8SUM:
25951        /* TODO: Implement emulation of D8SUM instruction. */
25952        MIPS_INVAL("OPC_MXU_D8SUM");
25953        generate_exception_end(ctx, EXCP_RI);
25954        break;
25955    case OPC_MXU_D8SUMC:
25956        /* TODO: Implement emulation of D8SUMC instruction. */
25957        MIPS_INVAL("OPC_MXU_D8SUMC");
25958        generate_exception_end(ctx, EXCP_RI);
25959        break;
25960    default:
25961        MIPS_INVAL("decode_opc_mxu");
25962        generate_exception_end(ctx, EXCP_RI);
25963        break;
25964    }
25965}
25966
25967/*
25968 *
25969 * Decode MXU pool15
25970 *
25971 *  S32MUL, S32MULU, S32EXTRV:
25972 *   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
25973 *  +-----------+---------+---------+---+-------+-------+-----------+
25974 *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
25975 *  +-----------+---------+---------+---+-------+-------+-----------+
25976 *
25977 *  S32EXTR:
25978 *   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
25979 *  +-----------+---------+---------+---+-------+-------+-----------+
25980 *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
25981 *  +-----------+---------+---------+---+-------+-------+-----------+
25982 *
25983 */
25984static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25985{
25986    uint32_t opcode = extract32(ctx->opcode, 14, 2);
25987
25988    switch (opcode) {
25989    case OPC_MXU_S32MUL:
25990        /* TODO: Implement emulation of S32MUL instruction. */
25991        MIPS_INVAL("OPC_MXU_S32MUL");
25992        generate_exception_end(ctx, EXCP_RI);
25993        break;
25994    case OPC_MXU_S32MULU:
25995        /* TODO: Implement emulation of S32MULU instruction. */
25996        MIPS_INVAL("OPC_MXU_S32MULU");
25997        generate_exception_end(ctx, EXCP_RI);
25998        break;
25999    case OPC_MXU_S32EXTR:
26000        /* TODO: Implement emulation of S32EXTR instruction. */
26001        MIPS_INVAL("OPC_MXU_S32EXTR");
26002        generate_exception_end(ctx, EXCP_RI);
26003        break;
26004    case OPC_MXU_S32EXTRV:
26005        /* TODO: Implement emulation of S32EXTRV instruction. */
26006        MIPS_INVAL("OPC_MXU_S32EXTRV");
26007        generate_exception_end(ctx, EXCP_RI);
26008        break;
26009    default:
26010        MIPS_INVAL("decode_opc_mxu");
26011        generate_exception_end(ctx, EXCP_RI);
26012        break;
26013    }
26014}
26015
26016/*
26017 *
26018 * Decode MXU pool16
26019 *
26020 *  D32SARW:
26021 *   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
26022 *  +-----------+---------+-----+-------+-------+-------+-----------+
26023 *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26024 *  +-----------+---------+-----+-------+-------+-------+-----------+
26025 *
26026 *  S32ALN:
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 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26030 *  +-----------+---------+-----+-------+-------+-------+-----------+
26031 *
26032 *  S32ALNI:
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 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26036 *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26037 *
26038 *  S32LUI:
26039 *   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
26040 *  +-----------+-----+---+-----+-------+---------------+-----------+
26041 *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26042 *  +-----------+-----+---+-----+-------+---------------+-----------+
26043 *
26044 *  S32NOR, S32AND, S32OR, S32XOR:
26045 *   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
26046 *  +-----------+---------+-----+-------+-------+-------+-----------+
26047 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26048 *  +-----------+---------+-----+-------+-------+-------+-----------+
26049 *
26050 */
26051static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26052{
26053    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26054
26055    switch (opcode) {
26056    case OPC_MXU_D32SARW:
26057        /* TODO: Implement emulation of D32SARW instruction. */
26058        MIPS_INVAL("OPC_MXU_D32SARW");
26059        generate_exception_end(ctx, EXCP_RI);
26060        break;
26061    case OPC_MXU_S32ALN:
26062        /* TODO: Implement emulation of S32ALN instruction. */
26063        MIPS_INVAL("OPC_MXU_S32ALN");
26064        generate_exception_end(ctx, EXCP_RI);
26065        break;
26066    case OPC_MXU_S32ALNI:
26067        gen_mxu_S32ALNI(ctx);
26068        break;
26069    case OPC_MXU_S32LUI:
26070        /* TODO: Implement emulation of S32LUI instruction. */
26071        MIPS_INVAL("OPC_MXU_S32LUI");
26072        generate_exception_end(ctx, EXCP_RI);
26073        break;
26074    case OPC_MXU_S32NOR:
26075        gen_mxu_S32NOR(ctx);
26076        break;
26077    case OPC_MXU_S32AND:
26078        gen_mxu_S32AND(ctx);
26079        break;
26080    case OPC_MXU_S32OR:
26081        gen_mxu_S32OR(ctx);
26082        break;
26083    case OPC_MXU_S32XOR:
26084        gen_mxu_S32XOR(ctx);
26085        break;
26086    default:
26087        MIPS_INVAL("decode_opc_mxu");
26088        generate_exception_end(ctx, EXCP_RI);
26089        break;
26090    }
26091}
26092
26093/*
26094 *
26095 * Decode MXU pool17
26096 *
26097 *   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
26098 *  +-----------+---------+---------+---+---------+-----+-----------+
26099 *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26100 *  +-----------+---------+---------+---+---------+-----+-----------+
26101 *
26102 */
26103static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26104{
26105    uint32_t opcode = extract32(ctx->opcode, 6, 2);
26106
26107    switch (opcode) {
26108    case OPC_MXU_LXW:
26109        /* TODO: Implement emulation of LXW instruction. */
26110        MIPS_INVAL("OPC_MXU_LXW");
26111        generate_exception_end(ctx, EXCP_RI);
26112        break;
26113    case OPC_MXU_LXH:
26114        /* TODO: Implement emulation of LXH instruction. */
26115        MIPS_INVAL("OPC_MXU_LXH");
26116        generate_exception_end(ctx, EXCP_RI);
26117        break;
26118    case OPC_MXU_LXHU:
26119        /* TODO: Implement emulation of LXHU instruction. */
26120        MIPS_INVAL("OPC_MXU_LXHU");
26121        generate_exception_end(ctx, EXCP_RI);
26122        break;
26123    case OPC_MXU_LXB:
26124        /* TODO: Implement emulation of LXB instruction. */
26125        MIPS_INVAL("OPC_MXU_LXB");
26126        generate_exception_end(ctx, EXCP_RI);
26127        break;
26128    case OPC_MXU_LXBU:
26129        /* TODO: Implement emulation of LXBU instruction. */
26130        MIPS_INVAL("OPC_MXU_LXBU");
26131        generate_exception_end(ctx, EXCP_RI);
26132        break;
26133    default:
26134        MIPS_INVAL("decode_opc_mxu");
26135        generate_exception_end(ctx, EXCP_RI);
26136        break;
26137    }
26138}
26139/*
26140 *
26141 * Decode MXU pool18
26142 *
26143 *   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
26144 *  +-----------+---------+-----+-------+-------+-------+-----------+
26145 *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26146 *  +-----------+---------+-----+-------+-------+-------+-----------+
26147 *
26148 */
26149static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26150{
26151    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26152
26153    switch (opcode) {
26154    case OPC_MXU_D32SLLV:
26155        /* TODO: Implement emulation of D32SLLV instruction. */
26156        MIPS_INVAL("OPC_MXU_D32SLLV");
26157        generate_exception_end(ctx, EXCP_RI);
26158        break;
26159    case OPC_MXU_D32SLRV:
26160        /* TODO: Implement emulation of D32SLRV instruction. */
26161        MIPS_INVAL("OPC_MXU_D32SLRV");
26162        generate_exception_end(ctx, EXCP_RI);
26163        break;
26164    case OPC_MXU_D32SARV:
26165        /* TODO: Implement emulation of D32SARV instruction. */
26166        MIPS_INVAL("OPC_MXU_D32SARV");
26167        generate_exception_end(ctx, EXCP_RI);
26168        break;
26169    case OPC_MXU_Q16SLLV:
26170        /* TODO: Implement emulation of Q16SLLV instruction. */
26171        MIPS_INVAL("OPC_MXU_Q16SLLV");
26172        generate_exception_end(ctx, EXCP_RI);
26173        break;
26174    case OPC_MXU_Q16SLRV:
26175        /* TODO: Implement emulation of Q16SLRV instruction. */
26176        MIPS_INVAL("OPC_MXU_Q16SLRV");
26177        generate_exception_end(ctx, EXCP_RI);
26178        break;
26179    case OPC_MXU_Q16SARV:
26180        /* TODO: Implement emulation of Q16SARV instruction. */
26181        MIPS_INVAL("OPC_MXU_Q16SARV");
26182        generate_exception_end(ctx, EXCP_RI);
26183        break;
26184    default:
26185        MIPS_INVAL("decode_opc_mxu");
26186        generate_exception_end(ctx, EXCP_RI);
26187        break;
26188    }
26189}
26190
26191/*
26192 *
26193 * Decode MXU pool19
26194 *
26195 *   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
26196 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26197 *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26198 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26199 *
26200 */
26201static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26202{
26203    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26204
26205    switch (opcode) {
26206    case OPC_MXU_Q8MUL:
26207    case OPC_MXU_Q8MULSU:
26208        gen_mxu_q8mul_q8mulsu(ctx);
26209        break;
26210    default:
26211        MIPS_INVAL("decode_opc_mxu");
26212        generate_exception_end(ctx, EXCP_RI);
26213        break;
26214    }
26215}
26216
26217/*
26218 *
26219 * Decode MXU pool20
26220 *
26221 *   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
26222 *  +-----------+---------+-----+-------+-------+-------+-----------+
26223 *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26224 *  +-----------+---------+-----+-------+-------+-------+-----------+
26225 *
26226 */
26227static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26228{
26229    uint32_t opcode = extract32(ctx->opcode, 18, 3);
26230
26231    switch (opcode) {
26232    case OPC_MXU_Q8MOVZ:
26233        /* TODO: Implement emulation of Q8MOVZ instruction. */
26234        MIPS_INVAL("OPC_MXU_Q8MOVZ");
26235        generate_exception_end(ctx, EXCP_RI);
26236        break;
26237    case OPC_MXU_Q8MOVN:
26238        /* TODO: Implement emulation of Q8MOVN instruction. */
26239        MIPS_INVAL("OPC_MXU_Q8MOVN");
26240        generate_exception_end(ctx, EXCP_RI);
26241        break;
26242    case OPC_MXU_D16MOVZ:
26243        /* TODO: Implement emulation of D16MOVZ instruction. */
26244        MIPS_INVAL("OPC_MXU_D16MOVZ");
26245        generate_exception_end(ctx, EXCP_RI);
26246        break;
26247    case OPC_MXU_D16MOVN:
26248        /* TODO: Implement emulation of D16MOVN instruction. */
26249        MIPS_INVAL("OPC_MXU_D16MOVN");
26250        generate_exception_end(ctx, EXCP_RI);
26251        break;
26252    case OPC_MXU_S32MOVZ:
26253        /* TODO: Implement emulation of S32MOVZ instruction. */
26254        MIPS_INVAL("OPC_MXU_S32MOVZ");
26255        generate_exception_end(ctx, EXCP_RI);
26256        break;
26257    case OPC_MXU_S32MOVN:
26258        /* TODO: Implement emulation of S32MOVN instruction. */
26259        MIPS_INVAL("OPC_MXU_S32MOVN");
26260        generate_exception_end(ctx, EXCP_RI);
26261        break;
26262    default:
26263        MIPS_INVAL("decode_opc_mxu");
26264        generate_exception_end(ctx, EXCP_RI);
26265        break;
26266    }
26267}
26268
26269/*
26270 *
26271 * Decode MXU pool21
26272 *
26273 *   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
26274 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26275 *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26276 *  +-----------+---+---+-------+-------+-------+-------+-----------+
26277 *
26278 */
26279static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26280{
26281    uint32_t opcode = extract32(ctx->opcode, 22, 2);
26282
26283    switch (opcode) {
26284    case OPC_MXU_Q8MAC:
26285        /* TODO: Implement emulation of Q8MAC instruction. */
26286        MIPS_INVAL("OPC_MXU_Q8MAC");
26287        generate_exception_end(ctx, EXCP_RI);
26288        break;
26289    case OPC_MXU_Q8MACSU:
26290        /* TODO: Implement emulation of Q8MACSU instruction. */
26291        MIPS_INVAL("OPC_MXU_Q8MACSU");
26292        generate_exception_end(ctx, EXCP_RI);
26293        break;
26294    default:
26295        MIPS_INVAL("decode_opc_mxu");
26296        generate_exception_end(ctx, EXCP_RI);
26297        break;
26298    }
26299}
26300
26301
26302/*
26303 * Main MXU decoding function
26304 *
26305 *   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
26306 *  +-----------+---------------------------------------+-----------+
26307 *  |  SPECIAL2 |                                       |x x x x x x|
26308 *  +-----------+---------------------------------------+-----------+
26309 *
26310 */
26311static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26312{
26313    /*
26314     * TODO: Investigate necessity of including handling of
26315     * CLZ, CLO, SDBB in this function, as they belong to
26316     * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26317     */
26318    uint32_t opcode = extract32(ctx->opcode, 0, 6);
26319
26320    if (opcode == OPC__MXU_MUL) {
26321        uint32_t  rs, rt, rd, op1;
26322
26323        rs = extract32(ctx->opcode, 21, 5);
26324        rt = extract32(ctx->opcode, 16, 5);
26325        rd = extract32(ctx->opcode, 11, 5);
26326        op1 = MASK_SPECIAL2(ctx->opcode);
26327
26328        gen_arith(ctx, op1, rd, rs, rt);
26329
26330        return;
26331    }
26332
26333    if (opcode == OPC_MXU_S32M2I) {
26334        gen_mxu_s32m2i(ctx);
26335        return;
26336    }
26337
26338    if (opcode == OPC_MXU_S32I2M) {
26339        gen_mxu_s32i2m(ctx);
26340        return;
26341    }
26342
26343    {
26344        TCGv t_mxu_cr = tcg_temp_new();
26345        TCGLabel *l_exit = gen_new_label();
26346
26347        gen_load_mxu_cr(t_mxu_cr);
26348        tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26349        tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26350
26351        switch (opcode) {
26352        case OPC_MXU_S32MADD:
26353            /* TODO: Implement emulation of S32MADD instruction. */
26354            MIPS_INVAL("OPC_MXU_S32MADD");
26355            generate_exception_end(ctx, EXCP_RI);
26356            break;
26357        case OPC_MXU_S32MADDU:
26358            /* TODO: Implement emulation of S32MADDU instruction. */
26359            MIPS_INVAL("OPC_MXU_S32MADDU");
26360            generate_exception_end(ctx, EXCP_RI);
26361            break;
26362        case OPC_MXU__POOL00:
26363            decode_opc_mxu__pool00(env, ctx);
26364            break;
26365        case OPC_MXU_S32MSUB:
26366            /* TODO: Implement emulation of S32MSUB instruction. */
26367            MIPS_INVAL("OPC_MXU_S32MSUB");
26368            generate_exception_end(ctx, EXCP_RI);
26369            break;
26370        case OPC_MXU_S32MSUBU:
26371            /* TODO: Implement emulation of S32MSUBU instruction. */
26372            MIPS_INVAL("OPC_MXU_S32MSUBU");
26373            generate_exception_end(ctx, EXCP_RI);
26374            break;
26375        case OPC_MXU__POOL01:
26376            decode_opc_mxu__pool01(env, ctx);
26377            break;
26378        case OPC_MXU__POOL02:
26379            decode_opc_mxu__pool02(env, ctx);
26380            break;
26381        case OPC_MXU_D16MUL:
26382            gen_mxu_d16mul(ctx);
26383            break;
26384        case OPC_MXU__POOL03:
26385            decode_opc_mxu__pool03(env, ctx);
26386            break;
26387        case OPC_MXU_D16MAC:
26388            gen_mxu_d16mac(ctx);
26389            break;
26390        case OPC_MXU_D16MACF:
26391            /* TODO: Implement emulation of D16MACF instruction. */
26392            MIPS_INVAL("OPC_MXU_D16MACF");
26393            generate_exception_end(ctx, EXCP_RI);
26394            break;
26395        case OPC_MXU_D16MADL:
26396            /* TODO: Implement emulation of D16MADL instruction. */
26397            MIPS_INVAL("OPC_MXU_D16MADL");
26398            generate_exception_end(ctx, EXCP_RI);
26399            break;
26400        case OPC_MXU_S16MAD:
26401            /* TODO: Implement emulation of S16MAD instruction. */
26402            MIPS_INVAL("OPC_MXU_S16MAD");
26403            generate_exception_end(ctx, EXCP_RI);
26404            break;
26405        case OPC_MXU_Q16ADD:
26406            /* TODO: Implement emulation of Q16ADD instruction. */
26407            MIPS_INVAL("OPC_MXU_Q16ADD");
26408            generate_exception_end(ctx, EXCP_RI);
26409            break;
26410        case OPC_MXU_D16MACE:
26411            /* TODO: Implement emulation of D16MACE instruction. */
26412            MIPS_INVAL("OPC_MXU_D16MACE");
26413            generate_exception_end(ctx, EXCP_RI);
26414            break;
26415        case OPC_MXU__POOL04:
26416            decode_opc_mxu__pool04(env, ctx);
26417            break;
26418        case OPC_MXU__POOL05:
26419            decode_opc_mxu__pool05(env, ctx);
26420            break;
26421        case OPC_MXU__POOL06:
26422            decode_opc_mxu__pool06(env, ctx);
26423            break;
26424        case OPC_MXU__POOL07:
26425            decode_opc_mxu__pool07(env, ctx);
26426            break;
26427        case OPC_MXU__POOL08:
26428            decode_opc_mxu__pool08(env, ctx);
26429            break;
26430        case OPC_MXU__POOL09:
26431            decode_opc_mxu__pool09(env, ctx);
26432            break;
26433        case OPC_MXU__POOL10:
26434            decode_opc_mxu__pool10(env, ctx);
26435            break;
26436        case OPC_MXU__POOL11:
26437            decode_opc_mxu__pool11(env, ctx);
26438            break;
26439        case OPC_MXU_D32ADD:
26440            /* TODO: Implement emulation of D32ADD instruction. */
26441            MIPS_INVAL("OPC_MXU_D32ADD");
26442            generate_exception_end(ctx, EXCP_RI);
26443            break;
26444        case OPC_MXU__POOL12:
26445            decode_opc_mxu__pool12(env, ctx);
26446            break;
26447        case OPC_MXU__POOL13:
26448            decode_opc_mxu__pool13(env, ctx);
26449            break;
26450        case OPC_MXU__POOL14:
26451            decode_opc_mxu__pool14(env, ctx);
26452            break;
26453        case OPC_MXU_Q8ACCE:
26454            /* TODO: Implement emulation of Q8ACCE instruction. */
26455            MIPS_INVAL("OPC_MXU_Q8ACCE");
26456            generate_exception_end(ctx, EXCP_RI);
26457            break;
26458        case OPC_MXU_S8LDD:
26459            gen_mxu_s8ldd(ctx);
26460            break;
26461        case OPC_MXU_S8STD:
26462            /* TODO: Implement emulation of S8STD instruction. */
26463            MIPS_INVAL("OPC_MXU_S8STD");
26464            generate_exception_end(ctx, EXCP_RI);
26465            break;
26466        case OPC_MXU_S8LDI:
26467            /* TODO: Implement emulation of S8LDI instruction. */
26468            MIPS_INVAL("OPC_MXU_S8LDI");
26469            generate_exception_end(ctx, EXCP_RI);
26470            break;
26471        case OPC_MXU_S8SDI:
26472            /* TODO: Implement emulation of S8SDI instruction. */
26473            MIPS_INVAL("OPC_MXU_S8SDI");
26474            generate_exception_end(ctx, EXCP_RI);
26475            break;
26476        case OPC_MXU__POOL15:
26477            decode_opc_mxu__pool15(env, ctx);
26478            break;
26479        case OPC_MXU__POOL16:
26480            decode_opc_mxu__pool16(env, ctx);
26481            break;
26482        case OPC_MXU__POOL17:
26483            decode_opc_mxu__pool17(env, ctx);
26484            break;
26485        case OPC_MXU_S16LDD:
26486            /* TODO: Implement emulation of S16LDD instruction. */
26487            MIPS_INVAL("OPC_MXU_S16LDD");
26488            generate_exception_end(ctx, EXCP_RI);
26489            break;
26490        case OPC_MXU_S16STD:
26491            /* TODO: Implement emulation of S16STD instruction. */
26492            MIPS_INVAL("OPC_MXU_S16STD");
26493            generate_exception_end(ctx, EXCP_RI);
26494            break;
26495        case OPC_MXU_S16LDI:
26496            /* TODO: Implement emulation of S16LDI instruction. */
26497            MIPS_INVAL("OPC_MXU_S16LDI");
26498            generate_exception_end(ctx, EXCP_RI);
26499            break;
26500        case OPC_MXU_S16SDI:
26501            /* TODO: Implement emulation of S16SDI instruction. */
26502            MIPS_INVAL("OPC_MXU_S16SDI");
26503            generate_exception_end(ctx, EXCP_RI);
26504            break;
26505        case OPC_MXU_D32SLL:
26506            /* TODO: Implement emulation of D32SLL instruction. */
26507            MIPS_INVAL("OPC_MXU_D32SLL");
26508            generate_exception_end(ctx, EXCP_RI);
26509            break;
26510        case OPC_MXU_D32SLR:
26511            /* TODO: Implement emulation of D32SLR instruction. */
26512            MIPS_INVAL("OPC_MXU_D32SLR");
26513            generate_exception_end(ctx, EXCP_RI);
26514            break;
26515        case OPC_MXU_D32SARL:
26516            /* TODO: Implement emulation of D32SARL instruction. */
26517            MIPS_INVAL("OPC_MXU_D32SARL");
26518            generate_exception_end(ctx, EXCP_RI);
26519            break;
26520        case OPC_MXU_D32SAR:
26521            /* TODO: Implement emulation of D32SAR instruction. */
26522            MIPS_INVAL("OPC_MXU_D32SAR");
26523            generate_exception_end(ctx, EXCP_RI);
26524            break;
26525        case OPC_MXU_Q16SLL:
26526            /* TODO: Implement emulation of Q16SLL instruction. */
26527            MIPS_INVAL("OPC_MXU_Q16SLL");
26528            generate_exception_end(ctx, EXCP_RI);
26529            break;
26530        case OPC_MXU_Q16SLR:
26531            /* TODO: Implement emulation of Q16SLR instruction. */
26532            MIPS_INVAL("OPC_MXU_Q16SLR");
26533            generate_exception_end(ctx, EXCP_RI);
26534            break;
26535        case OPC_MXU__POOL18:
26536            decode_opc_mxu__pool18(env, ctx);
26537            break;
26538        case OPC_MXU_Q16SAR:
26539            /* TODO: Implement emulation of Q16SAR instruction. */
26540            MIPS_INVAL("OPC_MXU_Q16SAR");
26541            generate_exception_end(ctx, EXCP_RI);
26542            break;
26543        case OPC_MXU__POOL19:
26544            decode_opc_mxu__pool19(env, ctx);
26545            break;
26546        case OPC_MXU__POOL20:
26547            decode_opc_mxu__pool20(env, ctx);
26548            break;
26549        case OPC_MXU__POOL21:
26550            decode_opc_mxu__pool21(env, ctx);
26551            break;
26552        case OPC_MXU_Q16SCOP:
26553            /* TODO: Implement emulation of Q16SCOP instruction. */
26554            MIPS_INVAL("OPC_MXU_Q16SCOP");
26555            generate_exception_end(ctx, EXCP_RI);
26556            break;
26557        case OPC_MXU_Q8MADL:
26558            /* TODO: Implement emulation of Q8MADL instruction. */
26559            MIPS_INVAL("OPC_MXU_Q8MADL");
26560            generate_exception_end(ctx, EXCP_RI);
26561            break;
26562        case OPC_MXU_S32SFL:
26563            /* TODO: Implement emulation of S32SFL instruction. */
26564            MIPS_INVAL("OPC_MXU_S32SFL");
26565            generate_exception_end(ctx, EXCP_RI);
26566            break;
26567        case OPC_MXU_Q8SAD:
26568            /* TODO: Implement emulation of Q8SAD instruction. */
26569            MIPS_INVAL("OPC_MXU_Q8SAD");
26570            generate_exception_end(ctx, EXCP_RI);
26571            break;
26572        default:
26573            MIPS_INVAL("decode_opc_mxu");
26574            generate_exception_end(ctx, EXCP_RI);
26575        }
26576
26577        gen_set_label(l_exit);
26578        tcg_temp_free(t_mxu_cr);
26579    }
26580}
26581
26582#endif /* !defined(TARGET_MIPS64) */
26583
26584
26585static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26586{
26587    int rs, rt, rd;
26588    uint32_t op1;
26589
26590    check_insn_opc_removed(ctx, ISA_MIPS32R6);
26591
26592    rs = (ctx->opcode >> 21) & 0x1f;
26593    rt = (ctx->opcode >> 16) & 0x1f;
26594    rd = (ctx->opcode >> 11) & 0x1f;
26595
26596    op1 = MASK_SPECIAL2(ctx->opcode);
26597    switch (op1) {
26598    case OPC_MADD: /* Multiply and add/sub */
26599    case OPC_MADDU:
26600    case OPC_MSUB:
26601    case OPC_MSUBU:
26602        check_insn(ctx, ISA_MIPS32);
26603        gen_muldiv(ctx, op1, rd & 3, rs, rt);
26604        break;
26605    case OPC_MUL:
26606        gen_arith(ctx, op1, rd, rs, rt);
26607        break;
26608    case OPC_DIV_G_2F:
26609    case OPC_DIVU_G_2F:
26610    case OPC_MULT_G_2F:
26611    case OPC_MULTU_G_2F:
26612    case OPC_MOD_G_2F:
26613    case OPC_MODU_G_2F:
26614        check_insn(ctx, INSN_LOONGSON2F);
26615        gen_loongson_integer(ctx, op1, rd, rs, rt);
26616        break;
26617    case OPC_CLO:
26618    case OPC_CLZ:
26619        check_insn(ctx, ISA_MIPS32);
26620        gen_cl(ctx, op1, rd, rs);
26621        break;
26622    case OPC_SDBBP:
26623        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26624            gen_helper_do_semihosting(cpu_env);
26625        } else {
26626            /* XXX: not clear which exception should be raised
26627             *      when in debug mode...
26628             */
26629            check_insn(ctx, ISA_MIPS32);
26630            generate_exception_end(ctx, EXCP_DBp);
26631        }
26632        break;
26633#if defined(TARGET_MIPS64)
26634    case OPC_DCLO:
26635    case OPC_DCLZ:
26636        check_insn(ctx, ISA_MIPS64);
26637        check_mips_64(ctx);
26638        gen_cl(ctx, op1, rd, rs);
26639        break;
26640    case OPC_DMULT_G_2F:
26641    case OPC_DMULTU_G_2F:
26642    case OPC_DDIV_G_2F:
26643    case OPC_DDIVU_G_2F:
26644    case OPC_DMOD_G_2F:
26645    case OPC_DMODU_G_2F:
26646        check_insn(ctx, INSN_LOONGSON2F);
26647        gen_loongson_integer(ctx, op1, rd, rs, rt);
26648        break;
26649#endif
26650    default:            /* Invalid */
26651        MIPS_INVAL("special2_legacy");
26652        generate_exception_end(ctx, EXCP_RI);
26653        break;
26654    }
26655}
26656
26657static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26658{
26659    int rs, rt, rd, sa;
26660    uint32_t op1, op2;
26661    int16_t imm;
26662
26663    rs = (ctx->opcode >> 21) & 0x1f;
26664    rt = (ctx->opcode >> 16) & 0x1f;
26665    rd = (ctx->opcode >> 11) & 0x1f;
26666    sa = (ctx->opcode >> 6) & 0x1f;
26667    imm = (int16_t)ctx->opcode >> 7;
26668
26669    op1 = MASK_SPECIAL3(ctx->opcode);
26670    switch (op1) {
26671    case R6_OPC_PREF:
26672        if (rt >= 24) {
26673            /* hint codes 24-31 are reserved and signal RI */
26674            generate_exception_end(ctx, EXCP_RI);
26675        }
26676        /* Treat as NOP. */
26677        break;
26678    case R6_OPC_CACHE:
26679        check_cp0_enabled(ctx);
26680        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26681            gen_cache_operation(ctx, rt, rs, imm);
26682        }
26683        break;
26684    case R6_OPC_SC:
26685        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
26686        break;
26687    case R6_OPC_LL:
26688        gen_ld(ctx, op1, rt, rs, imm);
26689        break;
26690    case OPC_BSHFL:
26691        {
26692            if (rd == 0) {
26693                /* Treat as NOP. */
26694                break;
26695            }
26696            op2 = MASK_BSHFL(ctx->opcode);
26697            switch (op2) {
26698            case OPC_ALIGN:
26699            case OPC_ALIGN_1:
26700            case OPC_ALIGN_2:
26701            case OPC_ALIGN_3:
26702                gen_align(ctx, 32, rd, rs, rt, sa & 3);
26703                break;
26704            case OPC_BITSWAP:
26705                gen_bitswap(ctx, op2, rd, rt);
26706                break;
26707            }
26708        }
26709        break;
26710#if defined(TARGET_MIPS64)
26711    case R6_OPC_SCD:
26712        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
26713        break;
26714    case R6_OPC_LLD:
26715        gen_ld(ctx, op1, rt, rs, imm);
26716        break;
26717    case OPC_DBSHFL:
26718        check_mips_64(ctx);
26719        {
26720            if (rd == 0) {
26721                /* Treat as NOP. */
26722                break;
26723            }
26724            op2 = MASK_DBSHFL(ctx->opcode);
26725            switch (op2) {
26726            case OPC_DALIGN:
26727            case OPC_DALIGN_1:
26728            case OPC_DALIGN_2:
26729            case OPC_DALIGN_3:
26730            case OPC_DALIGN_4:
26731            case OPC_DALIGN_5:
26732            case OPC_DALIGN_6:
26733            case OPC_DALIGN_7:
26734                gen_align(ctx, 64, rd, rs, rt, sa & 7);
26735                break;
26736            case OPC_DBITSWAP:
26737                gen_bitswap(ctx, op2, rd, rt);
26738                break;
26739            }
26740
26741        }
26742        break;
26743#endif
26744    default:            /* Invalid */
26745        MIPS_INVAL("special3_r6");
26746        generate_exception_end(ctx, EXCP_RI);
26747        break;
26748    }
26749}
26750
26751static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26752{
26753    int rs, rt, rd;
26754    uint32_t op1, op2;
26755
26756    rs = (ctx->opcode >> 21) & 0x1f;
26757    rt = (ctx->opcode >> 16) & 0x1f;
26758    rd = (ctx->opcode >> 11) & 0x1f;
26759
26760    op1 = MASK_SPECIAL3(ctx->opcode);
26761    switch (op1) {
26762    case OPC_DIV_G_2E:
26763    case OPC_DIVU_G_2E:
26764    case OPC_MOD_G_2E:
26765    case OPC_MODU_G_2E:
26766    case OPC_MULT_G_2E:
26767    case OPC_MULTU_G_2E:
26768        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26769         * the same mask and op1. */
26770        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26771            op2 = MASK_ADDUH_QB(ctx->opcode);
26772            switch (op2) {
26773            case OPC_ADDUH_QB:
26774            case OPC_ADDUH_R_QB:
26775            case OPC_ADDQH_PH:
26776            case OPC_ADDQH_R_PH:
26777            case OPC_ADDQH_W:
26778            case OPC_ADDQH_R_W:
26779            case OPC_SUBUH_QB:
26780            case OPC_SUBUH_R_QB:
26781            case OPC_SUBQH_PH:
26782            case OPC_SUBQH_R_PH:
26783            case OPC_SUBQH_W:
26784            case OPC_SUBQH_R_W:
26785                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26786                break;
26787            case OPC_MUL_PH:
26788            case OPC_MUL_S_PH:
26789            case OPC_MULQ_S_W:
26790            case OPC_MULQ_RS_W:
26791                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26792                break;
26793            default:
26794                MIPS_INVAL("MASK ADDUH.QB");
26795                generate_exception_end(ctx, EXCP_RI);
26796                break;
26797            }
26798        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26799            gen_loongson_integer(ctx, op1, rd, rs, rt);
26800        } else {
26801            generate_exception_end(ctx, EXCP_RI);
26802        }
26803        break;
26804    case OPC_LX_DSP:
26805        op2 = MASK_LX(ctx->opcode);
26806        switch (op2) {
26807#if defined(TARGET_MIPS64)
26808        case OPC_LDX:
26809#endif
26810        case OPC_LBUX:
26811        case OPC_LHX:
26812        case OPC_LWX:
26813            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26814            break;
26815        default:            /* Invalid */
26816            MIPS_INVAL("MASK LX");
26817            generate_exception_end(ctx, EXCP_RI);
26818            break;
26819        }
26820        break;
26821    case OPC_ABSQ_S_PH_DSP:
26822        op2 = MASK_ABSQ_S_PH(ctx->opcode);
26823        switch (op2) {
26824        case OPC_ABSQ_S_QB:
26825        case OPC_ABSQ_S_PH:
26826        case OPC_ABSQ_S_W:
26827        case OPC_PRECEQ_W_PHL:
26828        case OPC_PRECEQ_W_PHR:
26829        case OPC_PRECEQU_PH_QBL:
26830        case OPC_PRECEQU_PH_QBR:
26831        case OPC_PRECEQU_PH_QBLA:
26832        case OPC_PRECEQU_PH_QBRA:
26833        case OPC_PRECEU_PH_QBL:
26834        case OPC_PRECEU_PH_QBR:
26835        case OPC_PRECEU_PH_QBLA:
26836        case OPC_PRECEU_PH_QBRA:
26837            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26838            break;
26839        case OPC_BITREV:
26840        case OPC_REPL_QB:
26841        case OPC_REPLV_QB:
26842        case OPC_REPL_PH:
26843        case OPC_REPLV_PH:
26844            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26845            break;
26846        default:
26847            MIPS_INVAL("MASK ABSQ_S.PH");
26848            generate_exception_end(ctx, EXCP_RI);
26849            break;
26850        }
26851        break;
26852    case OPC_ADDU_QB_DSP:
26853        op2 = MASK_ADDU_QB(ctx->opcode);
26854        switch (op2) {
26855        case OPC_ADDQ_PH:
26856        case OPC_ADDQ_S_PH:
26857        case OPC_ADDQ_S_W:
26858        case OPC_ADDU_QB:
26859        case OPC_ADDU_S_QB:
26860        case OPC_ADDU_PH:
26861        case OPC_ADDU_S_PH:
26862        case OPC_SUBQ_PH:
26863        case OPC_SUBQ_S_PH:
26864        case OPC_SUBQ_S_W:
26865        case OPC_SUBU_QB:
26866        case OPC_SUBU_S_QB:
26867        case OPC_SUBU_PH:
26868        case OPC_SUBU_S_PH:
26869        case OPC_ADDSC:
26870        case OPC_ADDWC:
26871        case OPC_MODSUB:
26872        case OPC_RADDU_W_QB:
26873            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26874            break;
26875        case OPC_MULEU_S_PH_QBL:
26876        case OPC_MULEU_S_PH_QBR:
26877        case OPC_MULQ_RS_PH:
26878        case OPC_MULEQ_S_W_PHL:
26879        case OPC_MULEQ_S_W_PHR:
26880        case OPC_MULQ_S_PH:
26881            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26882            break;
26883        default:            /* Invalid */
26884            MIPS_INVAL("MASK ADDU.QB");
26885            generate_exception_end(ctx, EXCP_RI);
26886            break;
26887
26888        }
26889        break;
26890    case OPC_CMPU_EQ_QB_DSP:
26891        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26892        switch (op2) {
26893        case OPC_PRECR_SRA_PH_W:
26894        case OPC_PRECR_SRA_R_PH_W:
26895            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26896            break;
26897        case OPC_PRECR_QB_PH:
26898        case OPC_PRECRQ_QB_PH:
26899        case OPC_PRECRQ_PH_W:
26900        case OPC_PRECRQ_RS_PH_W:
26901        case OPC_PRECRQU_S_QB_PH:
26902            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26903            break;
26904        case OPC_CMPU_EQ_QB:
26905        case OPC_CMPU_LT_QB:
26906        case OPC_CMPU_LE_QB:
26907        case OPC_CMP_EQ_PH:
26908        case OPC_CMP_LT_PH:
26909        case OPC_CMP_LE_PH:
26910            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26911            break;
26912        case OPC_CMPGU_EQ_QB:
26913        case OPC_CMPGU_LT_QB:
26914        case OPC_CMPGU_LE_QB:
26915        case OPC_CMPGDU_EQ_QB:
26916        case OPC_CMPGDU_LT_QB:
26917        case OPC_CMPGDU_LE_QB:
26918        case OPC_PICK_QB:
26919        case OPC_PICK_PH:
26920        case OPC_PACKRL_PH:
26921            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26922            break;
26923        default:            /* Invalid */
26924            MIPS_INVAL("MASK CMPU.EQ.QB");
26925            generate_exception_end(ctx, EXCP_RI);
26926            break;
26927        }
26928        break;
26929    case OPC_SHLL_QB_DSP:
26930        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26931        break;
26932    case OPC_DPA_W_PH_DSP:
26933        op2 = MASK_DPA_W_PH(ctx->opcode);
26934        switch (op2) {
26935        case OPC_DPAU_H_QBL:
26936        case OPC_DPAU_H_QBR:
26937        case OPC_DPSU_H_QBL:
26938        case OPC_DPSU_H_QBR:
26939        case OPC_DPA_W_PH:
26940        case OPC_DPAX_W_PH:
26941        case OPC_DPAQ_S_W_PH:
26942        case OPC_DPAQX_S_W_PH:
26943        case OPC_DPAQX_SA_W_PH:
26944        case OPC_DPS_W_PH:
26945        case OPC_DPSX_W_PH:
26946        case OPC_DPSQ_S_W_PH:
26947        case OPC_DPSQX_S_W_PH:
26948        case OPC_DPSQX_SA_W_PH:
26949        case OPC_MULSAQ_S_W_PH:
26950        case OPC_DPAQ_SA_L_W:
26951        case OPC_DPSQ_SA_L_W:
26952        case OPC_MAQ_S_W_PHL:
26953        case OPC_MAQ_S_W_PHR:
26954        case OPC_MAQ_SA_W_PHL:
26955        case OPC_MAQ_SA_W_PHR:
26956        case OPC_MULSA_W_PH:
26957            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26958            break;
26959        default:            /* Invalid */
26960            MIPS_INVAL("MASK DPAW.PH");
26961            generate_exception_end(ctx, EXCP_RI);
26962            break;
26963        }
26964        break;
26965    case OPC_INSV_DSP:
26966        op2 = MASK_INSV(ctx->opcode);
26967        switch (op2) {
26968        case OPC_INSV:
26969            check_dsp(ctx);
26970            {
26971                TCGv t0, t1;
26972
26973                if (rt == 0) {
26974                    break;
26975                }
26976
26977                t0 = tcg_temp_new();
26978                t1 = tcg_temp_new();
26979
26980                gen_load_gpr(t0, rt);
26981                gen_load_gpr(t1, rs);
26982
26983                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26984
26985                tcg_temp_free(t0);
26986                tcg_temp_free(t1);
26987                break;
26988            }
26989        default:            /* Invalid */
26990            MIPS_INVAL("MASK INSV");
26991            generate_exception_end(ctx, EXCP_RI);
26992            break;
26993        }
26994        break;
26995    case OPC_APPEND_DSP:
26996        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26997        break;
26998    case OPC_EXTR_W_DSP:
26999        op2 = MASK_EXTR_W(ctx->opcode);
27000        switch (op2) {
27001        case OPC_EXTR_W:
27002        case OPC_EXTR_R_W:
27003        case OPC_EXTR_RS_W:
27004        case OPC_EXTR_S_H:
27005        case OPC_EXTRV_S_H:
27006        case OPC_EXTRV_W:
27007        case OPC_EXTRV_R_W:
27008        case OPC_EXTRV_RS_W:
27009        case OPC_EXTP:
27010        case OPC_EXTPV:
27011        case OPC_EXTPDP:
27012        case OPC_EXTPDPV:
27013            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27014            break;
27015        case OPC_RDDSP:
27016            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27017            break;
27018        case OPC_SHILO:
27019        case OPC_SHILOV:
27020        case OPC_MTHLIP:
27021        case OPC_WRDSP:
27022            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27023            break;
27024        default:            /* Invalid */
27025            MIPS_INVAL("MASK EXTR.W");
27026            generate_exception_end(ctx, EXCP_RI);
27027            break;
27028        }
27029        break;
27030#if defined(TARGET_MIPS64)
27031    case OPC_DDIV_G_2E:
27032    case OPC_DDIVU_G_2E:
27033    case OPC_DMULT_G_2E:
27034    case OPC_DMULTU_G_2E:
27035    case OPC_DMOD_G_2E:
27036    case OPC_DMODU_G_2E:
27037        check_insn(ctx, INSN_LOONGSON2E);
27038        gen_loongson_integer(ctx, op1, rd, rs, rt);
27039        break;
27040    case OPC_ABSQ_S_QH_DSP:
27041        op2 = MASK_ABSQ_S_QH(ctx->opcode);
27042        switch (op2) {
27043        case OPC_PRECEQ_L_PWL:
27044        case OPC_PRECEQ_L_PWR:
27045        case OPC_PRECEQ_PW_QHL:
27046        case OPC_PRECEQ_PW_QHR:
27047        case OPC_PRECEQ_PW_QHLA:
27048        case OPC_PRECEQ_PW_QHRA:
27049        case OPC_PRECEQU_QH_OBL:
27050        case OPC_PRECEQU_QH_OBR:
27051        case OPC_PRECEQU_QH_OBLA:
27052        case OPC_PRECEQU_QH_OBRA:
27053        case OPC_PRECEU_QH_OBL:
27054        case OPC_PRECEU_QH_OBR:
27055        case OPC_PRECEU_QH_OBLA:
27056        case OPC_PRECEU_QH_OBRA:
27057        case OPC_ABSQ_S_OB:
27058        case OPC_ABSQ_S_PW:
27059        case OPC_ABSQ_S_QH:
27060            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27061            break;
27062        case OPC_REPL_OB:
27063        case OPC_REPL_PW:
27064        case OPC_REPL_QH:
27065        case OPC_REPLV_OB:
27066        case OPC_REPLV_PW:
27067        case OPC_REPLV_QH:
27068            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27069            break;
27070        default:            /* Invalid */
27071            MIPS_INVAL("MASK ABSQ_S.QH");
27072            generate_exception_end(ctx, EXCP_RI);
27073            break;
27074        }
27075        break;
27076    case OPC_ADDU_OB_DSP:
27077        op2 = MASK_ADDU_OB(ctx->opcode);
27078        switch (op2) {
27079        case OPC_RADDU_L_OB:
27080        case OPC_SUBQ_PW:
27081        case OPC_SUBQ_S_PW:
27082        case OPC_SUBQ_QH:
27083        case OPC_SUBQ_S_QH:
27084        case OPC_SUBU_OB:
27085        case OPC_SUBU_S_OB:
27086        case OPC_SUBU_QH:
27087        case OPC_SUBU_S_QH:
27088        case OPC_SUBUH_OB:
27089        case OPC_SUBUH_R_OB:
27090        case OPC_ADDQ_PW:
27091        case OPC_ADDQ_S_PW:
27092        case OPC_ADDQ_QH:
27093        case OPC_ADDQ_S_QH:
27094        case OPC_ADDU_OB:
27095        case OPC_ADDU_S_OB:
27096        case OPC_ADDU_QH:
27097        case OPC_ADDU_S_QH:
27098        case OPC_ADDUH_OB:
27099        case OPC_ADDUH_R_OB:
27100            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27101            break;
27102        case OPC_MULEQ_S_PW_QHL:
27103        case OPC_MULEQ_S_PW_QHR:
27104        case OPC_MULEU_S_QH_OBL:
27105        case OPC_MULEU_S_QH_OBR:
27106        case OPC_MULQ_RS_QH:
27107            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27108            break;
27109        default:            /* Invalid */
27110            MIPS_INVAL("MASK ADDU.OB");
27111            generate_exception_end(ctx, EXCP_RI);
27112            break;
27113        }
27114        break;
27115    case OPC_CMPU_EQ_OB_DSP:
27116        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27117        switch (op2) {
27118        case OPC_PRECR_SRA_QH_PW:
27119        case OPC_PRECR_SRA_R_QH_PW:
27120            /* Return value is rt. */
27121            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27122            break;
27123        case OPC_PRECR_OB_QH:
27124        case OPC_PRECRQ_OB_QH:
27125        case OPC_PRECRQ_PW_L:
27126        case OPC_PRECRQ_QH_PW:
27127        case OPC_PRECRQ_RS_QH_PW:
27128        case OPC_PRECRQU_S_OB_QH:
27129            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27130            break;
27131        case OPC_CMPU_EQ_OB:
27132        case OPC_CMPU_LT_OB:
27133        case OPC_CMPU_LE_OB:
27134        case OPC_CMP_EQ_QH:
27135        case OPC_CMP_LT_QH:
27136        case OPC_CMP_LE_QH:
27137        case OPC_CMP_EQ_PW:
27138        case OPC_CMP_LT_PW:
27139        case OPC_CMP_LE_PW:
27140            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27141            break;
27142        case OPC_CMPGDU_EQ_OB:
27143        case OPC_CMPGDU_LT_OB:
27144        case OPC_CMPGDU_LE_OB:
27145        case OPC_CMPGU_EQ_OB:
27146        case OPC_CMPGU_LT_OB:
27147        case OPC_CMPGU_LE_OB:
27148        case OPC_PACKRL_PW:
27149        case OPC_PICK_OB:
27150        case OPC_PICK_PW:
27151        case OPC_PICK_QH:
27152            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27153            break;
27154        default:            /* Invalid */
27155            MIPS_INVAL("MASK CMPU_EQ.OB");
27156            generate_exception_end(ctx, EXCP_RI);
27157            break;
27158        }
27159        break;
27160    case OPC_DAPPEND_DSP:
27161        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27162        break;
27163    case OPC_DEXTR_W_DSP:
27164        op2 = MASK_DEXTR_W(ctx->opcode);
27165        switch (op2) {
27166        case OPC_DEXTP:
27167        case OPC_DEXTPDP:
27168        case OPC_DEXTPDPV:
27169        case OPC_DEXTPV:
27170        case OPC_DEXTR_L:
27171        case OPC_DEXTR_R_L:
27172        case OPC_DEXTR_RS_L:
27173        case OPC_DEXTR_W:
27174        case OPC_DEXTR_R_W:
27175        case OPC_DEXTR_RS_W:
27176        case OPC_DEXTR_S_H:
27177        case OPC_DEXTRV_L:
27178        case OPC_DEXTRV_R_L:
27179        case OPC_DEXTRV_RS_L:
27180        case OPC_DEXTRV_S_H:
27181        case OPC_DEXTRV_W:
27182        case OPC_DEXTRV_R_W:
27183        case OPC_DEXTRV_RS_W:
27184            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27185            break;
27186        case OPC_DMTHLIP:
27187        case OPC_DSHILO:
27188        case OPC_DSHILOV:
27189            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27190            break;
27191        default:            /* Invalid */
27192            MIPS_INVAL("MASK EXTR.W");
27193            generate_exception_end(ctx, EXCP_RI);
27194            break;
27195        }
27196        break;
27197    case OPC_DPAQ_W_QH_DSP:
27198        op2 = MASK_DPAQ_W_QH(ctx->opcode);
27199        switch (op2) {
27200        case OPC_DPAU_H_OBL:
27201        case OPC_DPAU_H_OBR:
27202        case OPC_DPSU_H_OBL:
27203        case OPC_DPSU_H_OBR:
27204        case OPC_DPA_W_QH:
27205        case OPC_DPAQ_S_W_QH:
27206        case OPC_DPS_W_QH:
27207        case OPC_DPSQ_S_W_QH:
27208        case OPC_MULSAQ_S_W_QH:
27209        case OPC_DPAQ_SA_L_PW:
27210        case OPC_DPSQ_SA_L_PW:
27211        case OPC_MULSAQ_S_L_PW:
27212            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27213            break;
27214        case OPC_MAQ_S_W_QHLL:
27215        case OPC_MAQ_S_W_QHLR:
27216        case OPC_MAQ_S_W_QHRL:
27217        case OPC_MAQ_S_W_QHRR:
27218        case OPC_MAQ_SA_W_QHLL:
27219        case OPC_MAQ_SA_W_QHLR:
27220        case OPC_MAQ_SA_W_QHRL:
27221        case OPC_MAQ_SA_W_QHRR:
27222        case OPC_MAQ_S_L_PWL:
27223        case OPC_MAQ_S_L_PWR:
27224        case OPC_DMADD:
27225        case OPC_DMADDU:
27226        case OPC_DMSUB:
27227        case OPC_DMSUBU:
27228            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27229            break;
27230        default:            /* Invalid */
27231            MIPS_INVAL("MASK DPAQ.W.QH");
27232            generate_exception_end(ctx, EXCP_RI);
27233            break;
27234        }
27235        break;
27236    case OPC_DINSV_DSP:
27237        op2 = MASK_INSV(ctx->opcode);
27238        switch (op2) {
27239        case OPC_DINSV:
27240        {
27241            TCGv t0, t1;
27242
27243            if (rt == 0) {
27244                break;
27245            }
27246            check_dsp(ctx);
27247
27248            t0 = tcg_temp_new();
27249            t1 = tcg_temp_new();
27250
27251            gen_load_gpr(t0, rt);
27252            gen_load_gpr(t1, rs);
27253
27254            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27255
27256            tcg_temp_free(t0);
27257            tcg_temp_free(t1);
27258            break;
27259        }
27260        default:            /* Invalid */
27261            MIPS_INVAL("MASK DINSV");
27262            generate_exception_end(ctx, EXCP_RI);
27263            break;
27264        }
27265        break;
27266    case OPC_SHLL_OB_DSP:
27267        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27268        break;
27269#endif
27270    default:            /* Invalid */
27271        MIPS_INVAL("special3_legacy");
27272        generate_exception_end(ctx, EXCP_RI);
27273        break;
27274    }
27275}
27276
27277
27278#if defined(TARGET_MIPS64)
27279
27280static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27281{
27282    uint32_t opc = MASK_MMI0(ctx->opcode);
27283
27284    switch (opc) {
27285    case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27286    case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27287    case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27288    case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27289    case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27290    case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27291    case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27292    case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27293    case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27294    case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27295    case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27296    case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27297    case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27298    case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27299    case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27300    case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27301    case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27302    case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27303    case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27304    case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27305    case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27306    case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27307    case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27308    case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27309    case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27310        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27311        break;
27312    default:
27313        MIPS_INVAL("TX79 MMI class MMI0");
27314        generate_exception_end(ctx, EXCP_RI);
27315        break;
27316    }
27317}
27318
27319static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27320{
27321    uint32_t opc = MASK_MMI1(ctx->opcode);
27322
27323    switch (opc) {
27324    case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27325    case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27326    case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27327    case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27328    case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27329    case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27330    case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27331    case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27332    case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27333    case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27334    case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27335    case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27336    case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27337    case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27338    case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27339    case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27340    case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27341    case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27342        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27343        break;
27344    default:
27345        MIPS_INVAL("TX79 MMI class MMI1");
27346        generate_exception_end(ctx, EXCP_RI);
27347        break;
27348    }
27349}
27350
27351static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27352{
27353    uint32_t opc = MASK_MMI2(ctx->opcode);
27354
27355    switch (opc) {
27356    case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27357    case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27358    case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27359    case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27360    case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27361    case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27362    case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27363    case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27364    case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27365    case MMI_OPC_2_PCPYLD:    /* TODO: MMI_OPC_2_PCPYLD */
27366    case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27367    case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27368    case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27369    case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27370    case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27371    case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27372    case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27373    case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27374    case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27375    case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27376    case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27377    case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27378        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27379        break;
27380    default:
27381        MIPS_INVAL("TX79 MMI class MMI2");
27382        generate_exception_end(ctx, EXCP_RI);
27383        break;
27384    }
27385}
27386
27387static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27388{
27389    uint32_t opc = MASK_MMI3(ctx->opcode);
27390
27391    switch (opc) {
27392    case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27393    case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27394    case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27395    case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27396    case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27397    case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27398    case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27399    case MMI_OPC_3_PCPYUD:     /* TODO: MMI_OPC_3_PCPYUD */
27400    case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27401    case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27402    case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27403    case MMI_OPC_3_PCPYH:      /* TODO: MMI_OPC_3_PCPYH */
27404    case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27405        generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27406        break;
27407    default:
27408        MIPS_INVAL("TX79 MMI class MMI3");
27409        generate_exception_end(ctx, EXCP_RI);
27410        break;
27411    }
27412}
27413
27414static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27415{
27416    uint32_t opc = MASK_MMI(ctx->opcode);
27417    int rs = extract32(ctx->opcode, 21, 5);
27418    int rt = extract32(ctx->opcode, 16, 5);
27419    int rd = extract32(ctx->opcode, 11, 5);
27420
27421    switch (opc) {
27422    case MMI_OPC_CLASS_MMI0:
27423        decode_mmi0(env, ctx);
27424        break;
27425    case MMI_OPC_CLASS_MMI1:
27426        decode_mmi1(env, ctx);
27427        break;
27428    case MMI_OPC_CLASS_MMI2:
27429        decode_mmi2(env, ctx);
27430        break;
27431    case MMI_OPC_CLASS_MMI3:
27432        decode_mmi3(env, ctx);
27433        break;
27434    case MMI_OPC_MULT1:
27435    case MMI_OPC_MULTU1:
27436    case MMI_OPC_MADD:
27437    case MMI_OPC_MADDU:
27438    case MMI_OPC_MADD1:
27439    case MMI_OPC_MADDU1:
27440        gen_mul_txx9(ctx, opc, rd, rs, rt);
27441        break;
27442    case MMI_OPC_DIV1:
27443    case MMI_OPC_DIVU1:
27444        gen_div1_tx79(ctx, opc, rs, rt);
27445        break;
27446    case MMI_OPC_MTLO1:
27447    case MMI_OPC_MTHI1:
27448        gen_HILO1_tx79(ctx, opc, rs);
27449        break;
27450    case MMI_OPC_MFLO1:
27451    case MMI_OPC_MFHI1:
27452        gen_HILO1_tx79(ctx, opc, rd);
27453        break;
27454    case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
27455    case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
27456    case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
27457    case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
27458    case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
27459    case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
27460    case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
27461    case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
27462    case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
27463        generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
27464        break;
27465    default:
27466        MIPS_INVAL("TX79 MMI class");
27467        generate_exception_end(ctx, EXCP_RI);
27468        break;
27469    }
27470}
27471
27472static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27473{
27474    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
27475}
27476
27477static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27478{
27479    generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
27480}
27481
27482/*
27483 * The TX79-specific instruction Store Quadword
27484 *
27485 * +--------+-------+-------+------------------------+
27486 * | 011111 |  base |   rt  |           offset       | SQ
27487 * +--------+-------+-------+------------------------+
27488 *      6       5       5                 16
27489 *
27490 * has the same opcode as the Read Hardware Register instruction
27491 *
27492 * +--------+-------+-------+-------+-------+--------+
27493 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
27494 * +--------+-------+-------+-------+-------+--------+
27495 *      6       5       5       5       5        6
27496 *
27497 * that is required, trapped and emulated by the Linux kernel. However, all
27498 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27499 * offset is odd. Therefore all valid SQ instructions can execute normally.
27500 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27501 * between SQ and RDHWR, as the Linux kernel does.
27502 */
27503static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27504{
27505    int base = extract32(ctx->opcode, 21, 5);
27506    int rt = extract32(ctx->opcode, 16, 5);
27507    int offset = extract32(ctx->opcode, 0, 16);
27508
27509#ifdef CONFIG_USER_ONLY
27510    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27511    uint32_t op2 = extract32(ctx->opcode, 6, 5);
27512
27513    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27514        int rd = extract32(ctx->opcode, 11, 5);
27515
27516        gen_rdhwr(ctx, rt, rd, 0);
27517        return;
27518    }
27519#endif
27520
27521    gen_mmi_sq(ctx, base, rt, offset);
27522}
27523
27524#endif
27525
27526static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27527{
27528    int rs, rt, rd, sa;
27529    uint32_t op1, op2;
27530    int16_t imm;
27531
27532    rs = (ctx->opcode >> 21) & 0x1f;
27533    rt = (ctx->opcode >> 16) & 0x1f;
27534    rd = (ctx->opcode >> 11) & 0x1f;
27535    sa = (ctx->opcode >> 6) & 0x1f;
27536    imm = sextract32(ctx->opcode, 7, 9);
27537
27538    op1 = MASK_SPECIAL3(ctx->opcode);
27539
27540    /*
27541     * EVA loads and stores overlap Loongson 2E instructions decoded by
27542     * decode_opc_special3_legacy(), so be careful to allow their decoding when
27543     * EVA is absent.
27544     */
27545    if (ctx->eva) {
27546        switch (op1) {
27547        case OPC_LWLE:
27548        case OPC_LWRE:
27549            check_insn_opc_removed(ctx, ISA_MIPS32R6);
27550            /* fall through */
27551        case OPC_LBUE:
27552        case OPC_LHUE:
27553        case OPC_LBE:
27554        case OPC_LHE:
27555        case OPC_LLE:
27556        case OPC_LWE:
27557            check_cp0_enabled(ctx);
27558            gen_ld(ctx, op1, rt, rs, imm);
27559            return;
27560        case OPC_SWLE:
27561        case OPC_SWRE:
27562            check_insn_opc_removed(ctx, ISA_MIPS32R6);
27563            /* fall through */
27564        case OPC_SBE:
27565        case OPC_SHE:
27566        case OPC_SWE:
27567            check_cp0_enabled(ctx);
27568            gen_st(ctx, op1, rt, rs, imm);
27569            return;
27570        case OPC_SCE:
27571            check_cp0_enabled(ctx);
27572            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27573            return;
27574        case OPC_CACHEE:
27575            check_cp0_enabled(ctx);
27576            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27577                gen_cache_operation(ctx, rt, rs, imm);
27578            }
27579            /* Treat as NOP. */
27580            return;
27581        case OPC_PREFE:
27582            check_cp0_enabled(ctx);
27583            /* Treat as NOP. */
27584            return;
27585        }
27586    }
27587
27588    switch (op1) {
27589    case OPC_EXT:
27590    case OPC_INS:
27591        check_insn(ctx, ISA_MIPS32R2);
27592        gen_bitops(ctx, op1, rt, rs, sa, rd);
27593        break;
27594    case OPC_BSHFL:
27595        op2 = MASK_BSHFL(ctx->opcode);
27596        switch (op2) {
27597        case OPC_ALIGN:
27598        case OPC_ALIGN_1:
27599        case OPC_ALIGN_2:
27600        case OPC_ALIGN_3:
27601        case OPC_BITSWAP:
27602            check_insn(ctx, ISA_MIPS32R6);
27603            decode_opc_special3_r6(env, ctx);
27604            break;
27605        default:
27606            check_insn(ctx, ISA_MIPS32R2);
27607            gen_bshfl(ctx, op2, rt, rd);
27608            break;
27609        }
27610        break;
27611#if defined(TARGET_MIPS64)
27612    case OPC_DEXTM:
27613    case OPC_DEXTU:
27614    case OPC_DEXT:
27615    case OPC_DINSM:
27616    case OPC_DINSU:
27617    case OPC_DINS:
27618        check_insn(ctx, ISA_MIPS64R2);
27619        check_mips_64(ctx);
27620        gen_bitops(ctx, op1, rt, rs, sa, rd);
27621        break;
27622    case OPC_DBSHFL:
27623        op2 = MASK_DBSHFL(ctx->opcode);
27624        switch (op2) {
27625        case OPC_DALIGN:
27626        case OPC_DALIGN_1:
27627        case OPC_DALIGN_2:
27628        case OPC_DALIGN_3:
27629        case OPC_DALIGN_4:
27630        case OPC_DALIGN_5:
27631        case OPC_DALIGN_6:
27632        case OPC_DALIGN_7:
27633        case OPC_DBITSWAP:
27634            check_insn(ctx, ISA_MIPS32R6);
27635            decode_opc_special3_r6(env, ctx);
27636            break;
27637        default:
27638            check_insn(ctx, ISA_MIPS64R2);
27639            check_mips_64(ctx);
27640            op2 = MASK_DBSHFL(ctx->opcode);
27641            gen_bshfl(ctx, op2, rt, rd);
27642            break;
27643        }
27644        break;
27645#endif
27646    case OPC_RDHWR:
27647        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27648        break;
27649    case OPC_FORK:
27650        check_mt(ctx);
27651        {
27652            TCGv t0 = tcg_temp_new();
27653            TCGv t1 = tcg_temp_new();
27654
27655            gen_load_gpr(t0, rt);
27656            gen_load_gpr(t1, rs);
27657            gen_helper_fork(t0, t1);
27658            tcg_temp_free(t0);
27659            tcg_temp_free(t1);
27660        }
27661        break;
27662    case OPC_YIELD:
27663        check_mt(ctx);
27664        {
27665            TCGv t0 = tcg_temp_new();
27666
27667            gen_load_gpr(t0, rs);
27668            gen_helper_yield(t0, cpu_env, t0);
27669            gen_store_gpr(t0, rd);
27670            tcg_temp_free(t0);
27671        }
27672        break;
27673    default:
27674        if (ctx->insn_flags & ISA_MIPS32R6) {
27675            decode_opc_special3_r6(env, ctx);
27676        } else {
27677            decode_opc_special3_legacy(env, ctx);
27678        }
27679    }
27680}
27681
27682/* MIPS SIMD Architecture (MSA)  */
27683static inline int check_msa_access(DisasContext *ctx)
27684{
27685    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27686                 !(ctx->hflags & MIPS_HFLAG_F64))) {
27687        generate_exception_end(ctx, EXCP_RI);
27688        return 0;
27689    }
27690
27691    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27692        if (ctx->insn_flags & ASE_MSA) {
27693            generate_exception_end(ctx, EXCP_MSADIS);
27694            return 0;
27695        } else {
27696            generate_exception_end(ctx, EXCP_RI);
27697            return 0;
27698        }
27699    }
27700    return 1;
27701}
27702
27703static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27704{
27705    /* generates tcg ops to check if any element is 0 */
27706    /* Note this function only works with MSA_WRLEN = 128 */
27707    uint64_t eval_zero_or_big = 0;
27708    uint64_t eval_big = 0;
27709    TCGv_i64 t0 = tcg_temp_new_i64();
27710    TCGv_i64 t1 = tcg_temp_new_i64();
27711    switch (df) {
27712    case DF_BYTE:
27713        eval_zero_or_big = 0x0101010101010101ULL;
27714        eval_big = 0x8080808080808080ULL;
27715        break;
27716    case DF_HALF:
27717        eval_zero_or_big = 0x0001000100010001ULL;
27718        eval_big = 0x8000800080008000ULL;
27719        break;
27720    case DF_WORD:
27721        eval_zero_or_big = 0x0000000100000001ULL;
27722        eval_big = 0x8000000080000000ULL;
27723        break;
27724    case DF_DOUBLE:
27725        eval_zero_or_big = 0x0000000000000001ULL;
27726        eval_big = 0x8000000000000000ULL;
27727        break;
27728    }
27729    tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27730    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27731    tcg_gen_andi_i64(t0, t0, eval_big);
27732    tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27733    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27734    tcg_gen_andi_i64(t1, t1, eval_big);
27735    tcg_gen_or_i64(t0, t0, t1);
27736    /* if all bits are zero then all elements are not zero */
27737    /* if some bit is non-zero then some element is zero */
27738    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27739    tcg_gen_trunc_i64_tl(tresult, t0);
27740    tcg_temp_free_i64(t0);
27741    tcg_temp_free_i64(t1);
27742}
27743
27744static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27745{
27746    uint8_t df = (ctx->opcode >> 21) & 0x3;
27747    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27748    int64_t s16 = (int16_t)ctx->opcode;
27749
27750    check_msa_access(ctx);
27751
27752    if (ctx->hflags & MIPS_HFLAG_BMASK) {
27753        generate_exception_end(ctx, EXCP_RI);
27754        return;
27755    }
27756    switch (op1) {
27757    case OPC_BZ_V:
27758    case OPC_BNZ_V:
27759        {
27760            TCGv_i64 t0 = tcg_temp_new_i64();
27761            tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27762            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27763                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27764            tcg_gen_trunc_i64_tl(bcond, t0);
27765            tcg_temp_free_i64(t0);
27766        }
27767        break;
27768    case OPC_BZ_B:
27769    case OPC_BZ_H:
27770    case OPC_BZ_W:
27771    case OPC_BZ_D:
27772        gen_check_zero_element(bcond, df, wt);
27773        break;
27774    case OPC_BNZ_B:
27775    case OPC_BNZ_H:
27776    case OPC_BNZ_W:
27777    case OPC_BNZ_D:
27778        gen_check_zero_element(bcond, df, wt);
27779        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27780        break;
27781    }
27782
27783    ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27784
27785    ctx->hflags |= MIPS_HFLAG_BC;
27786    ctx->hflags |= MIPS_HFLAG_BDS32;
27787}
27788
27789static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27790{
27791#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27792    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27793    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27794    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27795
27796    TCGv_i32 twd = tcg_const_i32(wd);
27797    TCGv_i32 tws = tcg_const_i32(ws);
27798    TCGv_i32 ti8 = tcg_const_i32(i8);
27799
27800    switch (MASK_MSA_I8(ctx->opcode)) {
27801    case OPC_ANDI_B:
27802        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27803        break;
27804    case OPC_ORI_B:
27805        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27806        break;
27807    case OPC_NORI_B:
27808        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27809        break;
27810    case OPC_XORI_B:
27811        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27812        break;
27813    case OPC_BMNZI_B:
27814        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27815        break;
27816    case OPC_BMZI_B:
27817        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27818        break;
27819    case OPC_BSELI_B:
27820        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27821        break;
27822    case OPC_SHF_B:
27823    case OPC_SHF_H:
27824    case OPC_SHF_W:
27825        {
27826            uint8_t df = (ctx->opcode >> 24) & 0x3;
27827            if (df == DF_DOUBLE) {
27828                generate_exception_end(ctx, EXCP_RI);
27829            } else {
27830                TCGv_i32 tdf = tcg_const_i32(df);
27831                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27832                tcg_temp_free_i32(tdf);
27833            }
27834        }
27835        break;
27836    default:
27837        MIPS_INVAL("MSA instruction");
27838        generate_exception_end(ctx, EXCP_RI);
27839        break;
27840    }
27841
27842    tcg_temp_free_i32(twd);
27843    tcg_temp_free_i32(tws);
27844    tcg_temp_free_i32(ti8);
27845}
27846
27847static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27848{
27849#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27850    uint8_t df = (ctx->opcode >> 21) & 0x3;
27851    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27852    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27853    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27854    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27855
27856    TCGv_i32 tdf = tcg_const_i32(df);
27857    TCGv_i32 twd = tcg_const_i32(wd);
27858    TCGv_i32 tws = tcg_const_i32(ws);
27859    TCGv_i32 timm = tcg_temp_new_i32();
27860    tcg_gen_movi_i32(timm, u5);
27861
27862    switch (MASK_MSA_I5(ctx->opcode)) {
27863    case OPC_ADDVI_df:
27864        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27865        break;
27866    case OPC_SUBVI_df:
27867        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27868        break;
27869    case OPC_MAXI_S_df:
27870        tcg_gen_movi_i32(timm, s5);
27871        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27872        break;
27873    case OPC_MAXI_U_df:
27874        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27875        break;
27876    case OPC_MINI_S_df:
27877        tcg_gen_movi_i32(timm, s5);
27878        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27879        break;
27880    case OPC_MINI_U_df:
27881        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27882        break;
27883    case OPC_CEQI_df:
27884        tcg_gen_movi_i32(timm, s5);
27885        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27886        break;
27887    case OPC_CLTI_S_df:
27888        tcg_gen_movi_i32(timm, s5);
27889        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27890        break;
27891    case OPC_CLTI_U_df:
27892        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27893        break;
27894    case OPC_CLEI_S_df:
27895        tcg_gen_movi_i32(timm, s5);
27896        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27897        break;
27898    case OPC_CLEI_U_df:
27899        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27900        break;
27901    case OPC_LDI_df:
27902        {
27903            int32_t s10 = sextract32(ctx->opcode, 11, 10);
27904            tcg_gen_movi_i32(timm, s10);
27905            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27906        }
27907        break;
27908    default:
27909        MIPS_INVAL("MSA instruction");
27910        generate_exception_end(ctx, EXCP_RI);
27911        break;
27912    }
27913
27914    tcg_temp_free_i32(tdf);
27915    tcg_temp_free_i32(twd);
27916    tcg_temp_free_i32(tws);
27917    tcg_temp_free_i32(timm);
27918}
27919
27920static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27921{
27922#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27923    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27924    uint32_t df = 0, m = 0;
27925    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27926    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27927
27928    TCGv_i32 tdf;
27929    TCGv_i32 tm;
27930    TCGv_i32 twd;
27931    TCGv_i32 tws;
27932
27933    if ((dfm & 0x40) == 0x00) {
27934        m = dfm & 0x3f;
27935        df = DF_DOUBLE;
27936    } else if ((dfm & 0x60) == 0x40) {
27937        m = dfm & 0x1f;
27938        df = DF_WORD;
27939    } else if ((dfm & 0x70) == 0x60) {
27940        m = dfm & 0x0f;
27941        df = DF_HALF;
27942    } else if ((dfm & 0x78) == 0x70) {
27943        m = dfm & 0x7;
27944        df = DF_BYTE;
27945    } else {
27946        generate_exception_end(ctx, EXCP_RI);
27947        return;
27948    }
27949
27950    tdf = tcg_const_i32(df);
27951    tm  = tcg_const_i32(m);
27952    twd = tcg_const_i32(wd);
27953    tws = tcg_const_i32(ws);
27954
27955    switch (MASK_MSA_BIT(ctx->opcode)) {
27956    case OPC_SLLI_df:
27957        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27958        break;
27959    case OPC_SRAI_df:
27960        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27961        break;
27962    case OPC_SRLI_df:
27963        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27964        break;
27965    case OPC_BCLRI_df:
27966        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27967        break;
27968    case OPC_BSETI_df:
27969        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27970        break;
27971    case OPC_BNEGI_df:
27972        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27973        break;
27974    case OPC_BINSLI_df:
27975        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27976        break;
27977    case OPC_BINSRI_df:
27978        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27979        break;
27980    case OPC_SAT_S_df:
27981        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27982        break;
27983    case OPC_SAT_U_df:
27984        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27985        break;
27986    case OPC_SRARI_df:
27987        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27988        break;
27989    case OPC_SRLRI_df:
27990        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27991        break;
27992    default:
27993        MIPS_INVAL("MSA instruction");
27994        generate_exception_end(ctx, EXCP_RI);
27995        break;
27996    }
27997
27998    tcg_temp_free_i32(tdf);
27999    tcg_temp_free_i32(tm);
28000    tcg_temp_free_i32(twd);
28001    tcg_temp_free_i32(tws);
28002}
28003
28004static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28005{
28006#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28007    uint8_t df = (ctx->opcode >> 21) & 0x3;
28008    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28009    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28010    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28011
28012    TCGv_i32 tdf = tcg_const_i32(df);
28013    TCGv_i32 twd = tcg_const_i32(wd);
28014    TCGv_i32 tws = tcg_const_i32(ws);
28015    TCGv_i32 twt = tcg_const_i32(wt);
28016
28017    switch (MASK_MSA_3R(ctx->opcode)) {
28018    case OPC_SLL_df:
28019        gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28020        break;
28021    case OPC_ADDV_df:
28022        gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28023        break;
28024    case OPC_CEQ_df:
28025        gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28026        break;
28027    case OPC_ADD_A_df:
28028        gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28029        break;
28030    case OPC_SUBS_S_df:
28031        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28032        break;
28033    case OPC_MULV_df:
28034        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28035        break;
28036    case OPC_SLD_df:
28037        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28038        break;
28039    case OPC_VSHF_df:
28040        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28041        break;
28042    case OPC_SRA_df:
28043        gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28044        break;
28045    case OPC_SUBV_df:
28046        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28047        break;
28048    case OPC_ADDS_A_df:
28049        gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28050        break;
28051    case OPC_SUBS_U_df:
28052        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28053        break;
28054    case OPC_MADDV_df:
28055        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28056        break;
28057    case OPC_SPLAT_df:
28058        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28059        break;
28060    case OPC_SRAR_df:
28061        gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28062        break;
28063    case OPC_SRL_df:
28064        gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28065        break;
28066    case OPC_MAX_S_df:
28067        gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28068        break;
28069    case OPC_CLT_S_df:
28070        gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28071        break;
28072    case OPC_ADDS_S_df:
28073        gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28074        break;
28075    case OPC_SUBSUS_U_df:
28076        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28077        break;
28078    case OPC_MSUBV_df:
28079        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28080        break;
28081    case OPC_PCKEV_df:
28082        gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28083        break;
28084    case OPC_SRLR_df:
28085        gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28086        break;
28087    case OPC_BCLR_df:
28088        gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28089        break;
28090    case OPC_MAX_U_df:
28091        gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28092        break;
28093    case OPC_CLT_U_df:
28094        gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28095        break;
28096    case OPC_ADDS_U_df:
28097        gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28098        break;
28099    case OPC_SUBSUU_S_df:
28100        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28101        break;
28102    case OPC_PCKOD_df:
28103        gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28104        break;
28105    case OPC_BSET_df:
28106        gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28107        break;
28108    case OPC_MIN_S_df:
28109        gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28110        break;
28111    case OPC_CLE_S_df:
28112        gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28113        break;
28114    case OPC_AVE_S_df:
28115        gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28116        break;
28117    case OPC_ASUB_S_df:
28118        gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28119        break;
28120    case OPC_DIV_S_df:
28121        gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28122        break;
28123    case OPC_ILVL_df:
28124        gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28125        break;
28126    case OPC_BNEG_df:
28127        gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28128        break;
28129    case OPC_MIN_U_df:
28130        gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28131        break;
28132    case OPC_CLE_U_df:
28133        gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28134        break;
28135    case OPC_AVE_U_df:
28136        gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28137        break;
28138    case OPC_ASUB_U_df:
28139        gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28140        break;
28141    case OPC_DIV_U_df:
28142        gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28143        break;
28144    case OPC_ILVR_df:
28145        gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28146        break;
28147    case OPC_BINSL_df:
28148        gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28149        break;
28150    case OPC_MAX_A_df:
28151        gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28152        break;
28153    case OPC_AVER_S_df:
28154        gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28155        break;
28156    case OPC_MOD_S_df:
28157        gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28158        break;
28159    case OPC_ILVEV_df:
28160        gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28161        break;
28162    case OPC_BINSR_df:
28163        gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28164        break;
28165    case OPC_MIN_A_df:
28166        gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28167        break;
28168    case OPC_AVER_U_df:
28169        gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28170        break;
28171    case OPC_MOD_U_df:
28172        gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28173        break;
28174    case OPC_ILVOD_df:
28175        gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28176        break;
28177
28178    case OPC_DOTP_S_df:
28179    case OPC_DOTP_U_df:
28180    case OPC_DPADD_S_df:
28181    case OPC_DPADD_U_df:
28182    case OPC_DPSUB_S_df:
28183    case OPC_HADD_S_df:
28184    case OPC_DPSUB_U_df:
28185    case OPC_HADD_U_df:
28186    case OPC_HSUB_S_df:
28187    case OPC_HSUB_U_df:
28188        if (df == DF_BYTE) {
28189            generate_exception_end(ctx, EXCP_RI);
28190            break;
28191        }
28192        switch (MASK_MSA_3R(ctx->opcode)) {
28193        case OPC_DOTP_S_df:
28194            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28195            break;
28196        case OPC_DOTP_U_df:
28197            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28198            break;
28199        case OPC_DPADD_S_df:
28200            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28201            break;
28202        case OPC_DPADD_U_df:
28203            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28204            break;
28205        case OPC_DPSUB_S_df:
28206            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28207            break;
28208        case OPC_HADD_S_df:
28209            gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28210            break;
28211        case OPC_DPSUB_U_df:
28212            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28213            break;
28214        case OPC_HADD_U_df:
28215            gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28216            break;
28217        case OPC_HSUB_S_df:
28218            gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28219            break;
28220        case OPC_HSUB_U_df:
28221            gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28222            break;
28223        }
28224        break;
28225    default:
28226        MIPS_INVAL("MSA instruction");
28227        generate_exception_end(ctx, EXCP_RI);
28228        break;
28229    }
28230    tcg_temp_free_i32(twd);
28231    tcg_temp_free_i32(tws);
28232    tcg_temp_free_i32(twt);
28233    tcg_temp_free_i32(tdf);
28234}
28235
28236static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28237{
28238#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28239    uint8_t source = (ctx->opcode >> 11) & 0x1f;
28240    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28241    TCGv telm = tcg_temp_new();
28242    TCGv_i32 tsr = tcg_const_i32(source);
28243    TCGv_i32 tdt = tcg_const_i32(dest);
28244
28245    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28246    case OPC_CTCMSA:
28247        gen_load_gpr(telm, source);
28248        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28249        break;
28250    case OPC_CFCMSA:
28251        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28252        gen_store_gpr(telm, dest);
28253        break;
28254    case OPC_MOVE_V:
28255        gen_helper_msa_move_v(cpu_env, tdt, tsr);
28256        break;
28257    default:
28258        MIPS_INVAL("MSA instruction");
28259        generate_exception_end(ctx, EXCP_RI);
28260        break;
28261    }
28262
28263    tcg_temp_free(telm);
28264    tcg_temp_free_i32(tdt);
28265    tcg_temp_free_i32(tsr);
28266}
28267
28268static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28269        uint32_t n)
28270{
28271#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28272    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28273    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28274
28275    TCGv_i32 tws = tcg_const_i32(ws);
28276    TCGv_i32 twd = tcg_const_i32(wd);
28277    TCGv_i32 tn  = tcg_const_i32(n);
28278    TCGv_i32 tdf = tcg_const_i32(df);
28279
28280    switch (MASK_MSA_ELM(ctx->opcode)) {
28281    case OPC_SLDI_df:
28282        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28283        break;
28284    case OPC_SPLATI_df:
28285        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28286        break;
28287    case OPC_INSVE_df:
28288        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28289        break;
28290    case OPC_COPY_S_df:
28291    case OPC_COPY_U_df:
28292    case OPC_INSERT_df:
28293#if !defined(TARGET_MIPS64)
28294        /* Double format valid only for MIPS64 */
28295        if (df == DF_DOUBLE) {
28296            generate_exception_end(ctx, EXCP_RI);
28297            break;
28298        }
28299#endif
28300        switch (MASK_MSA_ELM(ctx->opcode)) {
28301        case OPC_COPY_S_df:
28302            if (likely(wd != 0)) {
28303                gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
28304            }
28305            break;
28306        case OPC_COPY_U_df:
28307            if (likely(wd != 0)) {
28308                gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
28309            }
28310            break;
28311        case OPC_INSERT_df:
28312            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
28313            break;
28314        }
28315        break;
28316    default:
28317        MIPS_INVAL("MSA instruction");
28318        generate_exception_end(ctx, EXCP_RI);
28319    }
28320    tcg_temp_free_i32(twd);
28321    tcg_temp_free_i32(tws);
28322    tcg_temp_free_i32(tn);
28323    tcg_temp_free_i32(tdf);
28324}
28325
28326static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28327{
28328    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28329    uint32_t df = 0, n = 0;
28330
28331    if ((dfn & 0x30) == 0x00) {
28332        n = dfn & 0x0f;
28333        df = DF_BYTE;
28334    } else if ((dfn & 0x38) == 0x20) {
28335        n = dfn & 0x07;
28336        df = DF_HALF;
28337    } else if ((dfn & 0x3c) == 0x30) {
28338        n = dfn & 0x03;
28339        df = DF_WORD;
28340    } else if ((dfn & 0x3e) == 0x38) {
28341        n = dfn & 0x01;
28342        df = DF_DOUBLE;
28343    } else if (dfn == 0x3E) {
28344        /* CTCMSA, CFCMSA, MOVE.V */
28345        gen_msa_elm_3e(env, ctx);
28346        return;
28347    } else {
28348        generate_exception_end(ctx, EXCP_RI);
28349        return;
28350    }
28351
28352    gen_msa_elm_df(env, ctx, df, n);
28353}
28354
28355static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28356{
28357#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28358    uint8_t df = (ctx->opcode >> 21) & 0x1;
28359    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28360    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28361    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28362
28363    TCGv_i32 twd = tcg_const_i32(wd);
28364    TCGv_i32 tws = tcg_const_i32(ws);
28365    TCGv_i32 twt = tcg_const_i32(wt);
28366    TCGv_i32 tdf = tcg_temp_new_i32();
28367
28368    /* adjust df value for floating-point instruction */
28369    tcg_gen_movi_i32(tdf, df + 2);
28370
28371    switch (MASK_MSA_3RF(ctx->opcode)) {
28372    case OPC_FCAF_df:
28373        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28374        break;
28375    case OPC_FADD_df:
28376        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28377        break;
28378    case OPC_FCUN_df:
28379        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28380        break;
28381    case OPC_FSUB_df:
28382        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28383        break;
28384    case OPC_FCOR_df:
28385        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28386        break;
28387    case OPC_FCEQ_df:
28388        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28389        break;
28390    case OPC_FMUL_df:
28391        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28392        break;
28393    case OPC_FCUNE_df:
28394        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28395        break;
28396    case OPC_FCUEQ_df:
28397        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28398        break;
28399    case OPC_FDIV_df:
28400        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28401        break;
28402    case OPC_FCNE_df:
28403        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28404        break;
28405    case OPC_FCLT_df:
28406        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28407        break;
28408    case OPC_FMADD_df:
28409        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28410        break;
28411    case OPC_MUL_Q_df:
28412        tcg_gen_movi_i32(tdf, df + 1);
28413        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28414        break;
28415    case OPC_FCULT_df:
28416        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28417        break;
28418    case OPC_FMSUB_df:
28419        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28420        break;
28421    case OPC_MADD_Q_df:
28422        tcg_gen_movi_i32(tdf, df + 1);
28423        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28424        break;
28425    case OPC_FCLE_df:
28426        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28427        break;
28428    case OPC_MSUB_Q_df:
28429        tcg_gen_movi_i32(tdf, df + 1);
28430        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28431        break;
28432    case OPC_FCULE_df:
28433        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28434        break;
28435    case OPC_FEXP2_df:
28436        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28437        break;
28438    case OPC_FSAF_df:
28439        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28440        break;
28441    case OPC_FEXDO_df:
28442        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28443        break;
28444    case OPC_FSUN_df:
28445        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28446        break;
28447    case OPC_FSOR_df:
28448        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28449        break;
28450    case OPC_FSEQ_df:
28451        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28452        break;
28453    case OPC_FTQ_df:
28454        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28455        break;
28456    case OPC_FSUNE_df:
28457        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28458        break;
28459    case OPC_FSUEQ_df:
28460        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28461        break;
28462    case OPC_FSNE_df:
28463        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28464        break;
28465    case OPC_FSLT_df:
28466        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28467        break;
28468    case OPC_FMIN_df:
28469        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28470        break;
28471    case OPC_MULR_Q_df:
28472        tcg_gen_movi_i32(tdf, df + 1);
28473        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28474        break;
28475    case OPC_FSULT_df:
28476        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28477        break;
28478    case OPC_FMIN_A_df:
28479        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28480        break;
28481    case OPC_MADDR_Q_df:
28482        tcg_gen_movi_i32(tdf, df + 1);
28483        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28484        break;
28485    case OPC_FSLE_df:
28486        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28487        break;
28488    case OPC_FMAX_df:
28489        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28490        break;
28491    case OPC_MSUBR_Q_df:
28492        tcg_gen_movi_i32(tdf, df + 1);
28493        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28494        break;
28495    case OPC_FSULE_df:
28496        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28497        break;
28498    case OPC_FMAX_A_df:
28499        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28500        break;
28501    default:
28502        MIPS_INVAL("MSA instruction");
28503        generate_exception_end(ctx, EXCP_RI);
28504        break;
28505    }
28506
28507    tcg_temp_free_i32(twd);
28508    tcg_temp_free_i32(tws);
28509    tcg_temp_free_i32(twt);
28510    tcg_temp_free_i32(tdf);
28511}
28512
28513static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28514{
28515#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28516                            (op & (0x7 << 18)))
28517    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28518    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28519    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28520    uint8_t df = (ctx->opcode >> 16) & 0x3;
28521    TCGv_i32 twd = tcg_const_i32(wd);
28522    TCGv_i32 tws = tcg_const_i32(ws);
28523    TCGv_i32 twt = tcg_const_i32(wt);
28524    TCGv_i32 tdf = tcg_const_i32(df);
28525
28526    switch (MASK_MSA_2R(ctx->opcode)) {
28527    case OPC_FILL_df:
28528#if !defined(TARGET_MIPS64)
28529        /* Double format valid only for MIPS64 */
28530        if (df == DF_DOUBLE) {
28531            generate_exception_end(ctx, EXCP_RI);
28532            break;
28533        }
28534#endif
28535        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28536        break;
28537    case OPC_PCNT_df:
28538        gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28539        break;
28540    case OPC_NLOC_df:
28541        gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28542        break;
28543    case OPC_NLZC_df:
28544        gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28545        break;
28546    default:
28547        MIPS_INVAL("MSA instruction");
28548        generate_exception_end(ctx, EXCP_RI);
28549        break;
28550    }
28551
28552    tcg_temp_free_i32(twd);
28553    tcg_temp_free_i32(tws);
28554    tcg_temp_free_i32(twt);
28555    tcg_temp_free_i32(tdf);
28556}
28557
28558static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28559{
28560#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28561                            (op & (0xf << 17)))
28562    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28563    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28564    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28565    uint8_t df = (ctx->opcode >> 16) & 0x1;
28566    TCGv_i32 twd = tcg_const_i32(wd);
28567    TCGv_i32 tws = tcg_const_i32(ws);
28568    TCGv_i32 twt = tcg_const_i32(wt);
28569    /* adjust df value for floating-point instruction */
28570    TCGv_i32 tdf = tcg_const_i32(df + 2);
28571
28572    switch (MASK_MSA_2RF(ctx->opcode)) {
28573    case OPC_FCLASS_df:
28574        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28575        break;
28576    case OPC_FTRUNC_S_df:
28577        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28578        break;
28579    case OPC_FTRUNC_U_df:
28580        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28581        break;
28582    case OPC_FSQRT_df:
28583        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28584        break;
28585    case OPC_FRSQRT_df:
28586        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28587        break;
28588    case OPC_FRCP_df:
28589        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28590        break;
28591    case OPC_FRINT_df:
28592        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28593        break;
28594    case OPC_FLOG2_df:
28595        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28596        break;
28597    case OPC_FEXUPL_df:
28598        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28599        break;
28600    case OPC_FEXUPR_df:
28601        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28602        break;
28603    case OPC_FFQL_df:
28604        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28605        break;
28606    case OPC_FFQR_df:
28607        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28608        break;
28609    case OPC_FTINT_S_df:
28610        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28611        break;
28612    case OPC_FTINT_U_df:
28613        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28614        break;
28615    case OPC_FFINT_S_df:
28616        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28617        break;
28618    case OPC_FFINT_U_df:
28619        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28620        break;
28621    }
28622
28623    tcg_temp_free_i32(twd);
28624    tcg_temp_free_i32(tws);
28625    tcg_temp_free_i32(twt);
28626    tcg_temp_free_i32(tdf);
28627}
28628
28629static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28630{
28631#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28632    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28633    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28634    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28635    TCGv_i32 twd = tcg_const_i32(wd);
28636    TCGv_i32 tws = tcg_const_i32(ws);
28637    TCGv_i32 twt = tcg_const_i32(wt);
28638
28639    switch (MASK_MSA_VEC(ctx->opcode)) {
28640    case OPC_AND_V:
28641        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28642        break;
28643    case OPC_OR_V:
28644        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28645        break;
28646    case OPC_NOR_V:
28647        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28648        break;
28649    case OPC_XOR_V:
28650        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28651        break;
28652    case OPC_BMNZ_V:
28653        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28654        break;
28655    case OPC_BMZ_V:
28656        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28657        break;
28658    case OPC_BSEL_V:
28659        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28660        break;
28661    default:
28662        MIPS_INVAL("MSA instruction");
28663        generate_exception_end(ctx, EXCP_RI);
28664        break;
28665    }
28666
28667    tcg_temp_free_i32(twd);
28668    tcg_temp_free_i32(tws);
28669    tcg_temp_free_i32(twt);
28670}
28671
28672static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28673{
28674    switch (MASK_MSA_VEC(ctx->opcode)) {
28675    case OPC_AND_V:
28676    case OPC_OR_V:
28677    case OPC_NOR_V:
28678    case OPC_XOR_V:
28679    case OPC_BMNZ_V:
28680    case OPC_BMZ_V:
28681    case OPC_BSEL_V:
28682        gen_msa_vec_v(env, ctx);
28683        break;
28684    case OPC_MSA_2R:
28685        gen_msa_2r(env, ctx);
28686        break;
28687    case OPC_MSA_2RF:
28688        gen_msa_2rf(env, ctx);
28689        break;
28690    default:
28691        MIPS_INVAL("MSA instruction");
28692        generate_exception_end(ctx, EXCP_RI);
28693        break;
28694    }
28695}
28696
28697static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28698{
28699    uint32_t opcode = ctx->opcode;
28700    check_insn(ctx, ASE_MSA);
28701    check_msa_access(ctx);
28702
28703    switch (MASK_MSA_MINOR(opcode)) {
28704    case OPC_MSA_I8_00:
28705    case OPC_MSA_I8_01:
28706    case OPC_MSA_I8_02:
28707        gen_msa_i8(env, ctx);
28708        break;
28709    case OPC_MSA_I5_06:
28710    case OPC_MSA_I5_07:
28711        gen_msa_i5(env, ctx);
28712        break;
28713    case OPC_MSA_BIT_09:
28714    case OPC_MSA_BIT_0A:
28715        gen_msa_bit(env, ctx);
28716        break;
28717    case OPC_MSA_3R_0D:
28718    case OPC_MSA_3R_0E:
28719    case OPC_MSA_3R_0F:
28720    case OPC_MSA_3R_10:
28721    case OPC_MSA_3R_11:
28722    case OPC_MSA_3R_12:
28723    case OPC_MSA_3R_13:
28724    case OPC_MSA_3R_14:
28725    case OPC_MSA_3R_15:
28726        gen_msa_3r(env, ctx);
28727        break;
28728    case OPC_MSA_ELM:
28729        gen_msa_elm(env, ctx);
28730        break;
28731    case OPC_MSA_3RF_1A:
28732    case OPC_MSA_3RF_1B:
28733    case OPC_MSA_3RF_1C:
28734        gen_msa_3rf(env, ctx);
28735        break;
28736    case OPC_MSA_VEC:
28737        gen_msa_vec(env, ctx);
28738        break;
28739    case OPC_LD_B:
28740    case OPC_LD_H:
28741    case OPC_LD_W:
28742    case OPC_LD_D:
28743    case OPC_ST_B:
28744    case OPC_ST_H:
28745    case OPC_ST_W:
28746    case OPC_ST_D:
28747        {
28748            int32_t s10 = sextract32(ctx->opcode, 16, 10);
28749            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28750            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28751            uint8_t df = (ctx->opcode >> 0) & 0x3;
28752
28753            TCGv_i32 twd = tcg_const_i32(wd);
28754            TCGv taddr = tcg_temp_new();
28755            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28756
28757            switch (MASK_MSA_MINOR(opcode)) {
28758            case OPC_LD_B:
28759                gen_helper_msa_ld_b(cpu_env, twd, taddr);
28760                break;
28761            case OPC_LD_H:
28762                gen_helper_msa_ld_h(cpu_env, twd, taddr);
28763                break;
28764            case OPC_LD_W:
28765                gen_helper_msa_ld_w(cpu_env, twd, taddr);
28766                break;
28767            case OPC_LD_D:
28768                gen_helper_msa_ld_d(cpu_env, twd, taddr);
28769                break;
28770            case OPC_ST_B:
28771                gen_helper_msa_st_b(cpu_env, twd, taddr);
28772                break;
28773            case OPC_ST_H:
28774                gen_helper_msa_st_h(cpu_env, twd, taddr);
28775                break;
28776            case OPC_ST_W:
28777                gen_helper_msa_st_w(cpu_env, twd, taddr);
28778                break;
28779            case OPC_ST_D:
28780                gen_helper_msa_st_d(cpu_env, twd, taddr);
28781                break;
28782            }
28783
28784            tcg_temp_free_i32(twd);
28785            tcg_temp_free(taddr);
28786        }
28787        break;
28788    default:
28789        MIPS_INVAL("MSA instruction");
28790        generate_exception_end(ctx, EXCP_RI);
28791        break;
28792    }
28793
28794}
28795
28796static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
28797{
28798    int32_t offset;
28799    int rs, rt, rd, sa;
28800    uint32_t op, op1;
28801    int16_t imm;
28802
28803    /* make sure instructions are on a word boundary */
28804    if (ctx->base.pc_next & 0x3) {
28805        env->CP0_BadVAddr = ctx->base.pc_next;
28806        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
28807        return;
28808    }
28809
28810    /* Handle blikely not taken case */
28811    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
28812        TCGLabel *l1 = gen_new_label();
28813
28814        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28815        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28816        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28817        gen_set_label(l1);
28818    }
28819
28820    op = MASK_OP_MAJOR(ctx->opcode);
28821    rs = (ctx->opcode >> 21) & 0x1f;
28822    rt = (ctx->opcode >> 16) & 0x1f;
28823    rd = (ctx->opcode >> 11) & 0x1f;
28824    sa = (ctx->opcode >> 6) & 0x1f;
28825    imm = (int16_t)ctx->opcode;
28826    switch (op) {
28827    case OPC_SPECIAL:
28828        decode_opc_special(env, ctx);
28829        break;
28830    case OPC_SPECIAL2:
28831#if defined(TARGET_MIPS64)
28832        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28833            decode_mmi(env, ctx);
28834#else
28835        if (ctx->insn_flags & ASE_MXU) {
28836            decode_opc_mxu(env, ctx);
28837#endif
28838        } else {
28839            decode_opc_special2_legacy(env, ctx);
28840        }
28841        break;
28842    case OPC_SPECIAL3:
28843#if defined(TARGET_MIPS64)
28844        if (ctx->insn_flags & INSN_R5900) {
28845            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
28846        } else {
28847            decode_opc_special3(env, ctx);
28848        }
28849#else
28850        decode_opc_special3(env, ctx);
28851#endif
28852        break;
28853    case OPC_REGIMM:
28854        op1 = MASK_REGIMM(ctx->opcode);
28855        switch (op1) {
28856        case OPC_BLTZL: /* REGIMM branches */
28857        case OPC_BGEZL:
28858        case OPC_BLTZALL:
28859        case OPC_BGEZALL:
28860            check_insn(ctx, ISA_MIPS2);
28861            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28862            /* Fallthrough */
28863        case OPC_BLTZ:
28864        case OPC_BGEZ:
28865            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28866            break;
28867        case OPC_BLTZAL:
28868        case OPC_BGEZAL:
28869            if (ctx->insn_flags & ISA_MIPS32R6) {
28870                if (rs == 0) {
28871                    /* OPC_NAL, OPC_BAL */
28872                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28873                } else {
28874                    generate_exception_end(ctx, EXCP_RI);
28875                }
28876            } else {
28877                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28878            }
28879            break;
28880        case OPC_TGEI: /* REGIMM traps */
28881        case OPC_TGEIU:
28882        case OPC_TLTI:
28883        case OPC_TLTIU:
28884        case OPC_TEQI:
28885
28886        case OPC_TNEI:
28887            check_insn(ctx, ISA_MIPS2);
28888            check_insn_opc_removed(ctx, ISA_MIPS32R6);
28889            gen_trap(ctx, op1, rs, -1, imm);
28890            break;
28891        case OPC_SIGRIE:
28892            check_insn(ctx, ISA_MIPS32R6);
28893            generate_exception_end(ctx, EXCP_RI);
28894            break;
28895        case OPC_SYNCI:
28896            check_insn(ctx, ISA_MIPS32R2);
28897            /* Break the TB to be able to sync copied instructions
28898               immediately */
28899            ctx->base.is_jmp = DISAS_STOP;
28900            break;
28901        case OPC_BPOSGE32:    /* MIPS DSP branch */
28902#if defined(TARGET_MIPS64)
28903        case OPC_BPOSGE64:
28904#endif
28905            check_dsp(ctx);
28906            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28907            break;
28908#if defined(TARGET_MIPS64)
28909        case OPC_DAHI:
28910            check_insn(ctx, ISA_MIPS32R6);
28911            check_mips_64(ctx);
28912            if (rs != 0) {
28913                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28914            }
28915            break;
28916        case OPC_DATI:
28917            check_insn(ctx, ISA_MIPS32R6);
28918            check_mips_64(ctx);
28919            if (rs != 0) {
28920                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28921            }
28922            break;
28923#endif
28924        default:            /* Invalid */
28925            MIPS_INVAL("regimm");
28926            generate_exception_end(ctx, EXCP_RI);
28927            break;
28928        }
28929        break;
28930    case OPC_CP0:
28931        check_cp0_enabled(ctx);
28932        op1 = MASK_CP0(ctx->opcode);
28933        switch (op1) {
28934        case OPC_MFC0:
28935        case OPC_MTC0:
28936        case OPC_MFTR:
28937        case OPC_MTTR:
28938        case OPC_MFHC0:
28939        case OPC_MTHC0:
28940#if defined(TARGET_MIPS64)
28941        case OPC_DMFC0:
28942        case OPC_DMTC0:
28943#endif
28944#ifndef CONFIG_USER_ONLY
28945            gen_cp0(env, ctx, op1, rt, rd);
28946#endif /* !CONFIG_USER_ONLY */
28947            break;
28948        case OPC_C0:
28949        case OPC_C0_1:
28950        case OPC_C0_2:
28951        case OPC_C0_3:
28952        case OPC_C0_4:
28953        case OPC_C0_5:
28954        case OPC_C0_6:
28955        case OPC_C0_7:
28956        case OPC_C0_8:
28957        case OPC_C0_9:
28958        case OPC_C0_A:
28959        case OPC_C0_B:
28960        case OPC_C0_C:
28961        case OPC_C0_D:
28962        case OPC_C0_E:
28963        case OPC_C0_F:
28964#ifndef CONFIG_USER_ONLY
28965            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28966#endif /* !CONFIG_USER_ONLY */
28967            break;
28968        case OPC_MFMC0:
28969#ifndef CONFIG_USER_ONLY
28970            {
28971                uint32_t op2;
28972                TCGv t0 = tcg_temp_new();
28973
28974                op2 = MASK_MFMC0(ctx->opcode);
28975                switch (op2) {
28976                case OPC_DMT:
28977                    check_cp0_mt(ctx);
28978                    gen_helper_dmt(t0);
28979                    gen_store_gpr(t0, rt);
28980                    break;
28981                case OPC_EMT:
28982                    check_cp0_mt(ctx);
28983                    gen_helper_emt(t0);
28984                    gen_store_gpr(t0, rt);
28985                    break;
28986                case OPC_DVPE:
28987                    check_cp0_mt(ctx);
28988                    gen_helper_dvpe(t0, cpu_env);
28989                    gen_store_gpr(t0, rt);
28990                    break;
28991                case OPC_EVPE:
28992                    check_cp0_mt(ctx);
28993                    gen_helper_evpe(t0, cpu_env);
28994                    gen_store_gpr(t0, rt);
28995                    break;
28996                case OPC_DVP:
28997                    check_insn(ctx, ISA_MIPS32R6);
28998                    if (ctx->vp) {
28999                        gen_helper_dvp(t0, cpu_env);
29000                        gen_store_gpr(t0, rt);
29001                    }
29002                    break;
29003                case OPC_EVP:
29004                    check_insn(ctx, ISA_MIPS32R6);
29005                    if (ctx->vp) {
29006                        gen_helper_evp(t0, cpu_env);
29007                        gen_store_gpr(t0, rt);
29008                    }
29009                    break;
29010                case OPC_DI:
29011                    check_insn(ctx, ISA_MIPS32R2);
29012                    save_cpu_state(ctx, 1);
29013                    gen_helper_di(t0, cpu_env);
29014                    gen_store_gpr(t0, rt);
29015                    /* Stop translation as we may have switched
29016                       the execution mode.  */
29017                    ctx->base.is_jmp = DISAS_STOP;
29018                    break;
29019                case OPC_EI:
29020                    check_insn(ctx, ISA_MIPS32R2);
29021                    save_cpu_state(ctx, 1);
29022                    gen_helper_ei(t0, cpu_env);
29023                    gen_store_gpr(t0, rt);
29024                    /* DISAS_STOP isn't sufficient, we need to ensure we break
29025                       out of translated code to check for pending interrupts */
29026                    gen_save_pc(ctx->base.pc_next + 4);
29027                    ctx->base.is_jmp = DISAS_EXIT;
29028                    break;
29029                default:            /* Invalid */
29030                    MIPS_INVAL("mfmc0");
29031                    generate_exception_end(ctx, EXCP_RI);
29032                    break;
29033                }
29034                tcg_temp_free(t0);
29035            }
29036#endif /* !CONFIG_USER_ONLY */
29037            break;
29038        case OPC_RDPGPR:
29039            check_insn(ctx, ISA_MIPS32R2);
29040            gen_load_srsgpr(rt, rd);
29041            break;
29042        case OPC_WRPGPR:
29043            check_insn(ctx, ISA_MIPS32R2);
29044            gen_store_srsgpr(rt, rd);
29045            break;
29046        default:
29047            MIPS_INVAL("cp0");
29048            generate_exception_end(ctx, EXCP_RI);
29049            break;
29050        }
29051        break;
29052    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29053        if (ctx->insn_flags & ISA_MIPS32R6) {
29054            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29055            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29056        } else {
29057            /* OPC_ADDI */
29058            /* Arithmetic with immediate opcode */
29059            gen_arith_imm(ctx, op, rt, rs, imm);
29060        }
29061        break;
29062    case OPC_ADDIU:
29063         gen_arith_imm(ctx, op, rt, rs, imm);
29064         break;
29065    case OPC_SLTI: /* Set on less than with immediate opcode */
29066    case OPC_SLTIU:
29067         gen_slt_imm(ctx, op, rt, rs, imm);
29068         break;
29069    case OPC_ANDI: /* Arithmetic with immediate opcode */
29070    case OPC_LUI: /* OPC_AUI */
29071    case OPC_ORI:
29072    case OPC_XORI:
29073         gen_logic_imm(ctx, op, rt, rs, imm);
29074         break;
29075    case OPC_J: /* Jump */
29076    case OPC_JAL:
29077         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29078         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29079         break;
29080    /* Branch */
29081    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29082        if (ctx->insn_flags & ISA_MIPS32R6) {
29083            if (rt == 0) {
29084                generate_exception_end(ctx, EXCP_RI);
29085                break;
29086            }
29087            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29088            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29089        } else {
29090            /* OPC_BLEZL */
29091            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29092        }
29093        break;
29094    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29095        if (ctx->insn_flags & ISA_MIPS32R6) {
29096            if (rt == 0) {
29097                generate_exception_end(ctx, EXCP_RI);
29098                break;
29099            }
29100            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29101            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29102        } else {
29103            /* OPC_BGTZL */
29104            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29105        }
29106        break;
29107    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29108        if (rt == 0) {
29109            /* OPC_BLEZ */
29110            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29111        } else {
29112            check_insn(ctx, ISA_MIPS32R6);
29113            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29114            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29115        }
29116        break;
29117    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29118        if (rt == 0) {
29119            /* OPC_BGTZ */
29120            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29121        } else {
29122            check_insn(ctx, ISA_MIPS32R6);
29123            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29124            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29125        }
29126        break;
29127    case OPC_BEQL:
29128    case OPC_BNEL:
29129        check_insn(ctx, ISA_MIPS2);
29130         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29131        /* Fallthrough */
29132    case OPC_BEQ:
29133    case OPC_BNE:
29134         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29135         break;
29136    case OPC_LL: /* Load and stores */
29137        check_insn(ctx, ISA_MIPS2);
29138        if (ctx->insn_flags & INSN_R5900) {
29139            check_insn_opc_user_only(ctx, INSN_R5900);
29140        }
29141        /* Fallthrough */
29142    case OPC_LWL:
29143    case OPC_LWR:
29144        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29145         /* Fallthrough */
29146    case OPC_LB:
29147    case OPC_LH:
29148    case OPC_LW:
29149    case OPC_LWPC:
29150    case OPC_LBU:
29151    case OPC_LHU:
29152         gen_ld(ctx, op, rt, rs, imm);
29153         break;
29154    case OPC_SWL:
29155    case OPC_SWR:
29156        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29157        /* fall through */
29158    case OPC_SB:
29159    case OPC_SH:
29160    case OPC_SW:
29161         gen_st(ctx, op, rt, rs, imm);
29162         break;
29163    case OPC_SC:
29164        check_insn(ctx, ISA_MIPS2);
29165         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29166        if (ctx->insn_flags & INSN_R5900) {
29167            check_insn_opc_user_only(ctx, INSN_R5900);
29168        }
29169        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29170        break;
29171    case OPC_CACHE:
29172        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29173        check_cp0_enabled(ctx);
29174        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29175        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29176            gen_cache_operation(ctx, rt, rs, imm);
29177        }
29178        /* Treat as NOP. */
29179        break;
29180    case OPC_PREF:
29181        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29182        if (ctx->insn_flags & INSN_R5900) {
29183            /* Treat as NOP. */
29184        } else {
29185            check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29186            /* Treat as NOP. */
29187        }
29188        break;
29189
29190    /* Floating point (COP1). */
29191    case OPC_LWC1:
29192    case OPC_LDC1:
29193    case OPC_SWC1:
29194    case OPC_SDC1:
29195        gen_cop1_ldst(ctx, op, rt, rs, imm);
29196        break;
29197
29198    case OPC_CP1:
29199        op1 = MASK_CP1(ctx->opcode);
29200
29201        switch (op1) {
29202        case OPC_MFHC1:
29203        case OPC_MTHC1:
29204            check_cp1_enabled(ctx);
29205            check_insn(ctx, ISA_MIPS32R2);
29206            /* fall through */
29207        case OPC_MFC1:
29208        case OPC_CFC1:
29209        case OPC_MTC1:
29210        case OPC_CTC1:
29211            check_cp1_enabled(ctx);
29212            gen_cp1(ctx, op1, rt, rd);
29213            break;
29214#if defined(TARGET_MIPS64)
29215        case OPC_DMFC1:
29216        case OPC_DMTC1:
29217            check_cp1_enabled(ctx);
29218            check_insn(ctx, ISA_MIPS3);
29219            check_mips_64(ctx);
29220            gen_cp1(ctx, op1, rt, rd);
29221            break;
29222#endif
29223        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29224            check_cp1_enabled(ctx);
29225            if (ctx->insn_flags & ISA_MIPS32R6) {
29226                /* OPC_BC1EQZ */
29227                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29228                                       rt, imm << 2, 4);
29229            } else {
29230                /* OPC_BC1ANY2 */
29231                check_cop1x(ctx);
29232                check_insn(ctx, ASE_MIPS3D);
29233                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29234                                    (rt >> 2) & 0x7, imm << 2);
29235            }
29236            break;
29237        case OPC_BC1NEZ:
29238            check_cp1_enabled(ctx);
29239            check_insn(ctx, ISA_MIPS32R6);
29240            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29241                                   rt, imm << 2, 4);
29242            break;
29243        case OPC_BC1ANY4:
29244            check_cp1_enabled(ctx);
29245            check_insn_opc_removed(ctx, ISA_MIPS32R6);
29246            check_cop1x(ctx);
29247            check_insn(ctx, ASE_MIPS3D);
29248            /* fall through */
29249        case OPC_BC1:
29250            check_cp1_enabled(ctx);
29251            check_insn_opc_removed(ctx, ISA_MIPS32R6);
29252            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29253                                (rt >> 2) & 0x7, imm << 2);
29254            break;
29255        case OPC_PS_FMT:
29256            check_ps(ctx);
29257            /* fall through */
29258        case OPC_S_FMT:
29259        case OPC_D_FMT:
29260            check_cp1_enabled(ctx);
29261            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29262                       (imm >> 8) & 0x7);
29263            break;
29264        case OPC_W_FMT:
29265        case OPC_L_FMT:
29266        {
29267            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29268            check_cp1_enabled(ctx);
29269            if (ctx->insn_flags & ISA_MIPS32R6) {
29270                switch (r6_op) {
29271                case R6_OPC_CMP_AF_S:
29272                case R6_OPC_CMP_UN_S:
29273                case R6_OPC_CMP_EQ_S:
29274                case R6_OPC_CMP_UEQ_S:
29275                case R6_OPC_CMP_LT_S:
29276                case R6_OPC_CMP_ULT_S:
29277                case R6_OPC_CMP_LE_S:
29278                case R6_OPC_CMP_ULE_S:
29279                case R6_OPC_CMP_SAF_S:
29280                case R6_OPC_CMP_SUN_S:
29281                case R6_OPC_CMP_SEQ_S:
29282                case R6_OPC_CMP_SEUQ_S:
29283                case R6_OPC_CMP_SLT_S:
29284                case R6_OPC_CMP_SULT_S:
29285                case R6_OPC_CMP_SLE_S:
29286                case R6_OPC_CMP_SULE_S:
29287                case R6_OPC_CMP_OR_S:
29288                case R6_OPC_CMP_UNE_S:
29289                case R6_OPC_CMP_NE_S:
29290                case R6_OPC_CMP_SOR_S:
29291                case R6_OPC_CMP_SUNE_S:
29292                case R6_OPC_CMP_SNE_S:
29293                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29294                    break;
29295                case R6_OPC_CMP_AF_D:
29296                case R6_OPC_CMP_UN_D:
29297                case R6_OPC_CMP_EQ_D:
29298                case R6_OPC_CMP_UEQ_D:
29299                case R6_OPC_CMP_LT_D:
29300                case R6_OPC_CMP_ULT_D:
29301                case R6_OPC_CMP_LE_D:
29302                case R6_OPC_CMP_ULE_D:
29303                case R6_OPC_CMP_SAF_D:
29304                case R6_OPC_CMP_SUN_D:
29305                case R6_OPC_CMP_SEQ_D:
29306                case R6_OPC_CMP_SEUQ_D:
29307                case R6_OPC_CMP_SLT_D:
29308                case R6_OPC_CMP_SULT_D:
29309                case R6_OPC_CMP_SLE_D:
29310                case R6_OPC_CMP_SULE_D:
29311                case R6_OPC_CMP_OR_D:
29312                case R6_OPC_CMP_UNE_D:
29313                case R6_OPC_CMP_NE_D:
29314                case R6_OPC_CMP_SOR_D:
29315                case R6_OPC_CMP_SUNE_D:
29316                case R6_OPC_CMP_SNE_D:
29317                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29318                    break;
29319                default:
29320                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29321                               rt, rd, sa, (imm >> 8) & 0x7);
29322
29323                    break;
29324                }
29325            } else {
29326                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29327                           (imm >> 8) & 0x7);
29328            }
29329            break;
29330        }
29331        case OPC_BZ_V:
29332        case OPC_BNZ_V:
29333        case OPC_BZ_B:
29334        case OPC_BZ_H:
29335        case OPC_BZ_W:
29336        case OPC_BZ_D:
29337        case OPC_BNZ_B:
29338        case OPC_BNZ_H:
29339        case OPC_BNZ_W:
29340        case OPC_BNZ_D:
29341            check_insn(ctx, ASE_MSA);
29342            gen_msa_branch(env, ctx, op1);
29343            break;
29344        default:
29345            MIPS_INVAL("cp1");
29346            generate_exception_end(ctx, EXCP_RI);
29347            break;
29348        }
29349        break;
29350
29351    /* Compact branches [R6] and COP2 [non-R6] */
29352    case OPC_BC: /* OPC_LWC2 */
29353    case OPC_BALC: /* OPC_SWC2 */
29354        if (ctx->insn_flags & ISA_MIPS32R6) {
29355            /* OPC_BC, OPC_BALC */
29356            gen_compute_compact_branch(ctx, op, 0, 0,
29357                                       sextract32(ctx->opcode << 2, 0, 28));
29358        } else {
29359            /* OPC_LWC2, OPC_SWC2 */
29360            /* COP2: Not implemented. */
29361            generate_exception_err(ctx, EXCP_CpU, 2);
29362        }
29363        break;
29364    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29365    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29366        if (ctx->insn_flags & ISA_MIPS32R6) {
29367            if (rs != 0) {
29368                /* OPC_BEQZC, OPC_BNEZC */
29369                gen_compute_compact_branch(ctx, op, rs, 0,
29370                                           sextract32(ctx->opcode << 2, 0, 23));
29371            } else {
29372                /* OPC_JIC, OPC_JIALC */
29373                gen_compute_compact_branch(ctx, op, 0, rt, imm);
29374            }
29375        } else {
29376            /* OPC_LWC2, OPC_SWC2 */
29377            /* COP2: Not implemented. */
29378            generate_exception_err(ctx, EXCP_CpU, 2);
29379        }
29380        break;
29381    case OPC_CP2:
29382        check_insn(ctx, INSN_LOONGSON2F);
29383        /* Note that these instructions use different fields.  */
29384        gen_loongson_multimedia(ctx, sa, rd, rt);
29385        break;
29386
29387    case OPC_CP3:
29388        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29389        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29390            check_cp1_enabled(ctx);
29391            op1 = MASK_CP3(ctx->opcode);
29392            switch (op1) {
29393            case OPC_LUXC1:
29394            case OPC_SUXC1:
29395                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29396                /* Fallthrough */
29397            case OPC_LWXC1:
29398            case OPC_LDXC1:
29399            case OPC_SWXC1:
29400            case OPC_SDXC1:
29401                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29402                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29403                break;
29404            case OPC_PREFX:
29405                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29406                /* Treat as NOP. */
29407                break;
29408            case OPC_ALNV_PS:
29409                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29410                /* Fallthrough */
29411            case OPC_MADD_S:
29412            case OPC_MADD_D:
29413            case OPC_MADD_PS:
29414            case OPC_MSUB_S:
29415            case OPC_MSUB_D:
29416            case OPC_MSUB_PS:
29417            case OPC_NMADD_S:
29418            case OPC_NMADD_D:
29419            case OPC_NMADD_PS:
29420            case OPC_NMSUB_S:
29421            case OPC_NMSUB_D:
29422            case OPC_NMSUB_PS:
29423                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29424                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29425                break;
29426            default:
29427                MIPS_INVAL("cp3");
29428                generate_exception_end(ctx, EXCP_RI);
29429                break;
29430            }
29431        } else {
29432            generate_exception_err(ctx, EXCP_CpU, 1);
29433        }
29434        break;
29435
29436#if defined(TARGET_MIPS64)
29437    /* MIPS64 opcodes */
29438    case OPC_LLD:
29439        if (ctx->insn_flags & INSN_R5900) {
29440            check_insn_opc_user_only(ctx, INSN_R5900);
29441        }
29442        /* fall through */
29443    case OPC_LDL:
29444    case OPC_LDR:
29445        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29446        /* fall through */
29447    case OPC_LWU:
29448    case OPC_LD:
29449        check_insn(ctx, ISA_MIPS3);
29450        check_mips_64(ctx);
29451        gen_ld(ctx, op, rt, rs, imm);
29452        break;
29453    case OPC_SDL:
29454    case OPC_SDR:
29455        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29456        /* fall through */
29457    case OPC_SD:
29458        check_insn(ctx, ISA_MIPS3);
29459        check_mips_64(ctx);
29460        gen_st(ctx, op, rt, rs, imm);
29461        break;
29462    case OPC_SCD:
29463        check_insn_opc_removed(ctx, ISA_MIPS32R6);
29464        check_insn(ctx, ISA_MIPS3);
29465        if (ctx->insn_flags & INSN_R5900) {
29466            check_insn_opc_user_only(ctx, INSN_R5900);
29467        }
29468        check_mips_64(ctx);
29469        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29470        break;
29471    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29472        if (ctx->insn_flags & ISA_MIPS32R6) {
29473            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29474            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29475        } else {
29476            /* OPC_DADDI */
29477            check_insn(ctx, ISA_MIPS3);
29478            check_mips_64(ctx);
29479            gen_arith_imm(ctx, op, rt, rs, imm);
29480        }
29481        break;
29482    case OPC_DADDIU:
29483        check_insn(ctx, ISA_MIPS3);
29484        check_mips_64(ctx);
29485        gen_arith_imm(ctx, op, rt, rs, imm);
29486        break;
29487#else
29488    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29489        if (ctx->insn_flags & ISA_MIPS32R6) {
29490            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29491        } else {
29492            MIPS_INVAL("major opcode");
29493            generate_exception_end(ctx, EXCP_RI);
29494        }
29495        break;
29496#endif
29497    case OPC_DAUI: /* OPC_JALX */
29498        if (ctx->insn_flags & ISA_MIPS32R6) {
29499#if defined(TARGET_MIPS64)
29500            /* OPC_DAUI */
29501            check_mips_64(ctx);
29502            if (rs == 0) {
29503                generate_exception(ctx, EXCP_RI);
29504            } else if (rt != 0) {
29505                TCGv t0 = tcg_temp_new();
29506                gen_load_gpr(t0, rs);
29507                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29508                tcg_temp_free(t0);
29509            }
29510#else
29511            generate_exception_end(ctx, EXCP_RI);
29512            MIPS_INVAL("major opcode");
29513#endif
29514        } else {
29515            /* OPC_JALX */
29516            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29517            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29518            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29519        }
29520        break;
29521    case OPC_MSA: /* OPC_MDMX */
29522        if (ctx->insn_flags & INSN_R5900) {
29523#if defined(TARGET_MIPS64)
29524            gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
29525#endif
29526        } else {
29527            /* MDMX: Not implemented. */
29528            gen_msa(env, ctx);
29529        }
29530        break;
29531    case OPC_PCREL:
29532        check_insn(ctx, ISA_MIPS32R6);
29533        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29534        break;
29535    default:            /* Invalid */
29536        MIPS_INVAL("major opcode");
29537        generate_exception_end(ctx, EXCP_RI);
29538        break;
29539    }
29540}
29541
29542static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29543{
29544    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29545    CPUMIPSState *env = cs->env_ptr;
29546
29547    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29548    ctx->saved_pc = -1;
29549    ctx->insn_flags = env->insn_flags;
29550    ctx->CP0_Config1 = env->CP0_Config1;
29551    ctx->CP0_Config2 = env->CP0_Config2;
29552    ctx->CP0_Config3 = env->CP0_Config3;
29553    ctx->CP0_Config5 = env->CP0_Config5;
29554    ctx->btarget = 0;
29555    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29556    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29557    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29558    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29559    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29560    ctx->PAMask = env->PAMask;
29561    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29562    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29563    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29564    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29565    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29566    /* Restore delay slot state from the tb context.  */
29567    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29568    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29569    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29570             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29571    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29572    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29573    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29574    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29575    restore_cpu_state(env, ctx);
29576#ifdef CONFIG_USER_ONLY
29577        ctx->mem_idx = MIPS_HFLAG_UM;
29578#else
29579        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29580#endif
29581    ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29582                                  MO_UNALN : MO_ALIGN;
29583
29584    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29585              ctx->hflags);
29586}
29587
29588static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29589{
29590}
29591
29592static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29593{
29594    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29595
29596    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29597                       ctx->btarget);
29598}
29599
29600static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29601                                     const CPUBreakpoint *bp)
29602{
29603    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29604
29605    save_cpu_state(ctx, 1);
29606    ctx->base.is_jmp = DISAS_NORETURN;
29607    gen_helper_raise_exception_debug(cpu_env);
29608    /* The address covered by the breakpoint must be included in
29609       [tb->pc, tb->pc + tb->size) in order to for it to be
29610       properly cleared -- thus we increment the PC here so that
29611       the logic setting tb->size below does the right thing.  */
29612    ctx->base.pc_next += 4;
29613    return true;
29614}
29615
29616static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29617{
29618    CPUMIPSState *env = cs->env_ptr;
29619    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29620    int insn_bytes;
29621    int is_slot;
29622
29623    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29624    if (ctx->insn_flags & ISA_NANOMIPS32) {
29625        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29626        insn_bytes = decode_nanomips_opc(env, ctx);
29627    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29628        ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29629        insn_bytes = 4;
29630        decode_opc(env, ctx);
29631    } else if (ctx->insn_flags & ASE_MICROMIPS) {
29632        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29633        insn_bytes = decode_micromips_opc(env, ctx);
29634    } else if (ctx->insn_flags & ASE_MIPS16) {
29635        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29636        insn_bytes = decode_mips16_opc(env, ctx);
29637    } else {
29638        generate_exception_end(ctx, EXCP_RI);
29639        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29640        return;
29641    }
29642
29643    if (ctx->hflags & MIPS_HFLAG_BMASK) {
29644        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29645                             MIPS_HFLAG_FBNSLOT))) {
29646            /* force to generate branch as there is neither delay nor
29647               forbidden slot */
29648            is_slot = 1;
29649        }
29650        if ((ctx->hflags & MIPS_HFLAG_M16) &&
29651            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29652            /* Force to generate branch as microMIPS R6 doesn't restrict
29653               branches in the forbidden slot. */
29654            is_slot = 1;
29655        }
29656    }
29657    if (is_slot) {
29658        gen_branch(ctx, insn_bytes);
29659    }
29660    ctx->base.pc_next += insn_bytes;
29661
29662    if (ctx->base.is_jmp != DISAS_NEXT) {
29663        return;
29664    }
29665    /* Execute a branch and its delay slot as a single instruction.
29666       This is what GDB expects and is consistent with what the
29667       hardware does (e.g. if a delay slot instruction faults, the
29668       reported PC is the PC of the branch).  */
29669    if (ctx->base.singlestep_enabled &&
29670        (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29671        ctx->base.is_jmp = DISAS_TOO_MANY;
29672    }
29673    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29674        ctx->base.is_jmp = DISAS_TOO_MANY;
29675    }
29676}
29677
29678static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29679{
29680    DisasContext *ctx = container_of(dcbase, DisasContext, base);
29681
29682    if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29683        save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29684        gen_helper_raise_exception_debug(cpu_env);
29685    } else {
29686        switch (ctx->base.is_jmp) {
29687        case DISAS_STOP:
29688            gen_save_pc(ctx->base.pc_next);
29689            tcg_gen_lookup_and_goto_ptr();
29690            break;
29691        case DISAS_NEXT:
29692        case DISAS_TOO_MANY:
29693            save_cpu_state(ctx, 0);
29694            gen_goto_tb(ctx, 0, ctx->base.pc_next);
29695            break;
29696        case DISAS_EXIT:
29697            tcg_gen_exit_tb(NULL, 0);
29698            break;
29699        case DISAS_NORETURN:
29700            break;
29701        default:
29702            g_assert_not_reached();
29703        }
29704    }
29705}
29706
29707static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29708{
29709    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29710    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29711}
29712
29713static const TranslatorOps mips_tr_ops = {
29714    .init_disas_context = mips_tr_init_disas_context,
29715    .tb_start           = mips_tr_tb_start,
29716    .insn_start         = mips_tr_insn_start,
29717    .breakpoint_check   = mips_tr_breakpoint_check,
29718    .translate_insn     = mips_tr_translate_insn,
29719    .tb_stop            = mips_tr_tb_stop,
29720    .disas_log          = mips_tr_disas_log,
29721};
29722
29723void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
29724{
29725    DisasContext ctx;
29726
29727    translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
29728}
29729
29730static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
29731                           int flags)
29732{
29733    int i;
29734    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29735
29736#define printfpr(fp)                                                    \
29737    do {                                                                \
29738        if (is_fpu64)                                                   \
29739            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29740                        " fd:%13g fs:%13g psu: %13g\n",                 \
29741                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
29742                        (double)(fp)->fd,                               \
29743                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
29744                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
29745        else {                                                          \
29746            fpr_t tmp;                                                  \
29747            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
29748            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
29749            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29750                        " fd:%13g fs:%13g psu:%13g\n",                  \
29751                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
29752                        (double)tmp.fd,                                 \
29753                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
29754                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
29755        }                                                               \
29756    } while(0)
29757
29758
29759    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
29760                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29761                get_float_exception_flags(&env->active_fpu.fp_status));
29762    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29763        fpu_fprintf(f, "%3s: ", fregnames[i]);
29764        printfpr(&env->active_fpu.fpr[i]);
29765    }
29766
29767#undef printfpr
29768}
29769
29770void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29771                         int flags)
29772{
29773    MIPSCPU *cpu = MIPS_CPU(cs);
29774    CPUMIPSState *env = &cpu->env;
29775    int i;
29776
29777    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29778                " LO=0x" TARGET_FMT_lx " ds %04x "
29779                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29780                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29781                env->hflags, env->btarget, env->bcond);
29782    for (i = 0; i < 32; i++) {
29783        if ((i & 3) == 0)
29784            cpu_fprintf(f, "GPR%02d:", i);
29785        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
29786        if ((i & 3) == 3)
29787            cpu_fprintf(f, "\n");
29788    }
29789
29790    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
29791                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
29792    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29793                PRIx64 "\n",
29794                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
29795    cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
29796                env->CP0_Config2, env->CP0_Config3);
29797    cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
29798                env->CP0_Config4, env->CP0_Config5);
29799    if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
29800        fpu_dump_state(env, f, cpu_fprintf, flags);
29801    }
29802}
29803
29804void mips_tcg_init(void)
29805{
29806    int i;
29807
29808    cpu_gpr[0] = NULL;
29809    for (i = 1; i < 32; i++)
29810        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
29811                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
29812                                        regnames[i]);
29813
29814    for (i = 0; i < 32; i++) {
29815        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29816        msa_wr_d[i * 2] =
29817                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
29818        /* The scalar floating-point unit (FPU) registers are mapped on
29819         * the MSA vector registers. */
29820        fpu_f64[i] = msa_wr_d[i * 2];
29821        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29822        msa_wr_d[i * 2 + 1] =
29823                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29824    }
29825
29826    cpu_PC = tcg_global_mem_new(cpu_env,
29827                                offsetof(CPUMIPSState, active_tc.PC), "PC");
29828    for (i = 0; i < MIPS_DSP_ACC; i++) {
29829        cpu_HI[i] = tcg_global_mem_new(cpu_env,
29830                                       offsetof(CPUMIPSState, active_tc.HI[i]),
29831                                       regnames_HI[i]);
29832        cpu_LO[i] = tcg_global_mem_new(cpu_env,
29833                                       offsetof(CPUMIPSState, active_tc.LO[i]),
29834                                       regnames_LO[i]);
29835    }
29836    cpu_dspctrl = tcg_global_mem_new(cpu_env,
29837                                     offsetof(CPUMIPSState, active_tc.DSPControl),
29838                                     "DSPControl");
29839    bcond = tcg_global_mem_new(cpu_env,
29840                               offsetof(CPUMIPSState, bcond), "bcond");
29841    btarget = tcg_global_mem_new(cpu_env,
29842                                 offsetof(CPUMIPSState, btarget), "btarget");
29843    hflags = tcg_global_mem_new_i32(cpu_env,
29844                                    offsetof(CPUMIPSState, hflags), "hflags");
29845
29846    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29847                                      offsetof(CPUMIPSState, active_fpu.fcr0),
29848                                      "fcr0");
29849    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29850                                       offsetof(CPUMIPSState, active_fpu.fcr31),
29851                                       "fcr31");
29852    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
29853                                    "lladdr");
29854    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
29855                                   "llval");
29856
29857#if defined(TARGET_MIPS64)
29858    cpu_mmr[0] = NULL;
29859    for (i = 1; i < 32; i++) {
29860        cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
29861                                            offsetof(CPUMIPSState,
29862                                                     active_tc.mmr[i]),
29863                                            regnames[i]);
29864    }
29865#endif
29866
29867#if !defined(TARGET_MIPS64)
29868    for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29869        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29870                                        offsetof(CPUMIPSState,
29871                                                 active_tc.mxu_gpr[i]),
29872                                        mxuregnames[i]);
29873    }
29874
29875    mxu_CR = tcg_global_mem_new(cpu_env,
29876                                offsetof(CPUMIPSState, active_tc.mxu_cr),
29877                                mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29878#endif
29879}
29880
29881#include "translate_init.inc.c"
29882
29883void cpu_mips_realize_env(CPUMIPSState *env)
29884{
29885    env->exception_base = (int32_t)0xBFC00000;
29886
29887#ifndef CONFIG_USER_ONLY
29888    mmu_init(env, env->cpu_model);
29889#endif
29890    fpu_init(env, env->cpu_model);
29891    mvp_init(env, env->cpu_model);
29892}
29893
29894bool cpu_supports_cps_smp(const char *cpu_type)
29895{
29896    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29897    return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29898}
29899
29900bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
29901{
29902    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29903    return (mcc->cpu_def->insn_flags & isa) != 0;
29904}
29905
29906void cpu_set_exception_base(int vp_index, target_ulong address)
29907{
29908    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29909    vp->env.exception_base = address;
29910}
29911
29912void cpu_state_reset(CPUMIPSState *env)
29913{
29914    MIPSCPU *cpu = mips_env_get_cpu(env);
29915    CPUState *cs = CPU(cpu);
29916
29917    /* Reset registers to their default values */
29918    env->CP0_PRid = env->cpu_model->CP0_PRid;
29919    env->CP0_Config0 = env->cpu_model->CP0_Config0;
29920#ifdef TARGET_WORDS_BIGENDIAN
29921    env->CP0_Config0 |= (1 << CP0C0_BE);
29922#endif
29923    env->CP0_Config1 = env->cpu_model->CP0_Config1;
29924    env->CP0_Config2 = env->cpu_model->CP0_Config2;
29925    env->CP0_Config3 = env->cpu_model->CP0_Config3;
29926    env->CP0_Config4 = env->cpu_model->CP0_Config4;
29927    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29928    env->CP0_Config5 = env->cpu_model->CP0_Config5;
29929    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29930    env->CP0_Config6 = env->cpu_model->CP0_Config6;
29931    env->CP0_Config7 = env->cpu_model->CP0_Config7;
29932    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29933                                 << env->cpu_model->CP0_LLAddr_shift;
29934    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29935    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29936    env->CCRes = env->cpu_model->CCRes;
29937    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29938    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29939    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29940    env->current_tc = 0;
29941    env->SEGBITS = env->cpu_model->SEGBITS;
29942    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29943#if defined(TARGET_MIPS64)
29944    if (env->cpu_model->insn_flags & ISA_MIPS3) {
29945        env->SEGMask |= 3ULL << 62;
29946    }
29947#endif
29948    env->PABITS = env->cpu_model->PABITS;
29949    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29950    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29951    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29952    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29953    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29954    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29955    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29956    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29957    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29958    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29959    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29960    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29961    env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29962    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29963    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29964    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29965    env->msair = env->cpu_model->MSAIR;
29966    env->insn_flags = env->cpu_model->insn_flags;
29967
29968#if defined(CONFIG_USER_ONLY)
29969    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29970# ifdef TARGET_MIPS64
29971    /* Enable 64-bit register mode.  */
29972    env->CP0_Status |= (1 << CP0St_PX);
29973# endif
29974# ifdef TARGET_ABI_MIPSN64
29975    /* Enable 64-bit address mode.  */
29976    env->CP0_Status |= (1 << CP0St_UX);
29977# endif
29978    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29979       hardware registers.  */
29980    env->CP0_HWREna |= 0x0000000F;
29981    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29982        env->CP0_Status |= (1 << CP0St_CU1);
29983    }
29984    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29985        env->CP0_Status |= (1 << CP0St_MX);
29986    }
29987# if defined(TARGET_MIPS64)
29988    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29989    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29990        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29991        env->CP0_Status |= (1 << CP0St_FR);
29992    }
29993# endif
29994#else
29995    if (env->hflags & MIPS_HFLAG_BMASK) {
29996        /* If the exception was raised from a delay slot,
29997           come back to the jump.  */
29998        env->CP0_ErrorEPC = (env->active_tc.PC
29999                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30000    } else {
30001        env->CP0_ErrorEPC = env->active_tc.PC;
30002    }
30003    env->active_tc.PC = env->exception_base;
30004    env->CP0_Random = env->tlb->nb_tlb - 1;
30005    env->tlb->tlb_in_use = env->tlb->nb_tlb;
30006    env->CP0_Wired = 0;
30007    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30008    env->CP0_EBase = (cs->cpu_index & 0x3FF);
30009    if (mips_um_ksegs_enabled()) {
30010        env->CP0_EBase |= 0x40000000;
30011    } else {
30012        env->CP0_EBase |= (int32_t)0x80000000;
30013    }
30014    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30015        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30016    }
30017    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30018                                 0x3ff : 0xff;
30019    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30020    /* vectored interrupts not implemented, timer on int 7,
30021       no performance counters. */
30022    env->CP0_IntCtl = 0xe0000000;
30023    {
30024        int i;
30025
30026        for (i = 0; i < 7; i++) {
30027            env->CP0_WatchLo[i] = 0;
30028            env->CP0_WatchHi[i] = 0x80000000;
30029        }
30030        env->CP0_WatchLo[7] = 0;
30031        env->CP0_WatchHi[7] = 0;
30032    }
30033    /* Count register increments in debug mode, EJTAG version 1 */
30034    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30035
30036    cpu_mips_store_count(env, 1);
30037
30038    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30039        int i;
30040
30041        /* Only TC0 on VPE 0 starts as active.  */
30042        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30043            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30044            env->tcs[i].CP0_TCHalt = 1;
30045        }
30046        env->active_tc.CP0_TCHalt = 1;
30047        cs->halted = 1;
30048
30049        if (cs->cpu_index == 0) {
30050            /* VPE0 starts up enabled.  */
30051            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30052            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30053
30054            /* TC0 starts up unhalted.  */
30055            cs->halted = 0;
30056            env->active_tc.CP0_TCHalt = 0;
30057            env->tcs[0].CP0_TCHalt = 0;
30058            /* With thread 0 active.  */
30059            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30060            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30061        }
30062    }
30063
30064    /*
30065     * Configure default legacy segmentation control. We use this regardless of
30066     * whether segmentation control is presented to the guest.
30067     */
30068    /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30069    env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
30070    /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30071    env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30072    /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30073    env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30074                         (2 << CP0SC_C);
30075    /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30076    env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30077                         (3 << CP0SC_C)) << 16;
30078    /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30079    env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30080                         (1 << CP0SC_EU) | (2 << CP0SC_C);
30081    /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30082    env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30083                         (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30084    /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30085    env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30086#endif
30087    if ((env->insn_flags & ISA_MIPS32R6) &&
30088        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30089        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30090        env->CP0_Status |= (1 << CP0St_FR);
30091    }
30092
30093    if (env->insn_flags & ISA_MIPS32R6) {
30094        /* PTW  =  1 */
30095        env->CP0_PWSize = 0x40;
30096        /* GDI  = 12 */
30097        /* UDI  = 12 */
30098        /* MDI  = 12 */
30099        /* PRI  = 12 */
30100        /* PTEI =  2 */
30101        env->CP0_PWField = 0x0C30C302;
30102    } else {
30103        /* GDI  =  0 */
30104        /* UDI  =  0 */
30105        /* MDI  =  0 */
30106        /* PRI  =  0 */
30107        /* PTEI =  2 */
30108        env->CP0_PWField = 0x02;
30109    }
30110
30111    if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30112        /*  microMIPS on reset when Config3.ISA is 3 */
30113        env->hflags |= MIPS_HFLAG_M16;
30114    }
30115
30116    /* MSA */
30117    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30118        msa_reset(env);
30119    }
30120
30121    compute_hflags(env);
30122    restore_fp_status(env);
30123    restore_pamask(env);
30124    cs->exception_index = EXCP_NONE;
30125
30126    if (semihosting_get_argc()) {
30127        /* UHI interface can be used to obtain argc and argv */
30128        env->active_tc.gpr[4] = -1;
30129    }
30130}
30131
30132void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30133                          target_ulong *data)
30134{
30135    env->active_tc.PC = data[0];
30136    env->hflags &= ~MIPS_HFLAG_BMASK;
30137    env->hflags |= data[1];
30138    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30139    case MIPS_HFLAG_BR:
30140        break;
30141    case MIPS_HFLAG_BC:
30142    case MIPS_HFLAG_BL:
30143    case MIPS_HFLAG_B:
30144        env->btarget = data[2];
30145        break;
30146    }
30147}
30148