qemu/target-mips/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS32 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 "disas/disas.h"
  27#include "exec/exec-all.h"
  28#include "tcg-op.h"
  29#include "exec/cpu_ldst.h"
  30
  31#include "exec/helper-proto.h"
  32#include "exec/helper-gen.h"
  33#include "sysemu/kvm.h"
  34#include "exec/semihost.h"
  35
  36#include "trace-tcg.h"
  37#include "exec/log.h"
  38
  39#define MIPS_DEBUG_DISAS 0
  40
  41/* MIPS major opcodes */
  42#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  43
  44enum {
  45    /* indirect opcode tables */
  46    OPC_SPECIAL  = (0x00 << 26),
  47    OPC_REGIMM   = (0x01 << 26),
  48    OPC_CP0      = (0x10 << 26),
  49    OPC_CP1      = (0x11 << 26),
  50    OPC_CP2      = (0x12 << 26),
  51    OPC_CP3      = (0x13 << 26),
  52    OPC_SPECIAL2 = (0x1C << 26),
  53    OPC_SPECIAL3 = (0x1F << 26),
  54    /* arithmetic with immediate */
  55    OPC_ADDI     = (0x08 << 26),
  56    OPC_ADDIU    = (0x09 << 26),
  57    OPC_SLTI     = (0x0A << 26),
  58    OPC_SLTIU    = (0x0B << 26),
  59    /* logic with immediate */
  60    OPC_ANDI     = (0x0C << 26),
  61    OPC_ORI      = (0x0D << 26),
  62    OPC_XORI     = (0x0E << 26),
  63    OPC_LUI      = (0x0F << 26),
  64    /* arithmetic with immediate */
  65    OPC_DADDI    = (0x18 << 26),
  66    OPC_DADDIU   = (0x19 << 26),
  67    /* Jump and branches */
  68    OPC_J        = (0x02 << 26),
  69    OPC_JAL      = (0x03 << 26),
  70    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  71    OPC_BEQL     = (0x14 << 26),
  72    OPC_BNE      = (0x05 << 26),
  73    OPC_BNEL     = (0x15 << 26),
  74    OPC_BLEZ     = (0x06 << 26),
  75    OPC_BLEZL    = (0x16 << 26),
  76    OPC_BGTZ     = (0x07 << 26),
  77    OPC_BGTZL    = (0x17 << 26),
  78    OPC_JALX     = (0x1D << 26),
  79    OPC_DAUI     = (0x1D << 26),
  80    /* Load and stores */
  81    OPC_LDL      = (0x1A << 26),
  82    OPC_LDR      = (0x1B << 26),
  83    OPC_LB       = (0x20 << 26),
  84    OPC_LH       = (0x21 << 26),
  85    OPC_LWL      = (0x22 << 26),
  86    OPC_LW       = (0x23 << 26),
  87    OPC_LWPC     = OPC_LW | 0x5,
  88    OPC_LBU      = (0x24 << 26),
  89    OPC_LHU      = (0x25 << 26),
  90    OPC_LWR      = (0x26 << 26),
  91    OPC_LWU      = (0x27 << 26),
  92    OPC_SB       = (0x28 << 26),
  93    OPC_SH       = (0x29 << 26),
  94    OPC_SWL      = (0x2A << 26),
  95    OPC_SW       = (0x2B << 26),
  96    OPC_SDL      = (0x2C << 26),
  97    OPC_SDR      = (0x2D << 26),
  98    OPC_SWR      = (0x2E << 26),
  99    OPC_LL       = (0x30 << 26),
 100    OPC_LLD      = (0x34 << 26),
 101    OPC_LD       = (0x37 << 26),
 102    OPC_LDPC     = OPC_LD | 0x5,
 103    OPC_SC       = (0x38 << 26),
 104    OPC_SCD      = (0x3C << 26),
 105    OPC_SD       = (0x3F << 26),
 106    /* Floating point load/store */
 107    OPC_LWC1     = (0x31 << 26),
 108    OPC_LWC2     = (0x32 << 26),
 109    OPC_LDC1     = (0x35 << 26),
 110    OPC_LDC2     = (0x36 << 26),
 111    OPC_SWC1     = (0x39 << 26),
 112    OPC_SWC2     = (0x3A << 26),
 113    OPC_SDC1     = (0x3D << 26),
 114    OPC_SDC2     = (0x3E << 26),
 115    /* Compact Branches */
 116    OPC_BLEZALC  = (0x06 << 26),
 117    OPC_BGEZALC  = (0x06 << 26),
 118    OPC_BGEUC    = (0x06 << 26),
 119    OPC_BGTZALC  = (0x07 << 26),
 120    OPC_BLTZALC  = (0x07 << 26),
 121    OPC_BLTUC    = (0x07 << 26),
 122    OPC_BOVC     = (0x08 << 26),
 123    OPC_BEQZALC  = (0x08 << 26),
 124    OPC_BEQC     = (0x08 << 26),
 125    OPC_BLEZC    = (0x16 << 26),
 126    OPC_BGEZC    = (0x16 << 26),
 127    OPC_BGEC     = (0x16 << 26),
 128    OPC_BGTZC    = (0x17 << 26),
 129    OPC_BLTZC    = (0x17 << 26),
 130    OPC_BLTC     = (0x17 << 26),
 131    OPC_BNVC     = (0x18 << 26),
 132    OPC_BNEZALC  = (0x18 << 26),
 133    OPC_BNEC     = (0x18 << 26),
 134    OPC_BC       = (0x32 << 26),
 135    OPC_BEQZC    = (0x36 << 26),
 136    OPC_JIC      = (0x36 << 26),
 137    OPC_BALC     = (0x3A << 26),
 138    OPC_BNEZC    = (0x3E << 26),
 139    OPC_JIALC    = (0x3E << 26),
 140    /* MDMX ASE specific */
 141    OPC_MDMX     = (0x1E << 26),
 142    /* MSA ASE, same as MDMX */
 143    OPC_MSA      = OPC_MDMX,
 144    /* Cache and prefetch */
 145    OPC_CACHE    = (0x2F << 26),
 146    OPC_PREF     = (0x33 << 26),
 147    /* PC-relative address computation / loads */
 148    OPC_PCREL    = (0x3B << 26),
 149};
 150
 151/* PC-relative address computation / loads  */
 152#define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 153#define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 154enum {
 155    /* Instructions determined by bits 19 and 20 */
 156    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 157    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 158    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 159
 160    /* Instructions determined by bits 16 ... 20 */
 161    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 162    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 163
 164    /* Other */
 165    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 166};
 167
 168/* MIPS special opcodes */
 169#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 170
 171enum {
 172    /* Shifts */
 173    OPC_SLL      = 0x00 | OPC_SPECIAL,
 174    /* NOP is SLL r0, r0, 0   */
 175    /* SSNOP is SLL r0, r0, 1 */
 176    /* EHB is SLL r0, r0, 3 */
 177    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 178    OPC_ROTR     = OPC_SRL | (1 << 21),
 179    OPC_SRA      = 0x03 | OPC_SPECIAL,
 180    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 181    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 182    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 183    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 184    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 185    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 186    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 187    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 188    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 189    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 190    OPC_DROTR    = OPC_DSRL | (1 << 21),
 191    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 192    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 193    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 194    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 195    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 196    /* Multiplication / division */
 197    OPC_MULT     = 0x18 | OPC_SPECIAL,
 198    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 199    OPC_DIV      = 0x1A | OPC_SPECIAL,
 200    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 201    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 202    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 203    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 204    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 205
 206    /* 2 registers arithmetic / logic */
 207    OPC_ADD      = 0x20 | OPC_SPECIAL,
 208    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 209    OPC_SUB      = 0x22 | OPC_SPECIAL,
 210    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 211    OPC_AND      = 0x24 | OPC_SPECIAL,
 212    OPC_OR       = 0x25 | OPC_SPECIAL,
 213    OPC_XOR      = 0x26 | OPC_SPECIAL,
 214    OPC_NOR      = 0x27 | OPC_SPECIAL,
 215    OPC_SLT      = 0x2A | OPC_SPECIAL,
 216    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 217    OPC_DADD     = 0x2C | OPC_SPECIAL,
 218    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 219    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 220    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 221    /* Jumps */
 222    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 223    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 224    /* Traps */
 225    OPC_TGE      = 0x30 | OPC_SPECIAL,
 226    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 227    OPC_TLT      = 0x32 | OPC_SPECIAL,
 228    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 229    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 230    OPC_TNE      = 0x36 | OPC_SPECIAL,
 231    /* HI / LO registers load & stores */
 232    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 233    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 234    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 235    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 236    /* Conditional moves */
 237    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 238    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 239
 240    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 241    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 242
 243    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 244
 245    /* Special */
 246    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 247    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 248    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 249    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 250    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 251
 252    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 253    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 254    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 255    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 256};
 257
 258/* R6 Multiply and Divide instructions have the same Opcode
 259   and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
 260#define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
 261
 262enum {
 263    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 264    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 265    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 266    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 267    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 268    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 269    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 270    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 271
 272    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 273    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 274    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 275    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 276    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 277    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 278    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 279    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 280
 281    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 282    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 283    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 284    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 285    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 286
 287    OPC_LSA  = 0x05 | OPC_SPECIAL,
 288    OPC_DLSA = 0x15 | OPC_SPECIAL,
 289};
 290
 291/* Multiplication variants of the vr54xx. */
 292#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 293
 294enum {
 295    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 296    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 297    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 298    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 299    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 300    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 301    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 302    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 303    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 304    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 305    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 306    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 307    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 308    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 309};
 310
 311/* REGIMM (rt field) opcodes */
 312#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 313
 314enum {
 315    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 316    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 317    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 318    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 319    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 320    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 321    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 322    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 323    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 324    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 325    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 326    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 327    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 328    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 329    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 330    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 331
 332    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 333    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 334};
 335
 336/* Special2 opcodes */
 337#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 338
 339enum {
 340    /* Multiply & xxx operations */
 341    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 342    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 343    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 344    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 345    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 346    /* Loongson 2F */
 347    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 348    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 349    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 350    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 351    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 352    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 353    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 354    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 355    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 356    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 357    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 358    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 359    /* Misc */
 360    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 361    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 362    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 363    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 364    /* Special */
 365    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 366};
 367
 368/* Special3 opcodes */
 369#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 370
 371enum {
 372    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 373    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 374    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 375    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 376    OPC_INS      = 0x04 | OPC_SPECIAL3,
 377    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 378    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 379    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 380    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 381    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 382    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 383    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 384    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 385
 386    /* Loongson 2E */
 387    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 388    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 389    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 390    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 391    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 392    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 393    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 394    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 395    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 396    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 397    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 398    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 399
 400    /* MIPS DSP Load */
 401    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 402    /* MIPS DSP Arithmetic */
 403    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 404    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 405    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 406    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 407    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 408    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 409    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 410    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 411    /* MIPS DSP GPR-Based Shift Sub-class */
 412    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 413    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 414    /* MIPS DSP Multiply Sub-class insns */
 415    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 416    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 417    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 418    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 419    /* DSP Bit/Manipulation Sub-class */
 420    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 421    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 422    /* MIPS DSP Append Sub-class */
 423    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 424    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 425    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 426    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 427    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 428
 429    /* R6 */
 430    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 431    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 432    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 433    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 434    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 435    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 436};
 437
 438/* BSHFL opcodes */
 439#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 440
 441enum {
 442    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 443    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 444    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 445    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
 446    OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
 447    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 448};
 449
 450/* DBSHFL opcodes */
 451#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 452
 453enum {
 454    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 455    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 456    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
 457    OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
 458    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 459};
 460
 461/* MIPS DSP REGIMM opcodes */
 462enum {
 463    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 464    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 465};
 466
 467#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 468/* MIPS DSP Load */
 469enum {
 470    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 471    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 472    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 473    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 474};
 475
 476#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 477enum {
 478    /* MIPS DSP Arithmetic Sub-class */
 479    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 480    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 481    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 482    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 483    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 484    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 485    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 486    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 487    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 488    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 489    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 490    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 491    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 492    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 493    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 494    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 495    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 496    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 497    /* MIPS DSP Multiply Sub-class insns */
 498    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 499    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 500    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 501    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 502    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 503    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 504};
 505
 506#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 507#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 508enum {
 509    /* MIPS DSP Arithmetic Sub-class */
 510    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 511    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 512    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 513    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 514    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 515    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 516    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 517    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 518    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 519    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 520    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 521    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 522    /* MIPS DSP Multiply Sub-class insns */
 523    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 524    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 525    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 526    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 527};
 528
 529#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 530enum {
 531    /* MIPS DSP Arithmetic Sub-class */
 532    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 533    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 534    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 535    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 536    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 537    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 538    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 539    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 540    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 541    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 542    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 543    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 544    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 545    /* DSP Bit/Manipulation Sub-class */
 546    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 547    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 548    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 549    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 550    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 551};
 552
 553#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 554enum {
 555    /* MIPS DSP Arithmetic Sub-class */
 556    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 557    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 558    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 559    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 560    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 561    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 562    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 563    /* DSP Compare-Pick Sub-class */
 564    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 565    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 566    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 567    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 568    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 569    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 570    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 571    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 572    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 573    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 574    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 575    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 576    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 577    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 578    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 579};
 580
 581#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 582enum {
 583    /* MIPS DSP GPR-Based Shift Sub-class */
 584    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 585    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 586    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 587    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 588    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 589    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 590    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 591    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 592    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 593    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 594    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 595    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 596    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 597    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 598    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 599    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 600    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 601    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 602    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 603    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 604    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 605    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 606};
 607
 608#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 609enum {
 610    /* MIPS DSP Multiply Sub-class insns */
 611    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 612    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 613    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 614    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 615    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 616    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 617    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 618    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 619    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 620    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 621    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 622    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 623    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 624    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 625    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 626    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 627    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 628    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 629    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 630    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 631    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 632    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 633};
 634
 635#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 636enum {
 637    /* DSP Bit/Manipulation Sub-class */
 638    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 639};
 640
 641#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 642enum {
 643    /* MIPS DSP Append Sub-class */
 644    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 645    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 646    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 647};
 648
 649#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 650enum {
 651    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 652    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 653    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 654    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 655    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 656    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 657    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 658    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 659    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 660    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 661    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 662    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 663    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 664    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 665    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 666    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 667    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 668    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 669};
 670
 671#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 672enum {
 673    /* MIPS DSP Arithmetic Sub-class */
 674    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 675    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 676    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 677    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 678    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 679    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 680    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 681    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 682    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 683    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 684    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 685    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 686    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 687    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 688    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 689    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 690    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 691    /* DSP Bit/Manipulation Sub-class */
 692    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 693    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 694    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 695    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 696    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 697    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 698};
 699
 700#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 701enum {
 702    /* MIPS DSP Multiply Sub-class insns */
 703    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 704    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 705    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 706    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 707    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 708    /* MIPS DSP Arithmetic Sub-class */
 709    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 710    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 711    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 712    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 713    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 714    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 715    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 716    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 717    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 718    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 719    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 720    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 721    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 722    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 723    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 724    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 725    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 726    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 727    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 728    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 729    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 730};
 731
 732#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 733enum {
 734    /* DSP Compare-Pick Sub-class */
 735    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 736    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 737    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 738    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 739    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 740    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 741    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 742    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 743    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 744    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 745    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 746    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 747    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 748    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 749    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 750    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 751    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 752    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 753    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 754    /* MIPS DSP Arithmetic Sub-class */
 755    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 756    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 757    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 758    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 759    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 760    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 761    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 762    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 763};
 764
 765#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 766enum {
 767    /* DSP Append Sub-class */
 768    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 769    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 770    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 771    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 772};
 773
 774#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 775enum {
 776    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 777    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 778    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 779    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 780    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 781    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 782    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 783    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 784    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 785    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 786    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 787    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 788    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 789    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 790    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 791    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 792    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 793    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 794    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 795    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 796    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 797    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 798};
 799
 800#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 801enum {
 802    /* DSP Bit/Manipulation Sub-class */
 803    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 804};
 805
 806#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 807enum {
 808    /* MIPS DSP Multiply Sub-class insns */
 809    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 810    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 811    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 812    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 813    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 814    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 815    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 816    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 817    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 818    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 819    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 820    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 821    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 822    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 823    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 824    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 825    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 826    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 827    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 828    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 829    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 830    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 831    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 832    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 833    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 834    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 835};
 836
 837#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 838enum {
 839    /* MIPS DSP GPR-Based Shift Sub-class */
 840    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 841    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 842    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 843    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 844    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 845    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 846    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 847    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 848    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 849    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 850    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 851    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 852    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 853    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 854    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 855    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 856    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 857    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 858    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 859    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 860    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 861    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 862    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 863    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 864    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 865    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 866};
 867
 868/* Coprocessor 0 (rs field) */
 869#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 870
 871enum {
 872    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 873    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 874    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 875    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 876    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 877    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 878    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 879    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 880    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 881    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 882    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 883    OPC_C0       = (0x10 << 21) | OPC_CP0,
 884    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
 885    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
 886};
 887
 888/* MFMC0 opcodes */
 889#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 890
 891enum {
 892    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 893    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 894    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 895    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 896    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 897    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 898    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 899    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 900};
 901
 902/* Coprocessor 0 (with rs == C0) */
 903#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 904
 905enum {
 906    OPC_TLBR     = 0x01 | OPC_C0,
 907    OPC_TLBWI    = 0x02 | OPC_C0,
 908    OPC_TLBINV   = 0x03 | OPC_C0,
 909    OPC_TLBINVF  = 0x04 | OPC_C0,
 910    OPC_TLBWR    = 0x06 | OPC_C0,
 911    OPC_TLBP     = 0x08 | OPC_C0,
 912    OPC_RFE      = 0x10 | OPC_C0,
 913    OPC_ERET     = 0x18 | OPC_C0,
 914    OPC_DERET    = 0x1F | OPC_C0,
 915    OPC_WAIT     = 0x20 | OPC_C0,
 916};
 917
 918/* Coprocessor 1 (rs field) */
 919#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 920
 921/* Values for the fmt field in FP instructions */
 922enum {
 923    /* 0 - 15 are reserved */
 924    FMT_S = 16,          /* single fp */
 925    FMT_D = 17,          /* double fp */
 926    FMT_E = 18,          /* extended fp */
 927    FMT_Q = 19,          /* quad fp */
 928    FMT_W = 20,          /* 32-bit fixed */
 929    FMT_L = 21,          /* 64-bit fixed */
 930    FMT_PS = 22,         /* paired single fp */
 931    /* 23 - 31 are reserved */
 932};
 933
 934enum {
 935    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 936    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 937    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 938    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 939    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 940    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 941    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 942    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 943    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 944    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 945    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 946    OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
 947    OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
 948    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 949    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 950    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 951    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 952    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 953    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 954    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 955    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
 956    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
 957    OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
 958    OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
 959    OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
 960    OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
 961    OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
 962    OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
 963    OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
 964    OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
 965};
 966
 967#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
 968#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
 969
 970enum {
 971    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
 972    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
 973    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
 974    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
 975};
 976
 977enum {
 978    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
 979    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
 980};
 981
 982enum {
 983    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
 984    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
 985};
 986
 987#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 988
 989enum {
 990    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 991    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 992    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 993    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 994    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 995    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 996    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 997    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 998    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 999    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1000    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1001};
1002
1003#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1004
1005enum {
1006    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1007    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1008    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1009    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1010    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1011    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1012    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1013    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1014
1015    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1016    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1017    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1018    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1019    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1020    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1021    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1022    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1023
1024    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1025    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1026    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1027    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1028    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1029    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1030    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1031    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1032
1033    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1034    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1035    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1036    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1037    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1038    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1039    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1040    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1041
1042    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1043    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1044    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1045    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1046    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1047    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1048
1049    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1050    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1051    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1052    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1053    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1054    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1055
1056    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1057    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1058    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1059    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1060    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1061    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1062
1063    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1064    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1065    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1066    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1067    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1068    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1069
1070    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1071    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1072    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1073    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1074    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1075    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1076
1077    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1078    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1079    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1080    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1081    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1082    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1083
1084    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1085    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1086    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1087    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1088    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1089    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1090
1091    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1092    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1093    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1094    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1095    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1096    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1097};
1098
1099
1100#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1101
1102enum {
1103    OPC_LWXC1   = 0x00 | OPC_CP3,
1104    OPC_LDXC1   = 0x01 | OPC_CP3,
1105    OPC_LUXC1   = 0x05 | OPC_CP3,
1106    OPC_SWXC1   = 0x08 | OPC_CP3,
1107    OPC_SDXC1   = 0x09 | OPC_CP3,
1108    OPC_SUXC1   = 0x0D | OPC_CP3,
1109    OPC_PREFX   = 0x0F | OPC_CP3,
1110    OPC_ALNV_PS = 0x1E | OPC_CP3,
1111    OPC_MADD_S  = 0x20 | OPC_CP3,
1112    OPC_MADD_D  = 0x21 | OPC_CP3,
1113    OPC_MADD_PS = 0x26 | OPC_CP3,
1114    OPC_MSUB_S  = 0x28 | OPC_CP3,
1115    OPC_MSUB_D  = 0x29 | OPC_CP3,
1116    OPC_MSUB_PS = 0x2E | OPC_CP3,
1117    OPC_NMADD_S = 0x30 | OPC_CP3,
1118    OPC_NMADD_D = 0x31 | OPC_CP3,
1119    OPC_NMADD_PS= 0x36 | OPC_CP3,
1120    OPC_NMSUB_S = 0x38 | OPC_CP3,
1121    OPC_NMSUB_D = 0x39 | OPC_CP3,
1122    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1123};
1124
1125/* MSA Opcodes */
1126#define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1127enum {
1128    OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1129    OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1130    OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1131    OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1132    OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1133    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1134    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1135    OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1136    OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1137    OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1138    OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1139    OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1140    OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1141    OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1142    OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1143    OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1144    OPC_MSA_ELM     = 0x19 | OPC_MSA,
1145    OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1146    OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1147    OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1148    OPC_MSA_VEC     = 0x1E | OPC_MSA,
1149
1150    /* MI10 instruction */
1151    OPC_LD_B    = (0x20) | OPC_MSA,
1152    OPC_LD_H    = (0x21) | OPC_MSA,
1153    OPC_LD_W    = (0x22) | OPC_MSA,
1154    OPC_LD_D    = (0x23) | OPC_MSA,
1155    OPC_ST_B    = (0x24) | OPC_MSA,
1156    OPC_ST_H    = (0x25) | OPC_MSA,
1157    OPC_ST_W    = (0x26) | OPC_MSA,
1158    OPC_ST_D    = (0x27) | OPC_MSA,
1159};
1160
1161enum {
1162    /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1163    OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1164    OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1165    OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1166    OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1167    OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1168    OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1169    OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1170    OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1171    OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1172    OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1173    OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1174    OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1175
1176    /* I8 instruction */
1177    OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1178    OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1179    OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1180    OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1181    OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1182    OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1183    OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1184    OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1185    OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1186    OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1187
1188    /* VEC/2R/2RF instruction */
1189    OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1190    OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1191    OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1192    OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1193    OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1194    OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1195    OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1196
1197    OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1198    OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1199
1200    /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1201    OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1202    OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1203    OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1204    OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1205
1206    /* 2RF instruction df(bit 16) = _w, _d */
1207    OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1208    OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1209    OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1210    OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1211    OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1212    OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1213    OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1214    OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1215    OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1216    OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1217    OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1218    OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1219    OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1220    OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1221    OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1222    OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1223
1224    /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1225    OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1226    OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1227    OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1228    OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1229    OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1230    OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1231    OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1232    OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1233    OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1234    OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1235    OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1236    OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1237    OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1238    OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1239    OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1240    OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1241    OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1242    OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1243    OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1244    OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1245    OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1246    OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1247    OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1248    OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1249    OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1250    OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1251    OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1252    OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1253    OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1254    OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1255    OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1256    OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1257    OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1258    OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1259    OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1260    OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1261    OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1262    OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1263    OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1264    OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1265    OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1266    OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1267    OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1268    OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1269    OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1270    OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1271    OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1272    OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1273    OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1274    OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1275    OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1276    OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1277    OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1278    OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1279    OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1280    OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1281    OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1282    OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1283    OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1284    OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1285    OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1286    OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1287    OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1288
1289    /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1290    OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291    OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1292    OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293    OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1294    OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1295    OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1296    OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297    OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298    OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1299
1300    /* 3RF instruction _df(bit 21) = _w, _d */
1301    OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1302    OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1303    OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1304    OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1305    OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1306    OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1307    OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1308    OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1309    OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1310    OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1311    OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1312    OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1313    OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1314    OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1315    OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1316    OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1317    OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1318    OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1319    OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1320    OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1321    OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1322    OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1323    OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1324    OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1325    OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1326    OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1327    OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1328    OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1329    OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1330    OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1331    OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1332    OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1333    OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1334    OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1335    OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1336    OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1337    OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1338    OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1339    OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1340    OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1341    OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1342
1343    /* BIT instruction df(bits 22..16) = _B _H _W _D */
1344    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1345    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1346    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1347    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1348    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1349    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1350    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1351    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1352    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1353    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1354    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1355    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1356};
1357
1358/* global register indices */
1359static TCGv_env cpu_env;
1360static TCGv cpu_gpr[32], cpu_PC;
1361static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1362static TCGv cpu_dspctrl, btarget, bcond;
1363static TCGv_i32 hflags;
1364static TCGv_i32 fpu_fcr0, fpu_fcr31;
1365static TCGv_i64 fpu_f64[32];
1366static TCGv_i64 msa_wr_d[64];
1367
1368#include "exec/gen-icount.h"
1369
1370#define gen_helper_0e0i(name, arg) do {                           \
1371    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1372    gen_helper_##name(cpu_env, helper_tmp);                       \
1373    tcg_temp_free_i32(helper_tmp);                                \
1374    } while(0)
1375
1376#define gen_helper_0e1i(name, arg1, arg2) do {                    \
1377    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1378    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1379    tcg_temp_free_i32(helper_tmp);                                \
1380    } while(0)
1381
1382#define gen_helper_1e0i(name, ret, arg1) do {                     \
1383    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1384    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1385    tcg_temp_free_i32(helper_tmp);                                \
1386    } while(0)
1387
1388#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1389    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1390    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1391    tcg_temp_free_i32(helper_tmp);                                \
1392    } while(0)
1393
1394#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1395    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1396    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1397    tcg_temp_free_i32(helper_tmp);                                \
1398    } while(0)
1399
1400#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1401    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1402    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1403    tcg_temp_free_i32(helper_tmp);                                \
1404    } while(0)
1405
1406#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1407    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1408    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1409    tcg_temp_free_i32(helper_tmp);                                \
1410    } while(0)
1411
1412typedef struct DisasContext {
1413    struct TranslationBlock *tb;
1414    target_ulong pc, saved_pc;
1415    uint32_t opcode;
1416    int singlestep_enabled;
1417    int insn_flags;
1418    int32_t CP0_Config1;
1419    /* Routine used to access memory */
1420    int mem_idx;
1421    TCGMemOp default_tcg_memop_mask;
1422    uint32_t hflags, saved_hflags;
1423    int bstate;
1424    target_ulong btarget;
1425    bool ulri;
1426    int kscrexist;
1427    bool rxi;
1428    int ie;
1429    bool bi;
1430    bool bp;
1431    uint64_t PAMask;
1432    bool mvh;
1433    int CP0_LLAddr_shift;
1434    bool ps;
1435    bool vp;
1436    bool cmgcr;
1437    bool mrp;
1438    bool nan2008;
1439    bool abs2008;
1440} DisasContext;
1441
1442enum {
1443    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1444                      * exception condition */
1445    BS_STOP     = 1, /* We want to stop translation for any reason */
1446    BS_BRANCH   = 2, /* We reached a branch condition     */
1447    BS_EXCP     = 3, /* We reached an exception condition */
1448};
1449
1450static const char * const regnames[] = {
1451    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1452    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1453    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1454    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1455};
1456
1457static const char * const regnames_HI[] = {
1458    "HI0", "HI1", "HI2", "HI3",
1459};
1460
1461static const char * const regnames_LO[] = {
1462    "LO0", "LO1", "LO2", "LO3",
1463};
1464
1465static const char * const fregnames[] = {
1466    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1467    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1468    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1469    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1470};
1471
1472static const char * const msaregnames[] = {
1473    "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
1474    "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
1475    "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
1476    "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
1477    "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
1478    "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1479    "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1480    "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1481    "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1482    "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1483    "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1484    "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1485    "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1486    "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1487    "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1488    "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1489};
1490
1491#define LOG_DISAS(...)                                                        \
1492    do {                                                                      \
1493        if (MIPS_DEBUG_DISAS) {                                               \
1494            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
1495        }                                                                     \
1496    } while (0)
1497
1498#define MIPS_INVAL(op)                                                        \
1499    do {                                                                      \
1500        if (MIPS_DEBUG_DISAS) {                                               \
1501            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
1502                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1503                          ctx->pc, ctx->opcode, op, ctx->opcode >> 26,        \
1504                          ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));  \
1505        }                                                                     \
1506    } while (0)
1507
1508/* General purpose registers moves. */
1509static inline void gen_load_gpr (TCGv t, int reg)
1510{
1511    if (reg == 0)
1512        tcg_gen_movi_tl(t, 0);
1513    else
1514        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1515}
1516
1517static inline void gen_store_gpr (TCGv t, int reg)
1518{
1519    if (reg != 0)
1520        tcg_gen_mov_tl(cpu_gpr[reg], t);
1521}
1522
1523/* Moves to/from shadow registers. */
1524static inline void gen_load_srsgpr (int from, int to)
1525{
1526    TCGv t0 = tcg_temp_new();
1527
1528    if (from == 0)
1529        tcg_gen_movi_tl(t0, 0);
1530    else {
1531        TCGv_i32 t2 = tcg_temp_new_i32();
1532        TCGv_ptr addr = tcg_temp_new_ptr();
1533
1534        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1535        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1536        tcg_gen_andi_i32(t2, t2, 0xf);
1537        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1538        tcg_gen_ext_i32_ptr(addr, t2);
1539        tcg_gen_add_ptr(addr, cpu_env, addr);
1540
1541        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1542        tcg_temp_free_ptr(addr);
1543        tcg_temp_free_i32(t2);
1544    }
1545    gen_store_gpr(t0, to);
1546    tcg_temp_free(t0);
1547}
1548
1549static inline void gen_store_srsgpr (int from, int to)
1550{
1551    if (to != 0) {
1552        TCGv t0 = tcg_temp_new();
1553        TCGv_i32 t2 = tcg_temp_new_i32();
1554        TCGv_ptr addr = tcg_temp_new_ptr();
1555
1556        gen_load_gpr(t0, from);
1557        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1558        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1559        tcg_gen_andi_i32(t2, t2, 0xf);
1560        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1561        tcg_gen_ext_i32_ptr(addr, t2);
1562        tcg_gen_add_ptr(addr, cpu_env, addr);
1563
1564        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1565        tcg_temp_free_ptr(addr);
1566        tcg_temp_free_i32(t2);
1567        tcg_temp_free(t0);
1568    }
1569}
1570
1571/* Tests */
1572static inline void gen_save_pc(target_ulong pc)
1573{
1574    tcg_gen_movi_tl(cpu_PC, pc);
1575}
1576
1577static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1578{
1579    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1580    if (do_save_pc && ctx->pc != ctx->saved_pc) {
1581        gen_save_pc(ctx->pc);
1582        ctx->saved_pc = ctx->pc;
1583    }
1584    if (ctx->hflags != ctx->saved_hflags) {
1585        tcg_gen_movi_i32(hflags, ctx->hflags);
1586        ctx->saved_hflags = ctx->hflags;
1587        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1588        case MIPS_HFLAG_BR:
1589            break;
1590        case MIPS_HFLAG_BC:
1591        case MIPS_HFLAG_BL:
1592        case MIPS_HFLAG_B:
1593            tcg_gen_movi_tl(btarget, ctx->btarget);
1594            break;
1595        }
1596    }
1597}
1598
1599static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1600{
1601    ctx->saved_hflags = ctx->hflags;
1602    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1603    case MIPS_HFLAG_BR:
1604        break;
1605    case MIPS_HFLAG_BC:
1606    case MIPS_HFLAG_BL:
1607    case MIPS_HFLAG_B:
1608        ctx->btarget = env->btarget;
1609        break;
1610    }
1611}
1612
1613static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1614{
1615    TCGv_i32 texcp = tcg_const_i32(excp);
1616    TCGv_i32 terr = tcg_const_i32(err);
1617    save_cpu_state(ctx, 1);
1618    gen_helper_raise_exception_err(cpu_env, texcp, terr);
1619    tcg_temp_free_i32(terr);
1620    tcg_temp_free_i32(texcp);
1621    ctx->bstate = BS_EXCP;
1622}
1623
1624static inline void generate_exception(DisasContext *ctx, int excp)
1625{
1626    gen_helper_0e0i(raise_exception, excp);
1627}
1628
1629static inline void generate_exception_end(DisasContext *ctx, int excp)
1630{
1631    generate_exception_err(ctx, excp, 0);
1632}
1633
1634/* Floating point register moves. */
1635static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1636{
1637    if (ctx->hflags & MIPS_HFLAG_FRE) {
1638        generate_exception(ctx, EXCP_RI);
1639    }
1640    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1641}
1642
1643static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1644{
1645    TCGv_i64 t64;
1646    if (ctx->hflags & MIPS_HFLAG_FRE) {
1647        generate_exception(ctx, EXCP_RI);
1648    }
1649    t64 = tcg_temp_new_i64();
1650    tcg_gen_extu_i32_i64(t64, t);
1651    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1652    tcg_temp_free_i64(t64);
1653}
1654
1655static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1656{
1657    if (ctx->hflags & MIPS_HFLAG_F64) {
1658        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1659    } else {
1660        gen_load_fpr32(ctx, t, reg | 1);
1661    }
1662}
1663
1664static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1665{
1666    if (ctx->hflags & MIPS_HFLAG_F64) {
1667        TCGv_i64 t64 = tcg_temp_new_i64();
1668        tcg_gen_extu_i32_i64(t64, t);
1669        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1670        tcg_temp_free_i64(t64);
1671    } else {
1672        gen_store_fpr32(ctx, t, reg | 1);
1673    }
1674}
1675
1676static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1677{
1678    if (ctx->hflags & MIPS_HFLAG_F64) {
1679        tcg_gen_mov_i64(t, fpu_f64[reg]);
1680    } else {
1681        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1682    }
1683}
1684
1685static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1686{
1687    if (ctx->hflags & MIPS_HFLAG_F64) {
1688        tcg_gen_mov_i64(fpu_f64[reg], t);
1689    } else {
1690        TCGv_i64 t0;
1691        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1692        t0 = tcg_temp_new_i64();
1693        tcg_gen_shri_i64(t0, t, 32);
1694        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1695        tcg_temp_free_i64(t0);
1696    }
1697}
1698
1699static inline int get_fp_bit (int cc)
1700{
1701    if (cc)
1702        return 24 + cc;
1703    else
1704        return 23;
1705}
1706
1707/* Addresses computation */
1708static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1709{
1710    tcg_gen_add_tl(ret, arg0, arg1);
1711
1712#if defined(TARGET_MIPS64)
1713    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1714        tcg_gen_ext32s_i64(ret, ret);
1715    }
1716#endif
1717}
1718
1719/* Addresses computation (translation time) */
1720static target_long addr_add(DisasContext *ctx, target_long base,
1721                            target_long offset)
1722{
1723    target_long sum = base + offset;
1724
1725#if defined(TARGET_MIPS64)
1726    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1727        sum = (int32_t)sum;
1728    }
1729#endif
1730    return sum;
1731}
1732
1733/* Sign-extract the low 32-bits to a target_long.  */
1734static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1735{
1736#if defined(TARGET_MIPS64)
1737    tcg_gen_ext32s_i64(ret, arg);
1738#else
1739    tcg_gen_extrl_i64_i32(ret, arg);
1740#endif
1741}
1742
1743/* Sign-extract the high 32-bits to a target_long.  */
1744static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1745{
1746#if defined(TARGET_MIPS64)
1747    tcg_gen_sari_i64(ret, arg, 32);
1748#else
1749    tcg_gen_extrh_i64_i32(ret, arg);
1750#endif
1751}
1752
1753static inline void check_cp0_enabled(DisasContext *ctx)
1754{
1755    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1756        generate_exception_err(ctx, EXCP_CpU, 0);
1757}
1758
1759static inline void check_cp1_enabled(DisasContext *ctx)
1760{
1761    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1762        generate_exception_err(ctx, EXCP_CpU, 1);
1763}
1764
1765/* Verify that the processor is running with COP1X instructions enabled.
1766   This is associated with the nabla symbol in the MIPS32 and MIPS64
1767   opcode tables.  */
1768
1769static inline void check_cop1x(DisasContext *ctx)
1770{
1771    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1772        generate_exception_end(ctx, EXCP_RI);
1773}
1774
1775/* Verify that the processor is running with 64-bit floating-point
1776   operations enabled.  */
1777
1778static inline void check_cp1_64bitmode(DisasContext *ctx)
1779{
1780    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1781        generate_exception_end(ctx, EXCP_RI);
1782}
1783
1784/*
1785 * Verify if floating point register is valid; an operation is not defined
1786 * if bit 0 of any register specification is set and the FR bit in the
1787 * Status register equals zero, since the register numbers specify an
1788 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1789 * in the Status register equals one, both even and odd register numbers
1790 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1791 *
1792 * Multiple 64 bit wide registers can be checked by calling
1793 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1794 */
1795static inline void check_cp1_registers(DisasContext *ctx, int regs)
1796{
1797    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1798        generate_exception_end(ctx, EXCP_RI);
1799}
1800
1801/* Verify that the processor is running with DSP instructions enabled.
1802   This is enabled by CP0 Status register MX(24) bit.
1803 */
1804
1805static inline void check_dsp(DisasContext *ctx)
1806{
1807    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1808        if (ctx->insn_flags & ASE_DSP) {
1809            generate_exception_end(ctx, EXCP_DSPDIS);
1810        } else {
1811            generate_exception_end(ctx, EXCP_RI);
1812        }
1813    }
1814}
1815
1816static inline void check_dspr2(DisasContext *ctx)
1817{
1818    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1819        if (ctx->insn_flags & ASE_DSP) {
1820            generate_exception_end(ctx, EXCP_DSPDIS);
1821        } else {
1822            generate_exception_end(ctx, EXCP_RI);
1823        }
1824    }
1825}
1826
1827/* This code generates a "reserved instruction" exception if the
1828   CPU does not support the instruction set corresponding to flags. */
1829static inline void check_insn(DisasContext *ctx, int flags)
1830{
1831    if (unlikely(!(ctx->insn_flags & flags))) {
1832        generate_exception_end(ctx, EXCP_RI);
1833    }
1834}
1835
1836/* This code generates a "reserved instruction" exception if the
1837   CPU has corresponding flag set which indicates that the instruction
1838   has been removed. */
1839static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1840{
1841    if (unlikely(ctx->insn_flags & flags)) {
1842        generate_exception_end(ctx, EXCP_RI);
1843    }
1844}
1845
1846/* This code generates a "reserved instruction" exception if the
1847   CPU does not support 64-bit paired-single (PS) floating point data type */
1848static inline void check_ps(DisasContext *ctx)
1849{
1850    if (unlikely(!ctx->ps)) {
1851        generate_exception(ctx, EXCP_RI);
1852    }
1853    check_cp1_64bitmode(ctx);
1854}
1855
1856#ifdef TARGET_MIPS64
1857/* This code generates a "reserved instruction" exception if 64-bit
1858   instructions are not enabled. */
1859static inline void check_mips_64(DisasContext *ctx)
1860{
1861    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1862        generate_exception_end(ctx, EXCP_RI);
1863}
1864#endif
1865
1866#ifndef CONFIG_USER_ONLY
1867static inline void check_mvh(DisasContext *ctx)
1868{
1869    if (unlikely(!ctx->mvh)) {
1870        generate_exception(ctx, EXCP_RI);
1871    }
1872}
1873#endif
1874
1875/* Define small wrappers for gen_load_fpr* so that we have a uniform
1876   calling interface for 32 and 64-bit FPRs.  No sense in changing
1877   all callers for gen_load_fpr32 when we need the CTX parameter for
1878   this one use.  */
1879#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1880#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1881#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1882static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1883                                               int ft, int fs, int cc)        \
1884{                                                                             \
1885    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
1886    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
1887    switch (ifmt) {                                                           \
1888    case FMT_PS:                                                              \
1889        check_ps(ctx);                                                        \
1890        break;                                                                \
1891    case FMT_D:                                                               \
1892        if (abs) {                                                            \
1893            check_cop1x(ctx);                                                 \
1894        }                                                                     \
1895        check_cp1_registers(ctx, fs | ft);                                    \
1896        break;                                                                \
1897    case FMT_S:                                                               \
1898        if (abs) {                                                            \
1899            check_cop1x(ctx);                                                 \
1900        }                                                                     \
1901        break;                                                                \
1902    }                                                                         \
1903    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
1904    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
1905    switch (n) {                                                              \
1906    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
1907    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
1908    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
1909    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
1910    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
1911    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
1912    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
1913    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
1914    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
1915    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1916    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
1917    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
1918    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
1919    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
1920    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
1921    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
1922    default: abort();                                                         \
1923    }                                                                         \
1924    tcg_temp_free_i##bits (fp0);                                              \
1925    tcg_temp_free_i##bits (fp1);                                              \
1926}
1927
1928FOP_CONDS(, 0, d, FMT_D, 64)
1929FOP_CONDS(abs, 1, d, FMT_D, 64)
1930FOP_CONDS(, 0, s, FMT_S, 32)
1931FOP_CONDS(abs, 1, s, FMT_S, 32)
1932FOP_CONDS(, 0, ps, FMT_PS, 64)
1933FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1934#undef FOP_CONDS
1935
1936#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1937static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
1938                                      int ft, int fs, int fd)           \
1939{                                                                       \
1940    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1941    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1942    if (ifmt == FMT_D) {                                                \
1943        check_cp1_registers(ctx, fs | ft | fd);                         \
1944    }                                                                   \
1945    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1946    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1947    switch (n) {                                                        \
1948    case  0:                                                            \
1949        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1950        break;                                                          \
1951    case  1:                                                            \
1952        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1953        break;                                                          \
1954    case  2:                                                            \
1955        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1956        break;                                                          \
1957    case  3:                                                            \
1958        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1959        break;                                                          \
1960    case  4:                                                            \
1961        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1962        break;                                                          \
1963    case  5:                                                            \
1964        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1965        break;                                                          \
1966    case  6:                                                            \
1967        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1968        break;                                                          \
1969    case  7:                                                            \
1970        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1971        break;                                                          \
1972    case  8:                                                            \
1973        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1974        break;                                                          \
1975    case  9:                                                            \
1976        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1977        break;                                                          \
1978    case 10:                                                            \
1979        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1980        break;                                                          \
1981    case 11:                                                            \
1982        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1983        break;                                                          \
1984    case 12:                                                            \
1985        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1986        break;                                                          \
1987    case 13:                                                            \
1988        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1989        break;                                                          \
1990    case 14:                                                            \
1991        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1992        break;                                                          \
1993    case 15:                                                            \
1994        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1995        break;                                                          \
1996    case 17:                                                            \
1997        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1998        break;                                                          \
1999    case 18:                                                            \
2000        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
2001        break;                                                          \
2002    case 19:                                                            \
2003        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
2004        break;                                                          \
2005    case 25:                                                            \
2006        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
2007        break;                                                          \
2008    case 26:                                                            \
2009        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2010        break;                                                          \
2011    case 27:                                                            \
2012        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2013        break;                                                          \
2014    default:                                                            \
2015        abort();                                                        \
2016    }                                                                   \
2017    STORE;                                                              \
2018    tcg_temp_free_i ## bits (fp0);                                      \
2019    tcg_temp_free_i ## bits (fp1);                                      \
2020}
2021
2022FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2023FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2024#undef FOP_CONDNS
2025#undef gen_ldcmp_fpr32
2026#undef gen_ldcmp_fpr64
2027
2028/* load/store instructions. */
2029#ifdef CONFIG_USER_ONLY
2030#define OP_LD_ATOMIC(insn,fname)                                           \
2031static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
2032{                                                                          \
2033    TCGv t0 = tcg_temp_new();                                              \
2034    tcg_gen_mov_tl(t0, arg1);                                              \
2035    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2036    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
2037    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
2038    tcg_temp_free(t0);                                                     \
2039}
2040#else
2041#define OP_LD_ATOMIC(insn,fname)                                           \
2042static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
2043{                                                                          \
2044    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
2045}
2046#endif
2047OP_LD_ATOMIC(ll,ld32s);
2048#if defined(TARGET_MIPS64)
2049OP_LD_ATOMIC(lld,ld64);
2050#endif
2051#undef OP_LD_ATOMIC
2052
2053#ifdef CONFIG_USER_ONLY
2054#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2055static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2056{                                                                            \
2057    TCGv t0 = tcg_temp_new();                                                \
2058    TCGLabel *l1 = gen_new_label();                                          \
2059    TCGLabel *l2 = gen_new_label();                                          \
2060                                                                             \
2061    tcg_gen_andi_tl(t0, arg2, almask);                                       \
2062    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
2063    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2064    generate_exception(ctx, EXCP_AdES);                                      \
2065    gen_set_label(l1);                                                       \
2066    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2067    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
2068    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
2069    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
2070    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
2071    generate_exception_end(ctx, EXCP_SC);                                    \
2072    gen_set_label(l2);                                                       \
2073    tcg_gen_movi_tl(t0, 0);                                                  \
2074    gen_store_gpr(t0, rt);                                                   \
2075    tcg_temp_free(t0);                                                       \
2076}
2077#else
2078#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2079static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2080{                                                                            \
2081    TCGv t0 = tcg_temp_new();                                                \
2082    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
2083    gen_store_gpr(t0, rt);                                                   \
2084    tcg_temp_free(t0);                                                       \
2085}
2086#endif
2087OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2088#if defined(TARGET_MIPS64)
2089OP_ST_ATOMIC(scd,st64,ld64,0x7);
2090#endif
2091#undef OP_ST_ATOMIC
2092
2093static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2094                                  int base, int16_t offset)
2095{
2096    if (base == 0) {
2097        tcg_gen_movi_tl(addr, offset);
2098    } else if (offset == 0) {
2099        gen_load_gpr(addr, base);
2100    } else {
2101        tcg_gen_movi_tl(addr, offset);
2102        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2103    }
2104}
2105
2106static target_ulong pc_relative_pc (DisasContext *ctx)
2107{
2108    target_ulong pc = ctx->pc;
2109
2110    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2111        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2112
2113        pc -= branch_bytes;
2114    }
2115
2116    pc &= ~(target_ulong)3;
2117    return pc;
2118}
2119
2120/* Load */
2121static void gen_ld(DisasContext *ctx, uint32_t opc,
2122                   int rt, int base, int16_t offset)
2123{
2124    TCGv t0, t1, t2;
2125
2126    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2127        /* Loongson CPU uses a load to zero register for prefetch.
2128           We emulate it as a NOP. On other CPU we must perform the
2129           actual memory access. */
2130        return;
2131    }
2132
2133    t0 = tcg_temp_new();
2134    gen_base_offset_addr(ctx, t0, base, offset);
2135
2136    switch (opc) {
2137#if defined(TARGET_MIPS64)
2138    case OPC_LWU:
2139        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2140                           ctx->default_tcg_memop_mask);
2141        gen_store_gpr(t0, rt);
2142        break;
2143    case OPC_LD:
2144        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2145                           ctx->default_tcg_memop_mask);
2146        gen_store_gpr(t0, rt);
2147        break;
2148    case OPC_LLD:
2149    case R6_OPC_LLD:
2150        op_ld_lld(t0, t0, ctx);
2151        gen_store_gpr(t0, rt);
2152        break;
2153    case OPC_LDL:
2154        t1 = tcg_temp_new();
2155        /* Do a byte access to possibly trigger a page
2156           fault with the unaligned address.  */
2157        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2158        tcg_gen_andi_tl(t1, t0, 7);
2159#ifndef TARGET_WORDS_BIGENDIAN
2160        tcg_gen_xori_tl(t1, t1, 7);
2161#endif
2162        tcg_gen_shli_tl(t1, t1, 3);
2163        tcg_gen_andi_tl(t0, t0, ~7);
2164        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2165        tcg_gen_shl_tl(t0, t0, t1);
2166        t2 = tcg_const_tl(-1);
2167        tcg_gen_shl_tl(t2, t2, t1);
2168        gen_load_gpr(t1, rt);
2169        tcg_gen_andc_tl(t1, t1, t2);
2170        tcg_temp_free(t2);
2171        tcg_gen_or_tl(t0, t0, t1);
2172        tcg_temp_free(t1);
2173        gen_store_gpr(t0, rt);
2174        break;
2175    case OPC_LDR:
2176        t1 = tcg_temp_new();
2177        /* Do a byte access to possibly trigger a page
2178           fault with the unaligned address.  */
2179        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2180        tcg_gen_andi_tl(t1, t0, 7);
2181#ifdef TARGET_WORDS_BIGENDIAN
2182        tcg_gen_xori_tl(t1, t1, 7);
2183#endif
2184        tcg_gen_shli_tl(t1, t1, 3);
2185        tcg_gen_andi_tl(t0, t0, ~7);
2186        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2187        tcg_gen_shr_tl(t0, t0, t1);
2188        tcg_gen_xori_tl(t1, t1, 63);
2189        t2 = tcg_const_tl(0xfffffffffffffffeull);
2190        tcg_gen_shl_tl(t2, t2, t1);
2191        gen_load_gpr(t1, rt);
2192        tcg_gen_and_tl(t1, t1, t2);
2193        tcg_temp_free(t2);
2194        tcg_gen_or_tl(t0, t0, t1);
2195        tcg_temp_free(t1);
2196        gen_store_gpr(t0, rt);
2197        break;
2198    case OPC_LDPC:
2199        t1 = tcg_const_tl(pc_relative_pc(ctx));
2200        gen_op_addr_add(ctx, t0, t0, t1);
2201        tcg_temp_free(t1);
2202        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2203        gen_store_gpr(t0, rt);
2204        break;
2205#endif
2206    case OPC_LWPC:
2207        t1 = tcg_const_tl(pc_relative_pc(ctx));
2208        gen_op_addr_add(ctx, t0, t0, t1);
2209        tcg_temp_free(t1);
2210        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2211        gen_store_gpr(t0, rt);
2212        break;
2213    case OPC_LW:
2214        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2215                           ctx->default_tcg_memop_mask);
2216        gen_store_gpr(t0, rt);
2217        break;
2218    case OPC_LH:
2219        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2220                           ctx->default_tcg_memop_mask);
2221        gen_store_gpr(t0, rt);
2222        break;
2223    case OPC_LHU:
2224        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2225                           ctx->default_tcg_memop_mask);
2226        gen_store_gpr(t0, rt);
2227        break;
2228    case OPC_LB:
2229        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2230        gen_store_gpr(t0, rt);
2231        break;
2232    case OPC_LBU:
2233        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2234        gen_store_gpr(t0, rt);
2235        break;
2236    case OPC_LWL:
2237        t1 = tcg_temp_new();
2238        /* Do a byte access to possibly trigger a page
2239           fault with the unaligned address.  */
2240        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2241        tcg_gen_andi_tl(t1, t0, 3);
2242#ifndef TARGET_WORDS_BIGENDIAN
2243        tcg_gen_xori_tl(t1, t1, 3);
2244#endif
2245        tcg_gen_shli_tl(t1, t1, 3);
2246        tcg_gen_andi_tl(t0, t0, ~3);
2247        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2248        tcg_gen_shl_tl(t0, t0, t1);
2249        t2 = tcg_const_tl(-1);
2250        tcg_gen_shl_tl(t2, t2, t1);
2251        gen_load_gpr(t1, rt);
2252        tcg_gen_andc_tl(t1, t1, t2);
2253        tcg_temp_free(t2);
2254        tcg_gen_or_tl(t0, t0, t1);
2255        tcg_temp_free(t1);
2256        tcg_gen_ext32s_tl(t0, t0);
2257        gen_store_gpr(t0, rt);
2258        break;
2259    case OPC_LWR:
2260        t1 = tcg_temp_new();
2261        /* Do a byte access to possibly trigger a page
2262           fault with the unaligned address.  */
2263        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2264        tcg_gen_andi_tl(t1, t0, 3);
2265#ifdef TARGET_WORDS_BIGENDIAN
2266        tcg_gen_xori_tl(t1, t1, 3);
2267#endif
2268        tcg_gen_shli_tl(t1, t1, 3);
2269        tcg_gen_andi_tl(t0, t0, ~3);
2270        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2271        tcg_gen_shr_tl(t0, t0, t1);
2272        tcg_gen_xori_tl(t1, t1, 31);
2273        t2 = tcg_const_tl(0xfffffffeull);
2274        tcg_gen_shl_tl(t2, t2, t1);
2275        gen_load_gpr(t1, rt);
2276        tcg_gen_and_tl(t1, t1, t2);
2277        tcg_temp_free(t2);
2278        tcg_gen_or_tl(t0, t0, t1);
2279        tcg_temp_free(t1);
2280        tcg_gen_ext32s_tl(t0, t0);
2281        gen_store_gpr(t0, rt);
2282        break;
2283    case OPC_LL:
2284    case R6_OPC_LL:
2285        op_ld_ll(t0, t0, ctx);
2286        gen_store_gpr(t0, rt);
2287        break;
2288    }
2289    tcg_temp_free(t0);
2290}
2291
2292/* Store */
2293static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2294                    int base, int16_t offset)
2295{
2296    TCGv t0 = tcg_temp_new();
2297    TCGv t1 = tcg_temp_new();
2298
2299    gen_base_offset_addr(ctx, t0, base, offset);
2300    gen_load_gpr(t1, rt);
2301    switch (opc) {
2302#if defined(TARGET_MIPS64)
2303    case OPC_SD:
2304        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2305                           ctx->default_tcg_memop_mask);
2306        break;
2307    case OPC_SDL:
2308        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2309        break;
2310    case OPC_SDR:
2311        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2312        break;
2313#endif
2314    case OPC_SW:
2315        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2316                           ctx->default_tcg_memop_mask);
2317        break;
2318    case OPC_SH:
2319        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2320                           ctx->default_tcg_memop_mask);
2321        break;
2322    case OPC_SB:
2323        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2324        break;
2325    case OPC_SWL:
2326        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2327        break;
2328    case OPC_SWR:
2329        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2330        break;
2331    }
2332    tcg_temp_free(t0);
2333    tcg_temp_free(t1);
2334}
2335
2336
2337/* Store conditional */
2338static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2339                         int base, int16_t offset)
2340{
2341    TCGv t0, t1;
2342
2343#ifdef CONFIG_USER_ONLY
2344    t0 = tcg_temp_local_new();
2345    t1 = tcg_temp_local_new();
2346#else
2347    t0 = tcg_temp_new();
2348    t1 = tcg_temp_new();
2349#endif
2350    gen_base_offset_addr(ctx, t0, base, offset);
2351    gen_load_gpr(t1, rt);
2352    switch (opc) {
2353#if defined(TARGET_MIPS64)
2354    case OPC_SCD:
2355    case R6_OPC_SCD:
2356        op_st_scd(t1, t0, rt, ctx);
2357        break;
2358#endif
2359    case OPC_SC:
2360    case R6_OPC_SC:
2361        op_st_sc(t1, t0, rt, ctx);
2362        break;
2363    }
2364    tcg_temp_free(t1);
2365    tcg_temp_free(t0);
2366}
2367
2368/* Load and store */
2369static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2370                          int base, int16_t offset)
2371{
2372    TCGv t0 = tcg_temp_new();
2373
2374    gen_base_offset_addr(ctx, t0, base, offset);
2375    /* Don't do NOP if destination is zero: we must perform the actual
2376       memory access. */
2377    switch (opc) {
2378    case OPC_LWC1:
2379        {
2380            TCGv_i32 fp0 = tcg_temp_new_i32();
2381            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2382                                ctx->default_tcg_memop_mask);
2383            gen_store_fpr32(ctx, fp0, ft);
2384            tcg_temp_free_i32(fp0);
2385        }
2386        break;
2387    case OPC_SWC1:
2388        {
2389            TCGv_i32 fp0 = tcg_temp_new_i32();
2390            gen_load_fpr32(ctx, fp0, ft);
2391            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2392                                ctx->default_tcg_memop_mask);
2393            tcg_temp_free_i32(fp0);
2394        }
2395        break;
2396    case OPC_LDC1:
2397        {
2398            TCGv_i64 fp0 = tcg_temp_new_i64();
2399            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2400                                ctx->default_tcg_memop_mask);
2401            gen_store_fpr64(ctx, fp0, ft);
2402            tcg_temp_free_i64(fp0);
2403        }
2404        break;
2405    case OPC_SDC1:
2406        {
2407            TCGv_i64 fp0 = tcg_temp_new_i64();
2408            gen_load_fpr64(ctx, fp0, ft);
2409            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2410                                ctx->default_tcg_memop_mask);
2411            tcg_temp_free_i64(fp0);
2412        }
2413        break;
2414    default:
2415        MIPS_INVAL("flt_ldst");
2416        generate_exception_end(ctx, EXCP_RI);
2417        goto out;
2418    }
2419 out:
2420    tcg_temp_free(t0);
2421}
2422
2423static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2424                          int rs, int16_t imm)
2425{
2426    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2427        check_cp1_enabled(ctx);
2428        switch (op) {
2429        case OPC_LDC1:
2430        case OPC_SDC1:
2431            check_insn(ctx, ISA_MIPS2);
2432            /* Fallthrough */
2433        default:
2434            gen_flt_ldst(ctx, op, rt, rs, imm);
2435        }
2436    } else {
2437        generate_exception_err(ctx, EXCP_CpU, 1);
2438    }
2439}
2440
2441/* Arithmetic with immediate operand */
2442static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2443                          int rt, int rs, int16_t imm)
2444{
2445    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2446
2447    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2448        /* If no destination, treat it as a NOP.
2449           For addi, we must generate the overflow exception when needed. */
2450        return;
2451    }
2452    switch (opc) {
2453    case OPC_ADDI:
2454        {
2455            TCGv t0 = tcg_temp_local_new();
2456            TCGv t1 = tcg_temp_new();
2457            TCGv t2 = tcg_temp_new();
2458            TCGLabel *l1 = gen_new_label();
2459
2460            gen_load_gpr(t1, rs);
2461            tcg_gen_addi_tl(t0, t1, uimm);
2462            tcg_gen_ext32s_tl(t0, t0);
2463
2464            tcg_gen_xori_tl(t1, t1, ~uimm);
2465            tcg_gen_xori_tl(t2, t0, uimm);
2466            tcg_gen_and_tl(t1, t1, t2);
2467            tcg_temp_free(t2);
2468            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2469            tcg_temp_free(t1);
2470            /* operands of same sign, result different sign */
2471            generate_exception(ctx, EXCP_OVERFLOW);
2472            gen_set_label(l1);
2473            tcg_gen_ext32s_tl(t0, t0);
2474            gen_store_gpr(t0, rt);
2475            tcg_temp_free(t0);
2476        }
2477        break;
2478    case OPC_ADDIU:
2479        if (rs != 0) {
2480            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2481            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2482        } else {
2483            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2484        }
2485        break;
2486#if defined(TARGET_MIPS64)
2487    case OPC_DADDI:
2488        {
2489            TCGv t0 = tcg_temp_local_new();
2490            TCGv t1 = tcg_temp_new();
2491            TCGv t2 = tcg_temp_new();
2492            TCGLabel *l1 = gen_new_label();
2493
2494            gen_load_gpr(t1, rs);
2495            tcg_gen_addi_tl(t0, t1, uimm);
2496
2497            tcg_gen_xori_tl(t1, t1, ~uimm);
2498            tcg_gen_xori_tl(t2, t0, uimm);
2499            tcg_gen_and_tl(t1, t1, t2);
2500            tcg_temp_free(t2);
2501            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2502            tcg_temp_free(t1);
2503            /* operands of same sign, result different sign */
2504            generate_exception(ctx, EXCP_OVERFLOW);
2505            gen_set_label(l1);
2506            gen_store_gpr(t0, rt);
2507            tcg_temp_free(t0);
2508        }
2509        break;
2510    case OPC_DADDIU:
2511        if (rs != 0) {
2512            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2513        } else {
2514            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2515        }
2516        break;
2517#endif
2518    }
2519}
2520
2521/* Logic with immediate operand */
2522static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2523                          int rt, int rs, int16_t imm)
2524{
2525    target_ulong uimm;
2526
2527    if (rt == 0) {
2528        /* If no destination, treat it as a NOP. */
2529        return;
2530    }
2531    uimm = (uint16_t)imm;
2532    switch (opc) {
2533    case OPC_ANDI:
2534        if (likely(rs != 0))
2535            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2536        else
2537            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2538        break;
2539    case OPC_ORI:
2540        if (rs != 0)
2541            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2542        else
2543            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2544        break;
2545    case OPC_XORI:
2546        if (likely(rs != 0))
2547            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2548        else
2549            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2550        break;
2551    case OPC_LUI:
2552        if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2553            /* OPC_AUI */
2554            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2555            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2556        } else {
2557            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2558        }
2559        break;
2560
2561    default:
2562        break;
2563    }
2564}
2565
2566/* Set on less than with immediate operand */
2567static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2568                        int rt, int rs, int16_t imm)
2569{
2570    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2571    TCGv t0;
2572
2573    if (rt == 0) {
2574        /* If no destination, treat it as a NOP. */
2575        return;
2576    }
2577    t0 = tcg_temp_new();
2578    gen_load_gpr(t0, rs);
2579    switch (opc) {
2580    case OPC_SLTI:
2581        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2582        break;
2583    case OPC_SLTIU:
2584        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2585        break;
2586    }
2587    tcg_temp_free(t0);
2588}
2589
2590/* Shifts with immediate operand */
2591static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2592                          int rt, int rs, int16_t imm)
2593{
2594    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2595    TCGv t0;
2596
2597    if (rt == 0) {
2598        /* If no destination, treat it as a NOP. */
2599        return;
2600    }
2601
2602    t0 = tcg_temp_new();
2603    gen_load_gpr(t0, rs);
2604    switch (opc) {
2605    case OPC_SLL:
2606        tcg_gen_shli_tl(t0, t0, uimm);
2607        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2608        break;
2609    case OPC_SRA:
2610        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2611        break;
2612    case OPC_SRL:
2613        if (uimm != 0) {
2614            tcg_gen_ext32u_tl(t0, t0);
2615            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2616        } else {
2617            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2618        }
2619        break;
2620    case OPC_ROTR:
2621        if (uimm != 0) {
2622            TCGv_i32 t1 = tcg_temp_new_i32();
2623
2624            tcg_gen_trunc_tl_i32(t1, t0);
2625            tcg_gen_rotri_i32(t1, t1, uimm);
2626            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2627            tcg_temp_free_i32(t1);
2628        } else {
2629            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2630        }
2631        break;
2632#if defined(TARGET_MIPS64)
2633    case OPC_DSLL:
2634        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2635        break;
2636    case OPC_DSRA:
2637        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2638        break;
2639    case OPC_DSRL:
2640        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2641        break;
2642    case OPC_DROTR:
2643        if (uimm != 0) {
2644            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2645        } else {
2646            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2647        }
2648        break;
2649    case OPC_DSLL32:
2650        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2651        break;
2652    case OPC_DSRA32:
2653        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2654        break;
2655    case OPC_DSRL32:
2656        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2657        break;
2658    case OPC_DROTR32:
2659        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2660        break;
2661#endif
2662    }
2663    tcg_temp_free(t0);
2664}
2665
2666/* Arithmetic */
2667static void gen_arith(DisasContext *ctx, uint32_t opc,
2668                      int rd, int rs, int rt)
2669{
2670    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2671       && opc != OPC_DADD && opc != OPC_DSUB) {
2672        /* If no destination, treat it as a NOP.
2673           For add & sub, we must generate the overflow exception when needed. */
2674        return;
2675    }
2676
2677    switch (opc) {
2678    case OPC_ADD:
2679        {
2680            TCGv t0 = tcg_temp_local_new();
2681            TCGv t1 = tcg_temp_new();
2682            TCGv t2 = tcg_temp_new();
2683            TCGLabel *l1 = gen_new_label();
2684
2685            gen_load_gpr(t1, rs);
2686            gen_load_gpr(t2, rt);
2687            tcg_gen_add_tl(t0, t1, t2);
2688            tcg_gen_ext32s_tl(t0, t0);
2689            tcg_gen_xor_tl(t1, t1, t2);
2690            tcg_gen_xor_tl(t2, t0, t2);
2691            tcg_gen_andc_tl(t1, t2, t1);
2692            tcg_temp_free(t2);
2693            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2694            tcg_temp_free(t1);
2695            /* operands of same sign, result different sign */
2696            generate_exception(ctx, EXCP_OVERFLOW);
2697            gen_set_label(l1);
2698            gen_store_gpr(t0, rd);
2699            tcg_temp_free(t0);
2700        }
2701        break;
2702    case OPC_ADDU:
2703        if (rs != 0 && rt != 0) {
2704            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2705            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2706        } else if (rs == 0 && rt != 0) {
2707            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2708        } else if (rs != 0 && rt == 0) {
2709            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2710        } else {
2711            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2712        }
2713        break;
2714    case OPC_SUB:
2715        {
2716            TCGv t0 = tcg_temp_local_new();
2717            TCGv t1 = tcg_temp_new();
2718            TCGv t2 = tcg_temp_new();
2719            TCGLabel *l1 = gen_new_label();
2720
2721            gen_load_gpr(t1, rs);
2722            gen_load_gpr(t2, rt);
2723            tcg_gen_sub_tl(t0, t1, t2);
2724            tcg_gen_ext32s_tl(t0, t0);
2725            tcg_gen_xor_tl(t2, t1, t2);
2726            tcg_gen_xor_tl(t1, t0, t1);
2727            tcg_gen_and_tl(t1, t1, t2);
2728            tcg_temp_free(t2);
2729            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2730            tcg_temp_free(t1);
2731            /* operands of different sign, first operand and result different sign */
2732            generate_exception(ctx, EXCP_OVERFLOW);
2733            gen_set_label(l1);
2734            gen_store_gpr(t0, rd);
2735            tcg_temp_free(t0);
2736        }
2737        break;
2738    case OPC_SUBU:
2739        if (rs != 0 && rt != 0) {
2740            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2741            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2742        } else if (rs == 0 && rt != 0) {
2743            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2744            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2745        } else if (rs != 0 && rt == 0) {
2746            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2747        } else {
2748            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2749        }
2750        break;
2751#if defined(TARGET_MIPS64)
2752    case OPC_DADD:
2753        {
2754            TCGv t0 = tcg_temp_local_new();
2755            TCGv t1 = tcg_temp_new();
2756            TCGv t2 = tcg_temp_new();
2757            TCGLabel *l1 = gen_new_label();
2758
2759            gen_load_gpr(t1, rs);
2760            gen_load_gpr(t2, rt);
2761            tcg_gen_add_tl(t0, t1, t2);
2762            tcg_gen_xor_tl(t1, t1, t2);
2763            tcg_gen_xor_tl(t2, t0, t2);
2764            tcg_gen_andc_tl(t1, t2, t1);
2765            tcg_temp_free(t2);
2766            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2767            tcg_temp_free(t1);
2768            /* operands of same sign, result different sign */
2769            generate_exception(ctx, EXCP_OVERFLOW);
2770            gen_set_label(l1);
2771            gen_store_gpr(t0, rd);
2772            tcg_temp_free(t0);
2773        }
2774        break;
2775    case OPC_DADDU:
2776        if (rs != 0 && rt != 0) {
2777            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2778        } else if (rs == 0 && rt != 0) {
2779            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2780        } else if (rs != 0 && rt == 0) {
2781            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2782        } else {
2783            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2784        }
2785        break;
2786    case OPC_DSUB:
2787        {
2788            TCGv t0 = tcg_temp_local_new();
2789            TCGv t1 = tcg_temp_new();
2790            TCGv t2 = tcg_temp_new();
2791            TCGLabel *l1 = gen_new_label();
2792
2793            gen_load_gpr(t1, rs);
2794            gen_load_gpr(t2, rt);
2795            tcg_gen_sub_tl(t0, t1, t2);
2796            tcg_gen_xor_tl(t2, t1, t2);
2797            tcg_gen_xor_tl(t1, t0, t1);
2798            tcg_gen_and_tl(t1, t1, t2);
2799            tcg_temp_free(t2);
2800            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2801            tcg_temp_free(t1);
2802            /* operands of different sign, first operand and result different sign */
2803            generate_exception(ctx, EXCP_OVERFLOW);
2804            gen_set_label(l1);
2805            gen_store_gpr(t0, rd);
2806            tcg_temp_free(t0);
2807        }
2808        break;
2809    case OPC_DSUBU:
2810        if (rs != 0 && rt != 0) {
2811            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2812        } else if (rs == 0 && rt != 0) {
2813            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2814        } else if (rs != 0 && rt == 0) {
2815            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2816        } else {
2817            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2818        }
2819        break;
2820#endif
2821    case OPC_MUL:
2822        if (likely(rs != 0 && rt != 0)) {
2823            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2824            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2825        } else {
2826            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2827        }
2828        break;
2829    }
2830}
2831
2832/* Conditional move */
2833static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2834                          int rd, int rs, int rt)
2835{
2836    TCGv t0, t1, t2;
2837
2838    if (rd == 0) {
2839        /* If no destination, treat it as a NOP. */
2840        return;
2841    }
2842
2843    t0 = tcg_temp_new();
2844    gen_load_gpr(t0, rt);
2845    t1 = tcg_const_tl(0);
2846    t2 = tcg_temp_new();
2847    gen_load_gpr(t2, rs);
2848    switch (opc) {
2849    case OPC_MOVN:
2850        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2851        break;
2852    case OPC_MOVZ:
2853        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2854        break;
2855    case OPC_SELNEZ:
2856        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2857        break;
2858    case OPC_SELEQZ:
2859        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2860        break;
2861    }
2862    tcg_temp_free(t2);
2863    tcg_temp_free(t1);
2864    tcg_temp_free(t0);
2865}
2866
2867/* Logic */
2868static void gen_logic(DisasContext *ctx, uint32_t opc,
2869                      int rd, int rs, int rt)
2870{
2871    if (rd == 0) {
2872        /* If no destination, treat it as a NOP. */
2873        return;
2874    }
2875
2876    switch (opc) {
2877    case OPC_AND:
2878        if (likely(rs != 0 && rt != 0)) {
2879            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2880        } else {
2881            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2882        }
2883        break;
2884    case OPC_NOR:
2885        if (rs != 0 && rt != 0) {
2886            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2887        } else if (rs == 0 && rt != 0) {
2888            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2889        } else if (rs != 0 && rt == 0) {
2890            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2891        } else {
2892            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2893        }
2894        break;
2895    case OPC_OR:
2896        if (likely(rs != 0 && rt != 0)) {
2897            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2898        } else if (rs == 0 && rt != 0) {
2899            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2900        } else if (rs != 0 && rt == 0) {
2901            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2902        } else {
2903            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2904        }
2905        break;
2906    case OPC_XOR:
2907        if (likely(rs != 0 && rt != 0)) {
2908            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2909        } else if (rs == 0 && rt != 0) {
2910            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2911        } else if (rs != 0 && rt == 0) {
2912            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2913        } else {
2914            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2915        }
2916        break;
2917    }
2918}
2919
2920/* Set on lower than */
2921static void gen_slt(DisasContext *ctx, uint32_t opc,
2922                    int rd, int rs, int rt)
2923{
2924    TCGv t0, t1;
2925
2926    if (rd == 0) {
2927        /* If no destination, treat it as a NOP. */
2928        return;
2929    }
2930
2931    t0 = tcg_temp_new();
2932    t1 = tcg_temp_new();
2933    gen_load_gpr(t0, rs);
2934    gen_load_gpr(t1, rt);
2935    switch (opc) {
2936    case OPC_SLT:
2937        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2938        break;
2939    case OPC_SLTU:
2940        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2941        break;
2942    }
2943    tcg_temp_free(t0);
2944    tcg_temp_free(t1);
2945}
2946
2947/* Shifts */
2948static void gen_shift(DisasContext *ctx, uint32_t opc,
2949                      int rd, int rs, int rt)
2950{
2951    TCGv t0, t1;
2952
2953    if (rd == 0) {
2954        /* If no destination, treat it as a NOP.
2955           For add & sub, we must generate the overflow exception when needed. */
2956        return;
2957    }
2958
2959    t0 = tcg_temp_new();
2960    t1 = tcg_temp_new();
2961    gen_load_gpr(t0, rs);
2962    gen_load_gpr(t1, rt);
2963    switch (opc) {
2964    case OPC_SLLV:
2965        tcg_gen_andi_tl(t0, t0, 0x1f);
2966        tcg_gen_shl_tl(t0, t1, t0);
2967        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2968        break;
2969    case OPC_SRAV:
2970        tcg_gen_andi_tl(t0, t0, 0x1f);
2971        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2972        break;
2973    case OPC_SRLV:
2974        tcg_gen_ext32u_tl(t1, t1);
2975        tcg_gen_andi_tl(t0, t0, 0x1f);
2976        tcg_gen_shr_tl(t0, t1, t0);
2977        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2978        break;
2979    case OPC_ROTRV:
2980        {
2981            TCGv_i32 t2 = tcg_temp_new_i32();
2982            TCGv_i32 t3 = tcg_temp_new_i32();
2983
2984            tcg_gen_trunc_tl_i32(t2, t0);
2985            tcg_gen_trunc_tl_i32(t3, t1);
2986            tcg_gen_andi_i32(t2, t2, 0x1f);
2987            tcg_gen_rotr_i32(t2, t3, t2);
2988            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2989            tcg_temp_free_i32(t2);
2990            tcg_temp_free_i32(t3);
2991        }
2992        break;
2993#if defined(TARGET_MIPS64)
2994    case OPC_DSLLV:
2995        tcg_gen_andi_tl(t0, t0, 0x3f);
2996        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2997        break;
2998    case OPC_DSRAV:
2999        tcg_gen_andi_tl(t0, t0, 0x3f);
3000        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3001        break;
3002    case OPC_DSRLV:
3003        tcg_gen_andi_tl(t0, t0, 0x3f);
3004        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3005        break;
3006    case OPC_DROTRV:
3007        tcg_gen_andi_tl(t0, t0, 0x3f);
3008        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3009        break;
3010#endif
3011    }
3012    tcg_temp_free(t0);
3013    tcg_temp_free(t1);
3014}
3015
3016/* Arithmetic on HI/LO registers */
3017static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3018{
3019    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3020        /* Treat as NOP. */
3021        return;
3022    }
3023
3024    if (acc != 0) {
3025        check_dsp(ctx);
3026    }
3027
3028    switch (opc) {
3029    case OPC_MFHI:
3030#if defined(TARGET_MIPS64)
3031        if (acc != 0) {
3032            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3033        } else
3034#endif
3035        {
3036            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3037        }
3038        break;
3039    case OPC_MFLO:
3040#if defined(TARGET_MIPS64)
3041        if (acc != 0) {
3042            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3043        } else
3044#endif
3045        {
3046            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3047        }
3048        break;
3049    case OPC_MTHI:
3050        if (reg != 0) {
3051#if defined(TARGET_MIPS64)
3052            if (acc != 0) {
3053                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3054            } else
3055#endif
3056            {
3057                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3058            }
3059        } else {
3060            tcg_gen_movi_tl(cpu_HI[acc], 0);
3061        }
3062        break;
3063    case OPC_MTLO:
3064        if (reg != 0) {
3065#if defined(TARGET_MIPS64)
3066            if (acc != 0) {
3067                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3068            } else
3069#endif
3070            {
3071                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3072            }
3073        } else {
3074            tcg_gen_movi_tl(cpu_LO[acc], 0);
3075        }
3076        break;
3077    }
3078}
3079
3080static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3081                             TCGMemOp memop)
3082{
3083    TCGv t0 = tcg_const_tl(addr);
3084    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3085    gen_store_gpr(t0, reg);
3086    tcg_temp_free(t0);
3087}
3088
3089static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3090                             int rs)
3091{
3092    target_long offset;
3093    target_long addr;
3094
3095    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3096    case OPC_ADDIUPC:
3097        if (rs != 0) {
3098            offset = sextract32(ctx->opcode << 2, 0, 21);
3099            addr = addr_add(ctx, pc, offset);
3100            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3101        }
3102        break;
3103    case R6_OPC_LWPC:
3104        offset = sextract32(ctx->opcode << 2, 0, 21);
3105        addr = addr_add(ctx, pc, offset);
3106        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3107        break;
3108#if defined(TARGET_MIPS64)
3109    case OPC_LWUPC:
3110        check_mips_64(ctx);
3111        offset = sextract32(ctx->opcode << 2, 0, 21);
3112        addr = addr_add(ctx, pc, offset);
3113        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3114        break;
3115#endif
3116    default:
3117        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3118        case OPC_AUIPC:
3119            if (rs != 0) {
3120                offset = sextract32(ctx->opcode, 0, 16) << 16;
3121                addr = addr_add(ctx, pc, offset);
3122                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3123            }
3124            break;
3125        case OPC_ALUIPC:
3126            if (rs != 0) {
3127                offset = sextract32(ctx->opcode, 0, 16) << 16;
3128                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3129                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3130            }
3131            break;
3132#if defined(TARGET_MIPS64)
3133        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3134        case R6_OPC_LDPC + (1 << 16):
3135        case R6_OPC_LDPC + (2 << 16):
3136        case R6_OPC_LDPC + (3 << 16):
3137            check_mips_64(ctx);
3138            offset = sextract32(ctx->opcode << 3, 0, 21);
3139            addr = addr_add(ctx, (pc & ~0x7), offset);
3140            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3141            break;
3142#endif
3143        default:
3144            MIPS_INVAL("OPC_PCREL");
3145            generate_exception_end(ctx, EXCP_RI);
3146            break;
3147        }
3148        break;
3149    }
3150}
3151
3152static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3153{
3154    TCGv t0, t1;
3155
3156    if (rd == 0) {
3157        /* Treat as NOP. */
3158        return;
3159    }
3160
3161    t0 = tcg_temp_new();
3162    t1 = tcg_temp_new();
3163
3164    gen_load_gpr(t0, rs);
3165    gen_load_gpr(t1, rt);
3166
3167    switch (opc) {
3168    case R6_OPC_DIV:
3169        {
3170            TCGv t2 = tcg_temp_new();
3171            TCGv t3 = tcg_temp_new();
3172            tcg_gen_ext32s_tl(t0, t0);
3173            tcg_gen_ext32s_tl(t1, t1);
3174            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3175            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3176            tcg_gen_and_tl(t2, t2, t3);
3177            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3178            tcg_gen_or_tl(t2, t2, t3);
3179            tcg_gen_movi_tl(t3, 0);
3180            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3181            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3182            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3183            tcg_temp_free(t3);
3184            tcg_temp_free(t2);
3185        }
3186        break;
3187    case R6_OPC_MOD:
3188        {
3189            TCGv t2 = tcg_temp_new();
3190            TCGv t3 = tcg_temp_new();
3191            tcg_gen_ext32s_tl(t0, t0);
3192            tcg_gen_ext32s_tl(t1, t1);
3193            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3194            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3195            tcg_gen_and_tl(t2, t2, t3);
3196            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3197            tcg_gen_or_tl(t2, t2, t3);
3198            tcg_gen_movi_tl(t3, 0);
3199            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3200            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3201            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3202            tcg_temp_free(t3);
3203            tcg_temp_free(t2);
3204        }
3205        break;
3206    case R6_OPC_DIVU:
3207        {
3208            TCGv t2 = tcg_const_tl(0);
3209            TCGv t3 = tcg_const_tl(1);
3210            tcg_gen_ext32u_tl(t0, t0);
3211            tcg_gen_ext32u_tl(t1, t1);
3212            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3213            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3214            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3215            tcg_temp_free(t3);
3216            tcg_temp_free(t2);
3217        }
3218        break;
3219    case R6_OPC_MODU:
3220        {
3221            TCGv t2 = tcg_const_tl(0);
3222            TCGv t3 = tcg_const_tl(1);
3223            tcg_gen_ext32u_tl(t0, t0);
3224            tcg_gen_ext32u_tl(t1, t1);
3225            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3226            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3227            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3228            tcg_temp_free(t3);
3229            tcg_temp_free(t2);
3230        }
3231        break;
3232    case R6_OPC_MUL:
3233        {
3234            TCGv_i32 t2 = tcg_temp_new_i32();
3235            TCGv_i32 t3 = tcg_temp_new_i32();
3236            tcg_gen_trunc_tl_i32(t2, t0);
3237            tcg_gen_trunc_tl_i32(t3, t1);
3238            tcg_gen_mul_i32(t2, t2, t3);
3239            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3240            tcg_temp_free_i32(t2);
3241            tcg_temp_free_i32(t3);
3242        }
3243        break;
3244    case R6_OPC_MUH:
3245        {
3246            TCGv_i32 t2 = tcg_temp_new_i32();
3247            TCGv_i32 t3 = tcg_temp_new_i32();
3248            tcg_gen_trunc_tl_i32(t2, t0);
3249            tcg_gen_trunc_tl_i32(t3, t1);
3250            tcg_gen_muls2_i32(t2, t3, t2, t3);
3251            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3252            tcg_temp_free_i32(t2);
3253            tcg_temp_free_i32(t3);
3254        }
3255        break;
3256    case R6_OPC_MULU:
3257        {
3258            TCGv_i32 t2 = tcg_temp_new_i32();
3259            TCGv_i32 t3 = tcg_temp_new_i32();
3260            tcg_gen_trunc_tl_i32(t2, t0);
3261            tcg_gen_trunc_tl_i32(t3, t1);
3262            tcg_gen_mul_i32(t2, t2, t3);
3263            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3264            tcg_temp_free_i32(t2);
3265            tcg_temp_free_i32(t3);
3266        }
3267        break;
3268    case R6_OPC_MUHU:
3269        {
3270            TCGv_i32 t2 = tcg_temp_new_i32();
3271            TCGv_i32 t3 = tcg_temp_new_i32();
3272            tcg_gen_trunc_tl_i32(t2, t0);
3273            tcg_gen_trunc_tl_i32(t3, t1);
3274            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3275            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3276            tcg_temp_free_i32(t2);
3277            tcg_temp_free_i32(t3);
3278        }
3279        break;
3280#if defined(TARGET_MIPS64)
3281    case R6_OPC_DDIV:
3282        {
3283            TCGv t2 = tcg_temp_new();
3284            TCGv t3 = tcg_temp_new();
3285            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3286            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3287            tcg_gen_and_tl(t2, t2, t3);
3288            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3289            tcg_gen_or_tl(t2, t2, t3);
3290            tcg_gen_movi_tl(t3, 0);
3291            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3292            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3293            tcg_temp_free(t3);
3294            tcg_temp_free(t2);
3295        }
3296        break;
3297    case R6_OPC_DMOD:
3298        {
3299            TCGv t2 = tcg_temp_new();
3300            TCGv t3 = tcg_temp_new();
3301            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3302            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3303            tcg_gen_and_tl(t2, t2, t3);
3304            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3305            tcg_gen_or_tl(t2, t2, t3);
3306            tcg_gen_movi_tl(t3, 0);
3307            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3308            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3309            tcg_temp_free(t3);
3310            tcg_temp_free(t2);
3311        }
3312        break;
3313    case R6_OPC_DDIVU:
3314        {
3315            TCGv t2 = tcg_const_tl(0);
3316            TCGv t3 = tcg_const_tl(1);
3317            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3318            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3319            tcg_temp_free(t3);
3320            tcg_temp_free(t2);
3321        }
3322        break;
3323    case R6_OPC_DMODU:
3324        {
3325            TCGv t2 = tcg_const_tl(0);
3326            TCGv t3 = tcg_const_tl(1);
3327            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3328            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3329            tcg_temp_free(t3);
3330            tcg_temp_free(t2);
3331        }
3332        break;
3333    case R6_OPC_DMUL:
3334        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3335        break;
3336    case R6_OPC_DMUH:
3337        {
3338            TCGv t2 = tcg_temp_new();
3339            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3340            tcg_temp_free(t2);
3341        }
3342        break;
3343    case R6_OPC_DMULU:
3344        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3345        break;
3346    case R6_OPC_DMUHU:
3347        {
3348            TCGv t2 = tcg_temp_new();
3349            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3350            tcg_temp_free(t2);
3351        }
3352        break;
3353#endif
3354    default:
3355        MIPS_INVAL("r6 mul/div");
3356        generate_exception_end(ctx, EXCP_RI);
3357        goto out;
3358    }
3359 out:
3360    tcg_temp_free(t0);
3361    tcg_temp_free(t1);
3362}
3363
3364static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3365                       int acc, int rs, int rt)
3366{
3367    TCGv t0, t1;
3368
3369    t0 = tcg_temp_new();
3370    t1 = tcg_temp_new();
3371
3372    gen_load_gpr(t0, rs);
3373    gen_load_gpr(t1, rt);
3374
3375    if (acc != 0) {
3376        check_dsp(ctx);
3377    }
3378
3379    switch (opc) {
3380    case OPC_DIV:
3381        {
3382            TCGv t2 = tcg_temp_new();
3383            TCGv t3 = tcg_temp_new();
3384            tcg_gen_ext32s_tl(t0, t0);
3385            tcg_gen_ext32s_tl(t1, t1);
3386            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3387            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3388            tcg_gen_and_tl(t2, t2, t3);
3389            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3390            tcg_gen_or_tl(t2, t2, t3);
3391            tcg_gen_movi_tl(t3, 0);
3392            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3393            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3394            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3395            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3396            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3397            tcg_temp_free(t3);
3398            tcg_temp_free(t2);
3399        }
3400        break;
3401    case OPC_DIVU:
3402        {
3403            TCGv t2 = tcg_const_tl(0);
3404            TCGv t3 = tcg_const_tl(1);
3405            tcg_gen_ext32u_tl(t0, t0);
3406            tcg_gen_ext32u_tl(t1, t1);
3407            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3408            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3409            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3410            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3411            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3412            tcg_temp_free(t3);
3413            tcg_temp_free(t2);
3414        }
3415        break;
3416    case OPC_MULT:
3417        {
3418            TCGv_i32 t2 = tcg_temp_new_i32();
3419            TCGv_i32 t3 = tcg_temp_new_i32();
3420            tcg_gen_trunc_tl_i32(t2, t0);
3421            tcg_gen_trunc_tl_i32(t3, t1);
3422            tcg_gen_muls2_i32(t2, t3, t2, t3);
3423            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3424            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3425            tcg_temp_free_i32(t2);
3426            tcg_temp_free_i32(t3);
3427        }
3428        break;
3429    case OPC_MULTU:
3430        {
3431            TCGv_i32 t2 = tcg_temp_new_i32();
3432            TCGv_i32 t3 = tcg_temp_new_i32();
3433            tcg_gen_trunc_tl_i32(t2, t0);
3434            tcg_gen_trunc_tl_i32(t3, t1);
3435            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3436            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3437            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3438            tcg_temp_free_i32(t2);
3439            tcg_temp_free_i32(t3);
3440        }
3441        break;
3442#if defined(TARGET_MIPS64)
3443    case OPC_DDIV:
3444        {
3445            TCGv t2 = tcg_temp_new();
3446            TCGv t3 = tcg_temp_new();
3447            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3448            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3449            tcg_gen_and_tl(t2, t2, t3);
3450            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3451            tcg_gen_or_tl(t2, t2, t3);
3452            tcg_gen_movi_tl(t3, 0);
3453            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3454            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3455            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3456            tcg_temp_free(t3);
3457            tcg_temp_free(t2);
3458        }
3459        break;
3460    case OPC_DDIVU:
3461        {
3462            TCGv t2 = tcg_const_tl(0);
3463            TCGv t3 = tcg_const_tl(1);
3464            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3465            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3466            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3467            tcg_temp_free(t3);
3468            tcg_temp_free(t2);
3469        }
3470        break;
3471    case OPC_DMULT:
3472        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3473        break;
3474    case OPC_DMULTU:
3475        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3476        break;
3477#endif
3478    case OPC_MADD:
3479        {
3480            TCGv_i64 t2 = tcg_temp_new_i64();
3481            TCGv_i64 t3 = tcg_temp_new_i64();
3482
3483            tcg_gen_ext_tl_i64(t2, t0);
3484            tcg_gen_ext_tl_i64(t3, t1);
3485            tcg_gen_mul_i64(t2, t2, t3);
3486            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3487            tcg_gen_add_i64(t2, t2, t3);
3488            tcg_temp_free_i64(t3);
3489            gen_move_low32(cpu_LO[acc], t2);
3490            gen_move_high32(cpu_HI[acc], t2);
3491            tcg_temp_free_i64(t2);
3492        }
3493        break;
3494    case OPC_MADDU:
3495        {
3496            TCGv_i64 t2 = tcg_temp_new_i64();
3497            TCGv_i64 t3 = tcg_temp_new_i64();
3498
3499            tcg_gen_ext32u_tl(t0, t0);
3500            tcg_gen_ext32u_tl(t1, t1);
3501            tcg_gen_extu_tl_i64(t2, t0);
3502            tcg_gen_extu_tl_i64(t3, t1);
3503            tcg_gen_mul_i64(t2, t2, t3);
3504            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3505            tcg_gen_add_i64(t2, t2, t3);
3506            tcg_temp_free_i64(t3);
3507            gen_move_low32(cpu_LO[acc], t2);
3508            gen_move_high32(cpu_HI[acc], t2);
3509            tcg_temp_free_i64(t2);
3510        }
3511        break;
3512    case OPC_MSUB:
3513        {
3514            TCGv_i64 t2 = tcg_temp_new_i64();
3515            TCGv_i64 t3 = tcg_temp_new_i64();
3516
3517            tcg_gen_ext_tl_i64(t2, t0);
3518            tcg_gen_ext_tl_i64(t3, t1);
3519            tcg_gen_mul_i64(t2, t2, t3);
3520            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3521            tcg_gen_sub_i64(t2, t3, t2);
3522            tcg_temp_free_i64(t3);
3523            gen_move_low32(cpu_LO[acc], t2);
3524            gen_move_high32(cpu_HI[acc], t2);
3525            tcg_temp_free_i64(t2);
3526        }
3527        break;
3528    case OPC_MSUBU:
3529        {
3530            TCGv_i64 t2 = tcg_temp_new_i64();
3531            TCGv_i64 t3 = tcg_temp_new_i64();
3532
3533            tcg_gen_ext32u_tl(t0, t0);
3534            tcg_gen_ext32u_tl(t1, t1);
3535            tcg_gen_extu_tl_i64(t2, t0);
3536            tcg_gen_extu_tl_i64(t3, t1);
3537            tcg_gen_mul_i64(t2, t2, t3);
3538            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3539            tcg_gen_sub_i64(t2, t3, t2);
3540            tcg_temp_free_i64(t3);
3541            gen_move_low32(cpu_LO[acc], t2);
3542            gen_move_high32(cpu_HI[acc], t2);
3543            tcg_temp_free_i64(t2);
3544        }
3545        break;
3546    default:
3547        MIPS_INVAL("mul/div");
3548        generate_exception_end(ctx, EXCP_RI);
3549        goto out;
3550    }
3551 out:
3552    tcg_temp_free(t0);
3553    tcg_temp_free(t1);
3554}
3555
3556static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3557                            int rd, int rs, int rt)
3558{
3559    TCGv t0 = tcg_temp_new();
3560    TCGv t1 = tcg_temp_new();
3561
3562    gen_load_gpr(t0, rs);
3563    gen_load_gpr(t1, rt);
3564
3565    switch (opc) {
3566    case OPC_VR54XX_MULS:
3567        gen_helper_muls(t0, cpu_env, t0, t1);
3568        break;
3569    case OPC_VR54XX_MULSU:
3570        gen_helper_mulsu(t0, cpu_env, t0, t1);
3571        break;
3572    case OPC_VR54XX_MACC:
3573        gen_helper_macc(t0, cpu_env, t0, t1);
3574        break;
3575    case OPC_VR54XX_MACCU:
3576        gen_helper_maccu(t0, cpu_env, t0, t1);
3577        break;
3578    case OPC_VR54XX_MSAC:
3579        gen_helper_msac(t0, cpu_env, t0, t1);
3580        break;
3581    case OPC_VR54XX_MSACU:
3582        gen_helper_msacu(t0, cpu_env, t0, t1);
3583        break;
3584    case OPC_VR54XX_MULHI:
3585        gen_helper_mulhi(t0, cpu_env, t0, t1);
3586        break;
3587    case OPC_VR54XX_MULHIU:
3588        gen_helper_mulhiu(t0, cpu_env, t0, t1);
3589        break;
3590    case OPC_VR54XX_MULSHI:
3591        gen_helper_mulshi(t0, cpu_env, t0, t1);
3592        break;
3593    case OPC_VR54XX_MULSHIU:
3594        gen_helper_mulshiu(t0, cpu_env, t0, t1);
3595        break;
3596    case OPC_VR54XX_MACCHI:
3597        gen_helper_macchi(t0, cpu_env, t0, t1);
3598        break;
3599    case OPC_VR54XX_MACCHIU:
3600        gen_helper_macchiu(t0, cpu_env, t0, t1);
3601        break;
3602    case OPC_VR54XX_MSACHI:
3603        gen_helper_msachi(t0, cpu_env, t0, t1);
3604        break;
3605    case OPC_VR54XX_MSACHIU:
3606        gen_helper_msachiu(t0, cpu_env, t0, t1);
3607        break;
3608    default:
3609        MIPS_INVAL("mul vr54xx");
3610        generate_exception_end(ctx, EXCP_RI);
3611        goto out;
3612    }
3613    gen_store_gpr(t0, rd);
3614
3615 out:
3616    tcg_temp_free(t0);
3617    tcg_temp_free(t1);
3618}
3619
3620static void gen_cl (DisasContext *ctx, uint32_t opc,
3621                    int rd, int rs)
3622{
3623    TCGv t0;
3624
3625    if (rd == 0) {
3626        /* Treat as NOP. */
3627        return;
3628    }
3629    t0 = tcg_temp_new();
3630    gen_load_gpr(t0, rs);
3631    switch (opc) {
3632    case OPC_CLO:
3633    case R6_OPC_CLO:
3634        gen_helper_clo(cpu_gpr[rd], t0);
3635        break;
3636    case OPC_CLZ:
3637    case R6_OPC_CLZ:
3638        gen_helper_clz(cpu_gpr[rd], t0);
3639        break;
3640#if defined(TARGET_MIPS64)
3641    case OPC_DCLO:
3642    case R6_OPC_DCLO:
3643        gen_helper_dclo(cpu_gpr[rd], t0);
3644        break;
3645    case OPC_DCLZ:
3646    case R6_OPC_DCLZ:
3647        gen_helper_dclz(cpu_gpr[rd], t0);
3648        break;
3649#endif
3650    }
3651    tcg_temp_free(t0);
3652}
3653
3654/* Godson integer instructions */
3655static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3656                                 int rd, int rs, int rt)
3657{
3658    TCGv t0, t1;
3659
3660    if (rd == 0) {
3661        /* Treat as NOP. */
3662        return;
3663    }
3664
3665    switch (opc) {
3666    case OPC_MULT_G_2E:
3667    case OPC_MULT_G_2F:
3668    case OPC_MULTU_G_2E:
3669    case OPC_MULTU_G_2F:
3670#if defined(TARGET_MIPS64)
3671    case OPC_DMULT_G_2E:
3672    case OPC_DMULT_G_2F:
3673    case OPC_DMULTU_G_2E:
3674    case OPC_DMULTU_G_2F:
3675#endif
3676        t0 = tcg_temp_new();
3677        t1 = tcg_temp_new();
3678        break;
3679    default:
3680        t0 = tcg_temp_local_new();
3681        t1 = tcg_temp_local_new();
3682        break;
3683    }
3684
3685    gen_load_gpr(t0, rs);
3686    gen_load_gpr(t1, rt);
3687
3688    switch (opc) {
3689    case OPC_MULT_G_2E:
3690    case OPC_MULT_G_2F:
3691        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3692        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3693        break;
3694    case OPC_MULTU_G_2E:
3695    case OPC_MULTU_G_2F:
3696        tcg_gen_ext32u_tl(t0, t0);
3697        tcg_gen_ext32u_tl(t1, t1);
3698        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3699        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3700        break;
3701    case OPC_DIV_G_2E:
3702    case OPC_DIV_G_2F:
3703        {
3704            TCGLabel *l1 = gen_new_label();
3705            TCGLabel *l2 = gen_new_label();
3706            TCGLabel *l3 = gen_new_label();
3707            tcg_gen_ext32s_tl(t0, t0);
3708            tcg_gen_ext32s_tl(t1, t1);
3709            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3710            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3711            tcg_gen_br(l3);
3712            gen_set_label(l1);
3713            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3714            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3715            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3716            tcg_gen_br(l3);
3717            gen_set_label(l2);
3718            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3719            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3720            gen_set_label(l3);
3721        }
3722        break;
3723    case OPC_DIVU_G_2E:
3724    case OPC_DIVU_G_2F:
3725        {
3726            TCGLabel *l1 = gen_new_label();
3727            TCGLabel *l2 = gen_new_label();
3728            tcg_gen_ext32u_tl(t0, t0);
3729            tcg_gen_ext32u_tl(t1, t1);
3730            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3731            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3732            tcg_gen_br(l2);
3733            gen_set_label(l1);
3734            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3735            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3736            gen_set_label(l2);
3737        }
3738        break;
3739    case OPC_MOD_G_2E:
3740    case OPC_MOD_G_2F:
3741        {
3742            TCGLabel *l1 = gen_new_label();
3743            TCGLabel *l2 = gen_new_label();
3744            TCGLabel *l3 = gen_new_label();
3745            tcg_gen_ext32u_tl(t0, t0);
3746            tcg_gen_ext32u_tl(t1, t1);
3747            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3748            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3749            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3750            gen_set_label(l1);
3751            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3752            tcg_gen_br(l3);
3753            gen_set_label(l2);
3754            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3755            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3756            gen_set_label(l3);
3757        }
3758        break;
3759    case OPC_MODU_G_2E:
3760    case OPC_MODU_G_2F:
3761        {
3762            TCGLabel *l1 = gen_new_label();
3763            TCGLabel *l2 = gen_new_label();
3764            tcg_gen_ext32u_tl(t0, t0);
3765            tcg_gen_ext32u_tl(t1, t1);
3766            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3767            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3768            tcg_gen_br(l2);
3769            gen_set_label(l1);
3770            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3771            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3772            gen_set_label(l2);
3773        }
3774        break;
3775#if defined(TARGET_MIPS64)
3776    case OPC_DMULT_G_2E:
3777    case OPC_DMULT_G_2F:
3778        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3779        break;
3780    case OPC_DMULTU_G_2E:
3781    case OPC_DMULTU_G_2F:
3782        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3783        break;
3784    case OPC_DDIV_G_2E:
3785    case OPC_DDIV_G_2F:
3786        {
3787            TCGLabel *l1 = gen_new_label();
3788            TCGLabel *l2 = gen_new_label();
3789            TCGLabel *l3 = gen_new_label();
3790            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3791            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3792            tcg_gen_br(l3);
3793            gen_set_label(l1);
3794            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3795            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3796            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3797            tcg_gen_br(l3);
3798            gen_set_label(l2);
3799            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3800            gen_set_label(l3);
3801        }
3802        break;
3803    case OPC_DDIVU_G_2E:
3804    case OPC_DDIVU_G_2F:
3805        {
3806            TCGLabel *l1 = gen_new_label();
3807            TCGLabel *l2 = gen_new_label();
3808            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3809            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3810            tcg_gen_br(l2);
3811            gen_set_label(l1);
3812            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3813            gen_set_label(l2);
3814        }
3815        break;
3816    case OPC_DMOD_G_2E:
3817    case OPC_DMOD_G_2F:
3818        {
3819            TCGLabel *l1 = gen_new_label();
3820            TCGLabel *l2 = gen_new_label();
3821            TCGLabel *l3 = gen_new_label();
3822            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3823            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3824            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3825            gen_set_label(l1);
3826            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3827            tcg_gen_br(l3);
3828            gen_set_label(l2);
3829            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3830            gen_set_label(l3);
3831        }
3832        break;
3833    case OPC_DMODU_G_2E:
3834    case OPC_DMODU_G_2F:
3835        {
3836            TCGLabel *l1 = gen_new_label();
3837            TCGLabel *l2 = gen_new_label();
3838            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3839            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3840            tcg_gen_br(l2);
3841            gen_set_label(l1);
3842            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3843            gen_set_label(l2);
3844        }
3845        break;
3846#endif
3847    }
3848
3849    tcg_temp_free(t0);
3850    tcg_temp_free(t1);
3851}
3852
3853/* Loongson multimedia instructions */
3854static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3855{
3856    uint32_t opc, shift_max;
3857    TCGv_i64 t0, t1;
3858
3859    opc = MASK_LMI(ctx->opcode);
3860    switch (opc) {
3861    case OPC_ADD_CP2:
3862    case OPC_SUB_CP2:
3863    case OPC_DADD_CP2:
3864    case OPC_DSUB_CP2:
3865        t0 = tcg_temp_local_new_i64();
3866        t1 = tcg_temp_local_new_i64();
3867        break;
3868    default:
3869        t0 = tcg_temp_new_i64();
3870        t1 = tcg_temp_new_i64();
3871        break;
3872    }
3873
3874    gen_load_fpr64(ctx, t0, rs);
3875    gen_load_fpr64(ctx, t1, rt);
3876
3877#define LMI_HELPER(UP, LO) \
3878    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3879#define LMI_HELPER_1(UP, LO) \
3880    case OPC_##UP: gen_helper_##LO(t0, t0); break
3881#define LMI_DIRECT(UP, LO, OP) \
3882    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3883
3884    switch (opc) {
3885    LMI_HELPER(PADDSH, paddsh);
3886    LMI_HELPER(PADDUSH, paddush);
3887    LMI_HELPER(PADDH, paddh);
3888    LMI_HELPER(PADDW, paddw);
3889    LMI_HELPER(PADDSB, paddsb);
3890    LMI_HELPER(PADDUSB, paddusb);
3891    LMI_HELPER(PADDB, paddb);
3892
3893    LMI_HELPER(PSUBSH, psubsh);
3894    LMI_HELPER(PSUBUSH, psubush);
3895    LMI_HELPER(PSUBH, psubh);
3896    LMI_HELPER(PSUBW, psubw);
3897    LMI_HELPER(PSUBSB, psubsb);
3898    LMI_HELPER(PSUBUSB, psubusb);
3899    LMI_HELPER(PSUBB, psubb);
3900
3901    LMI_HELPER(PSHUFH, pshufh);
3902    LMI_HELPER(PACKSSWH, packsswh);
3903    LMI_HELPER(PACKSSHB, packsshb);
3904    LMI_HELPER(PACKUSHB, packushb);
3905
3906    LMI_HELPER(PUNPCKLHW, punpcklhw);
3907    LMI_HELPER(PUNPCKHHW, punpckhhw);
3908    LMI_HELPER(PUNPCKLBH, punpcklbh);
3909    LMI_HELPER(PUNPCKHBH, punpckhbh);
3910    LMI_HELPER(PUNPCKLWD, punpcklwd);
3911    LMI_HELPER(PUNPCKHWD, punpckhwd);
3912
3913    LMI_HELPER(PAVGH, pavgh);
3914    LMI_HELPER(PAVGB, pavgb);
3915    LMI_HELPER(PMAXSH, pmaxsh);
3916    LMI_HELPER(PMINSH, pminsh);
3917    LMI_HELPER(PMAXUB, pmaxub);
3918    LMI_HELPER(PMINUB, pminub);
3919
3920    LMI_HELPER(PCMPEQW, pcmpeqw);
3921    LMI_HELPER(PCMPGTW, pcmpgtw);
3922    LMI_HELPER(PCMPEQH, pcmpeqh);
3923    LMI_HELPER(PCMPGTH, pcmpgth);
3924    LMI_HELPER(PCMPEQB, pcmpeqb);
3925    LMI_HELPER(PCMPGTB, pcmpgtb);
3926
3927    LMI_HELPER(PSLLW, psllw);
3928    LMI_HELPER(PSLLH, psllh);
3929    LMI_HELPER(PSRLW, psrlw);
3930    LMI_HELPER(PSRLH, psrlh);
3931    LMI_HELPER(PSRAW, psraw);
3932    LMI_HELPER(PSRAH, psrah);
3933
3934    LMI_HELPER(PMULLH, pmullh);
3935    LMI_HELPER(PMULHH, pmulhh);
3936    LMI_HELPER(PMULHUH, pmulhuh);
3937    LMI_HELPER(PMADDHW, pmaddhw);
3938
3939    LMI_HELPER(PASUBUB, pasubub);
3940    LMI_HELPER_1(BIADD, biadd);
3941    LMI_HELPER_1(PMOVMSKB, pmovmskb);
3942
3943    LMI_DIRECT(PADDD, paddd, add);
3944    LMI_DIRECT(PSUBD, psubd, sub);
3945    LMI_DIRECT(XOR_CP2, xor, xor);
3946    LMI_DIRECT(NOR_CP2, nor, nor);
3947    LMI_DIRECT(AND_CP2, and, and);
3948    LMI_DIRECT(PANDN, pandn, andc);
3949    LMI_DIRECT(OR, or, or);
3950
3951    case OPC_PINSRH_0:
3952        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3953        break;
3954    case OPC_PINSRH_1:
3955        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3956        break;
3957    case OPC_PINSRH_2:
3958        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3959        break;
3960    case OPC_PINSRH_3:
3961        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3962        break;
3963
3964    case OPC_PEXTRH:
3965        tcg_gen_andi_i64(t1, t1, 3);
3966        tcg_gen_shli_i64(t1, t1, 4);
3967        tcg_gen_shr_i64(t0, t0, t1);
3968        tcg_gen_ext16u_i64(t0, t0);
3969        break;
3970
3971    case OPC_ADDU_CP2:
3972        tcg_gen_add_i64(t0, t0, t1);
3973        tcg_gen_ext32s_i64(t0, t0);
3974        break;
3975    case OPC_SUBU_CP2:
3976        tcg_gen_sub_i64(t0, t0, t1);
3977        tcg_gen_ext32s_i64(t0, t0);
3978        break;
3979
3980    case OPC_SLL_CP2:
3981        shift_max = 32;
3982        goto do_shift;
3983    case OPC_SRL_CP2:
3984        shift_max = 32;
3985        goto do_shift;
3986    case OPC_SRA_CP2:
3987        shift_max = 32;
3988        goto do_shift;
3989    case OPC_DSLL_CP2:
3990        shift_max = 64;
3991        goto do_shift;
3992    case OPC_DSRL_CP2:
3993        shift_max = 64;
3994        goto do_shift;
3995    case OPC_DSRA_CP2:
3996        shift_max = 64;
3997        goto do_shift;
3998    do_shift:
3999        /* Make sure shift count isn't TCG undefined behaviour.  */
4000        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4001
4002        switch (opc) {
4003        case OPC_SLL_CP2:
4004        case OPC_DSLL_CP2:
4005            tcg_gen_shl_i64(t0, t0, t1);
4006            break;
4007        case OPC_SRA_CP2:
4008        case OPC_DSRA_CP2:
4009            /* Since SRA is UndefinedResult without sign-extended inputs,
4010               we can treat SRA and DSRA the same.  */
4011            tcg_gen_sar_i64(t0, t0, t1);
4012            break;
4013        case OPC_SRL_CP2:
4014            /* We want to shift in zeros for SRL; zero-extend first.  */
4015            tcg_gen_ext32u_i64(t0, t0);
4016            /* FALLTHRU */
4017        case OPC_DSRL_CP2:
4018            tcg_gen_shr_i64(t0, t0, t1);
4019            break;
4020        }
4021
4022        if (shift_max == 32) {
4023            tcg_gen_ext32s_i64(t0, t0);
4024        }
4025
4026        /* Shifts larger than MAX produce zero.  */
4027        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4028        tcg_gen_neg_i64(t1, t1);
4029        tcg_gen_and_i64(t0, t0, t1);
4030        break;
4031
4032    case OPC_ADD_CP2:
4033    case OPC_DADD_CP2:
4034        {
4035            TCGv_i64 t2 = tcg_temp_new_i64();
4036            TCGLabel *lab = gen_new_label();
4037
4038            tcg_gen_mov_i64(t2, t0);
4039            tcg_gen_add_i64(t0, t1, t2);
4040            if (opc == OPC_ADD_CP2) {
4041                tcg_gen_ext32s_i64(t0, t0);
4042            }
4043            tcg_gen_xor_i64(t1, t1, t2);
4044            tcg_gen_xor_i64(t2, t2, t0);
4045            tcg_gen_andc_i64(t1, t2, t1);
4046            tcg_temp_free_i64(t2);
4047            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4048            generate_exception(ctx, EXCP_OVERFLOW);
4049            gen_set_label(lab);
4050            break;
4051        }
4052
4053    case OPC_SUB_CP2:
4054    case OPC_DSUB_CP2:
4055        {
4056            TCGv_i64 t2 = tcg_temp_new_i64();
4057            TCGLabel *lab = gen_new_label();
4058
4059            tcg_gen_mov_i64(t2, t0);
4060            tcg_gen_sub_i64(t0, t1, t2);
4061            if (opc == OPC_SUB_CP2) {
4062                tcg_gen_ext32s_i64(t0, t0);
4063            }
4064            tcg_gen_xor_i64(t1, t1, t2);
4065            tcg_gen_xor_i64(t2, t2, t0);
4066            tcg_gen_and_i64(t1, t1, t2);
4067            tcg_temp_free_i64(t2);
4068            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4069            generate_exception(ctx, EXCP_OVERFLOW);
4070            gen_set_label(lab);
4071            break;
4072        }
4073
4074    case OPC_PMULUW:
4075        tcg_gen_ext32u_i64(t0, t0);
4076        tcg_gen_ext32u_i64(t1, t1);
4077        tcg_gen_mul_i64(t0, t0, t1);
4078        break;
4079
4080    case OPC_SEQU_CP2:
4081    case OPC_SEQ_CP2:
4082    case OPC_SLTU_CP2:
4083    case OPC_SLT_CP2:
4084    case OPC_SLEU_CP2:
4085    case OPC_SLE_CP2:
4086        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4087           FD field is the CC field?  */
4088    default:
4089        MIPS_INVAL("loongson_cp2");
4090        generate_exception_end(ctx, EXCP_RI);
4091        return;
4092    }
4093
4094#undef LMI_HELPER
4095#undef LMI_DIRECT
4096
4097    gen_store_fpr64(ctx, t0, rd);
4098
4099    tcg_temp_free_i64(t0);
4100    tcg_temp_free_i64(t1);
4101}
4102
4103/* Traps */
4104static void gen_trap (DisasContext *ctx, uint32_t opc,
4105                      int rs, int rt, int16_t imm)
4106{
4107    int cond;
4108    TCGv t0 = tcg_temp_new();
4109    TCGv t1 = tcg_temp_new();
4110
4111    cond = 0;
4112    /* Load needed operands */
4113    switch (opc) {
4114    case OPC_TEQ:
4115    case OPC_TGE:
4116    case OPC_TGEU:
4117    case OPC_TLT:
4118    case OPC_TLTU:
4119    case OPC_TNE:
4120        /* Compare two registers */
4121        if (rs != rt) {
4122            gen_load_gpr(t0, rs);
4123            gen_load_gpr(t1, rt);
4124            cond = 1;
4125        }
4126        break;
4127    case OPC_TEQI:
4128    case OPC_TGEI:
4129    case OPC_TGEIU:
4130    case OPC_TLTI:
4131    case OPC_TLTIU:
4132    case OPC_TNEI:
4133        /* Compare register to immediate */
4134        if (rs != 0 || imm != 0) {
4135            gen_load_gpr(t0, rs);
4136            tcg_gen_movi_tl(t1, (int32_t)imm);
4137            cond = 1;
4138        }
4139        break;
4140    }
4141    if (cond == 0) {
4142        switch (opc) {
4143        case OPC_TEQ:   /* rs == rs */
4144        case OPC_TEQI:  /* r0 == 0  */
4145        case OPC_TGE:   /* rs >= rs */
4146        case OPC_TGEI:  /* r0 >= 0  */
4147        case OPC_TGEU:  /* rs >= rs unsigned */
4148        case OPC_TGEIU: /* r0 >= 0  unsigned */
4149            /* Always trap */
4150            generate_exception_end(ctx, EXCP_TRAP);
4151            break;
4152        case OPC_TLT:   /* rs < rs           */
4153        case OPC_TLTI:  /* r0 < 0            */
4154        case OPC_TLTU:  /* rs < rs unsigned  */
4155        case OPC_TLTIU: /* r0 < 0  unsigned  */
4156        case OPC_TNE:   /* rs != rs          */
4157        case OPC_TNEI:  /* r0 != 0           */
4158            /* Never trap: treat as NOP. */
4159            break;
4160        }
4161    } else {
4162        TCGLabel *l1 = gen_new_label();
4163
4164        switch (opc) {
4165        case OPC_TEQ:
4166        case OPC_TEQI:
4167            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4168            break;
4169        case OPC_TGE:
4170        case OPC_TGEI:
4171            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4172            break;
4173        case OPC_TGEU:
4174        case OPC_TGEIU:
4175            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4176            break;
4177        case OPC_TLT:
4178        case OPC_TLTI:
4179            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4180            break;
4181        case OPC_TLTU:
4182        case OPC_TLTIU:
4183            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4184            break;
4185        case OPC_TNE:
4186        case OPC_TNEI:
4187            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4188            break;
4189        }
4190        generate_exception(ctx, EXCP_TRAP);
4191        gen_set_label(l1);
4192    }
4193    tcg_temp_free(t0);
4194    tcg_temp_free(t1);
4195}
4196
4197static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4198{
4199    if (unlikely(ctx->singlestep_enabled)) {
4200        return false;
4201    }
4202
4203#ifndef CONFIG_USER_ONLY
4204    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4205#else
4206    return true;
4207#endif
4208}
4209
4210static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4211{
4212    if (use_goto_tb(ctx, dest)) {
4213        tcg_gen_goto_tb(n);
4214        gen_save_pc(dest);
4215        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4216    } else {
4217        gen_save_pc(dest);
4218        if (ctx->singlestep_enabled) {
4219            save_cpu_state(ctx, 0);
4220            gen_helper_raise_exception_debug(cpu_env);
4221        }
4222        tcg_gen_exit_tb(0);
4223    }
4224}
4225
4226/* Branches (before delay slot) */
4227static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4228                                int insn_bytes,
4229                                int rs, int rt, int32_t offset,
4230                                int delayslot_size)
4231{
4232    target_ulong btgt = -1;
4233    int blink = 0;
4234    int bcond_compute = 0;
4235    TCGv t0 = tcg_temp_new();
4236    TCGv t1 = tcg_temp_new();
4237
4238    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4239#ifdef MIPS_DEBUG_DISAS
4240        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4241                  TARGET_FMT_lx "\n", ctx->pc);
4242#endif
4243        generate_exception_end(ctx, EXCP_RI);
4244        goto out;
4245    }
4246
4247    /* Load needed operands */
4248    switch (opc) {
4249    case OPC_BEQ:
4250    case OPC_BEQL:
4251    case OPC_BNE:
4252    case OPC_BNEL:
4253        /* Compare two registers */
4254        if (rs != rt) {
4255            gen_load_gpr(t0, rs);
4256            gen_load_gpr(t1, rt);
4257            bcond_compute = 1;
4258        }
4259        btgt = ctx->pc + insn_bytes + offset;
4260        break;
4261    case OPC_BGEZ:
4262    case OPC_BGEZAL:
4263    case OPC_BGEZALL:
4264    case OPC_BGEZL:
4265    case OPC_BGTZ:
4266    case OPC_BGTZL:
4267    case OPC_BLEZ:
4268    case OPC_BLEZL:
4269    case OPC_BLTZ:
4270    case OPC_BLTZAL:
4271    case OPC_BLTZALL:
4272    case OPC_BLTZL:
4273        /* Compare to zero */
4274        if (rs != 0) {
4275            gen_load_gpr(t0, rs);
4276            bcond_compute = 1;
4277        }
4278        btgt = ctx->pc + insn_bytes + offset;
4279        break;
4280    case OPC_BPOSGE32:
4281#if defined(TARGET_MIPS64)
4282    case OPC_BPOSGE64:
4283        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4284#else
4285        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4286#endif
4287        bcond_compute = 1;
4288        btgt = ctx->pc + insn_bytes + offset;
4289        break;
4290    case OPC_J:
4291    case OPC_JAL:
4292    case OPC_JALX:
4293        /* Jump to immediate */
4294        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4295        break;
4296    case OPC_JR:
4297    case OPC_JALR:
4298        /* Jump to register */
4299        if (offset != 0 && offset != 16) {
4300            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4301               others are reserved. */
4302            MIPS_INVAL("jump hint");
4303            generate_exception_end(ctx, EXCP_RI);
4304            goto out;
4305        }
4306        gen_load_gpr(btarget, rs);
4307        break;
4308    default:
4309        MIPS_INVAL("branch/jump");
4310        generate_exception_end(ctx, EXCP_RI);
4311        goto out;
4312    }
4313    if (bcond_compute == 0) {
4314        /* No condition to be computed */
4315        switch (opc) {
4316        case OPC_BEQ:     /* rx == rx        */
4317        case OPC_BEQL:    /* rx == rx likely */
4318        case OPC_BGEZ:    /* 0 >= 0          */
4319        case OPC_BGEZL:   /* 0 >= 0 likely   */
4320        case OPC_BLEZ:    /* 0 <= 0          */
4321        case OPC_BLEZL:   /* 0 <= 0 likely   */
4322            /* Always take */
4323            ctx->hflags |= MIPS_HFLAG_B;
4324            break;
4325        case OPC_BGEZAL:  /* 0 >= 0          */
4326        case OPC_BGEZALL: /* 0 >= 0 likely   */
4327            /* Always take and link */
4328            blink = 31;
4329            ctx->hflags |= MIPS_HFLAG_B;
4330            break;
4331        case OPC_BNE:     /* rx != rx        */
4332        case OPC_BGTZ:    /* 0 > 0           */
4333        case OPC_BLTZ:    /* 0 < 0           */
4334            /* Treat as NOP. */
4335            goto out;
4336        case OPC_BLTZAL:  /* 0 < 0           */
4337            /* Handle as an unconditional branch to get correct delay
4338               slot checking.  */
4339            blink = 31;
4340            btgt = ctx->pc + insn_bytes + delayslot_size;
4341            ctx->hflags |= MIPS_HFLAG_B;
4342            break;
4343        case OPC_BLTZALL: /* 0 < 0 likely */
4344            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4345            /* Skip the instruction in the delay slot */
4346            ctx->pc += 4;
4347            goto out;
4348        case OPC_BNEL:    /* rx != rx likely */
4349        case OPC_BGTZL:   /* 0 > 0 likely */
4350        case OPC_BLTZL:   /* 0 < 0 likely */
4351            /* Skip the instruction in the delay slot */
4352            ctx->pc += 4;
4353            goto out;
4354        case OPC_J:
4355            ctx->hflags |= MIPS_HFLAG_B;
4356            break;
4357        case OPC_JALX:
4358            ctx->hflags |= MIPS_HFLAG_BX;
4359            /* Fallthrough */
4360        case OPC_JAL:
4361            blink = 31;
4362            ctx->hflags |= MIPS_HFLAG_B;
4363            break;
4364        case OPC_JR:
4365            ctx->hflags |= MIPS_HFLAG_BR;
4366            break;
4367        case OPC_JALR:
4368            blink = rt;
4369            ctx->hflags |= MIPS_HFLAG_BR;
4370            break;
4371        default:
4372            MIPS_INVAL("branch/jump");
4373            generate_exception_end(ctx, EXCP_RI);
4374            goto out;
4375        }
4376    } else {
4377        switch (opc) {
4378        case OPC_BEQ:
4379            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4380            goto not_likely;
4381        case OPC_BEQL:
4382            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4383            goto likely;
4384        case OPC_BNE:
4385            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4386            goto not_likely;
4387        case OPC_BNEL:
4388            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4389            goto likely;
4390        case OPC_BGEZ:
4391            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4392            goto not_likely;
4393        case OPC_BGEZL:
4394            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4395            goto likely;
4396        case OPC_BGEZAL:
4397            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4398            blink = 31;
4399            goto not_likely;
4400        case OPC_BGEZALL:
4401            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4402            blink = 31;
4403            goto likely;
4404        case OPC_BGTZ:
4405            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4406            goto not_likely;
4407        case OPC_BGTZL:
4408            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4409            goto likely;
4410        case OPC_BLEZ:
4411            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4412            goto not_likely;
4413        case OPC_BLEZL:
4414            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4415            goto likely;
4416        case OPC_BLTZ:
4417            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4418            goto not_likely;
4419        case OPC_BLTZL:
4420            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4421            goto likely;
4422        case OPC_BPOSGE32:
4423            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4424            goto not_likely;
4425#if defined(TARGET_MIPS64)
4426        case OPC_BPOSGE64:
4427            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4428            goto not_likely;
4429#endif
4430        case OPC_BLTZAL:
4431            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4432            blink = 31;
4433        not_likely:
4434            ctx->hflags |= MIPS_HFLAG_BC;
4435            break;
4436        case OPC_BLTZALL:
4437            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4438            blink = 31;
4439        likely:
4440            ctx->hflags |= MIPS_HFLAG_BL;
4441            break;
4442        default:
4443            MIPS_INVAL("conditional branch/jump");
4444            generate_exception_end(ctx, EXCP_RI);
4445            goto out;
4446        }
4447    }
4448
4449    ctx->btarget = btgt;
4450
4451    switch (delayslot_size) {
4452    case 2:
4453        ctx->hflags |= MIPS_HFLAG_BDS16;
4454        break;
4455    case 4:
4456        ctx->hflags |= MIPS_HFLAG_BDS32;
4457        break;
4458    }
4459
4460    if (blink > 0) {
4461        int post_delay = insn_bytes + delayslot_size;
4462        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4463
4464        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4465    }
4466
4467 out:
4468    if (insn_bytes == 2)
4469        ctx->hflags |= MIPS_HFLAG_B16;
4470    tcg_temp_free(t0);
4471    tcg_temp_free(t1);
4472}
4473
4474/* special3 bitfield operations */
4475static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4476                        int rs, int lsb, int msb)
4477{
4478    TCGv t0 = tcg_temp_new();
4479    TCGv t1 = tcg_temp_new();
4480
4481    gen_load_gpr(t1, rs);
4482    switch (opc) {
4483    case OPC_EXT:
4484        if (lsb + msb > 31) {
4485            goto fail;
4486        }
4487        tcg_gen_shri_tl(t0, t1, lsb);
4488        if (msb != 31) {
4489            tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4490        } else {
4491            tcg_gen_ext32s_tl(t0, t0);
4492        }
4493        break;
4494#if defined(TARGET_MIPS64)
4495    case OPC_DEXTU:
4496        lsb += 32;
4497        goto do_dext;
4498    case OPC_DEXTM:
4499        msb += 32;
4500        goto do_dext;
4501    case OPC_DEXT:
4502    do_dext:
4503        if (lsb + msb > 63) {
4504            goto fail;
4505        }
4506        tcg_gen_shri_tl(t0, t1, lsb);
4507        if (msb != 63) {
4508            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4509        }
4510        break;
4511#endif
4512    case OPC_INS:
4513        if (lsb > msb) {
4514            goto fail;
4515        }
4516        gen_load_gpr(t0, rt);
4517        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4518        tcg_gen_ext32s_tl(t0, t0);
4519        break;
4520#if defined(TARGET_MIPS64)
4521    case OPC_DINSU:
4522        lsb += 32;
4523        /* FALLTHRU */
4524    case OPC_DINSM:
4525        msb += 32;
4526        /* FALLTHRU */
4527    case OPC_DINS:
4528        if (lsb > msb) {
4529            goto fail;
4530        }
4531        gen_load_gpr(t0, rt);
4532        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4533        break;
4534#endif
4535    default:
4536fail:
4537        MIPS_INVAL("bitops");
4538        generate_exception_end(ctx, EXCP_RI);
4539        tcg_temp_free(t0);
4540        tcg_temp_free(t1);
4541        return;
4542    }
4543    gen_store_gpr(t0, rt);
4544    tcg_temp_free(t0);
4545    tcg_temp_free(t1);
4546}
4547
4548static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4549{
4550    TCGv t0;
4551
4552    if (rd == 0) {
4553        /* If no destination, treat it as a NOP. */
4554        return;
4555    }
4556
4557    t0 = tcg_temp_new();
4558    gen_load_gpr(t0, rt);
4559    switch (op2) {
4560    case OPC_WSBH:
4561        {
4562            TCGv t1 = tcg_temp_new();
4563
4564            tcg_gen_shri_tl(t1, t0, 8);
4565            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4566            tcg_gen_shli_tl(t0, t0, 8);
4567            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4568            tcg_gen_or_tl(t0, t0, t1);
4569            tcg_temp_free(t1);
4570            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4571        }
4572        break;
4573    case OPC_SEB:
4574        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4575        break;
4576    case OPC_SEH:
4577        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4578        break;
4579#if defined(TARGET_MIPS64)
4580    case OPC_DSBH:
4581        {
4582            TCGv t1 = tcg_temp_new();
4583
4584            tcg_gen_shri_tl(t1, t0, 8);
4585            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4586            tcg_gen_shli_tl(t0, t0, 8);
4587            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4588            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4589            tcg_temp_free(t1);
4590        }
4591        break;
4592    case OPC_DSHD:
4593        {
4594            TCGv t1 = tcg_temp_new();
4595
4596            tcg_gen_shri_tl(t1, t0, 16);
4597            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4598            tcg_gen_shli_tl(t0, t0, 16);
4599            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4600            tcg_gen_or_tl(t0, t0, t1);
4601            tcg_gen_shri_tl(t1, t0, 32);
4602            tcg_gen_shli_tl(t0, t0, 32);
4603            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4604            tcg_temp_free(t1);
4605        }
4606        break;
4607#endif
4608    default:
4609        MIPS_INVAL("bsfhl");
4610        generate_exception_end(ctx, EXCP_RI);
4611        tcg_temp_free(t0);
4612        return;
4613    }
4614    tcg_temp_free(t0);
4615}
4616
4617static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4618                    int imm2)
4619{
4620    TCGv t0;
4621    TCGv t1;
4622    if (rd == 0) {
4623        /* Treat as NOP. */
4624        return;
4625    }
4626    t0 = tcg_temp_new();
4627    t1 = tcg_temp_new();
4628    gen_load_gpr(t0, rs);
4629    gen_load_gpr(t1, rt);
4630    tcg_gen_shli_tl(t0, t0, imm2 + 1);
4631    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4632    if (opc == OPC_LSA) {
4633        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4634    }
4635
4636    tcg_temp_free(t1);
4637    tcg_temp_free(t0);
4638
4639    return;
4640}
4641
4642static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4643                      int bp)
4644{
4645    TCGv t0;
4646    if (rd == 0) {
4647        /* Treat as NOP. */
4648        return;
4649    }
4650    t0 = tcg_temp_new();
4651    gen_load_gpr(t0, rt);
4652    if (bp == 0) {
4653        switch (opc) {
4654        case OPC_ALIGN:
4655            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4656            break;
4657#if defined(TARGET_MIPS64)
4658        case OPC_DALIGN:
4659            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4660            break;
4661#endif
4662        }
4663    } else {
4664        TCGv t1 = tcg_temp_new();
4665        gen_load_gpr(t1, rs);
4666        switch (opc) {
4667        case OPC_ALIGN:
4668            {
4669                TCGv_i64 t2 = tcg_temp_new_i64();
4670                tcg_gen_concat_tl_i64(t2, t1, t0);
4671                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4672                gen_move_low32(cpu_gpr[rd], t2);
4673                tcg_temp_free_i64(t2);
4674            }
4675            break;
4676#if defined(TARGET_MIPS64)
4677        case OPC_DALIGN:
4678            tcg_gen_shli_tl(t0, t0, 8 * bp);
4679            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4680            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4681            break;
4682#endif
4683        }
4684        tcg_temp_free(t1);
4685    }
4686
4687    tcg_temp_free(t0);
4688}
4689
4690static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4691{
4692    TCGv t0;
4693    if (rd == 0) {
4694        /* Treat as NOP. */
4695        return;
4696    }
4697    t0 = tcg_temp_new();
4698    gen_load_gpr(t0, rt);
4699    switch (opc) {
4700    case OPC_BITSWAP:
4701        gen_helper_bitswap(cpu_gpr[rd], t0);
4702        break;
4703#if defined(TARGET_MIPS64)
4704    case OPC_DBITSWAP:
4705        gen_helper_dbitswap(cpu_gpr[rd], t0);
4706        break;
4707#endif
4708    }
4709    tcg_temp_free(t0);
4710}
4711
4712#ifndef CONFIG_USER_ONLY
4713/* CP0 (MMU and control) */
4714static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4715{
4716    TCGv_i64 t0 = tcg_temp_new_i64();
4717    TCGv_i64 t1 = tcg_temp_new_i64();
4718
4719    tcg_gen_ext_tl_i64(t0, arg);
4720    tcg_gen_ld_i64(t1, cpu_env, off);
4721#if defined(TARGET_MIPS64)
4722    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4723#else
4724    tcg_gen_concat32_i64(t1, t1, t0);
4725#endif
4726    tcg_gen_st_i64(t1, cpu_env, off);
4727    tcg_temp_free_i64(t1);
4728    tcg_temp_free_i64(t0);
4729}
4730
4731static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4732{
4733    TCGv_i64 t0 = tcg_temp_new_i64();
4734    TCGv_i64 t1 = tcg_temp_new_i64();
4735
4736    tcg_gen_ext_tl_i64(t0, arg);
4737    tcg_gen_ld_i64(t1, cpu_env, off);
4738    tcg_gen_concat32_i64(t1, t1, t0);
4739    tcg_gen_st_i64(t1, cpu_env, off);
4740    tcg_temp_free_i64(t1);
4741    tcg_temp_free_i64(t0);
4742}
4743
4744static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4745{
4746    TCGv_i64 t0 = tcg_temp_new_i64();
4747
4748    tcg_gen_ld_i64(t0, cpu_env, off);
4749#if defined(TARGET_MIPS64)
4750    tcg_gen_shri_i64(t0, t0, 30);
4751#else
4752    tcg_gen_shri_i64(t0, t0, 32);
4753#endif
4754    gen_move_low32(arg, t0);
4755    tcg_temp_free_i64(t0);
4756}
4757
4758static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4759{
4760    TCGv_i64 t0 = tcg_temp_new_i64();
4761
4762    tcg_gen_ld_i64(t0, cpu_env, off);
4763    tcg_gen_shri_i64(t0, t0, 32 + shift);
4764    gen_move_low32(arg, t0);
4765    tcg_temp_free_i64(t0);
4766}
4767
4768static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4769{
4770    TCGv_i32 t0 = tcg_temp_new_i32();
4771
4772    tcg_gen_ld_i32(t0, cpu_env, off);
4773    tcg_gen_ext_i32_tl(arg, t0);
4774    tcg_temp_free_i32(t0);
4775}
4776
4777static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4778{
4779    tcg_gen_ld_tl(arg, cpu_env, off);
4780    tcg_gen_ext32s_tl(arg, arg);
4781}
4782
4783static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4784{
4785    TCGv_i32 t0 = tcg_temp_new_i32();
4786
4787    tcg_gen_trunc_tl_i32(t0, arg);
4788    tcg_gen_st_i32(t0, cpu_env, off);
4789    tcg_temp_free_i32(t0);
4790}
4791
4792#define CP0_CHECK(c)                            \
4793    do {                                        \
4794        if (!(c)) {                             \
4795            goto cp0_unimplemented;             \
4796        }                                       \
4797    } while (0)
4798
4799static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4800{
4801    const char *rn = "invalid";
4802
4803    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4804
4805    switch (reg) {
4806    case 2:
4807        switch (sel) {
4808        case 0:
4809            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4810            rn = "EntryLo0";
4811            break;
4812        default:
4813            goto cp0_unimplemented;
4814        }
4815        break;
4816    case 3:
4817        switch (sel) {
4818        case 0:
4819            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4820            rn = "EntryLo1";
4821            break;
4822        default:
4823            goto cp0_unimplemented;
4824        }
4825        break;
4826    case 17:
4827        switch (sel) {
4828        case 0:
4829            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4830                             ctx->CP0_LLAddr_shift);
4831            rn = "LLAddr";
4832            break;
4833        case 1:
4834            CP0_CHECK(ctx->mrp);
4835            gen_helper_mfhc0_maar(arg, cpu_env);
4836            rn = "MAAR";
4837            break;
4838        default:
4839            goto cp0_unimplemented;
4840        }
4841        break;
4842    case 28:
4843        switch (sel) {
4844        case 0:
4845        case 2:
4846        case 4:
4847        case 6:
4848            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4849            rn = "TagLo";
4850            break;
4851        default:
4852            goto cp0_unimplemented;
4853        }
4854        break;
4855    default:
4856        goto cp0_unimplemented;
4857    }
4858
4859    (void)rn; /* avoid a compiler warning */
4860    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4861    return;
4862
4863cp0_unimplemented:
4864    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4865    tcg_gen_movi_tl(arg, 0);
4866}
4867
4868static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4869{
4870    const char *rn = "invalid";
4871    uint64_t mask = ctx->PAMask >> 36;
4872
4873    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4874
4875    switch (reg) {
4876    case 2:
4877        switch (sel) {
4878        case 0:
4879            tcg_gen_andi_tl(arg, arg, mask);
4880            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4881            rn = "EntryLo0";
4882            break;
4883        default:
4884            goto cp0_unimplemented;
4885        }
4886        break;
4887    case 3:
4888        switch (sel) {
4889        case 0:
4890            tcg_gen_andi_tl(arg, arg, mask);
4891            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4892            rn = "EntryLo1";
4893            break;
4894        default:
4895            goto cp0_unimplemented;
4896        }
4897        break;
4898    case 17:
4899        switch (sel) {
4900        case 0:
4901            /* LLAddr is read-only (the only exception is bit 0 if LLB is
4902               supported); the CP0_LLAddr_rw_bitmask does not seem to be
4903               relevant for modern MIPS cores supporting MTHC0, therefore
4904               treating MTHC0 to LLAddr as NOP. */
4905            rn = "LLAddr";
4906            break;
4907        case 1:
4908            CP0_CHECK(ctx->mrp);
4909            gen_helper_mthc0_maar(cpu_env, arg);
4910            rn = "MAAR";
4911            break;
4912        default:
4913            goto cp0_unimplemented;
4914        }
4915        break;
4916    case 28:
4917        switch (sel) {
4918        case 0:
4919        case 2:
4920        case 4:
4921        case 6:
4922            tcg_gen_andi_tl(arg, arg, mask);
4923            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4924            rn = "TagLo";
4925            break;
4926        default:
4927            goto cp0_unimplemented;
4928        }
4929        break;
4930    default:
4931        goto cp0_unimplemented;
4932    }
4933
4934    (void)rn; /* avoid a compiler warning */
4935cp0_unimplemented:
4936    LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4937}
4938
4939static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4940{
4941    if (ctx->insn_flags & ISA_MIPS32R6) {
4942        tcg_gen_movi_tl(arg, 0);
4943    } else {
4944        tcg_gen_movi_tl(arg, ~0);
4945    }
4946}
4947
4948static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4949{
4950    const char *rn = "invalid";
4951
4952    if (sel != 0)
4953        check_insn(ctx, ISA_MIPS32);
4954
4955    switch (reg) {
4956    case 0:
4957        switch (sel) {
4958        case 0:
4959            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4960            rn = "Index";
4961            break;
4962        case 1:
4963            CP0_CHECK(ctx->insn_flags & ASE_MT);
4964            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4965            rn = "MVPControl";
4966            break;
4967        case 2:
4968            CP0_CHECK(ctx->insn_flags & ASE_MT);
4969            gen_helper_mfc0_mvpconf0(arg, cpu_env);
4970            rn = "MVPConf0";
4971            break;
4972        case 3:
4973            CP0_CHECK(ctx->insn_flags & ASE_MT);
4974            gen_helper_mfc0_mvpconf1(arg, cpu_env);
4975            rn = "MVPConf1";
4976            break;
4977        case 4:
4978            CP0_CHECK(ctx->vp);
4979            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4980            rn = "VPControl";
4981            break;
4982        default:
4983            goto cp0_unimplemented;
4984        }
4985        break;
4986    case 1:
4987        switch (sel) {
4988        case 0:
4989            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4990            gen_helper_mfc0_random(arg, cpu_env);
4991            rn = "Random";
4992            break;
4993        case 1:
4994            CP0_CHECK(ctx->insn_flags & ASE_MT);
4995            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4996            rn = "VPEControl";
4997            break;
4998        case 2:
4999            CP0_CHECK(ctx->insn_flags & ASE_MT);
5000            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5001            rn = "VPEConf0";
5002            break;
5003        case 3:
5004            CP0_CHECK(ctx->insn_flags & ASE_MT);
5005            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5006            rn = "VPEConf1";
5007            break;
5008        case 4:
5009            CP0_CHECK(ctx->insn_flags & ASE_MT);
5010            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5011            rn = "YQMask";
5012            break;
5013        case 5:
5014            CP0_CHECK(ctx->insn_flags & ASE_MT);
5015            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5016            rn = "VPESchedule";
5017            break;
5018        case 6:
5019            CP0_CHECK(ctx->insn_flags & ASE_MT);
5020            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5021            rn = "VPEScheFBack";
5022            break;
5023        case 7:
5024            CP0_CHECK(ctx->insn_flags & ASE_MT);
5025            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5026            rn = "VPEOpt";
5027            break;
5028        default:
5029            goto cp0_unimplemented;
5030        }
5031        break;
5032    case 2:
5033        switch (sel) {
5034        case 0:
5035            {
5036                TCGv_i64 tmp = tcg_temp_new_i64();
5037                tcg_gen_ld_i64(tmp, cpu_env,
5038                               offsetof(CPUMIPSState, CP0_EntryLo0));
5039#if defined(TARGET_MIPS64)
5040                if (ctx->rxi) {
5041                    /* Move RI/XI fields to bits 31:30 */
5042                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5043                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5044                }
5045#endif
5046                gen_move_low32(arg, tmp);
5047                tcg_temp_free_i64(tmp);
5048            }
5049            rn = "EntryLo0";
5050            break;
5051        case 1:
5052            CP0_CHECK(ctx->insn_flags & ASE_MT);
5053            gen_helper_mfc0_tcstatus(arg, cpu_env);
5054            rn = "TCStatus";
5055            break;
5056        case 2:
5057            CP0_CHECK(ctx->insn_flags & ASE_MT);
5058            gen_helper_mfc0_tcbind(arg, cpu_env);
5059            rn = "TCBind";
5060            break;
5061        case 3:
5062            CP0_CHECK(ctx->insn_flags & ASE_MT);
5063            gen_helper_mfc0_tcrestart(arg, cpu_env);
5064            rn = "TCRestart";
5065            break;
5066        case 4:
5067            CP0_CHECK(ctx->insn_flags & ASE_MT);
5068            gen_helper_mfc0_tchalt(arg, cpu_env);
5069            rn = "TCHalt";
5070            break;
5071        case 5:
5072            CP0_CHECK(ctx->insn_flags & ASE_MT);
5073            gen_helper_mfc0_tccontext(arg, cpu_env);
5074            rn = "TCContext";
5075            break;
5076        case 6:
5077            CP0_CHECK(ctx->insn_flags & ASE_MT);
5078            gen_helper_mfc0_tcschedule(arg, cpu_env);
5079            rn = "TCSchedule";
5080            break;
5081        case 7:
5082            CP0_CHECK(ctx->insn_flags & ASE_MT);
5083            gen_helper_mfc0_tcschefback(arg, cpu_env);
5084            rn = "TCScheFBack";
5085            break;
5086        default:
5087            goto cp0_unimplemented;
5088        }
5089        break;
5090    case 3:
5091        switch (sel) {
5092        case 0:
5093            {
5094                TCGv_i64 tmp = tcg_temp_new_i64();
5095                tcg_gen_ld_i64(tmp, cpu_env,
5096                               offsetof(CPUMIPSState, CP0_EntryLo1));
5097#if defined(TARGET_MIPS64)
5098                if (ctx->rxi) {
5099                    /* Move RI/XI fields to bits 31:30 */
5100                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5101                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5102                }
5103#endif
5104                gen_move_low32(arg, tmp);
5105                tcg_temp_free_i64(tmp);
5106            }
5107            rn = "EntryLo1";
5108            break;
5109        case 1:
5110            CP0_CHECK(ctx->vp);
5111            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5112            rn = "GlobalNumber";
5113            break;
5114        default:
5115            goto cp0_unimplemented;
5116        }
5117        break;
5118    case 4:
5119        switch (sel) {
5120        case 0:
5121            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5122            tcg_gen_ext32s_tl(arg, arg);
5123            rn = "Context";
5124            break;
5125        case 1:
5126//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5127            rn = "ContextConfig";
5128            goto cp0_unimplemented;
5129//            break;
5130        case 2:
5131            CP0_CHECK(ctx->ulri);
5132            tcg_gen_ld32s_tl(arg, cpu_env,
5133                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5134            rn = "UserLocal";
5135            break;
5136        default:
5137            goto cp0_unimplemented;
5138        }
5139        break;
5140    case 5:
5141        switch (sel) {
5142        case 0:
5143            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5144            rn = "PageMask";
5145            break;
5146        case 1:
5147            check_insn(ctx, ISA_MIPS32R2);
5148            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5149            rn = "PageGrain";
5150            break;
5151        default:
5152            goto cp0_unimplemented;
5153        }
5154        break;
5155    case 6:
5156        switch (sel) {
5157        case 0:
5158            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5159            rn = "Wired";
5160            break;
5161        case 1:
5162            check_insn(ctx, ISA_MIPS32R2);
5163            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5164            rn = "SRSConf0";
5165            break;
5166        case 2:
5167            check_insn(ctx, ISA_MIPS32R2);
5168            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5169            rn = "SRSConf1";
5170            break;
5171        case 3:
5172            check_insn(ctx, ISA_MIPS32R2);
5173            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5174            rn = "SRSConf2";
5175            break;
5176        case 4:
5177            check_insn(ctx, ISA_MIPS32R2);
5178            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5179            rn = "SRSConf3";
5180            break;
5181        case 5:
5182            check_insn(ctx, ISA_MIPS32R2);
5183            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5184            rn = "SRSConf4";
5185            break;
5186        default:
5187            goto cp0_unimplemented;
5188        }
5189        break;
5190    case 7:
5191        switch (sel) {
5192        case 0:
5193            check_insn(ctx, ISA_MIPS32R2);
5194            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5195            rn = "HWREna";
5196            break;
5197        default:
5198            goto cp0_unimplemented;
5199        }
5200        break;
5201    case 8:
5202        switch (sel) {
5203        case 0:
5204            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5205            tcg_gen_ext32s_tl(arg, arg);
5206            rn = "BadVAddr";
5207            break;
5208        case 1:
5209            CP0_CHECK(ctx->bi);
5210            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5211            rn = "BadInstr";
5212            break;
5213        case 2:
5214            CP0_CHECK(ctx->bp);
5215            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5216            rn = "BadInstrP";
5217            break;
5218        default:
5219            goto cp0_unimplemented;
5220        }
5221        break;
5222    case 9:
5223        switch (sel) {
5224        case 0:
5225            /* Mark as an IO operation because we read the time.  */
5226            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5227                gen_io_start();
5228            }
5229            gen_helper_mfc0_count(arg, cpu_env);
5230            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5231                gen_io_end();
5232            }
5233            /* Break the TB to be able to take timer interrupts immediately
5234               after reading count.  */
5235            ctx->bstate = BS_STOP;
5236            rn = "Count";
5237            break;
5238        /* 6,7 are implementation dependent */
5239        default:
5240            goto cp0_unimplemented;
5241        }
5242        break;
5243    case 10:
5244        switch (sel) {
5245        case 0:
5246            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5247            tcg_gen_ext32s_tl(arg, arg);
5248            rn = "EntryHi";
5249            break;
5250        default:
5251            goto cp0_unimplemented;
5252        }
5253        break;
5254    case 11:
5255        switch (sel) {
5256        case 0:
5257            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5258            rn = "Compare";
5259            break;
5260        /* 6,7 are implementation dependent */
5261        default:
5262            goto cp0_unimplemented;
5263        }
5264        break;
5265    case 12:
5266        switch (sel) {
5267        case 0:
5268            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5269            rn = "Status";
5270            break;
5271        case 1:
5272            check_insn(ctx, ISA_MIPS32R2);
5273            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5274            rn = "IntCtl";
5275            break;
5276        case 2:
5277            check_insn(ctx, ISA_MIPS32R2);
5278            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5279            rn = "SRSCtl";
5280            break;
5281        case 3:
5282            check_insn(ctx, ISA_MIPS32R2);
5283            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5284            rn = "SRSMap";
5285            break;
5286        default:
5287            goto cp0_unimplemented;
5288       }
5289        break;
5290    case 13:
5291        switch (sel) {
5292        case 0:
5293            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5294            rn = "Cause";
5295            break;
5296        default:
5297            goto cp0_unimplemented;
5298       }
5299        break;
5300    case 14:
5301        switch (sel) {
5302        case 0:
5303            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5304            tcg_gen_ext32s_tl(arg, arg);
5305            rn = "EPC";
5306            break;
5307        default:
5308            goto cp0_unimplemented;
5309        }
5310        break;
5311    case 15:
5312        switch (sel) {
5313        case 0:
5314            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5315            rn = "PRid";
5316            break;
5317        case 1:
5318            check_insn(ctx, ISA_MIPS32R2);
5319            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5320            rn = "EBase";
5321            break;
5322        case 3:
5323            check_insn(ctx, ISA_MIPS32R2);
5324            CP0_CHECK(ctx->cmgcr);
5325            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5326            tcg_gen_ext32s_tl(arg, arg);
5327            rn = "CMGCRBase";
5328            break;
5329        default:
5330            goto cp0_unimplemented;
5331       }
5332        break;
5333    case 16:
5334        switch (sel) {
5335        case 0:
5336            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5337            rn = "Config";
5338            break;
5339        case 1:
5340            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5341            rn = "Config1";
5342            break;
5343        case 2:
5344            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5345            rn = "Config2";
5346            break;
5347        case 3:
5348            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5349            rn = "Config3";
5350            break;
5351        case 4:
5352            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5353            rn = "Config4";
5354            break;
5355        case 5:
5356            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5357            rn = "Config5";
5358            break;
5359        /* 6,7 are implementation dependent */
5360        case 6:
5361            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5362            rn = "Config6";
5363            break;
5364        case 7:
5365            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5366            rn = "Config7";
5367            break;
5368        default:
5369            goto cp0_unimplemented;
5370        }
5371        break;
5372    case 17:
5373        switch (sel) {
5374        case 0:
5375            gen_helper_mfc0_lladdr(arg, cpu_env);
5376            rn = "LLAddr";
5377            break;
5378        case 1:
5379            CP0_CHECK(ctx->mrp);
5380            gen_helper_mfc0_maar(arg, cpu_env);
5381            rn = "MAAR";
5382            break;
5383        case 2:
5384            CP0_CHECK(ctx->mrp);
5385            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5386            rn = "MAARI";
5387            break;
5388        default:
5389            goto cp0_unimplemented;
5390        }
5391        break;
5392    case 18:
5393        switch (sel) {
5394        case 0 ... 7:
5395            gen_helper_1e0i(mfc0_watchlo, arg, sel);
5396            rn = "WatchLo";
5397            break;
5398        default:
5399            goto cp0_unimplemented;
5400        }
5401        break;
5402    case 19:
5403        switch (sel) {
5404        case 0 ...7:
5405            gen_helper_1e0i(mfc0_watchhi, arg, sel);
5406            rn = "WatchHi";
5407            break;
5408        default:
5409            goto cp0_unimplemented;
5410        }
5411        break;
5412    case 20:
5413        switch (sel) {
5414        case 0:
5415#if defined(TARGET_MIPS64)
5416            check_insn(ctx, ISA_MIPS3);
5417            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5418            tcg_gen_ext32s_tl(arg, arg);
5419            rn = "XContext";
5420            break;
5421#endif
5422        default:
5423            goto cp0_unimplemented;
5424        }
5425        break;
5426    case 21:
5427       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5428        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5429        switch (sel) {
5430        case 0:
5431            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5432            rn = "Framemask";
5433            break;
5434        default:
5435            goto cp0_unimplemented;
5436        }
5437        break;
5438    case 22:
5439        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5440        rn = "'Diagnostic"; /* implementation dependent */
5441        break;
5442    case 23:
5443        switch (sel) {
5444        case 0:
5445            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5446            rn = "Debug";
5447            break;
5448        case 1:
5449//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5450            rn = "TraceControl";
5451//            break;
5452        case 2:
5453//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5454            rn = "TraceControl2";
5455//            break;
5456        case 3:
5457//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5458            rn = "UserTraceData";
5459//            break;
5460        case 4:
5461//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5462            rn = "TraceBPC";
5463//            break;
5464        default:
5465            goto cp0_unimplemented;
5466        }
5467        break;
5468    case 24:
5469        switch (sel) {
5470        case 0:
5471            /* EJTAG support */
5472            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5473            tcg_gen_ext32s_tl(arg, arg);
5474            rn = "DEPC";
5475            break;
5476        default:
5477            goto cp0_unimplemented;
5478        }
5479        break;
5480    case 25:
5481        switch (sel) {
5482        case 0:
5483            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5484            rn = "Performance0";
5485            break;
5486        case 1:
5487//            gen_helper_mfc0_performance1(arg);
5488            rn = "Performance1";
5489//            break;
5490        case 2:
5491//            gen_helper_mfc0_performance2(arg);
5492            rn = "Performance2";
5493//            break;
5494        case 3:
5495//            gen_helper_mfc0_performance3(arg);
5496            rn = "Performance3";
5497//            break;
5498        case 4:
5499//            gen_helper_mfc0_performance4(arg);
5500            rn = "Performance4";
5501//            break;
5502        case 5:
5503//            gen_helper_mfc0_performance5(arg);
5504            rn = "Performance5";
5505//            break;
5506        case 6:
5507//            gen_helper_mfc0_performance6(arg);
5508            rn = "Performance6";
5509//            break;
5510        case 7:
5511//            gen_helper_mfc0_performance7(arg);
5512            rn = "Performance7";
5513//            break;
5514        default:
5515            goto cp0_unimplemented;
5516        }
5517        break;
5518    case 26:
5519        switch (sel) {
5520        case 0:
5521            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5522            rn = "ErrCtl";
5523            break;
5524        default:
5525            goto cp0_unimplemented;
5526        }
5527        break;
5528    case 27:
5529        switch (sel) {
5530        case 0 ... 3:
5531            tcg_gen_movi_tl(arg, 0); /* unimplemented */
5532            rn = "CacheErr";
5533            break;
5534        default:
5535            goto cp0_unimplemented;
5536        }
5537        break;
5538    case 28:
5539        switch (sel) {
5540        case 0:
5541        case 2:
5542        case 4:
5543        case 6:
5544            {
5545                TCGv_i64 tmp = tcg_temp_new_i64();
5546                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5547                gen_move_low32(arg, tmp);
5548                tcg_temp_free_i64(tmp);
5549            }
5550            rn = "TagLo";
5551            break;
5552        case 1:
5553        case 3:
5554        case 5:
5555        case 7:
5556            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5557            rn = "DataLo";
5558            break;
5559        default:
5560            goto cp0_unimplemented;
5561        }
5562        break;
5563    case 29:
5564        switch (sel) {
5565        case 0:
5566        case 2:
5567        case 4:
5568        case 6:
5569            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5570            rn = "TagHi";
5571            break;
5572        case 1:
5573        case 3:
5574        case 5:
5575        case 7:
5576            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5577            rn = "DataHi";
5578            break;
5579        default:
5580            goto cp0_unimplemented;
5581        }
5582        break;
5583    case 30:
5584        switch (sel) {
5585        case 0:
5586            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5587            tcg_gen_ext32s_tl(arg, arg);
5588            rn = "ErrorEPC";
5589            break;
5590        default:
5591            goto cp0_unimplemented;
5592        }
5593        break;
5594    case 31:
5595        switch (sel) {
5596        case 0:
5597            /* EJTAG support */
5598            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5599            rn = "DESAVE";
5600            break;
5601        case 2 ... 7:
5602            CP0_CHECK(ctx->kscrexist & (1 << sel));
5603            tcg_gen_ld_tl(arg, cpu_env,
5604                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5605            tcg_gen_ext32s_tl(arg, arg);
5606            rn = "KScratch";
5607            break;
5608        default:
5609            goto cp0_unimplemented;
5610        }
5611        break;
5612    default:
5613       goto cp0_unimplemented;
5614    }
5615    (void)rn; /* avoid a compiler warning */
5616    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5617    return;
5618
5619cp0_unimplemented:
5620    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5621    gen_mfc0_unimplemented(ctx, arg);
5622}
5623
5624static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5625{
5626    const char *rn = "invalid";
5627
5628    if (sel != 0)
5629        check_insn(ctx, ISA_MIPS32);
5630
5631    if (ctx->tb->cflags & CF_USE_ICOUNT) {
5632        gen_io_start();
5633    }
5634
5635    switch (reg) {
5636    case 0:
5637        switch (sel) {
5638        case 0:
5639            gen_helper_mtc0_index(cpu_env, arg);
5640            rn = "Index";
5641            break;
5642        case 1:
5643            CP0_CHECK(ctx->insn_flags & ASE_MT);
5644            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5645            rn = "MVPControl";
5646            break;
5647        case 2:
5648            CP0_CHECK(ctx->insn_flags & ASE_MT);
5649            /* ignored */
5650            rn = "MVPConf0";
5651            break;
5652        case 3:
5653            CP0_CHECK(ctx->insn_flags & ASE_MT);
5654            /* ignored */
5655            rn = "MVPConf1";
5656            break;
5657        case 4:
5658            CP0_CHECK(ctx->vp);
5659            /* ignored */
5660            rn = "VPControl";
5661            break;
5662        default:
5663            goto cp0_unimplemented;
5664        }
5665        break;
5666    case 1:
5667        switch (sel) {
5668        case 0:
5669            /* ignored */
5670            rn = "Random";
5671            break;
5672        case 1:
5673            CP0_CHECK(ctx->insn_flags & ASE_MT);
5674            gen_helper_mtc0_vpecontrol(cpu_env, arg);
5675            rn = "VPEControl";
5676            break;
5677        case 2:
5678            CP0_CHECK(ctx->insn_flags & ASE_MT);
5679            gen_helper_mtc0_vpeconf0(cpu_env, arg);
5680            rn = "VPEConf0";
5681            break;
5682        case 3:
5683            CP0_CHECK(ctx->insn_flags & ASE_MT);
5684            gen_helper_mtc0_vpeconf1(cpu_env, arg);
5685            rn = "VPEConf1";
5686            break;
5687        case 4:
5688            CP0_CHECK(ctx->insn_flags & ASE_MT);
5689            gen_helper_mtc0_yqmask(cpu_env, arg);
5690            rn = "YQMask";
5691            break;
5692        case 5:
5693            CP0_CHECK(ctx->insn_flags & ASE_MT);
5694            tcg_gen_st_tl(arg, cpu_env,
5695                          offsetof(CPUMIPSState, CP0_VPESchedule));
5696            rn = "VPESchedule";
5697            break;
5698        case 6:
5699            CP0_CHECK(ctx->insn_flags & ASE_MT);
5700            tcg_gen_st_tl(arg, cpu_env,
5701                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
5702            rn = "VPEScheFBack";
5703            break;
5704        case 7:
5705            CP0_CHECK(ctx->insn_flags & ASE_MT);
5706            gen_helper_mtc0_vpeopt(cpu_env, arg);
5707            rn = "VPEOpt";
5708            break;
5709        default:
5710            goto cp0_unimplemented;
5711        }
5712        break;
5713    case 2:
5714        switch (sel) {
5715        case 0:
5716            gen_helper_mtc0_entrylo0(cpu_env, arg);
5717            rn = "EntryLo0";
5718            break;
5719        case 1:
5720            CP0_CHECK(ctx->insn_flags & ASE_MT);
5721            gen_helper_mtc0_tcstatus(cpu_env, arg);
5722            rn = "TCStatus";
5723            break;
5724        case 2:
5725            CP0_CHECK(ctx->insn_flags & ASE_MT);
5726            gen_helper_mtc0_tcbind(cpu_env, arg);
5727            rn = "TCBind";
5728            break;
5729        case 3:
5730            CP0_CHECK(ctx->insn_flags & ASE_MT);
5731            gen_helper_mtc0_tcrestart(cpu_env, arg);
5732            rn = "TCRestart";
5733            break;
5734        case 4:
5735            CP0_CHECK(ctx->insn_flags & ASE_MT);
5736            gen_helper_mtc0_tchalt(cpu_env, arg);
5737            rn = "TCHalt";
5738            break;
5739        case 5:
5740            CP0_CHECK(ctx->insn_flags & ASE_MT);
5741            gen_helper_mtc0_tccontext(cpu_env, arg);
5742            rn = "TCContext";
5743            break;
5744        case 6:
5745            CP0_CHECK(ctx->insn_flags & ASE_MT);
5746            gen_helper_mtc0_tcschedule(cpu_env, arg);
5747            rn = "TCSchedule";
5748            break;
5749        case 7:
5750            CP0_CHECK(ctx->insn_flags & ASE_MT);
5751            gen_helper_mtc0_tcschefback(cpu_env, arg);
5752            rn = "TCScheFBack";
5753            break;
5754        default:
5755            goto cp0_unimplemented;
5756        }
5757        break;
5758    case 3:
5759        switch (sel) {
5760        case 0:
5761            gen_helper_mtc0_entrylo1(cpu_env, arg);
5762            rn = "EntryLo1";
5763            break;
5764        case 1:
5765            CP0_CHECK(ctx->vp);
5766            /* ignored */
5767            rn = "GlobalNumber";
5768            break;
5769        default:
5770            goto cp0_unimplemented;
5771        }
5772        break;
5773    case 4:
5774        switch (sel) {
5775        case 0:
5776            gen_helper_mtc0_context(cpu_env, arg);
5777            rn = "Context";
5778            break;
5779        case 1:
5780//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5781            rn = "ContextConfig";
5782            goto cp0_unimplemented;
5783//            break;
5784        case 2:
5785            CP0_CHECK(ctx->ulri);
5786            tcg_gen_st_tl(arg, cpu_env,
5787                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5788            rn = "UserLocal";
5789            break;
5790        default:
5791            goto cp0_unimplemented;
5792        }
5793        break;
5794    case 5:
5795        switch (sel) {
5796        case 0:
5797            gen_helper_mtc0_pagemask(cpu_env, arg);
5798            rn = "PageMask";
5799            break;
5800        case 1:
5801            check_insn(ctx, ISA_MIPS32R2);
5802            gen_helper_mtc0_pagegrain(cpu_env, arg);
5803            rn = "PageGrain";
5804            ctx->bstate = BS_STOP;
5805            break;
5806        default:
5807            goto cp0_unimplemented;
5808        }
5809        break;
5810    case 6:
5811        switch (sel) {
5812        case 0:
5813            gen_helper_mtc0_wired(cpu_env, arg);
5814            rn = "Wired";
5815            break;
5816        case 1:
5817            check_insn(ctx, ISA_MIPS32R2);
5818            gen_helper_mtc0_srsconf0(cpu_env, arg);
5819            rn = "SRSConf0";
5820            break;
5821        case 2:
5822            check_insn(ctx, ISA_MIPS32R2);
5823            gen_helper_mtc0_srsconf1(cpu_env, arg);
5824            rn = "SRSConf1";
5825            break;
5826        case 3:
5827            check_insn(ctx, ISA_MIPS32R2);
5828            gen_helper_mtc0_srsconf2(cpu_env, arg);
5829            rn = "SRSConf2";
5830            break;
5831        case 4:
5832            check_insn(ctx, ISA_MIPS32R2);
5833            gen_helper_mtc0_srsconf3(cpu_env, arg);
5834            rn = "SRSConf3";
5835            break;
5836        case 5:
5837            check_insn(ctx, ISA_MIPS32R2);
5838            gen_helper_mtc0_srsconf4(cpu_env, arg);
5839            rn = "SRSConf4";
5840            break;
5841        default:
5842            goto cp0_unimplemented;
5843        }
5844        break;
5845    case 7:
5846        switch (sel) {
5847        case 0:
5848            check_insn(ctx, ISA_MIPS32R2);
5849            gen_helper_mtc0_hwrena(cpu_env, arg);
5850            ctx->bstate = BS_STOP;
5851            rn = "HWREna";
5852            break;
5853        default:
5854            goto cp0_unimplemented;
5855        }
5856        break;
5857    case 8:
5858        switch (sel) {
5859        case 0:
5860            /* ignored */
5861            rn = "BadVAddr";
5862            break;
5863        case 1:
5864            /* ignored */
5865            rn = "BadInstr";
5866            break;
5867        case 2:
5868            /* ignored */
5869            rn = "BadInstrP";
5870            break;
5871        default:
5872            goto cp0_unimplemented;
5873        }
5874        break;
5875    case 9:
5876        switch (sel) {
5877        case 0:
5878            gen_helper_mtc0_count(cpu_env, arg);
5879            rn = "Count";
5880            break;
5881        /* 6,7 are implementation dependent */
5882        default:
5883            goto cp0_unimplemented;
5884        }
5885        break;
5886    case 10:
5887        switch (sel) {
5888        case 0:
5889            gen_helper_mtc0_entryhi(cpu_env, arg);
5890            rn = "EntryHi";
5891            break;
5892        default:
5893            goto cp0_unimplemented;
5894        }
5895        break;
5896    case 11:
5897        switch (sel) {
5898        case 0:
5899            gen_helper_mtc0_compare(cpu_env, arg);
5900            rn = "Compare";
5901            break;
5902        /* 6,7 are implementation dependent */
5903        default:
5904            goto cp0_unimplemented;
5905        }
5906        break;
5907    case 12:
5908        switch (sel) {
5909        case 0:
5910            save_cpu_state(ctx, 1);
5911            gen_helper_mtc0_status(cpu_env, arg);
5912            /* BS_STOP isn't good enough here, hflags may have changed. */
5913            gen_save_pc(ctx->pc + 4);
5914            ctx->bstate = BS_EXCP;
5915            rn = "Status";
5916            break;
5917        case 1:
5918            check_insn(ctx, ISA_MIPS32R2);
5919            gen_helper_mtc0_intctl(cpu_env, arg);
5920            /* Stop translation as we may have switched the execution mode */
5921            ctx->bstate = BS_STOP;
5922            rn = "IntCtl";
5923            break;
5924        case 2:
5925            check_insn(ctx, ISA_MIPS32R2);
5926            gen_helper_mtc0_srsctl(cpu_env, arg);
5927            /* Stop translation as we may have switched the execution mode */
5928            ctx->bstate = BS_STOP;
5929            rn = "SRSCtl";
5930            break;
5931        case 3:
5932            check_insn(ctx, ISA_MIPS32R2);
5933            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5934            /* Stop translation as we may have switched the execution mode */
5935            ctx->bstate = BS_STOP;
5936            rn = "SRSMap";
5937            break;
5938        default:
5939            goto cp0_unimplemented;
5940        }
5941        break;
5942    case 13:
5943        switch (sel) {
5944        case 0:
5945            save_cpu_state(ctx, 1);
5946            gen_helper_mtc0_cause(cpu_env, arg);
5947            rn = "Cause";
5948            break;
5949        default:
5950            goto cp0_unimplemented;
5951        }
5952        break;
5953    case 14:
5954        switch (sel) {
5955        case 0:
5956            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5957            rn = "EPC";
5958            break;
5959        default:
5960            goto cp0_unimplemented;
5961        }
5962        break;
5963    case 15:
5964        switch (sel) {
5965        case 0:
5966            /* ignored */
5967            rn = "PRid";
5968            break;
5969        case 1:
5970            check_insn(ctx, ISA_MIPS32R2);
5971            gen_helper_mtc0_ebase(cpu_env, arg);
5972            rn = "EBase";
5973            break;
5974        default:
5975            goto cp0_unimplemented;
5976        }
5977        break;
5978    case 16:
5979        switch (sel) {
5980        case 0:
5981            gen_helper_mtc0_config0(cpu_env, arg);
5982            rn = "Config";
5983            /* Stop translation as we may have switched the execution mode */
5984            ctx->bstate = BS_STOP;
5985            break;
5986        case 1:
5987            /* ignored, read only */
5988            rn = "Config1";
5989            break;
5990        case 2:
5991            gen_helper_mtc0_config2(cpu_env, arg);
5992            rn = "Config2";
5993            /* Stop translation as we may have switched the execution mode */
5994            ctx->bstate = BS_STOP;
5995            break;
5996        case 3:
5997            gen_helper_mtc0_config3(cpu_env, arg);
5998            rn = "Config3";
5999            /* Stop translation as we may have switched the execution mode */
6000            ctx->bstate = BS_STOP;
6001            break;
6002        case 4:
6003            gen_helper_mtc0_config4(cpu_env, arg);
6004            rn = "Config4";
6005            ctx->bstate = BS_STOP;
6006            break;
6007        case 5:
6008            gen_helper_mtc0_config5(cpu_env, arg);
6009            rn = "Config5";
6010            /* Stop translation as we may have switched the execution mode */
6011            ctx->bstate = BS_STOP;
6012            break;
6013        /* 6,7 are implementation dependent */
6014        case 6:
6015            /* ignored */
6016            rn = "Config6";
6017            break;
6018        case 7:
6019            /* ignored */
6020            rn = "Config7";
6021            break;
6022        default:
6023            rn = "Invalid config selector";
6024            goto cp0_unimplemented;
6025        }
6026        break;
6027    case 17:
6028        switch (sel) {
6029        case 0:
6030            gen_helper_mtc0_lladdr(cpu_env, arg);
6031            rn = "LLAddr";
6032            break;
6033        case 1:
6034            CP0_CHECK(ctx->mrp);
6035            gen_helper_mtc0_maar(cpu_env, arg);
6036            rn = "MAAR";
6037            break;
6038        case 2:
6039            CP0_CHECK(ctx->mrp);
6040            gen_helper_mtc0_maari(cpu_env, arg);
6041            rn = "MAARI";
6042            break;
6043        default:
6044            goto cp0_unimplemented;
6045        }
6046        break;
6047    case 18:
6048        switch (sel) {
6049        case 0 ... 7:
6050            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6051            rn = "WatchLo";
6052            break;
6053        default:
6054            goto cp0_unimplemented;
6055        }
6056        break;
6057    case 19:
6058        switch (sel) {
6059        case 0 ... 7:
6060            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6061            rn = "WatchHi";
6062            break;
6063        default:
6064            goto cp0_unimplemented;
6065        }
6066        break;
6067    case 20:
6068        switch (sel) {
6069        case 0:
6070#if defined(TARGET_MIPS64)
6071            check_insn(ctx, ISA_MIPS3);
6072            gen_helper_mtc0_xcontext(cpu_env, arg);
6073            rn = "XContext";
6074            break;
6075#endif
6076        default:
6077            goto cp0_unimplemented;
6078        }
6079        break;
6080    case 21:
6081       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6082        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6083        switch (sel) {
6084        case 0:
6085            gen_helper_mtc0_framemask(cpu_env, arg);
6086            rn = "Framemask";
6087            break;
6088        default:
6089            goto cp0_unimplemented;
6090        }
6091        break;
6092    case 22:
6093        /* ignored */
6094        rn = "Diagnostic"; /* implementation dependent */
6095        break;
6096    case 23:
6097        switch (sel) {
6098        case 0:
6099            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6100            /* BS_STOP isn't good enough here, hflags may have changed. */
6101            gen_save_pc(ctx->pc + 4);
6102            ctx->bstate = BS_EXCP;
6103            rn = "Debug";
6104            break;
6105        case 1:
6106//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6107            rn = "TraceControl";
6108            /* Stop translation as we may have switched the execution mode */
6109            ctx->bstate = BS_STOP;
6110//            break;
6111        case 2:
6112//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6113            rn = "TraceControl2";
6114            /* Stop translation as we may have switched the execution mode */
6115            ctx->bstate = BS_STOP;
6116//            break;
6117        case 3:
6118            /* Stop translation as we may have switched the execution mode */
6119            ctx->bstate = BS_STOP;
6120//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6121            rn = "UserTraceData";
6122            /* Stop translation as we may have switched the execution mode */
6123            ctx->bstate = BS_STOP;
6124//            break;
6125        case 4:
6126//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6127            /* Stop translation as we may have switched the execution mode */
6128            ctx->bstate = BS_STOP;
6129            rn = "TraceBPC";
6130//            break;
6131        default:
6132            goto cp0_unimplemented;
6133        }
6134        break;
6135    case 24:
6136        switch (sel) {
6137        case 0:
6138            /* EJTAG support */
6139            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6140            rn = "DEPC";
6141            break;
6142        default:
6143            goto cp0_unimplemented;
6144        }
6145        break;
6146    case 25:
6147        switch (sel) {
6148        case 0:
6149            gen_helper_mtc0_performance0(cpu_env, arg);
6150            rn = "Performance0";
6151            break;
6152        case 1:
6153//            gen_helper_mtc0_performance1(arg);
6154            rn = "Performance1";
6155//            break;
6156        case 2:
6157//            gen_helper_mtc0_performance2(arg);
6158            rn = "Performance2";
6159//            break;
6160        case 3:
6161//            gen_helper_mtc0_performance3(arg);
6162            rn = "Performance3";
6163//            break;
6164        case 4:
6165//            gen_helper_mtc0_performance4(arg);
6166            rn = "Performance4";
6167//            break;
6168        case 5:
6169//            gen_helper_mtc0_performance5(arg);
6170            rn = "Performance5";
6171//            break;
6172        case 6:
6173//            gen_helper_mtc0_performance6(arg);
6174            rn = "Performance6";
6175//            break;
6176        case 7:
6177//            gen_helper_mtc0_performance7(arg);
6178            rn = "Performance7";
6179//            break;
6180        default:
6181            goto cp0_unimplemented;
6182        }
6183       break;
6184    case 26:
6185        switch (sel) {
6186        case 0:
6187            gen_helper_mtc0_errctl(cpu_env, arg);
6188            ctx->bstate = BS_STOP;
6189            rn = "ErrCtl";
6190            break;
6191        default:
6192            goto cp0_unimplemented;
6193        }
6194        break;
6195    case 27:
6196        switch (sel) {
6197        case 0 ... 3:
6198            /* ignored */
6199            rn = "CacheErr";
6200            break;
6201        default:
6202            goto cp0_unimplemented;
6203        }
6204       break;
6205    case 28:
6206        switch (sel) {
6207        case 0:
6208        case 2:
6209        case 4:
6210        case 6:
6211            gen_helper_mtc0_taglo(cpu_env, arg);
6212            rn = "TagLo";
6213            break;
6214        case 1:
6215        case 3:
6216        case 5:
6217        case 7:
6218            gen_helper_mtc0_datalo(cpu_env, arg);
6219            rn = "DataLo";
6220            break;
6221        default:
6222            goto cp0_unimplemented;
6223        }
6224        break;
6225    case 29:
6226        switch (sel) {
6227        case 0:
6228        case 2:
6229        case 4:
6230        case 6:
6231            gen_helper_mtc0_taghi(cpu_env, arg);
6232            rn = "TagHi";
6233            break;
6234        case 1:
6235        case 3:
6236        case 5:
6237        case 7:
6238            gen_helper_mtc0_datahi(cpu_env, arg);
6239            rn = "DataHi";
6240            break;
6241        default:
6242            rn = "invalid sel";
6243            goto cp0_unimplemented;
6244        }
6245       break;
6246    case 30:
6247        switch (sel) {
6248        case 0:
6249            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6250            rn = "ErrorEPC";
6251            break;
6252        default:
6253            goto cp0_unimplemented;
6254        }
6255        break;
6256    case 31:
6257        switch (sel) {
6258        case 0:
6259            /* EJTAG support */
6260            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6261            rn = "DESAVE";
6262            break;
6263        case 2 ... 7:
6264            CP0_CHECK(ctx->kscrexist & (1 << sel));
6265            tcg_gen_st_tl(arg, cpu_env,
6266                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6267            rn = "KScratch";
6268            break;
6269        default:
6270            goto cp0_unimplemented;
6271        }
6272        /* Stop translation as we may have switched the execution mode */
6273        ctx->bstate = BS_STOP;
6274        break;
6275    default:
6276       goto cp0_unimplemented;
6277    }
6278    (void)rn; /* avoid a compiler warning */
6279    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6280    /* For simplicity assume that all writes can cause interrupts.  */
6281    if (ctx->tb->cflags & CF_USE_ICOUNT) {
6282        gen_io_end();
6283        ctx->bstate = BS_STOP;
6284    }
6285    return;
6286
6287cp0_unimplemented:
6288    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6289}
6290
6291#if defined(TARGET_MIPS64)
6292static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6293{
6294    const char *rn = "invalid";
6295
6296    if (sel != 0)
6297        check_insn(ctx, ISA_MIPS64);
6298
6299    switch (reg) {
6300    case 0:
6301        switch (sel) {
6302        case 0:
6303            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6304            rn = "Index";
6305            break;
6306        case 1:
6307            CP0_CHECK(ctx->insn_flags & ASE_MT);
6308            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6309            rn = "MVPControl";
6310            break;
6311        case 2:
6312            CP0_CHECK(ctx->insn_flags & ASE_MT);
6313            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6314            rn = "MVPConf0";
6315            break;
6316        case 3:
6317            CP0_CHECK(ctx->insn_flags & ASE_MT);
6318            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6319            rn = "MVPConf1";
6320            break;
6321        case 4:
6322            CP0_CHECK(ctx->vp);
6323            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6324            rn = "VPControl";
6325            break;
6326        default:
6327            goto cp0_unimplemented;
6328        }
6329        break;
6330    case 1:
6331        switch (sel) {
6332        case 0:
6333            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6334            gen_helper_mfc0_random(arg, cpu_env);
6335            rn = "Random";
6336            break;
6337        case 1:
6338            CP0_CHECK(ctx->insn_flags & ASE_MT);
6339            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6340            rn = "VPEControl";
6341            break;
6342        case 2:
6343            CP0_CHECK(ctx->insn_flags & ASE_MT);
6344            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6345            rn = "VPEConf0";
6346            break;
6347        case 3:
6348            CP0_CHECK(ctx->insn_flags & ASE_MT);
6349            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6350            rn = "VPEConf1";
6351            break;
6352        case 4:
6353            CP0_CHECK(ctx->insn_flags & ASE_MT);
6354            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6355            rn = "YQMask";
6356            break;
6357        case 5:
6358            CP0_CHECK(ctx->insn_flags & ASE_MT);
6359            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6360            rn = "VPESchedule";
6361            break;
6362        case 6:
6363            CP0_CHECK(ctx->insn_flags & ASE_MT);
6364            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6365            rn = "VPEScheFBack";
6366            break;
6367        case 7:
6368            CP0_CHECK(ctx->insn_flags & ASE_MT);
6369            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6370            rn = "VPEOpt";
6371            break;
6372        default:
6373            goto cp0_unimplemented;
6374        }
6375        break;
6376    case 2:
6377        switch (sel) {
6378        case 0:
6379            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6380            rn = "EntryLo0";
6381            break;
6382        case 1:
6383            CP0_CHECK(ctx->insn_flags & ASE_MT);
6384            gen_helper_mfc0_tcstatus(arg, cpu_env);
6385            rn = "TCStatus";
6386            break;
6387        case 2:
6388            CP0_CHECK(ctx->insn_flags & ASE_MT);
6389            gen_helper_mfc0_tcbind(arg, cpu_env);
6390            rn = "TCBind";
6391            break;
6392        case 3:
6393            CP0_CHECK(ctx->insn_flags & ASE_MT);
6394            gen_helper_dmfc0_tcrestart(arg, cpu_env);
6395            rn = "TCRestart";
6396            break;
6397        case 4:
6398            CP0_CHECK(ctx->insn_flags & ASE_MT);
6399            gen_helper_dmfc0_tchalt(arg, cpu_env);
6400            rn = "TCHalt";
6401            break;
6402        case 5:
6403            CP0_CHECK(ctx->insn_flags & ASE_MT);
6404            gen_helper_dmfc0_tccontext(arg, cpu_env);
6405            rn = "TCContext";
6406            break;
6407        case 6:
6408            CP0_CHECK(ctx->insn_flags & ASE_MT);
6409            gen_helper_dmfc0_tcschedule(arg, cpu_env);
6410            rn = "TCSchedule";
6411            break;
6412        case 7:
6413            CP0_CHECK(ctx->insn_flags & ASE_MT);
6414            gen_helper_dmfc0_tcschefback(arg, cpu_env);
6415            rn = "TCScheFBack";
6416            break;
6417        default:
6418            goto cp0_unimplemented;
6419        }
6420        break;
6421    case 3:
6422        switch (sel) {
6423        case 0:
6424            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6425            rn = "EntryLo1";
6426            break;
6427        case 1:
6428            CP0_CHECK(ctx->vp);
6429            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6430            rn = "GlobalNumber";
6431            break;
6432        default:
6433            goto cp0_unimplemented;
6434        }
6435        break;
6436    case 4:
6437        switch (sel) {
6438        case 0:
6439            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6440            rn = "Context";
6441            break;
6442        case 1:
6443//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6444            rn = "ContextConfig";
6445            goto cp0_unimplemented;
6446//            break;
6447        case 2:
6448            CP0_CHECK(ctx->ulri);
6449            tcg_gen_ld_tl(arg, cpu_env,
6450                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6451            rn = "UserLocal";
6452            break;
6453        default:
6454            goto cp0_unimplemented;
6455        }
6456        break;
6457    case 5:
6458        switch (sel) {
6459        case 0:
6460            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6461            rn = "PageMask";
6462            break;
6463        case 1:
6464            check_insn(ctx, ISA_MIPS32R2);
6465            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6466            rn = "PageGrain";
6467            break;
6468        default:
6469            goto cp0_unimplemented;
6470        }
6471        break;
6472    case 6:
6473        switch (sel) {
6474        case 0:
6475            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6476            rn = "Wired";
6477            break;
6478        case 1:
6479            check_insn(ctx, ISA_MIPS32R2);
6480            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6481            rn = "SRSConf0";
6482            break;
6483        case 2:
6484            check_insn(ctx, ISA_MIPS32R2);
6485            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6486            rn = "SRSConf1";
6487            break;
6488        case 3:
6489            check_insn(ctx, ISA_MIPS32R2);
6490            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6491            rn = "SRSConf2";
6492            break;
6493        case 4:
6494            check_insn(ctx, ISA_MIPS32R2);
6495            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6496            rn = "SRSConf3";
6497            break;
6498        case 5:
6499            check_insn(ctx, ISA_MIPS32R2);
6500            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6501            rn = "SRSConf4";
6502            break;
6503        default:
6504            goto cp0_unimplemented;
6505        }
6506        break;
6507    case 7:
6508        switch (sel) {
6509        case 0:
6510            check_insn(ctx, ISA_MIPS32R2);
6511            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6512            rn = "HWREna";
6513            break;
6514        default:
6515            goto cp0_unimplemented;
6516        }
6517        break;
6518    case 8:
6519        switch (sel) {
6520        case 0:
6521            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6522            rn = "BadVAddr";
6523            break;
6524        case 1:
6525            CP0_CHECK(ctx->bi);
6526            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6527            rn = "BadInstr";
6528            break;
6529        case 2:
6530            CP0_CHECK(ctx->bp);
6531            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6532            rn = "BadInstrP";
6533            break;
6534        default:
6535            goto cp0_unimplemented;
6536        }
6537        break;
6538    case 9:
6539        switch (sel) {
6540        case 0:
6541            /* Mark as an IO operation because we read the time.  */
6542            if (ctx->tb->cflags & CF_USE_ICOUNT) {
6543                gen_io_start();
6544            }
6545            gen_helper_mfc0_count(arg, cpu_env);
6546            if (ctx->tb->cflags & CF_USE_ICOUNT) {
6547                gen_io_end();
6548            }
6549            /* Break the TB to be able to take timer interrupts immediately
6550               after reading count.  */
6551            ctx->bstate = BS_STOP;
6552            rn = "Count";
6553            break;
6554        /* 6,7 are implementation dependent */
6555        default:
6556            goto cp0_unimplemented;
6557        }
6558        break;
6559    case 10:
6560        switch (sel) {
6561        case 0:
6562            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6563            rn = "EntryHi";
6564            break;
6565        default:
6566            goto cp0_unimplemented;
6567        }
6568        break;
6569    case 11:
6570        switch (sel) {
6571        case 0:
6572            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6573            rn = "Compare";
6574            break;
6575        /* 6,7 are implementation dependent */
6576        default:
6577            goto cp0_unimplemented;
6578        }
6579        break;
6580    case 12:
6581        switch (sel) {
6582        case 0:
6583            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6584            rn = "Status";
6585            break;
6586        case 1:
6587            check_insn(ctx, ISA_MIPS32R2);
6588            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6589            rn = "IntCtl";
6590            break;
6591        case 2:
6592            check_insn(ctx, ISA_MIPS32R2);
6593            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6594            rn = "SRSCtl";
6595            break;
6596        case 3:
6597            check_insn(ctx, ISA_MIPS32R2);
6598            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6599            rn = "SRSMap";
6600            break;
6601        default:
6602            goto cp0_unimplemented;
6603        }
6604        break;
6605    case 13:
6606        switch (sel) {
6607        case 0:
6608            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6609            rn = "Cause";
6610            break;
6611        default:
6612            goto cp0_unimplemented;
6613        }
6614        break;
6615    case 14:
6616        switch (sel) {
6617        case 0:
6618            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6619            rn = "EPC";
6620            break;
6621        default:
6622            goto cp0_unimplemented;
6623        }
6624        break;
6625    case 15:
6626        switch (sel) {
6627        case 0:
6628            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6629            rn = "PRid";
6630            break;
6631        case 1:
6632            check_insn(ctx, ISA_MIPS32R2);
6633            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6634            rn = "EBase";
6635            break;
6636        case 3:
6637            check_insn(ctx, ISA_MIPS32R2);
6638            CP0_CHECK(ctx->cmgcr);
6639            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6640            rn = "CMGCRBase";
6641            break;
6642        default:
6643            goto cp0_unimplemented;
6644        }
6645        break;
6646    case 16:
6647        switch (sel) {
6648        case 0:
6649            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6650            rn = "Config";
6651            break;
6652        case 1:
6653            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6654            rn = "Config1";
6655            break;
6656        case 2:
6657            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6658            rn = "Config2";
6659            break;
6660        case 3:
6661            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6662            rn = "Config3";
6663            break;
6664        case 4:
6665            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6666            rn = "Config4";
6667            break;
6668        case 5:
6669            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6670            rn = "Config5";
6671            break;
6672       /* 6,7 are implementation dependent */
6673        case 6:
6674            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6675            rn = "Config6";
6676            break;
6677        case 7:
6678            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6679            rn = "Config7";
6680            break;
6681        default:
6682            goto cp0_unimplemented;
6683        }
6684        break;
6685    case 17:
6686        switch (sel) {
6687        case 0:
6688            gen_helper_dmfc0_lladdr(arg, cpu_env);
6689            rn = "LLAddr";
6690            break;
6691        case 1:
6692            CP0_CHECK(ctx->mrp);
6693            gen_helper_dmfc0_maar(arg, cpu_env);
6694            rn = "MAAR";
6695            break;
6696        case 2:
6697            CP0_CHECK(ctx->mrp);
6698            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6699            rn = "MAARI";
6700            break;
6701        default:
6702            goto cp0_unimplemented;
6703        }
6704        break;
6705    case 18:
6706        switch (sel) {
6707        case 0 ... 7:
6708            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6709            rn = "WatchLo";
6710            break;
6711        default:
6712            goto cp0_unimplemented;
6713        }
6714        break;
6715    case 19:
6716        switch (sel) {
6717        case 0 ... 7:
6718            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6719            rn = "WatchHi";
6720            break;
6721        default:
6722            goto cp0_unimplemented;
6723        }
6724        break;
6725    case 20:
6726        switch (sel) {
6727        case 0:
6728            check_insn(ctx, ISA_MIPS3);
6729            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6730            rn = "XContext";
6731            break;
6732        default:
6733            goto cp0_unimplemented;
6734        }
6735        break;
6736    case 21:
6737       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6738        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6739        switch (sel) {
6740        case 0:
6741            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6742            rn = "Framemask";
6743            break;
6744        default:
6745            goto cp0_unimplemented;
6746        }
6747        break;
6748    case 22:
6749        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6750        rn = "'Diagnostic"; /* implementation dependent */
6751        break;
6752    case 23:
6753        switch (sel) {
6754        case 0:
6755            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6756            rn = "Debug";
6757            break;
6758        case 1:
6759//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6760            rn = "TraceControl";
6761//            break;
6762        case 2:
6763//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6764            rn = "TraceControl2";
6765//            break;
6766        case 3:
6767//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6768            rn = "UserTraceData";
6769//            break;
6770        case 4:
6771//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6772            rn = "TraceBPC";
6773//            break;
6774        default:
6775            goto cp0_unimplemented;
6776        }
6777        break;
6778    case 24:
6779        switch (sel) {
6780        case 0:
6781            /* EJTAG support */
6782            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6783            rn = "DEPC";
6784            break;
6785        default:
6786            goto cp0_unimplemented;
6787        }
6788        break;
6789    case 25:
6790        switch (sel) {
6791        case 0:
6792            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6793            rn = "Performance0";
6794            break;
6795        case 1:
6796//            gen_helper_dmfc0_performance1(arg);
6797            rn = "Performance1";
6798//            break;
6799        case 2:
6800//            gen_helper_dmfc0_performance2(arg);
6801            rn = "Performance2";
6802//            break;
6803        case 3:
6804//            gen_helper_dmfc0_performance3(arg);
6805            rn = "Performance3";
6806//            break;
6807        case 4:
6808//            gen_helper_dmfc0_performance4(arg);
6809            rn = "Performance4";
6810//            break;
6811        case 5:
6812//            gen_helper_dmfc0_performance5(arg);
6813            rn = "Performance5";
6814//            break;
6815        case 6:
6816//            gen_helper_dmfc0_performance6(arg);
6817            rn = "Performance6";
6818//            break;
6819        case 7:
6820//            gen_helper_dmfc0_performance7(arg);
6821            rn = "Performance7";
6822//            break;
6823        default:
6824            goto cp0_unimplemented;
6825        }
6826        break;
6827    case 26:
6828        switch (sel) {
6829        case 0:
6830            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6831            rn = "ErrCtl";
6832            break;
6833        default:
6834            goto cp0_unimplemented;
6835        }
6836        break;
6837    case 27:
6838        switch (sel) {
6839        /* ignored */
6840        case 0 ... 3:
6841            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6842            rn = "CacheErr";
6843            break;
6844        default:
6845            goto cp0_unimplemented;
6846        }
6847        break;
6848    case 28:
6849        switch (sel) {
6850        case 0:
6851        case 2:
6852        case 4:
6853        case 6:
6854            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6855            rn = "TagLo";
6856            break;
6857        case 1:
6858        case 3:
6859        case 5:
6860        case 7:
6861            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6862            rn = "DataLo";
6863            break;
6864        default:
6865            goto cp0_unimplemented;
6866        }
6867        break;
6868    case 29:
6869        switch (sel) {
6870        case 0:
6871        case 2:
6872        case 4:
6873        case 6:
6874            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6875            rn = "TagHi";
6876            break;
6877        case 1:
6878        case 3:
6879        case 5:
6880        case 7:
6881            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6882            rn = "DataHi";
6883            break;
6884        default:
6885            goto cp0_unimplemented;
6886        }
6887        break;
6888    case 30:
6889        switch (sel) {
6890        case 0:
6891            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6892            rn = "ErrorEPC";
6893            break;
6894        default:
6895            goto cp0_unimplemented;
6896        }
6897        break;
6898    case 31:
6899        switch (sel) {
6900        case 0:
6901            /* EJTAG support */
6902            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6903            rn = "DESAVE";
6904            break;
6905        case 2 ... 7:
6906            CP0_CHECK(ctx->kscrexist & (1 << sel));
6907            tcg_gen_ld_tl(arg, cpu_env,
6908                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6909            rn = "KScratch";
6910            break;
6911        default:
6912            goto cp0_unimplemented;
6913        }
6914        break;
6915    default:
6916        goto cp0_unimplemented;
6917    }
6918    (void)rn; /* avoid a compiler warning */
6919    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6920    return;
6921
6922cp0_unimplemented:
6923    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6924    gen_mfc0_unimplemented(ctx, arg);
6925}
6926
6927static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6928{
6929    const char *rn = "invalid";
6930
6931    if (sel != 0)
6932        check_insn(ctx, ISA_MIPS64);
6933
6934    if (ctx->tb->cflags & CF_USE_ICOUNT) {
6935        gen_io_start();
6936    }
6937
6938    switch (reg) {
6939    case 0:
6940        switch (sel) {
6941        case 0:
6942            gen_helper_mtc0_index(cpu_env, arg);
6943            rn = "Index";
6944            break;
6945        case 1:
6946            CP0_CHECK(ctx->insn_flags & ASE_MT);
6947            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6948            rn = "MVPControl";
6949            break;
6950        case 2:
6951            CP0_CHECK(ctx->insn_flags & ASE_MT);
6952            /* ignored */
6953            rn = "MVPConf0";
6954            break;
6955        case 3:
6956            CP0_CHECK(ctx->insn_flags & ASE_MT);
6957            /* ignored */
6958            rn = "MVPConf1";
6959            break;
6960        case 4:
6961            CP0_CHECK(ctx->vp);
6962            /* ignored */
6963            rn = "VPControl";
6964            break;
6965        default:
6966            goto cp0_unimplemented;
6967        }
6968        break;
6969    case 1:
6970        switch (sel) {
6971        case 0:
6972            /* ignored */
6973            rn = "Random";
6974            break;
6975        case 1:
6976            CP0_CHECK(ctx->insn_flags & ASE_MT);
6977            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6978            rn = "VPEControl";
6979            break;
6980        case 2:
6981            CP0_CHECK(ctx->insn_flags & ASE_MT);
6982            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6983            rn = "VPEConf0";
6984            break;
6985        case 3:
6986            CP0_CHECK(ctx->insn_flags & ASE_MT);
6987            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6988            rn = "VPEConf1";
6989            break;
6990        case 4:
6991            CP0_CHECK(ctx->insn_flags & ASE_MT);
6992            gen_helper_mtc0_yqmask(cpu_env, arg);
6993            rn = "YQMask";
6994            break;
6995        case 5:
6996            CP0_CHECK(ctx->insn_flags & ASE_MT);
6997            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6998            rn = "VPESchedule";
6999            break;
7000        case 6:
7001            CP0_CHECK(ctx->insn_flags & ASE_MT);
7002            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7003            rn = "VPEScheFBack";
7004            break;
7005        case 7:
7006            CP0_CHECK(ctx->insn_flags & ASE_MT);
7007            gen_helper_mtc0_vpeopt(cpu_env, arg);
7008            rn = "VPEOpt";
7009            break;
7010        default:
7011            goto cp0_unimplemented;
7012        }
7013        break;
7014    case 2:
7015        switch (sel) {
7016        case 0:
7017            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7018            rn = "EntryLo0";
7019            break;
7020        case 1:
7021            CP0_CHECK(ctx->insn_flags & ASE_MT);
7022            gen_helper_mtc0_tcstatus(cpu_env, arg);
7023            rn = "TCStatus";
7024            break;
7025        case 2:
7026            CP0_CHECK(ctx->insn_flags & ASE_MT);
7027            gen_helper_mtc0_tcbind(cpu_env, arg);
7028            rn = "TCBind";
7029            break;
7030        case 3:
7031            CP0_CHECK(ctx->insn_flags & ASE_MT);
7032            gen_helper_mtc0_tcrestart(cpu_env, arg);
7033            rn = "TCRestart";
7034            break;
7035        case 4:
7036            CP0_CHECK(ctx->insn_flags & ASE_MT);
7037            gen_helper_mtc0_tchalt(cpu_env, arg);
7038            rn = "TCHalt";
7039            break;
7040        case 5:
7041            CP0_CHECK(ctx->insn_flags & ASE_MT);
7042            gen_helper_mtc0_tccontext(cpu_env, arg);
7043            rn = "TCContext";
7044            break;
7045        case 6:
7046            CP0_CHECK(ctx->insn_flags & ASE_MT);
7047            gen_helper_mtc0_tcschedule(cpu_env, arg);
7048            rn = "TCSchedule";
7049            break;
7050        case 7:
7051            CP0_CHECK(ctx->insn_flags & ASE_MT);
7052            gen_helper_mtc0_tcschefback(cpu_env, arg);
7053            rn = "TCScheFBack";
7054            break;
7055        default:
7056            goto cp0_unimplemented;
7057        }
7058        break;
7059    case 3:
7060        switch (sel) {
7061        case 0:
7062            gen_helper_dmtc0_entrylo1(cpu_env, arg);
7063            rn = "EntryLo1";
7064            break;
7065        case 1:
7066            CP0_CHECK(ctx->vp);
7067            /* ignored */
7068            rn = "GlobalNumber";
7069            break;
7070        default:
7071            goto cp0_unimplemented;
7072        }
7073        break;
7074    case 4:
7075        switch (sel) {
7076        case 0:
7077            gen_helper_mtc0_context(cpu_env, arg);
7078            rn = "Context";
7079            break;
7080        case 1:
7081//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7082            rn = "ContextConfig";
7083            goto cp0_unimplemented;
7084//           break;
7085        case 2:
7086            CP0_CHECK(ctx->ulri);
7087            tcg_gen_st_tl(arg, cpu_env,
7088                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7089            rn = "UserLocal";
7090            break;
7091        default:
7092            goto cp0_unimplemented;
7093        }
7094        break;
7095    case 5:
7096        switch (sel) {
7097        case 0:
7098            gen_helper_mtc0_pagemask(cpu_env, arg);
7099            rn = "PageMask";
7100            break;
7101        case 1:
7102            check_insn(ctx, ISA_MIPS32R2);
7103            gen_helper_mtc0_pagegrain(cpu_env, arg);
7104            rn = "PageGrain";
7105            break;
7106        default:
7107            goto cp0_unimplemented;
7108        }
7109        break;
7110    case 6:
7111        switch (sel) {
7112        case 0:
7113            gen_helper_mtc0_wired(cpu_env, arg);
7114            rn = "Wired";
7115            break;
7116        case 1:
7117            check_insn(ctx, ISA_MIPS32R2);
7118            gen_helper_mtc0_srsconf0(cpu_env, arg);
7119            rn = "SRSConf0";
7120            break;
7121        case 2:
7122            check_insn(ctx, ISA_MIPS32R2);
7123            gen_helper_mtc0_srsconf1(cpu_env, arg);
7124            rn = "SRSConf1";
7125            break;
7126        case 3:
7127            check_insn(ctx, ISA_MIPS32R2);
7128            gen_helper_mtc0_srsconf2(cpu_env, arg);
7129            rn = "SRSConf2";
7130            break;
7131        case 4:
7132            check_insn(ctx, ISA_MIPS32R2);
7133            gen_helper_mtc0_srsconf3(cpu_env, arg);
7134            rn = "SRSConf3";
7135            break;
7136        case 5:
7137            check_insn(ctx, ISA_MIPS32R2);
7138            gen_helper_mtc0_srsconf4(cpu_env, arg);
7139            rn = "SRSConf4";
7140            break;
7141        default:
7142            goto cp0_unimplemented;
7143        }
7144        break;
7145    case 7:
7146        switch (sel) {
7147        case 0:
7148            check_insn(ctx, ISA_MIPS32R2);
7149            gen_helper_mtc0_hwrena(cpu_env, arg);
7150            ctx->bstate = BS_STOP;
7151            rn = "HWREna";
7152            break;
7153        default:
7154            goto cp0_unimplemented;
7155        }
7156        break;
7157    case 8:
7158        switch (sel) {
7159        case 0:
7160            /* ignored */
7161            rn = "BadVAddr";
7162            break;
7163        case 1:
7164            /* ignored */
7165            rn = "BadInstr";
7166            break;
7167        case 2:
7168            /* ignored */
7169            rn = "BadInstrP";
7170            break;
7171        default:
7172            goto cp0_unimplemented;
7173        }
7174        break;
7175    case 9:
7176        switch (sel) {
7177        case 0:
7178            gen_helper_mtc0_count(cpu_env, arg);
7179            rn = "Count";
7180            break;
7181        /* 6,7 are implementation dependent */
7182        default:
7183            goto cp0_unimplemented;
7184        }
7185        /* Stop translation as we may have switched the execution mode */
7186        ctx->bstate = BS_STOP;
7187        break;
7188    case 10:
7189        switch (sel) {
7190        case 0:
7191            gen_helper_mtc0_entryhi(cpu_env, arg);
7192            rn = "EntryHi";
7193            break;
7194        default:
7195            goto cp0_unimplemented;
7196        }
7197        break;
7198    case 11:
7199        switch (sel) {
7200        case 0:
7201            gen_helper_mtc0_compare(cpu_env, arg);
7202            rn = "Compare";
7203            break;
7204        /* 6,7 are implementation dependent */
7205        default:
7206            goto cp0_unimplemented;
7207        }
7208        /* Stop translation as we may have switched the execution mode */
7209        ctx->bstate = BS_STOP;
7210        break;
7211    case 12:
7212        switch (sel) {
7213        case 0:
7214            save_cpu_state(ctx, 1);
7215            gen_helper_mtc0_status(cpu_env, arg);
7216            /* BS_STOP isn't good enough here, hflags may have changed. */
7217            gen_save_pc(ctx->pc + 4);
7218            ctx->bstate = BS_EXCP;
7219            rn = "Status";
7220            break;
7221        case 1:
7222            check_insn(ctx, ISA_MIPS32R2);
7223            gen_helper_mtc0_intctl(cpu_env, arg);
7224            /* Stop translation as we may have switched the execution mode */
7225            ctx->bstate = BS_STOP;
7226            rn = "IntCtl";
7227            break;
7228        case 2:
7229            check_insn(ctx, ISA_MIPS32R2);
7230            gen_helper_mtc0_srsctl(cpu_env, arg);
7231            /* Stop translation as we may have switched the execution mode */
7232            ctx->bstate = BS_STOP;
7233            rn = "SRSCtl";
7234            break;
7235        case 3:
7236            check_insn(ctx, ISA_MIPS32R2);
7237            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7238            /* Stop translation as we may have switched the execution mode */
7239            ctx->bstate = BS_STOP;
7240            rn = "SRSMap";
7241            break;
7242        default:
7243            goto cp0_unimplemented;
7244        }
7245        break;
7246    case 13:
7247        switch (sel) {
7248        case 0:
7249            save_cpu_state(ctx, 1);
7250            /* Mark as an IO operation because we may trigger a software
7251               interrupt.  */
7252            if (ctx->tb->cflags & CF_USE_ICOUNT) {
7253                gen_io_start();
7254            }
7255            gen_helper_mtc0_cause(cpu_env, arg);
7256            if (ctx->tb->cflags & CF_USE_ICOUNT) {
7257                gen_io_end();
7258            }
7259            /* Stop translation as we may have triggered an intetrupt */
7260            ctx->bstate = BS_STOP;
7261            rn = "Cause";
7262            break;
7263        default:
7264            goto cp0_unimplemented;
7265        }
7266        break;
7267    case 14:
7268        switch (sel) {
7269        case 0:
7270            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7271            rn = "EPC";
7272            break;
7273        default:
7274            goto cp0_unimplemented;
7275        }
7276        break;
7277    case 15:
7278        switch (sel) {
7279        case 0:
7280            /* ignored */
7281            rn = "PRid";
7282            break;
7283        case 1:
7284            check_insn(ctx, ISA_MIPS32R2);
7285            gen_helper_mtc0_ebase(cpu_env, arg);
7286            rn = "EBase";
7287            break;
7288        default:
7289            goto cp0_unimplemented;
7290        }
7291        break;
7292    case 16:
7293        switch (sel) {
7294        case 0:
7295            gen_helper_mtc0_config0(cpu_env, arg);
7296            rn = "Config";
7297            /* Stop translation as we may have switched the execution mode */
7298            ctx->bstate = BS_STOP;
7299            break;
7300        case 1:
7301            /* ignored, read only */
7302            rn = "Config1";
7303            break;
7304        case 2:
7305            gen_helper_mtc0_config2(cpu_env, arg);
7306            rn = "Config2";
7307            /* Stop translation as we may have switched the execution mode */
7308            ctx->bstate = BS_STOP;
7309            break;
7310        case 3:
7311            gen_helper_mtc0_config3(cpu_env, arg);
7312            rn = "Config3";
7313            /* Stop translation as we may have switched the execution mode */
7314            ctx->bstate = BS_STOP;
7315            break;
7316        case 4:
7317            /* currently ignored */
7318            rn = "Config4";
7319            break;
7320        case 5:
7321            gen_helper_mtc0_config5(cpu_env, arg);
7322            rn = "Config5";
7323            /* Stop translation as we may have switched the execution mode */
7324            ctx->bstate = BS_STOP;
7325            break;
7326        /* 6,7 are implementation dependent */
7327        default:
7328            rn = "Invalid config selector";
7329            goto cp0_unimplemented;
7330        }
7331        break;
7332    case 17:
7333        switch (sel) {
7334        case 0:
7335            gen_helper_mtc0_lladdr(cpu_env, arg);
7336            rn = "LLAddr";
7337            break;
7338        case 1:
7339            CP0_CHECK(ctx->mrp);
7340            gen_helper_mtc0_maar(cpu_env, arg);
7341            rn = "MAAR";
7342            break;
7343        case 2:
7344            CP0_CHECK(ctx->mrp);
7345            gen_helper_mtc0_maari(cpu_env, arg);
7346            rn = "MAARI";
7347            break;
7348        default:
7349            goto cp0_unimplemented;
7350        }
7351        break;
7352    case 18:
7353        switch (sel) {
7354        case 0 ... 7:
7355            gen_helper_0e1i(mtc0_watchlo, arg, sel);
7356            rn = "WatchLo";
7357            break;
7358        default:
7359            goto cp0_unimplemented;
7360        }
7361        break;
7362    case 19:
7363        switch (sel) {
7364        case 0 ... 7:
7365            gen_helper_0e1i(mtc0_watchhi, arg, sel);
7366            rn = "WatchHi";
7367            break;
7368        default:
7369            goto cp0_unimplemented;
7370        }
7371        break;
7372    case 20:
7373        switch (sel) {
7374        case 0:
7375            check_insn(ctx, ISA_MIPS3);
7376            gen_helper_mtc0_xcontext(cpu_env, arg);
7377            rn = "XContext";
7378            break;
7379        default:
7380            goto cp0_unimplemented;
7381        }
7382        break;
7383    case 21:
7384       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7385        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7386        switch (sel) {
7387        case 0:
7388            gen_helper_mtc0_framemask(cpu_env, arg);
7389            rn = "Framemask";
7390            break;
7391        default:
7392            goto cp0_unimplemented;
7393        }
7394        break;
7395    case 22:
7396        /* ignored */
7397        rn = "Diagnostic"; /* implementation dependent */
7398        break;
7399    case 23:
7400        switch (sel) {
7401        case 0:
7402            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7403            /* BS_STOP isn't good enough here, hflags may have changed. */
7404            gen_save_pc(ctx->pc + 4);
7405            ctx->bstate = BS_EXCP;
7406            rn = "Debug";
7407            break;
7408        case 1:
7409//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7410            /* Stop translation as we may have switched the execution mode */
7411            ctx->bstate = BS_STOP;
7412            rn = "TraceControl";
7413//            break;
7414        case 2:
7415//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7416            /* Stop translation as we may have switched the execution mode */
7417            ctx->bstate = BS_STOP;
7418            rn = "TraceControl2";
7419//            break;
7420        case 3:
7421//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7422            /* Stop translation as we may have switched the execution mode */
7423            ctx->bstate = BS_STOP;
7424            rn = "UserTraceData";
7425//            break;
7426        case 4:
7427//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7428            /* Stop translation as we may have switched the execution mode */
7429            ctx->bstate = BS_STOP;
7430            rn = "TraceBPC";
7431//            break;
7432        default:
7433            goto cp0_unimplemented;
7434        }
7435        break;
7436    case 24:
7437        switch (sel) {
7438        case 0:
7439            /* EJTAG support */
7440            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7441            rn = "DEPC";
7442            break;
7443        default:
7444            goto cp0_unimplemented;
7445        }
7446        break;
7447    case 25:
7448        switch (sel) {
7449        case 0:
7450            gen_helper_mtc0_performance0(cpu_env, arg);
7451            rn = "Performance0";
7452            break;
7453        case 1:
7454//            gen_helper_mtc0_performance1(cpu_env, arg);
7455            rn = "Performance1";
7456//            break;
7457        case 2:
7458//            gen_helper_mtc0_performance2(cpu_env, arg);
7459            rn = "Performance2";
7460//            break;
7461        case 3:
7462//            gen_helper_mtc0_performance3(cpu_env, arg);
7463            rn = "Performance3";
7464//            break;
7465        case 4:
7466//            gen_helper_mtc0_performance4(cpu_env, arg);
7467            rn = "Performance4";
7468//            break;
7469        case 5:
7470//            gen_helper_mtc0_performance5(cpu_env, arg);
7471            rn = "Performance5";
7472//            break;
7473        case 6:
7474//            gen_helper_mtc0_performance6(cpu_env, arg);
7475            rn = "Performance6";
7476//            break;
7477        case 7:
7478//            gen_helper_mtc0_performance7(cpu_env, arg);
7479            rn = "Performance7";
7480//            break;
7481        default:
7482            goto cp0_unimplemented;
7483        }
7484        break;
7485    case 26:
7486        switch (sel) {
7487        case 0:
7488            gen_helper_mtc0_errctl(cpu_env, arg);
7489            ctx->bstate = BS_STOP;
7490            rn = "ErrCtl";
7491            break;
7492        default:
7493            goto cp0_unimplemented;
7494        }
7495        break;
7496    case 27:
7497        switch (sel) {
7498        case 0 ... 3:
7499            /* ignored */
7500            rn = "CacheErr";
7501            break;
7502        default:
7503            goto cp0_unimplemented;
7504        }
7505        break;
7506    case 28:
7507        switch (sel) {
7508        case 0:
7509        case 2:
7510        case 4:
7511        case 6:
7512            gen_helper_mtc0_taglo(cpu_env, arg);
7513            rn = "TagLo";
7514            break;
7515        case 1:
7516        case 3:
7517        case 5:
7518        case 7:
7519            gen_helper_mtc0_datalo(cpu_env, arg);
7520            rn = "DataLo";
7521            break;
7522        default:
7523            goto cp0_unimplemented;
7524        }
7525        break;
7526    case 29:
7527        switch (sel) {
7528        case 0:
7529        case 2:
7530        case 4:
7531        case 6:
7532            gen_helper_mtc0_taghi(cpu_env, arg);
7533            rn = "TagHi";
7534            break;
7535        case 1:
7536        case 3:
7537        case 5:
7538        case 7:
7539            gen_helper_mtc0_datahi(cpu_env, arg);
7540            rn = "DataHi";
7541            break;
7542        default:
7543            rn = "invalid sel";
7544            goto cp0_unimplemented;
7545        }
7546        break;
7547    case 30:
7548        switch (sel) {
7549        case 0:
7550            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7551            rn = "ErrorEPC";
7552            break;
7553        default:
7554            goto cp0_unimplemented;
7555        }
7556        break;
7557    case 31:
7558        switch (sel) {
7559        case 0:
7560            /* EJTAG support */
7561            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7562            rn = "DESAVE";
7563            break;
7564        case 2 ... 7:
7565            CP0_CHECK(ctx->kscrexist & (1 << sel));
7566            tcg_gen_st_tl(arg, cpu_env,
7567                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7568            rn = "KScratch";
7569            break;
7570        default:
7571            goto cp0_unimplemented;
7572        }
7573        /* Stop translation as we may have switched the execution mode */
7574        ctx->bstate = BS_STOP;
7575        break;
7576    default:
7577        goto cp0_unimplemented;
7578    }
7579    (void)rn; /* avoid a compiler warning */
7580    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7581    /* For simplicity assume that all writes can cause interrupts.  */
7582    if (ctx->tb->cflags & CF_USE_ICOUNT) {
7583        gen_io_end();
7584        ctx->bstate = BS_STOP;
7585    }
7586    return;
7587
7588cp0_unimplemented:
7589    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7590}
7591#endif /* TARGET_MIPS64 */
7592
7593static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7594                     int u, int sel, int h)
7595{
7596    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7597    TCGv t0 = tcg_temp_local_new();
7598
7599    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7600        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7601         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7602        tcg_gen_movi_tl(t0, -1);
7603    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7604             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7605        tcg_gen_movi_tl(t0, -1);
7606    else if (u == 0) {
7607        switch (rt) {
7608        case 1:
7609            switch (sel) {
7610            case 1:
7611                gen_helper_mftc0_vpecontrol(t0, cpu_env);
7612                break;
7613            case 2:
7614                gen_helper_mftc0_vpeconf0(t0, cpu_env);
7615                break;
7616            default:
7617                goto die;
7618                break;
7619            }
7620            break;
7621        case 2:
7622            switch (sel) {
7623            case 1:
7624                gen_helper_mftc0_tcstatus(t0, cpu_env);
7625                break;
7626            case 2:
7627                gen_helper_mftc0_tcbind(t0, cpu_env);
7628                break;
7629            case 3:
7630                gen_helper_mftc0_tcrestart(t0, cpu_env);
7631                break;
7632            case 4:
7633                gen_helper_mftc0_tchalt(t0, cpu_env);
7634                break;
7635            case 5:
7636                gen_helper_mftc0_tccontext(t0, cpu_env);
7637                break;
7638            case 6:
7639                gen_helper_mftc0_tcschedule(t0, cpu_env);
7640                break;
7641            case 7:
7642                gen_helper_mftc0_tcschefback(t0, cpu_env);
7643                break;
7644            default:
7645                gen_mfc0(ctx, t0, rt, sel);
7646                break;
7647            }
7648            break;
7649        case 10:
7650            switch (sel) {
7651            case 0:
7652                gen_helper_mftc0_entryhi(t0, cpu_env);
7653                break;
7654            default:
7655                gen_mfc0(ctx, t0, rt, sel);
7656                break;
7657            }
7658        case 12:
7659            switch (sel) {
7660            case 0:
7661                gen_helper_mftc0_status(t0, cpu_env);
7662                break;
7663            default:
7664                gen_mfc0(ctx, t0, rt, sel);
7665                break;
7666            }
7667        case 13:
7668            switch (sel) {
7669            case 0:
7670                gen_helper_mftc0_cause(t0, cpu_env);
7671                break;
7672            default:
7673                goto die;
7674                break;
7675            }
7676            break;
7677        case 14:
7678            switch (sel) {
7679            case 0:
7680                gen_helper_mftc0_epc(t0, cpu_env);
7681                break;
7682            default:
7683                goto die;
7684                break;
7685            }
7686            break;
7687        case 15:
7688            switch (sel) {
7689            case 1:
7690                gen_helper_mftc0_ebase(t0, cpu_env);
7691                break;
7692            default:
7693                goto die;
7694                break;
7695            }
7696            break;
7697        case 16:
7698            switch (sel) {
7699            case 0 ... 7:
7700                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7701                break;
7702            default:
7703                goto die;
7704                break;
7705            }
7706            break;
7707        case 23:
7708            switch (sel) {
7709            case 0:
7710                gen_helper_mftc0_debug(t0, cpu_env);
7711                break;
7712            default:
7713                gen_mfc0(ctx, t0, rt, sel);
7714                break;
7715            }
7716            break;
7717        default:
7718            gen_mfc0(ctx, t0, rt, sel);
7719        }
7720    } else switch (sel) {
7721    /* GPR registers. */
7722    case 0:
7723        gen_helper_1e0i(mftgpr, t0, rt);
7724        break;
7725    /* Auxiliary CPU registers */
7726    case 1:
7727        switch (rt) {
7728        case 0:
7729            gen_helper_1e0i(mftlo, t0, 0);
7730            break;
7731        case 1:
7732            gen_helper_1e0i(mfthi, t0, 0);
7733            break;
7734        case 2:
7735            gen_helper_1e0i(mftacx, t0, 0);
7736            break;
7737        case 4:
7738            gen_helper_1e0i(mftlo, t0, 1);
7739            break;
7740        case 5:
7741            gen_helper_1e0i(mfthi, t0, 1);
7742            break;
7743        case 6:
7744            gen_helper_1e0i(mftacx, t0, 1);
7745            break;
7746        case 8:
7747            gen_helper_1e0i(mftlo, t0, 2);
7748            break;
7749        case 9:
7750            gen_helper_1e0i(mfthi, t0, 2);
7751            break;
7752        case 10:
7753            gen_helper_1e0i(mftacx, t0, 2);
7754            break;
7755        case 12:
7756            gen_helper_1e0i(mftlo, t0, 3);
7757            break;
7758        case 13:
7759            gen_helper_1e0i(mfthi, t0, 3);
7760            break;
7761        case 14:
7762            gen_helper_1e0i(mftacx, t0, 3);
7763            break;
7764        case 16:
7765            gen_helper_mftdsp(t0, cpu_env);
7766            break;
7767        default:
7768            goto die;
7769        }
7770        break;
7771    /* Floating point (COP1). */
7772    case 2:
7773        /* XXX: For now we support only a single FPU context. */
7774        if (h == 0) {
7775            TCGv_i32 fp0 = tcg_temp_new_i32();
7776
7777            gen_load_fpr32(ctx, fp0, rt);
7778            tcg_gen_ext_i32_tl(t0, fp0);
7779            tcg_temp_free_i32(fp0);
7780        } else {
7781            TCGv_i32 fp0 = tcg_temp_new_i32();
7782
7783            gen_load_fpr32h(ctx, fp0, rt);
7784            tcg_gen_ext_i32_tl(t0, fp0);
7785            tcg_temp_free_i32(fp0);
7786        }
7787        break;
7788    case 3:
7789        /* XXX: For now we support only a single FPU context. */
7790        gen_helper_1e0i(cfc1, t0, rt);
7791        break;
7792    /* COP2: Not implemented. */
7793    case 4:
7794    case 5:
7795        /* fall through */
7796    default:
7797        goto die;
7798    }
7799    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7800    gen_store_gpr(t0, rd);
7801    tcg_temp_free(t0);
7802    return;
7803
7804die:
7805    tcg_temp_free(t0);
7806    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7807    generate_exception_end(ctx, EXCP_RI);
7808}
7809
7810static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7811                     int u, int sel, int h)
7812{
7813    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7814    TCGv t0 = tcg_temp_local_new();
7815
7816    gen_load_gpr(t0, rt);
7817    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7818        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7819         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7820        /* NOP */ ;
7821    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7822             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7823        /* NOP */ ;
7824    else if (u == 0) {
7825        switch (rd) {
7826        case 1:
7827            switch (sel) {
7828            case 1:
7829                gen_helper_mttc0_vpecontrol(cpu_env, t0);
7830                break;
7831            case 2:
7832                gen_helper_mttc0_vpeconf0(cpu_env, t0);
7833                break;
7834            default:
7835                goto die;
7836                break;
7837            }
7838            break;
7839        case 2:
7840            switch (sel) {
7841            case 1:
7842                gen_helper_mttc0_tcstatus(cpu_env, t0);
7843                break;
7844            case 2:
7845                gen_helper_mttc0_tcbind(cpu_env, t0);
7846                break;
7847            case 3:
7848                gen_helper_mttc0_tcrestart(cpu_env, t0);
7849                break;
7850            case 4:
7851                gen_helper_mttc0_tchalt(cpu_env, t0);
7852                break;
7853            case 5:
7854                gen_helper_mttc0_tccontext(cpu_env, t0);
7855                break;
7856            case 6:
7857                gen_helper_mttc0_tcschedule(cpu_env, t0);
7858                break;
7859            case 7:
7860                gen_helper_mttc0_tcschefback(cpu_env, t0);
7861                break;
7862            default:
7863                gen_mtc0(ctx, t0, rd, sel);
7864                break;
7865            }
7866            break;
7867        case 10:
7868            switch (sel) {
7869            case 0:
7870                gen_helper_mttc0_entryhi(cpu_env, t0);
7871                break;
7872            default:
7873                gen_mtc0(ctx, t0, rd, sel);
7874                break;
7875            }
7876        case 12:
7877            switch (sel) {
7878            case 0:
7879                gen_helper_mttc0_status(cpu_env, t0);
7880                break;
7881            default:
7882                gen_mtc0(ctx, t0, rd, sel);
7883                break;
7884            }
7885        case 13:
7886            switch (sel) {
7887            case 0:
7888                gen_helper_mttc0_cause(cpu_env, t0);
7889                break;
7890            default:
7891                goto die;
7892                break;
7893            }
7894            break;
7895        case 15:
7896            switch (sel) {
7897            case 1:
7898                gen_helper_mttc0_ebase(cpu_env, t0);
7899                break;
7900            default:
7901                goto die;
7902                break;
7903            }
7904            break;
7905        case 23:
7906            switch (sel) {
7907            case 0:
7908                gen_helper_mttc0_debug(cpu_env, t0);
7909                break;
7910            default:
7911                gen_mtc0(ctx, t0, rd, sel);
7912                break;
7913            }
7914            break;
7915        default:
7916            gen_mtc0(ctx, t0, rd, sel);
7917        }
7918    } else switch (sel) {
7919    /* GPR registers. */
7920    case 0:
7921        gen_helper_0e1i(mttgpr, t0, rd);
7922        break;
7923    /* Auxiliary CPU registers */
7924    case 1:
7925        switch (rd) {
7926        case 0:
7927            gen_helper_0e1i(mttlo, t0, 0);
7928            break;
7929        case 1:
7930            gen_helper_0e1i(mtthi, t0, 0);
7931            break;
7932        case 2:
7933            gen_helper_0e1i(mttacx, t0, 0);
7934            break;
7935        case 4:
7936            gen_helper_0e1i(mttlo, t0, 1);
7937            break;
7938        case 5:
7939            gen_helper_0e1i(mtthi, t0, 1);
7940            break;
7941        case 6:
7942            gen_helper_0e1i(mttacx, t0, 1);
7943            break;
7944        case 8:
7945            gen_helper_0e1i(mttlo, t0, 2);
7946            break;
7947        case 9:
7948            gen_helper_0e1i(mtthi, t0, 2);
7949            break;
7950        case 10:
7951            gen_helper_0e1i(mttacx, t0, 2);
7952            break;
7953        case 12:
7954            gen_helper_0e1i(mttlo, t0, 3);
7955            break;
7956        case 13:
7957            gen_helper_0e1i(mtthi, t0, 3);
7958            break;
7959        case 14:
7960            gen_helper_0e1i(mttacx, t0, 3);
7961            break;
7962        case 16:
7963            gen_helper_mttdsp(cpu_env, t0);
7964            break;
7965        default:
7966            goto die;
7967        }
7968        break;
7969    /* Floating point (COP1). */
7970    case 2:
7971        /* XXX: For now we support only a single FPU context. */
7972        if (h == 0) {
7973            TCGv_i32 fp0 = tcg_temp_new_i32();
7974
7975            tcg_gen_trunc_tl_i32(fp0, t0);
7976            gen_store_fpr32(ctx, fp0, rd);
7977            tcg_temp_free_i32(fp0);
7978        } else {
7979            TCGv_i32 fp0 = tcg_temp_new_i32();
7980
7981            tcg_gen_trunc_tl_i32(fp0, t0);
7982            gen_store_fpr32h(ctx, fp0, rd);
7983            tcg_temp_free_i32(fp0);
7984        }
7985        break;
7986    case 3:
7987        /* XXX: For now we support only a single FPU context. */
7988        {
7989            TCGv_i32 fs_tmp = tcg_const_i32(rd);
7990
7991            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7992            tcg_temp_free_i32(fs_tmp);
7993        }
7994        /* Stop translation as we may have changed hflags */
7995        ctx->bstate = BS_STOP;
7996        break;
7997    /* COP2: Not implemented. */
7998    case 4:
7999    case 5:
8000        /* fall through */
8001    default:
8002        goto die;
8003    }
8004    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8005    tcg_temp_free(t0);
8006    return;
8007
8008die:
8009    tcg_temp_free(t0);
8010    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8011    generate_exception_end(ctx, EXCP_RI);
8012}
8013
8014static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8015{
8016    const char *opn = "ldst";
8017
8018    check_cp0_enabled(ctx);
8019    switch (opc) {
8020    case OPC_MFC0:
8021        if (rt == 0) {
8022            /* Treat as NOP. */
8023            return;
8024        }
8025        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8026        opn = "mfc0";
8027        break;
8028    case OPC_MTC0:
8029        {
8030            TCGv t0 = tcg_temp_new();
8031
8032            gen_load_gpr(t0, rt);
8033            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8034            tcg_temp_free(t0);
8035        }
8036        opn = "mtc0";
8037        break;
8038#if defined(TARGET_MIPS64)
8039    case OPC_DMFC0:
8040        check_insn(ctx, ISA_MIPS3);
8041        if (rt == 0) {
8042            /* Treat as NOP. */
8043            return;
8044        }
8045        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8046        opn = "dmfc0";
8047        break;
8048    case OPC_DMTC0:
8049        check_insn(ctx, ISA_MIPS3);
8050        {
8051            TCGv t0 = tcg_temp_new();
8052
8053            gen_load_gpr(t0, rt);
8054            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8055            tcg_temp_free(t0);
8056        }
8057        opn = "dmtc0";
8058        break;
8059#endif
8060    case OPC_MFHC0:
8061        check_mvh(ctx);
8062        if (rt == 0) {
8063            /* Treat as NOP. */
8064            return;
8065        }
8066        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8067        opn = "mfhc0";
8068        break;
8069    case OPC_MTHC0:
8070        check_mvh(ctx);
8071        {
8072            TCGv t0 = tcg_temp_new();
8073            gen_load_gpr(t0, rt);
8074            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8075            tcg_temp_free(t0);
8076        }
8077        opn = "mthc0";
8078        break;
8079    case OPC_MFTR:
8080        check_insn(ctx, ASE_MT);
8081        if (rd == 0) {
8082            /* Treat as NOP. */
8083            return;
8084        }
8085        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8086                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8087        opn = "mftr";
8088        break;
8089    case OPC_MTTR:
8090        check_insn(ctx, ASE_MT);
8091        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8092                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8093        opn = "mttr";
8094        break;
8095    case OPC_TLBWI:
8096        opn = "tlbwi";
8097        if (!env->tlb->helper_tlbwi)
8098            goto die;
8099        gen_helper_tlbwi(cpu_env);
8100        break;
8101    case OPC_TLBINV:
8102        opn = "tlbinv";
8103        if (ctx->ie >= 2) {
8104            if (!env->tlb->helper_tlbinv) {
8105                goto die;
8106            }
8107            gen_helper_tlbinv(cpu_env);
8108        } /* treat as nop if TLBINV not supported */
8109        break;
8110    case OPC_TLBINVF:
8111        opn = "tlbinvf";
8112        if (ctx->ie >= 2) {
8113            if (!env->tlb->helper_tlbinvf) {
8114                goto die;
8115            }
8116            gen_helper_tlbinvf(cpu_env);
8117        } /* treat as nop if TLBINV not supported */
8118        break;
8119    case OPC_TLBWR:
8120        opn = "tlbwr";
8121        if (!env->tlb->helper_tlbwr)
8122            goto die;
8123        gen_helper_tlbwr(cpu_env);
8124        break;
8125    case OPC_TLBP:
8126        opn = "tlbp";
8127        if (!env->tlb->helper_tlbp)
8128            goto die;
8129        gen_helper_tlbp(cpu_env);
8130        break;
8131    case OPC_TLBR:
8132        opn = "tlbr";
8133        if (!env->tlb->helper_tlbr)
8134            goto die;
8135        gen_helper_tlbr(cpu_env);
8136        break;
8137    case OPC_ERET: /* OPC_ERETNC */
8138        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8139            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8140            goto die;
8141        } else {
8142            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8143            if (ctx->opcode & (1 << bit_shift)) {
8144                /* OPC_ERETNC */
8145                opn = "eretnc";
8146                check_insn(ctx, ISA_MIPS32R5);
8147                gen_helper_eretnc(cpu_env);
8148            } else {
8149                /* OPC_ERET */
8150                opn = "eret";
8151                check_insn(ctx, ISA_MIPS2);
8152                gen_helper_eret(cpu_env);
8153            }
8154            ctx->bstate = BS_EXCP;
8155        }
8156        break;
8157    case OPC_DERET:
8158        opn = "deret";
8159        check_insn(ctx, ISA_MIPS32);
8160        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8161            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8162            goto die;
8163        }
8164        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8165            MIPS_INVAL(opn);
8166            generate_exception_end(ctx, EXCP_RI);
8167        } else {
8168            gen_helper_deret(cpu_env);
8169            ctx->bstate = BS_EXCP;
8170        }
8171        break;
8172    case OPC_WAIT:
8173        opn = "wait";
8174        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8175        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8176            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8177            goto die;
8178        }
8179        /* If we get an exception, we want to restart at next instruction */
8180        ctx->pc += 4;
8181        save_cpu_state(ctx, 1);
8182        ctx->pc -= 4;
8183        gen_helper_wait(cpu_env);
8184        ctx->bstate = BS_EXCP;
8185        break;
8186    default:
8187 die:
8188        MIPS_INVAL(opn);
8189        generate_exception_end(ctx, EXCP_RI);
8190        return;
8191    }
8192    (void)opn; /* avoid a compiler warning */
8193}
8194#endif /* !CONFIG_USER_ONLY */
8195
8196/* CP1 Branches (before delay slot) */
8197static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8198                                int32_t cc, int32_t offset)
8199{
8200    target_ulong btarget;
8201    TCGv_i32 t0 = tcg_temp_new_i32();
8202
8203    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8204        generate_exception_end(ctx, EXCP_RI);
8205        goto out;
8206    }
8207
8208    if (cc != 0)
8209        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8210
8211    btarget = ctx->pc + 4 + offset;
8212
8213    switch (op) {
8214    case OPC_BC1F:
8215        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8216        tcg_gen_not_i32(t0, t0);
8217        tcg_gen_andi_i32(t0, t0, 1);
8218        tcg_gen_extu_i32_tl(bcond, t0);
8219        goto not_likely;
8220    case OPC_BC1FL:
8221        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8222        tcg_gen_not_i32(t0, t0);
8223        tcg_gen_andi_i32(t0, t0, 1);
8224        tcg_gen_extu_i32_tl(bcond, t0);
8225        goto likely;
8226    case OPC_BC1T:
8227        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8228        tcg_gen_andi_i32(t0, t0, 1);
8229        tcg_gen_extu_i32_tl(bcond, t0);
8230        goto not_likely;
8231    case OPC_BC1TL:
8232        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8233        tcg_gen_andi_i32(t0, t0, 1);
8234        tcg_gen_extu_i32_tl(bcond, t0);
8235    likely:
8236        ctx->hflags |= MIPS_HFLAG_BL;
8237        break;
8238    case OPC_BC1FANY2:
8239        {
8240            TCGv_i32 t1 = tcg_temp_new_i32();
8241            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8242            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8243            tcg_gen_nand_i32(t0, t0, t1);
8244            tcg_temp_free_i32(t1);
8245            tcg_gen_andi_i32(t0, t0, 1);
8246            tcg_gen_extu_i32_tl(bcond, t0);
8247        }
8248        goto not_likely;
8249    case OPC_BC1TANY2:
8250        {
8251            TCGv_i32 t1 = tcg_temp_new_i32();
8252            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8253            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8254            tcg_gen_or_i32(t0, t0, t1);
8255            tcg_temp_free_i32(t1);
8256            tcg_gen_andi_i32(t0, t0, 1);
8257            tcg_gen_extu_i32_tl(bcond, t0);
8258        }
8259        goto not_likely;
8260    case OPC_BC1FANY4:
8261        {
8262            TCGv_i32 t1 = tcg_temp_new_i32();
8263            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8264            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8265            tcg_gen_and_i32(t0, t0, t1);
8266            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8267            tcg_gen_and_i32(t0, t0, t1);
8268            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8269            tcg_gen_nand_i32(t0, t0, t1);
8270            tcg_temp_free_i32(t1);
8271            tcg_gen_andi_i32(t0, t0, 1);
8272            tcg_gen_extu_i32_tl(bcond, t0);
8273        }
8274        goto not_likely;
8275    case OPC_BC1TANY4:
8276        {
8277            TCGv_i32 t1 = tcg_temp_new_i32();
8278            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8279            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8280            tcg_gen_or_i32(t0, t0, t1);
8281            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8282            tcg_gen_or_i32(t0, t0, t1);
8283            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8284            tcg_gen_or_i32(t0, t0, t1);
8285            tcg_temp_free_i32(t1);
8286            tcg_gen_andi_i32(t0, t0, 1);
8287            tcg_gen_extu_i32_tl(bcond, t0);
8288        }
8289    not_likely:
8290        ctx->hflags |= MIPS_HFLAG_BC;
8291        break;
8292    default:
8293        MIPS_INVAL("cp1 cond branch");
8294        generate_exception_end(ctx, EXCP_RI);
8295        goto out;
8296    }
8297    ctx->btarget = btarget;
8298    ctx->hflags |= MIPS_HFLAG_BDS32;
8299 out:
8300    tcg_temp_free_i32(t0);
8301}
8302
8303/* R6 CP1 Branches */
8304static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8305                                   int32_t ft, int32_t offset,
8306                                   int delayslot_size)
8307{
8308    target_ulong btarget;
8309    TCGv_i64 t0 = tcg_temp_new_i64();
8310
8311    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8312#ifdef MIPS_DEBUG_DISAS
8313        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8314                  "\n", ctx->pc);
8315#endif
8316        generate_exception_end(ctx, EXCP_RI);
8317        goto out;
8318    }
8319
8320    gen_load_fpr64(ctx, t0, ft);
8321    tcg_gen_andi_i64(t0, t0, 1);
8322
8323    btarget = addr_add(ctx, ctx->pc + 4, offset);
8324
8325    switch (op) {
8326    case OPC_BC1EQZ:
8327        tcg_gen_xori_i64(t0, t0, 1);
8328        ctx->hflags |= MIPS_HFLAG_BC;
8329        break;
8330    case OPC_BC1NEZ:
8331        /* t0 already set */
8332        ctx->hflags |= MIPS_HFLAG_BC;
8333        break;
8334    default:
8335        MIPS_INVAL("cp1 cond branch");
8336        generate_exception_end(ctx, EXCP_RI);
8337        goto out;
8338    }
8339
8340    tcg_gen_trunc_i64_tl(bcond, t0);
8341
8342    ctx->btarget = btarget;
8343
8344    switch (delayslot_size) {
8345    case 2:
8346        ctx->hflags |= MIPS_HFLAG_BDS16;
8347        break;
8348    case 4:
8349        ctx->hflags |= MIPS_HFLAG_BDS32;
8350        break;
8351    }
8352
8353out:
8354    tcg_temp_free_i64(t0);
8355}
8356
8357/* Coprocessor 1 (FPU) */
8358
8359#define FOP(func, fmt) (((fmt) << 21) | (func))
8360
8361enum fopcode {
8362    OPC_ADD_S = FOP(0, FMT_S),
8363    OPC_SUB_S = FOP(1, FMT_S),
8364    OPC_MUL_S = FOP(2, FMT_S),
8365    OPC_DIV_S = FOP(3, FMT_S),
8366    OPC_SQRT_S = FOP(4, FMT_S),
8367    OPC_ABS_S = FOP(5, FMT_S),
8368    OPC_MOV_S = FOP(6, FMT_S),
8369    OPC_NEG_S = FOP(7, FMT_S),
8370    OPC_ROUND_L_S = FOP(8, FMT_S),
8371    OPC_TRUNC_L_S = FOP(9, FMT_S),
8372    OPC_CEIL_L_S = FOP(10, FMT_S),
8373    OPC_FLOOR_L_S = FOP(11, FMT_S),
8374    OPC_ROUND_W_S = FOP(12, FMT_S),
8375    OPC_TRUNC_W_S = FOP(13, FMT_S),
8376    OPC_CEIL_W_S = FOP(14, FMT_S),
8377    OPC_FLOOR_W_S = FOP(15, FMT_S),
8378    OPC_SEL_S = FOP(16, FMT_S),
8379    OPC_MOVCF_S = FOP(17, FMT_S),
8380    OPC_MOVZ_S = FOP(18, FMT_S),
8381    OPC_MOVN_S = FOP(19, FMT_S),
8382    OPC_SELEQZ_S = FOP(20, FMT_S),
8383    OPC_RECIP_S = FOP(21, FMT_S),
8384    OPC_RSQRT_S = FOP(22, FMT_S),
8385    OPC_SELNEZ_S = FOP(23, FMT_S),
8386    OPC_MADDF_S = FOP(24, FMT_S),
8387    OPC_MSUBF_S = FOP(25, FMT_S),
8388    OPC_RINT_S = FOP(26, FMT_S),
8389    OPC_CLASS_S = FOP(27, FMT_S),
8390    OPC_MIN_S = FOP(28, FMT_S),
8391    OPC_RECIP2_S = FOP(28, FMT_S),
8392    OPC_MINA_S = FOP(29, FMT_S),
8393    OPC_RECIP1_S = FOP(29, FMT_S),
8394    OPC_MAX_S = FOP(30, FMT_S),
8395    OPC_RSQRT1_S = FOP(30, FMT_S),
8396    OPC_MAXA_S = FOP(31, FMT_S),
8397    OPC_RSQRT2_S = FOP(31, FMT_S),
8398    OPC_CVT_D_S = FOP(33, FMT_S),
8399    OPC_CVT_W_S = FOP(36, FMT_S),
8400    OPC_CVT_L_S = FOP(37, FMT_S),
8401    OPC_CVT_PS_S = FOP(38, FMT_S),
8402    OPC_CMP_F_S = FOP (48, FMT_S),
8403    OPC_CMP_UN_S = FOP (49, FMT_S),
8404    OPC_CMP_EQ_S = FOP (50, FMT_S),
8405    OPC_CMP_UEQ_S = FOP (51, FMT_S),
8406    OPC_CMP_OLT_S = FOP (52, FMT_S),
8407    OPC_CMP_ULT_S = FOP (53, FMT_S),
8408    OPC_CMP_OLE_S = FOP (54, FMT_S),
8409    OPC_CMP_ULE_S = FOP (55, FMT_S),
8410    OPC_CMP_SF_S = FOP (56, FMT_S),
8411    OPC_CMP_NGLE_S = FOP (57, FMT_S),
8412    OPC_CMP_SEQ_S = FOP (58, FMT_S),
8413    OPC_CMP_NGL_S = FOP (59, FMT_S),
8414    OPC_CMP_LT_S = FOP (60, FMT_S),
8415    OPC_CMP_NGE_S = FOP (61, FMT_S),
8416    OPC_CMP_LE_S = FOP (62, FMT_S),
8417    OPC_CMP_NGT_S = FOP (63, FMT_S),
8418
8419    OPC_ADD_D = FOP(0, FMT_D),
8420    OPC_SUB_D = FOP(1, FMT_D),
8421    OPC_MUL_D = FOP(2, FMT_D),
8422    OPC_DIV_D = FOP(3, FMT_D),
8423    OPC_SQRT_D = FOP(4, FMT_D),
8424    OPC_ABS_D = FOP(5, FMT_D),
8425    OPC_MOV_D = FOP(6, FMT_D),
8426    OPC_NEG_D = FOP(7, FMT_D),
8427    OPC_ROUND_L_D = FOP(8, FMT_D),
8428    OPC_TRUNC_L_D = FOP(9, FMT_D),
8429    OPC_CEIL_L_D = FOP(10, FMT_D),
8430    OPC_FLOOR_L_D = FOP(11, FMT_D),
8431    OPC_ROUND_W_D = FOP(12, FMT_D),
8432    OPC_TRUNC_W_D = FOP(13, FMT_D),
8433    OPC_CEIL_W_D = FOP(14, FMT_D),
8434    OPC_FLOOR_W_D = FOP(15, FMT_D),
8435    OPC_SEL_D = FOP(16, FMT_D),
8436    OPC_MOVCF_D = FOP(17, FMT_D),
8437    OPC_MOVZ_D = FOP(18, FMT_D),
8438    OPC_MOVN_D = FOP(19, FMT_D),
8439    OPC_SELEQZ_D = FOP(20, FMT_D),
8440    OPC_RECIP_D = FOP(21, FMT_D),
8441    OPC_RSQRT_D = FOP(22, FMT_D),
8442    OPC_SELNEZ_D = FOP(23, FMT_D),
8443    OPC_MADDF_D = FOP(24, FMT_D),
8444    OPC_MSUBF_D = FOP(25, FMT_D),
8445    OPC_RINT_D = FOP(26, FMT_D),
8446    OPC_CLASS_D = FOP(27, FMT_D),
8447    OPC_MIN_D = FOP(28, FMT_D),
8448    OPC_RECIP2_D = FOP(28, FMT_D),
8449    OPC_MINA_D = FOP(29, FMT_D),
8450    OPC_RECIP1_D = FOP(29, FMT_D),
8451    OPC_MAX_D = FOP(30, FMT_D),
8452    OPC_RSQRT1_D = FOP(30, FMT_D),
8453    OPC_MAXA_D = FOP(31, FMT_D),
8454    OPC_RSQRT2_D = FOP(31, FMT_D),
8455    OPC_CVT_S_D = FOP(32, FMT_D),
8456    OPC_CVT_W_D = FOP(36, FMT_D),
8457    OPC_CVT_L_D = FOP(37, FMT_D),
8458    OPC_CMP_F_D = FOP (48, FMT_D),
8459    OPC_CMP_UN_D = FOP (49, FMT_D),
8460    OPC_CMP_EQ_D = FOP (50, FMT_D),
8461    OPC_CMP_UEQ_D = FOP (51, FMT_D),
8462    OPC_CMP_OLT_D = FOP (52, FMT_D),
8463    OPC_CMP_ULT_D = FOP (53, FMT_D),
8464    OPC_CMP_OLE_D = FOP (54, FMT_D),
8465    OPC_CMP_ULE_D = FOP (55, FMT_D),
8466    OPC_CMP_SF_D = FOP (56, FMT_D),
8467    OPC_CMP_NGLE_D = FOP (57, FMT_D),
8468    OPC_CMP_SEQ_D = FOP (58, FMT_D),
8469    OPC_CMP_NGL_D = FOP (59, FMT_D),
8470    OPC_CMP_LT_D = FOP (60, FMT_D),
8471    OPC_CMP_NGE_D = FOP (61, FMT_D),
8472    OPC_CMP_LE_D = FOP (62, FMT_D),
8473    OPC_CMP_NGT_D = FOP (63, FMT_D),
8474
8475    OPC_CVT_S_W = FOP(32, FMT_W),
8476    OPC_CVT_D_W = FOP(33, FMT_W),
8477    OPC_CVT_S_L = FOP(32, FMT_L),
8478    OPC_CVT_D_L = FOP(33, FMT_L),
8479    OPC_CVT_PS_PW = FOP(38, FMT_W),
8480
8481    OPC_ADD_PS = FOP(0, FMT_PS),
8482    OPC_SUB_PS = FOP(1, FMT_PS),
8483    OPC_MUL_PS = FOP(2, FMT_PS),
8484    OPC_DIV_PS = FOP(3, FMT_PS),
8485    OPC_ABS_PS = FOP(5, FMT_PS),
8486    OPC_MOV_PS = FOP(6, FMT_PS),
8487    OPC_NEG_PS = FOP(7, FMT_PS),
8488    OPC_MOVCF_PS = FOP(17, FMT_PS),
8489    OPC_MOVZ_PS = FOP(18, FMT_PS),
8490    OPC_MOVN_PS = FOP(19, FMT_PS),
8491    OPC_ADDR_PS = FOP(24, FMT_PS),
8492    OPC_MULR_PS = FOP(26, FMT_PS),
8493    OPC_RECIP2_PS = FOP(28, FMT_PS),
8494    OPC_RECIP1_PS = FOP(29, FMT_PS),
8495    OPC_RSQRT1_PS = FOP(30, FMT_PS),
8496    OPC_RSQRT2_PS = FOP(31, FMT_PS),
8497
8498    OPC_CVT_S_PU = FOP(32, FMT_PS),
8499    OPC_CVT_PW_PS = FOP(36, FMT_PS),
8500    OPC_CVT_S_PL = FOP(40, FMT_PS),
8501    OPC_PLL_PS = FOP(44, FMT_PS),
8502    OPC_PLU_PS = FOP(45, FMT_PS),
8503    OPC_PUL_PS = FOP(46, FMT_PS),
8504    OPC_PUU_PS = FOP(47, FMT_PS),
8505    OPC_CMP_F_PS = FOP (48, FMT_PS),
8506    OPC_CMP_UN_PS = FOP (49, FMT_PS),
8507    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8508    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8509    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8510    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8511    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8512    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8513    OPC_CMP_SF_PS = FOP (56, FMT_PS),
8514    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8515    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8516    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8517    OPC_CMP_LT_PS = FOP (60, FMT_PS),
8518    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8519    OPC_CMP_LE_PS = FOP (62, FMT_PS),
8520    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8521};
8522
8523enum r6_f_cmp_op {
8524    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
8525    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
8526    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
8527    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
8528    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
8529    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
8530    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
8531    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
8532    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
8533    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
8534    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
8535    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8536    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
8537    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8538    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
8539    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8540    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
8541    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
8542    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
8543    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
8544    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8545    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
8546
8547    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
8548    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
8549    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
8550    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
8551    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
8552    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
8553    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
8554    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
8555    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
8556    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
8557    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
8558    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8559    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
8560    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8561    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
8562    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8563    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
8564    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
8565    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
8566    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
8567    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8568    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
8569};
8570static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8571{
8572    TCGv t0 = tcg_temp_new();
8573
8574    switch (opc) {
8575    case OPC_MFC1:
8576        {
8577            TCGv_i32 fp0 = tcg_temp_new_i32();
8578
8579            gen_load_fpr32(ctx, fp0, fs);
8580            tcg_gen_ext_i32_tl(t0, fp0);
8581            tcg_temp_free_i32(fp0);
8582        }
8583        gen_store_gpr(t0, rt);
8584        break;
8585    case OPC_MTC1:
8586        gen_load_gpr(t0, rt);
8587        {
8588            TCGv_i32 fp0 = tcg_temp_new_i32();
8589
8590            tcg_gen_trunc_tl_i32(fp0, t0);
8591            gen_store_fpr32(ctx, fp0, fs);
8592            tcg_temp_free_i32(fp0);
8593        }
8594        break;
8595    case OPC_CFC1:
8596        gen_helper_1e0i(cfc1, t0, fs);
8597        gen_store_gpr(t0, rt);
8598        break;
8599    case OPC_CTC1:
8600        gen_load_gpr(t0, rt);
8601        save_cpu_state(ctx, 0);
8602        {
8603            TCGv_i32 fs_tmp = tcg_const_i32(fs);
8604
8605            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8606            tcg_temp_free_i32(fs_tmp);
8607        }
8608        /* Stop translation as we may have changed hflags */
8609        ctx->bstate = BS_STOP;
8610        break;
8611#if defined(TARGET_MIPS64)
8612    case OPC_DMFC1:
8613        gen_load_fpr64(ctx, t0, fs);
8614        gen_store_gpr(t0, rt);
8615        break;
8616    case OPC_DMTC1:
8617        gen_load_gpr(t0, rt);
8618        gen_store_fpr64(ctx, t0, fs);
8619        break;
8620#endif
8621    case OPC_MFHC1:
8622        {
8623            TCGv_i32 fp0 = tcg_temp_new_i32();
8624
8625            gen_load_fpr32h(ctx, fp0, fs);
8626            tcg_gen_ext_i32_tl(t0, fp0);
8627            tcg_temp_free_i32(fp0);
8628        }
8629        gen_store_gpr(t0, rt);
8630        break;
8631    case OPC_MTHC1:
8632        gen_load_gpr(t0, rt);
8633        {
8634            TCGv_i32 fp0 = tcg_temp_new_i32();
8635
8636            tcg_gen_trunc_tl_i32(fp0, t0);
8637            gen_store_fpr32h(ctx, fp0, fs);
8638            tcg_temp_free_i32(fp0);
8639        }
8640        break;
8641    default:
8642        MIPS_INVAL("cp1 move");
8643        generate_exception_end(ctx, EXCP_RI);
8644        goto out;
8645    }
8646
8647 out:
8648    tcg_temp_free(t0);
8649}
8650
8651static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8652{
8653    TCGLabel *l1;
8654    TCGCond cond;
8655    TCGv_i32 t0;
8656
8657    if (rd == 0) {
8658        /* Treat as NOP. */
8659        return;
8660    }
8661
8662    if (tf)
8663        cond = TCG_COND_EQ;
8664    else
8665        cond = TCG_COND_NE;
8666
8667    l1 = gen_new_label();
8668    t0 = tcg_temp_new_i32();
8669    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8670    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8671    tcg_temp_free_i32(t0);
8672    if (rs == 0) {
8673        tcg_gen_movi_tl(cpu_gpr[rd], 0);
8674    } else {
8675        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8676    }
8677    gen_set_label(l1);
8678}
8679
8680static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8681                               int tf)
8682{
8683    int cond;
8684    TCGv_i32 t0 = tcg_temp_new_i32();
8685    TCGLabel *l1 = gen_new_label();
8686
8687    if (tf)
8688        cond = TCG_COND_EQ;
8689    else
8690        cond = TCG_COND_NE;
8691
8692    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8693    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8694    gen_load_fpr32(ctx, t0, fs);
8695    gen_store_fpr32(ctx, t0, fd);
8696    gen_set_label(l1);
8697    tcg_temp_free_i32(t0);
8698}
8699
8700static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8701{
8702    int cond;
8703    TCGv_i32 t0 = tcg_temp_new_i32();
8704    TCGv_i64 fp0;
8705    TCGLabel *l1 = gen_new_label();
8706
8707    if (tf)
8708        cond = TCG_COND_EQ;
8709    else
8710        cond = TCG_COND_NE;
8711
8712    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8713    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8714    tcg_temp_free_i32(t0);
8715    fp0 = tcg_temp_new_i64();
8716    gen_load_fpr64(ctx, fp0, fs);
8717    gen_store_fpr64(ctx, fp0, fd);
8718    tcg_temp_free_i64(fp0);
8719    gen_set_label(l1);
8720}
8721
8722static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8723                                int cc, int tf)
8724{
8725    int cond;
8726    TCGv_i32 t0 = tcg_temp_new_i32();
8727    TCGLabel *l1 = gen_new_label();
8728    TCGLabel *l2 = gen_new_label();
8729
8730    if (tf)
8731        cond = TCG_COND_EQ;
8732    else
8733        cond = TCG_COND_NE;
8734
8735    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8736    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8737    gen_load_fpr32(ctx, t0, fs);
8738    gen_store_fpr32(ctx, t0, fd);
8739    gen_set_label(l1);
8740
8741    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8742    tcg_gen_brcondi_i32(cond, t0, 0, l2);
8743    gen_load_fpr32h(ctx, t0, fs);
8744    gen_store_fpr32h(ctx, t0, fd);
8745    tcg_temp_free_i32(t0);
8746    gen_set_label(l2);
8747}
8748
8749static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8750                      int fs)
8751{
8752    TCGv_i32 t1 = tcg_const_i32(0);
8753    TCGv_i32 fp0 = tcg_temp_new_i32();
8754    TCGv_i32 fp1 = tcg_temp_new_i32();
8755    TCGv_i32 fp2 = tcg_temp_new_i32();
8756    gen_load_fpr32(ctx, fp0, fd);
8757    gen_load_fpr32(ctx, fp1, ft);
8758    gen_load_fpr32(ctx, fp2, fs);
8759
8760    switch (op1) {
8761    case OPC_SEL_S:
8762        tcg_gen_andi_i32(fp0, fp0, 1);
8763        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8764        break;
8765    case OPC_SELEQZ_S:
8766        tcg_gen_andi_i32(fp1, fp1, 1);
8767        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8768        break;
8769    case OPC_SELNEZ_S:
8770        tcg_gen_andi_i32(fp1, fp1, 1);
8771        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8772        break;
8773    default:
8774        MIPS_INVAL("gen_sel_s");
8775        generate_exception_end(ctx, EXCP_RI);
8776        break;
8777    }
8778
8779    gen_store_fpr32(ctx, fp0, fd);
8780    tcg_temp_free_i32(fp2);
8781    tcg_temp_free_i32(fp1);
8782    tcg_temp_free_i32(fp0);
8783    tcg_temp_free_i32(t1);
8784}
8785
8786static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8787                      int fs)
8788{
8789    TCGv_i64 t1 = tcg_const_i64(0);
8790    TCGv_i64 fp0 = tcg_temp_new_i64();
8791    TCGv_i64 fp1 = tcg_temp_new_i64();
8792    TCGv_i64 fp2 = tcg_temp_new_i64();
8793    gen_load_fpr64(ctx, fp0, fd);
8794    gen_load_fpr64(ctx, fp1, ft);
8795    gen_load_fpr64(ctx, fp2, fs);
8796
8797    switch (op1) {
8798    case OPC_SEL_D:
8799        tcg_gen_andi_i64(fp0, fp0, 1);
8800        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8801        break;
8802    case OPC_SELEQZ_D:
8803        tcg_gen_andi_i64(fp1, fp1, 1);
8804        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8805        break;
8806    case OPC_SELNEZ_D:
8807        tcg_gen_andi_i64(fp1, fp1, 1);
8808        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8809        break;
8810    default:
8811        MIPS_INVAL("gen_sel_d");
8812        generate_exception_end(ctx, EXCP_RI);
8813        break;
8814    }
8815
8816    gen_store_fpr64(ctx, fp0, fd);
8817    tcg_temp_free_i64(fp2);
8818    tcg_temp_free_i64(fp1);
8819    tcg_temp_free_i64(fp0);
8820    tcg_temp_free_i64(t1);
8821}
8822
8823static void gen_farith (DisasContext *ctx, enum fopcode op1,
8824                        int ft, int fs, int fd, int cc)
8825{
8826    uint32_t func = ctx->opcode & 0x3f;
8827    switch (op1) {
8828    case OPC_ADD_S:
8829        {
8830            TCGv_i32 fp0 = tcg_temp_new_i32();
8831            TCGv_i32 fp1 = tcg_temp_new_i32();
8832
8833            gen_load_fpr32(ctx, fp0, fs);
8834            gen_load_fpr32(ctx, fp1, ft);
8835            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8836            tcg_temp_free_i32(fp1);
8837            gen_store_fpr32(ctx, fp0, fd);
8838            tcg_temp_free_i32(fp0);
8839        }
8840        break;
8841    case OPC_SUB_S:
8842        {
8843            TCGv_i32 fp0 = tcg_temp_new_i32();
8844            TCGv_i32 fp1 = tcg_temp_new_i32();
8845
8846            gen_load_fpr32(ctx, fp0, fs);
8847            gen_load_fpr32(ctx, fp1, ft);
8848            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8849            tcg_temp_free_i32(fp1);
8850            gen_store_fpr32(ctx, fp0, fd);
8851            tcg_temp_free_i32(fp0);
8852        }
8853        break;
8854    case OPC_MUL_S:
8855        {
8856            TCGv_i32 fp0 = tcg_temp_new_i32();
8857            TCGv_i32 fp1 = tcg_temp_new_i32();
8858
8859            gen_load_fpr32(ctx, fp0, fs);
8860            gen_load_fpr32(ctx, fp1, ft);
8861            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8862            tcg_temp_free_i32(fp1);
8863            gen_store_fpr32(ctx, fp0, fd);
8864            tcg_temp_free_i32(fp0);
8865        }
8866        break;
8867    case OPC_DIV_S:
8868        {
8869            TCGv_i32 fp0 = tcg_temp_new_i32();
8870            TCGv_i32 fp1 = tcg_temp_new_i32();
8871
8872            gen_load_fpr32(ctx, fp0, fs);
8873            gen_load_fpr32(ctx, fp1, ft);
8874            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8875            tcg_temp_free_i32(fp1);
8876            gen_store_fpr32(ctx, fp0, fd);
8877            tcg_temp_free_i32(fp0);
8878        }
8879        break;
8880    case OPC_SQRT_S:
8881        {
8882            TCGv_i32 fp0 = tcg_temp_new_i32();
8883
8884            gen_load_fpr32(ctx, fp0, fs);
8885            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8886            gen_store_fpr32(ctx, fp0, fd);
8887            tcg_temp_free_i32(fp0);
8888        }
8889        break;
8890    case OPC_ABS_S:
8891        {
8892            TCGv_i32 fp0 = tcg_temp_new_i32();
8893
8894            gen_load_fpr32(ctx, fp0, fs);
8895            if (ctx->abs2008) {
8896                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
8897            } else {
8898                gen_helper_float_abs_s(fp0, fp0);
8899            }
8900            gen_store_fpr32(ctx, fp0, fd);
8901            tcg_temp_free_i32(fp0);
8902        }
8903        break;
8904    case OPC_MOV_S:
8905        {
8906            TCGv_i32 fp0 = tcg_temp_new_i32();
8907
8908            gen_load_fpr32(ctx, fp0, fs);
8909            gen_store_fpr32(ctx, fp0, fd);
8910            tcg_temp_free_i32(fp0);
8911        }
8912        break;
8913    case OPC_NEG_S:
8914        {
8915            TCGv_i32 fp0 = tcg_temp_new_i32();
8916
8917            gen_load_fpr32(ctx, fp0, fs);
8918            if (ctx->abs2008) {
8919                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
8920            } else {
8921                gen_helper_float_chs_s(fp0, fp0);
8922            }
8923            gen_store_fpr32(ctx, fp0, fd);
8924            tcg_temp_free_i32(fp0);
8925        }
8926        break;
8927    case OPC_ROUND_L_S:
8928        check_cp1_64bitmode(ctx);
8929        {
8930            TCGv_i32 fp32 = tcg_temp_new_i32();
8931            TCGv_i64 fp64 = tcg_temp_new_i64();
8932
8933            gen_load_fpr32(ctx, fp32, fs);
8934            if (ctx->nan2008) {
8935                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
8936            } else {
8937                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
8938            }
8939            tcg_temp_free_i32(fp32);
8940            gen_store_fpr64(ctx, fp64, fd);
8941            tcg_temp_free_i64(fp64);
8942        }
8943        break;
8944    case OPC_TRUNC_L_S:
8945        check_cp1_64bitmode(ctx);
8946        {
8947            TCGv_i32 fp32 = tcg_temp_new_i32();
8948            TCGv_i64 fp64 = tcg_temp_new_i64();
8949
8950            gen_load_fpr32(ctx, fp32, fs);
8951            if (ctx->nan2008) {
8952                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
8953            } else {
8954                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
8955            }
8956            tcg_temp_free_i32(fp32);
8957            gen_store_fpr64(ctx, fp64, fd);
8958            tcg_temp_free_i64(fp64);
8959        }
8960        break;
8961    case OPC_CEIL_L_S:
8962        check_cp1_64bitmode(ctx);
8963        {
8964            TCGv_i32 fp32 = tcg_temp_new_i32();
8965            TCGv_i64 fp64 = tcg_temp_new_i64();
8966
8967            gen_load_fpr32(ctx, fp32, fs);
8968            if (ctx->nan2008) {
8969                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
8970            } else {
8971                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
8972            }
8973            tcg_temp_free_i32(fp32);
8974            gen_store_fpr64(ctx, fp64, fd);
8975            tcg_temp_free_i64(fp64);
8976        }
8977        break;
8978    case OPC_FLOOR_L_S:
8979        check_cp1_64bitmode(ctx);
8980        {
8981            TCGv_i32 fp32 = tcg_temp_new_i32();
8982            TCGv_i64 fp64 = tcg_temp_new_i64();
8983
8984            gen_load_fpr32(ctx, fp32, fs);
8985            if (ctx->nan2008) {
8986                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
8987            } else {
8988                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
8989            }
8990            tcg_temp_free_i32(fp32);
8991            gen_store_fpr64(ctx, fp64, fd);
8992            tcg_temp_free_i64(fp64);
8993        }
8994        break;
8995    case OPC_ROUND_W_S:
8996        {
8997            TCGv_i32 fp0 = tcg_temp_new_i32();
8998
8999            gen_load_fpr32(ctx, fp0, fs);
9000            if (ctx->nan2008) {
9001                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9002            } else {
9003                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9004            }
9005            gen_store_fpr32(ctx, fp0, fd);
9006            tcg_temp_free_i32(fp0);
9007        }
9008        break;
9009    case OPC_TRUNC_W_S:
9010        {
9011            TCGv_i32 fp0 = tcg_temp_new_i32();
9012
9013            gen_load_fpr32(ctx, fp0, fs);
9014            if (ctx->nan2008) {
9015                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9016            } else {
9017                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9018            }
9019            gen_store_fpr32(ctx, fp0, fd);
9020            tcg_temp_free_i32(fp0);
9021        }
9022        break;
9023    case OPC_CEIL_W_S:
9024        {
9025            TCGv_i32 fp0 = tcg_temp_new_i32();
9026
9027            gen_load_fpr32(ctx, fp0, fs);
9028            if (ctx->nan2008) {
9029                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9030            } else {
9031                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9032            }
9033            gen_store_fpr32(ctx, fp0, fd);
9034            tcg_temp_free_i32(fp0);
9035        }
9036        break;
9037    case OPC_FLOOR_W_S:
9038        {
9039            TCGv_i32 fp0 = tcg_temp_new_i32();
9040
9041            gen_load_fpr32(ctx, fp0, fs);
9042            if (ctx->nan2008) {
9043                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9044            } else {
9045                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9046            }
9047            gen_store_fpr32(ctx, fp0, fd);
9048            tcg_temp_free_i32(fp0);
9049        }
9050        break;
9051    case OPC_SEL_S:
9052        check_insn(ctx, ISA_MIPS32R6);
9053        gen_sel_s(ctx, op1, fd, ft, fs);
9054        break;
9055    case OPC_SELEQZ_S:
9056        check_insn(ctx, ISA_MIPS32R6);
9057        gen_sel_s(ctx, op1, fd, ft, fs);
9058        break;
9059    case OPC_SELNEZ_S:
9060        check_insn(ctx, ISA_MIPS32R6);
9061        gen_sel_s(ctx, op1, fd, ft, fs);
9062        break;
9063    case OPC_MOVCF_S:
9064        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9065        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9066        break;
9067    case OPC_MOVZ_S:
9068        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9069        {
9070            TCGLabel *l1 = gen_new_label();
9071            TCGv_i32 fp0;
9072
9073            if (ft != 0) {
9074                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9075            }
9076            fp0 = tcg_temp_new_i32();
9077            gen_load_fpr32(ctx, fp0, fs);
9078            gen_store_fpr32(ctx, fp0, fd);
9079            tcg_temp_free_i32(fp0);
9080            gen_set_label(l1);
9081        }
9082        break;
9083    case OPC_MOVN_S:
9084        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9085        {
9086            TCGLabel *l1 = gen_new_label();
9087            TCGv_i32 fp0;
9088
9089            if (ft != 0) {
9090                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9091                fp0 = tcg_temp_new_i32();
9092                gen_load_fpr32(ctx, fp0, fs);
9093                gen_store_fpr32(ctx, fp0, fd);
9094                tcg_temp_free_i32(fp0);
9095                gen_set_label(l1);
9096            }
9097        }
9098        break;
9099    case OPC_RECIP_S:
9100        {
9101            TCGv_i32 fp0 = tcg_temp_new_i32();
9102
9103            gen_load_fpr32(ctx, fp0, fs);
9104            gen_helper_float_recip_s(fp0, cpu_env, fp0);
9105            gen_store_fpr32(ctx, fp0, fd);
9106            tcg_temp_free_i32(fp0);
9107        }
9108        break;
9109    case OPC_RSQRT_S:
9110        {
9111            TCGv_i32 fp0 = tcg_temp_new_i32();
9112
9113            gen_load_fpr32(ctx, fp0, fs);
9114            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9115            gen_store_fpr32(ctx, fp0, fd);
9116            tcg_temp_free_i32(fp0);
9117        }
9118        break;
9119    case OPC_MADDF_S:
9120        check_insn(ctx, ISA_MIPS32R6);
9121        {
9122            TCGv_i32 fp0 = tcg_temp_new_i32();
9123            TCGv_i32 fp1 = tcg_temp_new_i32();
9124            TCGv_i32 fp2 = tcg_temp_new_i32();
9125            gen_load_fpr32(ctx, fp0, fs);
9126            gen_load_fpr32(ctx, fp1, ft);
9127            gen_load_fpr32(ctx, fp2, fd);
9128            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9129            gen_store_fpr32(ctx, fp2, fd);
9130            tcg_temp_free_i32(fp2);
9131            tcg_temp_free_i32(fp1);
9132            tcg_temp_free_i32(fp0);
9133        }
9134        break;
9135    case OPC_MSUBF_S:
9136        check_insn(ctx, ISA_MIPS32R6);
9137        {
9138            TCGv_i32 fp0 = tcg_temp_new_i32();
9139            TCGv_i32 fp1 = tcg_temp_new_i32();
9140            TCGv_i32 fp2 = tcg_temp_new_i32();
9141            gen_load_fpr32(ctx, fp0, fs);
9142            gen_load_fpr32(ctx, fp1, ft);
9143            gen_load_fpr32(ctx, fp2, fd);
9144            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9145            gen_store_fpr32(ctx, fp2, fd);
9146            tcg_temp_free_i32(fp2);
9147            tcg_temp_free_i32(fp1);
9148            tcg_temp_free_i32(fp0);
9149        }
9150        break;
9151    case OPC_RINT_S:
9152        check_insn(ctx, ISA_MIPS32R6);
9153        {
9154            TCGv_i32 fp0 = tcg_temp_new_i32();
9155            gen_load_fpr32(ctx, fp0, fs);
9156            gen_helper_float_rint_s(fp0, cpu_env, fp0);
9157            gen_store_fpr32(ctx, fp0, fd);
9158            tcg_temp_free_i32(fp0);
9159        }
9160        break;
9161    case OPC_CLASS_S:
9162        check_insn(ctx, ISA_MIPS32R6);
9163        {
9164            TCGv_i32 fp0 = tcg_temp_new_i32();
9165            gen_load_fpr32(ctx, fp0, fs);
9166            gen_helper_float_class_s(fp0, cpu_env, fp0);
9167            gen_store_fpr32(ctx, fp0, fd);
9168            tcg_temp_free_i32(fp0);
9169        }
9170        break;
9171    case OPC_MIN_S: /* OPC_RECIP2_S */
9172        if (ctx->insn_flags & ISA_MIPS32R6) {
9173            /* OPC_MIN_S */
9174            TCGv_i32 fp0 = tcg_temp_new_i32();
9175            TCGv_i32 fp1 = tcg_temp_new_i32();
9176            TCGv_i32 fp2 = tcg_temp_new_i32();
9177            gen_load_fpr32(ctx, fp0, fs);
9178            gen_load_fpr32(ctx, fp1, ft);
9179            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9180            gen_store_fpr32(ctx, fp2, fd);
9181            tcg_temp_free_i32(fp2);
9182            tcg_temp_free_i32(fp1);
9183            tcg_temp_free_i32(fp0);
9184        } else {
9185            /* OPC_RECIP2_S */
9186            check_cp1_64bitmode(ctx);
9187            {
9188                TCGv_i32 fp0 = tcg_temp_new_i32();
9189                TCGv_i32 fp1 = tcg_temp_new_i32();
9190
9191                gen_load_fpr32(ctx, fp0, fs);
9192                gen_load_fpr32(ctx, fp1, ft);
9193                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9194                tcg_temp_free_i32(fp1);
9195                gen_store_fpr32(ctx, fp0, fd);
9196                tcg_temp_free_i32(fp0);
9197            }
9198        }
9199        break;
9200    case OPC_MINA_S: /* OPC_RECIP1_S */
9201        if (ctx->insn_flags & ISA_MIPS32R6) {
9202            /* OPC_MINA_S */
9203            TCGv_i32 fp0 = tcg_temp_new_i32();
9204            TCGv_i32 fp1 = tcg_temp_new_i32();
9205            TCGv_i32 fp2 = tcg_temp_new_i32();
9206            gen_load_fpr32(ctx, fp0, fs);
9207            gen_load_fpr32(ctx, fp1, ft);
9208            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9209            gen_store_fpr32(ctx, fp2, fd);
9210            tcg_temp_free_i32(fp2);
9211            tcg_temp_free_i32(fp1);
9212            tcg_temp_free_i32(fp0);
9213        } else {
9214            /* OPC_RECIP1_S */
9215            check_cp1_64bitmode(ctx);
9216            {
9217                TCGv_i32 fp0 = tcg_temp_new_i32();
9218
9219                gen_load_fpr32(ctx, fp0, fs);
9220                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9221                gen_store_fpr32(ctx, fp0, fd);
9222                tcg_temp_free_i32(fp0);
9223            }
9224        }
9225        break;
9226    case OPC_MAX_S: /* OPC_RSQRT1_S */
9227        if (ctx->insn_flags & ISA_MIPS32R6) {
9228            /* OPC_MAX_S */
9229            TCGv_i32 fp0 = tcg_temp_new_i32();
9230            TCGv_i32 fp1 = tcg_temp_new_i32();
9231            gen_load_fpr32(ctx, fp0, fs);
9232            gen_load_fpr32(ctx, fp1, ft);
9233            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9234            gen_store_fpr32(ctx, fp1, fd);
9235            tcg_temp_free_i32(fp1);
9236            tcg_temp_free_i32(fp0);
9237        } else {
9238            /* OPC_RSQRT1_S */
9239            check_cp1_64bitmode(ctx);
9240            {
9241                TCGv_i32 fp0 = tcg_temp_new_i32();
9242
9243                gen_load_fpr32(ctx, fp0, fs);
9244                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9245                gen_store_fpr32(ctx, fp0, fd);
9246                tcg_temp_free_i32(fp0);
9247            }
9248        }
9249        break;
9250    case OPC_MAXA_S: /* OPC_RSQRT2_S */
9251        if (ctx->insn_flags & ISA_MIPS32R6) {
9252            /* OPC_MAXA_S */
9253            TCGv_i32 fp0 = tcg_temp_new_i32();
9254            TCGv_i32 fp1 = tcg_temp_new_i32();
9255            gen_load_fpr32(ctx, fp0, fs);
9256            gen_load_fpr32(ctx, fp1, ft);
9257            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9258            gen_store_fpr32(ctx, fp1, fd);
9259            tcg_temp_free_i32(fp1);
9260            tcg_temp_free_i32(fp0);
9261        } else {
9262            /* OPC_RSQRT2_S */
9263            check_cp1_64bitmode(ctx);
9264            {
9265                TCGv_i32 fp0 = tcg_temp_new_i32();
9266                TCGv_i32 fp1 = tcg_temp_new_i32();
9267
9268                gen_load_fpr32(ctx, fp0, fs);
9269                gen_load_fpr32(ctx, fp1, ft);
9270                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9271                tcg_temp_free_i32(fp1);
9272                gen_store_fpr32(ctx, fp0, fd);
9273                tcg_temp_free_i32(fp0);
9274            }
9275        }
9276        break;
9277    case OPC_CVT_D_S:
9278        check_cp1_registers(ctx, fd);
9279        {
9280            TCGv_i32 fp32 = tcg_temp_new_i32();
9281            TCGv_i64 fp64 = tcg_temp_new_i64();
9282
9283            gen_load_fpr32(ctx, fp32, fs);
9284            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9285            tcg_temp_free_i32(fp32);
9286            gen_store_fpr64(ctx, fp64, fd);
9287            tcg_temp_free_i64(fp64);
9288        }
9289        break;
9290    case OPC_CVT_W_S:
9291        {
9292            TCGv_i32 fp0 = tcg_temp_new_i32();
9293
9294            gen_load_fpr32(ctx, fp0, fs);
9295            if (ctx->nan2008) {
9296                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9297            } else {
9298                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9299            }
9300            gen_store_fpr32(ctx, fp0, fd);
9301            tcg_temp_free_i32(fp0);
9302        }
9303        break;
9304    case OPC_CVT_L_S:
9305        check_cp1_64bitmode(ctx);
9306        {
9307            TCGv_i32 fp32 = tcg_temp_new_i32();
9308            TCGv_i64 fp64 = tcg_temp_new_i64();
9309
9310            gen_load_fpr32(ctx, fp32, fs);
9311            if (ctx->nan2008) {
9312                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9313            } else {
9314                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9315            }
9316            tcg_temp_free_i32(fp32);
9317            gen_store_fpr64(ctx, fp64, fd);
9318            tcg_temp_free_i64(fp64);
9319        }
9320        break;
9321    case OPC_CVT_PS_S:
9322        check_ps(ctx);
9323        {
9324            TCGv_i64 fp64 = tcg_temp_new_i64();
9325            TCGv_i32 fp32_0 = tcg_temp_new_i32();
9326            TCGv_i32 fp32_1 = tcg_temp_new_i32();
9327
9328            gen_load_fpr32(ctx, fp32_0, fs);
9329            gen_load_fpr32(ctx, fp32_1, ft);
9330            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9331            tcg_temp_free_i32(fp32_1);
9332            tcg_temp_free_i32(fp32_0);
9333            gen_store_fpr64(ctx, fp64, fd);
9334            tcg_temp_free_i64(fp64);
9335        }
9336        break;
9337    case OPC_CMP_F_S:
9338    case OPC_CMP_UN_S:
9339    case OPC_CMP_EQ_S:
9340    case OPC_CMP_UEQ_S:
9341    case OPC_CMP_OLT_S:
9342    case OPC_CMP_ULT_S:
9343    case OPC_CMP_OLE_S:
9344    case OPC_CMP_ULE_S:
9345    case OPC_CMP_SF_S:
9346    case OPC_CMP_NGLE_S:
9347    case OPC_CMP_SEQ_S:
9348    case OPC_CMP_NGL_S:
9349    case OPC_CMP_LT_S:
9350    case OPC_CMP_NGE_S:
9351    case OPC_CMP_LE_S:
9352    case OPC_CMP_NGT_S:
9353        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9354        if (ctx->opcode & (1 << 6)) {
9355            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9356        } else {
9357            gen_cmp_s(ctx, func-48, ft, fs, cc);
9358        }
9359        break;
9360    case OPC_ADD_D:
9361        check_cp1_registers(ctx, fs | ft | fd);
9362        {
9363            TCGv_i64 fp0 = tcg_temp_new_i64();
9364            TCGv_i64 fp1 = tcg_temp_new_i64();
9365
9366            gen_load_fpr64(ctx, fp0, fs);
9367            gen_load_fpr64(ctx, fp1, ft);
9368            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9369            tcg_temp_free_i64(fp1);
9370            gen_store_fpr64(ctx, fp0, fd);
9371            tcg_temp_free_i64(fp0);
9372        }
9373        break;
9374    case OPC_SUB_D:
9375        check_cp1_registers(ctx, fs | ft | fd);
9376        {
9377            TCGv_i64 fp0 = tcg_temp_new_i64();
9378            TCGv_i64 fp1 = tcg_temp_new_i64();
9379
9380            gen_load_fpr64(ctx, fp0, fs);
9381            gen_load_fpr64(ctx, fp1, ft);
9382            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9383            tcg_temp_free_i64(fp1);
9384            gen_store_fpr64(ctx, fp0, fd);
9385            tcg_temp_free_i64(fp0);
9386        }
9387        break;
9388    case OPC_MUL_D:
9389        check_cp1_registers(ctx, fs | ft | fd);
9390        {
9391            TCGv_i64 fp0 = tcg_temp_new_i64();
9392            TCGv_i64 fp1 = tcg_temp_new_i64();
9393
9394            gen_load_fpr64(ctx, fp0, fs);
9395            gen_load_fpr64(ctx, fp1, ft);
9396            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9397            tcg_temp_free_i64(fp1);
9398            gen_store_fpr64(ctx, fp0, fd);
9399            tcg_temp_free_i64(fp0);
9400        }
9401        break;
9402    case OPC_DIV_D:
9403        check_cp1_registers(ctx, fs | ft | fd);
9404        {
9405            TCGv_i64 fp0 = tcg_temp_new_i64();
9406            TCGv_i64 fp1 = tcg_temp_new_i64();
9407
9408            gen_load_fpr64(ctx, fp0, fs);
9409            gen_load_fpr64(ctx, fp1, ft);
9410            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9411            tcg_temp_free_i64(fp1);
9412            gen_store_fpr64(ctx, fp0, fd);
9413            tcg_temp_free_i64(fp0);
9414        }
9415        break;
9416    case OPC_SQRT_D:
9417        check_cp1_registers(ctx, fs | fd);
9418        {
9419            TCGv_i64 fp0 = tcg_temp_new_i64();
9420
9421            gen_load_fpr64(ctx, fp0, fs);
9422            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9423            gen_store_fpr64(ctx, fp0, fd);
9424            tcg_temp_free_i64(fp0);
9425        }
9426        break;
9427    case OPC_ABS_D:
9428        check_cp1_registers(ctx, fs | fd);
9429        {
9430            TCGv_i64 fp0 = tcg_temp_new_i64();
9431
9432            gen_load_fpr64(ctx, fp0, fs);
9433            if (ctx->abs2008) {
9434                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9435            } else {
9436                gen_helper_float_abs_d(fp0, fp0);
9437            }
9438            gen_store_fpr64(ctx, fp0, fd);
9439            tcg_temp_free_i64(fp0);
9440        }
9441        break;
9442    case OPC_MOV_D:
9443        check_cp1_registers(ctx, fs | fd);
9444        {
9445            TCGv_i64 fp0 = tcg_temp_new_i64();
9446
9447            gen_load_fpr64(ctx, fp0, fs);
9448            gen_store_fpr64(ctx, fp0, fd);
9449            tcg_temp_free_i64(fp0);
9450        }
9451        break;
9452    case OPC_NEG_D:
9453        check_cp1_registers(ctx, fs | fd);
9454        {
9455            TCGv_i64 fp0 = tcg_temp_new_i64();
9456
9457            gen_load_fpr64(ctx, fp0, fs);
9458            if (ctx->abs2008) {
9459                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9460            } else {
9461                gen_helper_float_chs_d(fp0, fp0);
9462            }
9463            gen_store_fpr64(ctx, fp0, fd);
9464            tcg_temp_free_i64(fp0);
9465        }
9466        break;
9467    case OPC_ROUND_L_D:
9468        check_cp1_64bitmode(ctx);
9469        {
9470            TCGv_i64 fp0 = tcg_temp_new_i64();
9471
9472            gen_load_fpr64(ctx, fp0, fs);
9473            if (ctx->nan2008) {
9474                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9475            } else {
9476                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9477            }
9478            gen_store_fpr64(ctx, fp0, fd);
9479            tcg_temp_free_i64(fp0);
9480        }
9481        break;
9482    case OPC_TRUNC_L_D:
9483        check_cp1_64bitmode(ctx);
9484        {
9485            TCGv_i64 fp0 = tcg_temp_new_i64();
9486
9487            gen_load_fpr64(ctx, fp0, fs);
9488            if (ctx->nan2008) {
9489                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9490            } else {
9491                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9492            }
9493            gen_store_fpr64(ctx, fp0, fd);
9494            tcg_temp_free_i64(fp0);
9495        }
9496        break;
9497    case OPC_CEIL_L_D:
9498        check_cp1_64bitmode(ctx);
9499        {
9500            TCGv_i64 fp0 = tcg_temp_new_i64();
9501
9502            gen_load_fpr64(ctx, fp0, fs);
9503            if (ctx->nan2008) {
9504                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9505            } else {
9506                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9507            }
9508            gen_store_fpr64(ctx, fp0, fd);
9509            tcg_temp_free_i64(fp0);
9510        }
9511        break;
9512    case OPC_FLOOR_L_D:
9513        check_cp1_64bitmode(ctx);
9514        {
9515            TCGv_i64 fp0 = tcg_temp_new_i64();
9516
9517            gen_load_fpr64(ctx, fp0, fs);
9518            if (ctx->nan2008) {
9519                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9520            } else {
9521                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9522            }
9523            gen_store_fpr64(ctx, fp0, fd);
9524            tcg_temp_free_i64(fp0);
9525        }
9526        break;
9527    case OPC_ROUND_W_D:
9528        check_cp1_registers(ctx, fs);
9529        {
9530            TCGv_i32 fp32 = tcg_temp_new_i32();
9531            TCGv_i64 fp64 = tcg_temp_new_i64();
9532
9533            gen_load_fpr64(ctx, fp64, fs);
9534            if (ctx->nan2008) {
9535                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9536            } else {
9537                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9538            }
9539            tcg_temp_free_i64(fp64);
9540            gen_store_fpr32(ctx, fp32, fd);
9541            tcg_temp_free_i32(fp32);
9542        }
9543        break;
9544    case OPC_TRUNC_W_D:
9545        check_cp1_registers(ctx, fs);
9546        {
9547            TCGv_i32 fp32 = tcg_temp_new_i32();
9548            TCGv_i64 fp64 = tcg_temp_new_i64();
9549
9550            gen_load_fpr64(ctx, fp64, fs);
9551            if (ctx->nan2008) {
9552                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9553            } else {
9554                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9555            }
9556            tcg_temp_free_i64(fp64);
9557            gen_store_fpr32(ctx, fp32, fd);
9558            tcg_temp_free_i32(fp32);
9559        }
9560        break;
9561    case OPC_CEIL_W_D:
9562        check_cp1_registers(ctx, fs);
9563        {
9564            TCGv_i32 fp32 = tcg_temp_new_i32();
9565            TCGv_i64 fp64 = tcg_temp_new_i64();
9566
9567            gen_load_fpr64(ctx, fp64, fs);
9568            if (ctx->nan2008) {
9569                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9570            } else {
9571                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9572            }
9573            tcg_temp_free_i64(fp64);
9574            gen_store_fpr32(ctx, fp32, fd);
9575            tcg_temp_free_i32(fp32);
9576        }
9577        break;
9578    case OPC_FLOOR_W_D:
9579        check_cp1_registers(ctx, fs);
9580        {
9581            TCGv_i32 fp32 = tcg_temp_new_i32();
9582            TCGv_i64 fp64 = tcg_temp_new_i64();
9583
9584            gen_load_fpr64(ctx, fp64, fs);
9585            if (ctx->nan2008) {
9586                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9587            } else {
9588                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9589            }
9590            tcg_temp_free_i64(fp64);
9591            gen_store_fpr32(ctx, fp32, fd);
9592            tcg_temp_free_i32(fp32);
9593        }
9594        break;
9595    case OPC_SEL_D:
9596        check_insn(ctx, ISA_MIPS32R6);
9597        gen_sel_d(ctx, op1, fd, ft, fs);
9598        break;
9599    case OPC_SELEQZ_D:
9600        check_insn(ctx, ISA_MIPS32R6);
9601        gen_sel_d(ctx, op1, fd, ft, fs);
9602        break;
9603    case OPC_SELNEZ_D:
9604        check_insn(ctx, ISA_MIPS32R6);
9605        gen_sel_d(ctx, op1, fd, ft, fs);
9606        break;
9607    case OPC_MOVCF_D:
9608        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9609        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9610        break;
9611    case OPC_MOVZ_D:
9612        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9613        {
9614            TCGLabel *l1 = gen_new_label();
9615            TCGv_i64 fp0;
9616
9617            if (ft != 0) {
9618                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9619            }
9620            fp0 = tcg_temp_new_i64();
9621            gen_load_fpr64(ctx, fp0, fs);
9622            gen_store_fpr64(ctx, fp0, fd);
9623            tcg_temp_free_i64(fp0);
9624            gen_set_label(l1);
9625        }
9626        break;
9627    case OPC_MOVN_D:
9628        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9629        {
9630            TCGLabel *l1 = gen_new_label();
9631            TCGv_i64 fp0;
9632
9633            if (ft != 0) {
9634                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9635                fp0 = tcg_temp_new_i64();
9636                gen_load_fpr64(ctx, fp0, fs);
9637                gen_store_fpr64(ctx, fp0, fd);
9638                tcg_temp_free_i64(fp0);
9639                gen_set_label(l1);
9640            }
9641        }
9642        break;
9643    case OPC_RECIP_D:
9644        check_cp1_registers(ctx, fs | fd);
9645        {
9646            TCGv_i64 fp0 = tcg_temp_new_i64();
9647
9648            gen_load_fpr64(ctx, fp0, fs);
9649            gen_helper_float_recip_d(fp0, cpu_env, fp0);
9650            gen_store_fpr64(ctx, fp0, fd);
9651            tcg_temp_free_i64(fp0);
9652        }
9653        break;
9654    case OPC_RSQRT_D:
9655        check_cp1_registers(ctx, fs | fd);
9656        {
9657            TCGv_i64 fp0 = tcg_temp_new_i64();
9658
9659            gen_load_fpr64(ctx, fp0, fs);
9660            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9661            gen_store_fpr64(ctx, fp0, fd);
9662            tcg_temp_free_i64(fp0);
9663        }
9664        break;
9665    case OPC_MADDF_D:
9666        check_insn(ctx, ISA_MIPS32R6);
9667        {
9668            TCGv_i64 fp0 = tcg_temp_new_i64();
9669            TCGv_i64 fp1 = tcg_temp_new_i64();
9670            TCGv_i64 fp2 = tcg_temp_new_i64();
9671            gen_load_fpr64(ctx, fp0, fs);
9672            gen_load_fpr64(ctx, fp1, ft);
9673            gen_load_fpr64(ctx, fp2, fd);
9674            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9675            gen_store_fpr64(ctx, fp2, fd);
9676            tcg_temp_free_i64(fp2);
9677            tcg_temp_free_i64(fp1);
9678            tcg_temp_free_i64(fp0);
9679        }
9680        break;
9681    case OPC_MSUBF_D:
9682        check_insn(ctx, ISA_MIPS32R6);
9683        {
9684            TCGv_i64 fp0 = tcg_temp_new_i64();
9685            TCGv_i64 fp1 = tcg_temp_new_i64();
9686            TCGv_i64 fp2 = tcg_temp_new_i64();
9687            gen_load_fpr64(ctx, fp0, fs);
9688            gen_load_fpr64(ctx, fp1, ft);
9689            gen_load_fpr64(ctx, fp2, fd);
9690            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9691            gen_store_fpr64(ctx, fp2, fd);
9692            tcg_temp_free_i64(fp2);
9693            tcg_temp_free_i64(fp1);
9694            tcg_temp_free_i64(fp0);
9695        }
9696        break;
9697    case OPC_RINT_D:
9698        check_insn(ctx, ISA_MIPS32R6);
9699        {
9700            TCGv_i64 fp0 = tcg_temp_new_i64();
9701            gen_load_fpr64(ctx, fp0, fs);
9702            gen_helper_float_rint_d(fp0, cpu_env, fp0);
9703            gen_store_fpr64(ctx, fp0, fd);
9704            tcg_temp_free_i64(fp0);
9705        }
9706        break;
9707    case OPC_CLASS_D:
9708        check_insn(ctx, ISA_MIPS32R6);
9709        {
9710            TCGv_i64 fp0 = tcg_temp_new_i64();
9711            gen_load_fpr64(ctx, fp0, fs);
9712            gen_helper_float_class_d(fp0, cpu_env, fp0);
9713            gen_store_fpr64(ctx, fp0, fd);
9714            tcg_temp_free_i64(fp0);
9715        }
9716        break;
9717    case OPC_MIN_D: /* OPC_RECIP2_D */
9718        if (ctx->insn_flags & ISA_MIPS32R6) {
9719            /* OPC_MIN_D */
9720            TCGv_i64 fp0 = tcg_temp_new_i64();
9721            TCGv_i64 fp1 = tcg_temp_new_i64();
9722            gen_load_fpr64(ctx, fp0, fs);
9723            gen_load_fpr64(ctx, fp1, ft);
9724            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9725            gen_store_fpr64(ctx, fp1, fd);
9726            tcg_temp_free_i64(fp1);
9727            tcg_temp_free_i64(fp0);
9728        } else {
9729            /* OPC_RECIP2_D */
9730            check_cp1_64bitmode(ctx);
9731            {
9732                TCGv_i64 fp0 = tcg_temp_new_i64();
9733                TCGv_i64 fp1 = tcg_temp_new_i64();
9734
9735                gen_load_fpr64(ctx, fp0, fs);
9736                gen_load_fpr64(ctx, fp1, ft);
9737                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9738                tcg_temp_free_i64(fp1);
9739                gen_store_fpr64(ctx, fp0, fd);
9740                tcg_temp_free_i64(fp0);
9741            }
9742        }
9743        break;
9744    case OPC_MINA_D: /* OPC_RECIP1_D */
9745        if (ctx->insn_flags & ISA_MIPS32R6) {
9746            /* OPC_MINA_D */
9747            TCGv_i64 fp0 = tcg_temp_new_i64();
9748            TCGv_i64 fp1 = tcg_temp_new_i64();
9749            gen_load_fpr64(ctx, fp0, fs);
9750            gen_load_fpr64(ctx, fp1, ft);
9751            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9752            gen_store_fpr64(ctx, fp1, fd);
9753            tcg_temp_free_i64(fp1);
9754            tcg_temp_free_i64(fp0);
9755        } else {
9756            /* OPC_RECIP1_D */
9757            check_cp1_64bitmode(ctx);
9758            {
9759                TCGv_i64 fp0 = tcg_temp_new_i64();
9760
9761                gen_load_fpr64(ctx, fp0, fs);
9762                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9763                gen_store_fpr64(ctx, fp0, fd);
9764                tcg_temp_free_i64(fp0);
9765            }
9766        }
9767        break;
9768    case OPC_MAX_D: /*  OPC_RSQRT1_D */
9769        if (ctx->insn_flags & ISA_MIPS32R6) {
9770            /* OPC_MAX_D */
9771            TCGv_i64 fp0 = tcg_temp_new_i64();
9772            TCGv_i64 fp1 = tcg_temp_new_i64();
9773            gen_load_fpr64(ctx, fp0, fs);
9774            gen_load_fpr64(ctx, fp1, ft);
9775            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9776            gen_store_fpr64(ctx, fp1, fd);
9777            tcg_temp_free_i64(fp1);
9778            tcg_temp_free_i64(fp0);
9779        } else {
9780            /* OPC_RSQRT1_D */
9781            check_cp1_64bitmode(ctx);
9782            {
9783                TCGv_i64 fp0 = tcg_temp_new_i64();
9784
9785                gen_load_fpr64(ctx, fp0, fs);
9786                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9787                gen_store_fpr64(ctx, fp0, fd);
9788                tcg_temp_free_i64(fp0);
9789            }
9790        }
9791        break;
9792    case OPC_MAXA_D: /* OPC_RSQRT2_D */
9793        if (ctx->insn_flags & ISA_MIPS32R6) {
9794            /* OPC_MAXA_D */
9795            TCGv_i64 fp0 = tcg_temp_new_i64();
9796            TCGv_i64 fp1 = tcg_temp_new_i64();
9797            gen_load_fpr64(ctx, fp0, fs);
9798            gen_load_fpr64(ctx, fp1, ft);
9799            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9800            gen_store_fpr64(ctx, fp1, fd);
9801            tcg_temp_free_i64(fp1);
9802            tcg_temp_free_i64(fp0);
9803        } else {
9804            /* OPC_RSQRT2_D */
9805            check_cp1_64bitmode(ctx);
9806            {
9807                TCGv_i64 fp0 = tcg_temp_new_i64();
9808                TCGv_i64 fp1 = tcg_temp_new_i64();
9809
9810                gen_load_fpr64(ctx, fp0, fs);
9811                gen_load_fpr64(ctx, fp1, ft);
9812                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9813                tcg_temp_free_i64(fp1);
9814                gen_store_fpr64(ctx, fp0, fd);
9815                tcg_temp_free_i64(fp0);
9816            }
9817        }
9818        break;
9819    case OPC_CMP_F_D:
9820    case OPC_CMP_UN_D:
9821    case OPC_CMP_EQ_D:
9822    case OPC_CMP_UEQ_D:
9823    case OPC_CMP_OLT_D:
9824    case OPC_CMP_ULT_D:
9825    case OPC_CMP_OLE_D:
9826    case OPC_CMP_ULE_D:
9827    case OPC_CMP_SF_D:
9828    case OPC_CMP_NGLE_D:
9829    case OPC_CMP_SEQ_D:
9830    case OPC_CMP_NGL_D:
9831    case OPC_CMP_LT_D:
9832    case OPC_CMP_NGE_D:
9833    case OPC_CMP_LE_D:
9834    case OPC_CMP_NGT_D:
9835        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9836        if (ctx->opcode & (1 << 6)) {
9837            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9838        } else {
9839            gen_cmp_d(ctx, func-48, ft, fs, cc);
9840        }
9841        break;
9842    case OPC_CVT_S_D:
9843        check_cp1_registers(ctx, fs);
9844        {
9845            TCGv_i32 fp32 = tcg_temp_new_i32();
9846            TCGv_i64 fp64 = tcg_temp_new_i64();
9847
9848            gen_load_fpr64(ctx, fp64, fs);
9849            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9850            tcg_temp_free_i64(fp64);
9851            gen_store_fpr32(ctx, fp32, fd);
9852            tcg_temp_free_i32(fp32);
9853        }
9854        break;
9855    case OPC_CVT_W_D:
9856        check_cp1_registers(ctx, fs);
9857        {
9858            TCGv_i32 fp32 = tcg_temp_new_i32();
9859            TCGv_i64 fp64 = tcg_temp_new_i64();
9860
9861            gen_load_fpr64(ctx, fp64, fs);
9862            if (ctx->nan2008) {
9863                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
9864            } else {
9865                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
9866            }
9867            tcg_temp_free_i64(fp64);
9868            gen_store_fpr32(ctx, fp32, fd);
9869            tcg_temp_free_i32(fp32);
9870        }
9871        break;
9872    case OPC_CVT_L_D:
9873        check_cp1_64bitmode(ctx);
9874        {
9875            TCGv_i64 fp0 = tcg_temp_new_i64();
9876
9877            gen_load_fpr64(ctx, fp0, fs);
9878            if (ctx->nan2008) {
9879                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
9880            } else {
9881                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
9882            }
9883            gen_store_fpr64(ctx, fp0, fd);
9884            tcg_temp_free_i64(fp0);
9885        }
9886        break;
9887    case OPC_CVT_S_W:
9888        {
9889            TCGv_i32 fp0 = tcg_temp_new_i32();
9890
9891            gen_load_fpr32(ctx, fp0, fs);
9892            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9893            gen_store_fpr32(ctx, fp0, fd);
9894            tcg_temp_free_i32(fp0);
9895        }
9896        break;
9897    case OPC_CVT_D_W:
9898        check_cp1_registers(ctx, fd);
9899        {
9900            TCGv_i32 fp32 = tcg_temp_new_i32();
9901            TCGv_i64 fp64 = tcg_temp_new_i64();
9902
9903            gen_load_fpr32(ctx, fp32, fs);
9904            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9905            tcg_temp_free_i32(fp32);
9906            gen_store_fpr64(ctx, fp64, fd);
9907            tcg_temp_free_i64(fp64);
9908        }
9909        break;
9910    case OPC_CVT_S_L:
9911        check_cp1_64bitmode(ctx);
9912        {
9913            TCGv_i32 fp32 = tcg_temp_new_i32();
9914            TCGv_i64 fp64 = tcg_temp_new_i64();
9915
9916            gen_load_fpr64(ctx, fp64, fs);
9917            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9918            tcg_temp_free_i64(fp64);
9919            gen_store_fpr32(ctx, fp32, fd);
9920            tcg_temp_free_i32(fp32);
9921        }
9922        break;
9923    case OPC_CVT_D_L:
9924        check_cp1_64bitmode(ctx);
9925        {
9926            TCGv_i64 fp0 = tcg_temp_new_i64();
9927
9928            gen_load_fpr64(ctx, fp0, fs);
9929            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9930            gen_store_fpr64(ctx, fp0, fd);
9931            tcg_temp_free_i64(fp0);
9932        }
9933        break;
9934    case OPC_CVT_PS_PW:
9935        check_ps(ctx);
9936        {
9937            TCGv_i64 fp0 = tcg_temp_new_i64();
9938
9939            gen_load_fpr64(ctx, fp0, fs);
9940            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9941            gen_store_fpr64(ctx, fp0, fd);
9942            tcg_temp_free_i64(fp0);
9943        }
9944        break;
9945    case OPC_ADD_PS:
9946        check_ps(ctx);
9947        {
9948            TCGv_i64 fp0 = tcg_temp_new_i64();
9949            TCGv_i64 fp1 = tcg_temp_new_i64();
9950
9951            gen_load_fpr64(ctx, fp0, fs);
9952            gen_load_fpr64(ctx, fp1, ft);
9953            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9954            tcg_temp_free_i64(fp1);
9955            gen_store_fpr64(ctx, fp0, fd);
9956            tcg_temp_free_i64(fp0);
9957        }
9958        break;
9959    case OPC_SUB_PS:
9960        check_ps(ctx);
9961        {
9962            TCGv_i64 fp0 = tcg_temp_new_i64();
9963            TCGv_i64 fp1 = tcg_temp_new_i64();
9964
9965            gen_load_fpr64(ctx, fp0, fs);
9966            gen_load_fpr64(ctx, fp1, ft);
9967            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9968            tcg_temp_free_i64(fp1);
9969            gen_store_fpr64(ctx, fp0, fd);
9970            tcg_temp_free_i64(fp0);
9971        }
9972        break;
9973    case OPC_MUL_PS:
9974        check_ps(ctx);
9975        {
9976            TCGv_i64 fp0 = tcg_temp_new_i64();
9977            TCGv_i64 fp1 = tcg_temp_new_i64();
9978
9979            gen_load_fpr64(ctx, fp0, fs);
9980            gen_load_fpr64(ctx, fp1, ft);
9981            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9982            tcg_temp_free_i64(fp1);
9983            gen_store_fpr64(ctx, fp0, fd);
9984            tcg_temp_free_i64(fp0);
9985        }
9986        break;
9987    case OPC_ABS_PS:
9988        check_ps(ctx);
9989        {
9990            TCGv_i64 fp0 = tcg_temp_new_i64();
9991
9992            gen_load_fpr64(ctx, fp0, fs);
9993            gen_helper_float_abs_ps(fp0, fp0);
9994            gen_store_fpr64(ctx, fp0, fd);
9995            tcg_temp_free_i64(fp0);
9996        }
9997        break;
9998    case OPC_MOV_PS:
9999        check_ps(ctx);
10000        {
10001            TCGv_i64 fp0 = tcg_temp_new_i64();
10002
10003            gen_load_fpr64(ctx, fp0, fs);
10004            gen_store_fpr64(ctx, fp0, fd);
10005            tcg_temp_free_i64(fp0);
10006        }
10007        break;
10008    case OPC_NEG_PS:
10009        check_ps(ctx);
10010        {
10011            TCGv_i64 fp0 = tcg_temp_new_i64();
10012
10013            gen_load_fpr64(ctx, fp0, fs);
10014            gen_helper_float_chs_ps(fp0, fp0);
10015            gen_store_fpr64(ctx, fp0, fd);
10016            tcg_temp_free_i64(fp0);
10017        }
10018        break;
10019    case OPC_MOVCF_PS:
10020        check_ps(ctx);
10021        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10022        break;
10023    case OPC_MOVZ_PS:
10024        check_ps(ctx);
10025        {
10026            TCGLabel *l1 = gen_new_label();
10027            TCGv_i64 fp0;
10028
10029            if (ft != 0)
10030                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10031            fp0 = tcg_temp_new_i64();
10032            gen_load_fpr64(ctx, fp0, fs);
10033            gen_store_fpr64(ctx, fp0, fd);
10034            tcg_temp_free_i64(fp0);
10035            gen_set_label(l1);
10036        }
10037        break;
10038    case OPC_MOVN_PS:
10039        check_ps(ctx);
10040        {
10041            TCGLabel *l1 = gen_new_label();
10042            TCGv_i64 fp0;
10043
10044            if (ft != 0) {
10045                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10046                fp0 = tcg_temp_new_i64();
10047                gen_load_fpr64(ctx, fp0, fs);
10048                gen_store_fpr64(ctx, fp0, fd);
10049                tcg_temp_free_i64(fp0);
10050                gen_set_label(l1);
10051            }
10052        }
10053        break;
10054    case OPC_ADDR_PS:
10055        check_ps(ctx);
10056        {
10057            TCGv_i64 fp0 = tcg_temp_new_i64();
10058            TCGv_i64 fp1 = tcg_temp_new_i64();
10059
10060            gen_load_fpr64(ctx, fp0, ft);
10061            gen_load_fpr64(ctx, fp1, fs);
10062            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
10063            tcg_temp_free_i64(fp1);
10064            gen_store_fpr64(ctx, fp0, fd);
10065            tcg_temp_free_i64(fp0);
10066        }
10067        break;
10068    case OPC_MULR_PS:
10069        check_ps(ctx);
10070        {
10071            TCGv_i64 fp0 = tcg_temp_new_i64();
10072            TCGv_i64 fp1 = tcg_temp_new_i64();
10073
10074            gen_load_fpr64(ctx, fp0, ft);
10075            gen_load_fpr64(ctx, fp1, fs);
10076            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
10077            tcg_temp_free_i64(fp1);
10078            gen_store_fpr64(ctx, fp0, fd);
10079            tcg_temp_free_i64(fp0);
10080        }
10081        break;
10082    case OPC_RECIP2_PS:
10083        check_ps(ctx);
10084        {
10085            TCGv_i64 fp0 = tcg_temp_new_i64();
10086            TCGv_i64 fp1 = tcg_temp_new_i64();
10087
10088            gen_load_fpr64(ctx, fp0, fs);
10089            gen_load_fpr64(ctx, fp1, ft);
10090            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
10091            tcg_temp_free_i64(fp1);
10092            gen_store_fpr64(ctx, fp0, fd);
10093            tcg_temp_free_i64(fp0);
10094        }
10095        break;
10096    case OPC_RECIP1_PS:
10097        check_ps(ctx);
10098        {
10099            TCGv_i64 fp0 = tcg_temp_new_i64();
10100
10101            gen_load_fpr64(ctx, fp0, fs);
10102            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10103            gen_store_fpr64(ctx, fp0, fd);
10104            tcg_temp_free_i64(fp0);
10105        }
10106        break;
10107    case OPC_RSQRT1_PS:
10108        check_ps(ctx);
10109        {
10110            TCGv_i64 fp0 = tcg_temp_new_i64();
10111
10112            gen_load_fpr64(ctx, fp0, fs);
10113            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10114            gen_store_fpr64(ctx, fp0, fd);
10115            tcg_temp_free_i64(fp0);
10116        }
10117        break;
10118    case OPC_RSQRT2_PS:
10119        check_ps(ctx);
10120        {
10121            TCGv_i64 fp0 = tcg_temp_new_i64();
10122            TCGv_i64 fp1 = tcg_temp_new_i64();
10123
10124            gen_load_fpr64(ctx, fp0, fs);
10125            gen_load_fpr64(ctx, fp1, ft);
10126            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10127            tcg_temp_free_i64(fp1);
10128            gen_store_fpr64(ctx, fp0, fd);
10129            tcg_temp_free_i64(fp0);
10130        }
10131        break;
10132    case OPC_CVT_S_PU:
10133        check_cp1_64bitmode(ctx);
10134        {
10135            TCGv_i32 fp0 = tcg_temp_new_i32();
10136
10137            gen_load_fpr32h(ctx, fp0, fs);
10138            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10139            gen_store_fpr32(ctx, fp0, fd);
10140            tcg_temp_free_i32(fp0);
10141        }
10142        break;
10143    case OPC_CVT_PW_PS:
10144        check_ps(ctx);
10145        {
10146            TCGv_i64 fp0 = tcg_temp_new_i64();
10147
10148            gen_load_fpr64(ctx, fp0, fs);
10149            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10150            gen_store_fpr64(ctx, fp0, fd);
10151            tcg_temp_free_i64(fp0);
10152        }
10153        break;
10154    case OPC_CVT_S_PL:
10155        check_cp1_64bitmode(ctx);
10156        {
10157            TCGv_i32 fp0 = tcg_temp_new_i32();
10158
10159            gen_load_fpr32(ctx, fp0, fs);
10160            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10161            gen_store_fpr32(ctx, fp0, fd);
10162            tcg_temp_free_i32(fp0);
10163        }
10164        break;
10165    case OPC_PLL_PS:
10166        check_ps(ctx);
10167        {
10168            TCGv_i32 fp0 = tcg_temp_new_i32();
10169            TCGv_i32 fp1 = tcg_temp_new_i32();
10170
10171            gen_load_fpr32(ctx, fp0, fs);
10172            gen_load_fpr32(ctx, fp1, ft);
10173            gen_store_fpr32h(ctx, fp0, fd);
10174            gen_store_fpr32(ctx, fp1, fd);
10175            tcg_temp_free_i32(fp0);
10176            tcg_temp_free_i32(fp1);
10177        }
10178        break;
10179    case OPC_PLU_PS:
10180        check_ps(ctx);
10181        {
10182            TCGv_i32 fp0 = tcg_temp_new_i32();
10183            TCGv_i32 fp1 = tcg_temp_new_i32();
10184
10185            gen_load_fpr32(ctx, fp0, fs);
10186            gen_load_fpr32h(ctx, fp1, ft);
10187            gen_store_fpr32(ctx, fp1, fd);
10188            gen_store_fpr32h(ctx, fp0, fd);
10189            tcg_temp_free_i32(fp0);
10190            tcg_temp_free_i32(fp1);
10191        }
10192        break;
10193    case OPC_PUL_PS:
10194        check_ps(ctx);
10195        {
10196            TCGv_i32 fp0 = tcg_temp_new_i32();
10197            TCGv_i32 fp1 = tcg_temp_new_i32();
10198
10199            gen_load_fpr32h(ctx, fp0, fs);
10200            gen_load_fpr32(ctx, fp1, ft);
10201            gen_store_fpr32(ctx, fp1, fd);
10202            gen_store_fpr32h(ctx, fp0, fd);
10203            tcg_temp_free_i32(fp0);
10204            tcg_temp_free_i32(fp1);
10205        }
10206        break;
10207    case OPC_PUU_PS:
10208        check_ps(ctx);
10209        {
10210            TCGv_i32 fp0 = tcg_temp_new_i32();
10211            TCGv_i32 fp1 = tcg_temp_new_i32();
10212
10213            gen_load_fpr32h(ctx, fp0, fs);
10214            gen_load_fpr32h(ctx, fp1, ft);
10215            gen_store_fpr32(ctx, fp1, fd);
10216            gen_store_fpr32h(ctx, fp0, fd);
10217            tcg_temp_free_i32(fp0);
10218            tcg_temp_free_i32(fp1);
10219        }
10220        break;
10221    case OPC_CMP_F_PS:
10222    case OPC_CMP_UN_PS:
10223    case OPC_CMP_EQ_PS:
10224    case OPC_CMP_UEQ_PS:
10225    case OPC_CMP_OLT_PS:
10226    case OPC_CMP_ULT_PS:
10227    case OPC_CMP_OLE_PS:
10228    case OPC_CMP_ULE_PS:
10229    case OPC_CMP_SF_PS:
10230    case OPC_CMP_NGLE_PS:
10231    case OPC_CMP_SEQ_PS:
10232    case OPC_CMP_NGL_PS:
10233    case OPC_CMP_LT_PS:
10234    case OPC_CMP_NGE_PS:
10235    case OPC_CMP_LE_PS:
10236    case OPC_CMP_NGT_PS:
10237        if (ctx->opcode & (1 << 6)) {
10238            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10239        } else {
10240            gen_cmp_ps(ctx, func-48, ft, fs, cc);
10241        }
10242        break;
10243    default:
10244        MIPS_INVAL("farith");
10245        generate_exception_end(ctx, EXCP_RI);
10246        return;
10247    }
10248}
10249
10250/* Coprocessor 3 (FPU) */
10251static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10252                           int fd, int fs, int base, int index)
10253{
10254    TCGv t0 = tcg_temp_new();
10255
10256    if (base == 0) {
10257        gen_load_gpr(t0, index);
10258    } else if (index == 0) {
10259        gen_load_gpr(t0, base);
10260    } else {
10261        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10262    }
10263    /* Don't do NOP if destination is zero: we must perform the actual
10264       memory access. */
10265    switch (opc) {
10266    case OPC_LWXC1:
10267        check_cop1x(ctx);
10268        {
10269            TCGv_i32 fp0 = tcg_temp_new_i32();
10270
10271            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10272            tcg_gen_trunc_tl_i32(fp0, t0);
10273            gen_store_fpr32(ctx, fp0, fd);
10274            tcg_temp_free_i32(fp0);
10275        }
10276        break;
10277    case OPC_LDXC1:
10278        check_cop1x(ctx);
10279        check_cp1_registers(ctx, fd);
10280        {
10281            TCGv_i64 fp0 = tcg_temp_new_i64();
10282            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10283            gen_store_fpr64(ctx, fp0, fd);
10284            tcg_temp_free_i64(fp0);
10285        }
10286        break;
10287    case OPC_LUXC1:
10288        check_cp1_64bitmode(ctx);
10289        tcg_gen_andi_tl(t0, t0, ~0x7);
10290        {
10291            TCGv_i64 fp0 = tcg_temp_new_i64();
10292
10293            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10294            gen_store_fpr64(ctx, fp0, fd);
10295            tcg_temp_free_i64(fp0);
10296        }
10297        break;
10298    case OPC_SWXC1:
10299        check_cop1x(ctx);
10300        {
10301            TCGv_i32 fp0 = tcg_temp_new_i32();
10302            gen_load_fpr32(ctx, fp0, fs);
10303            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10304            tcg_temp_free_i32(fp0);
10305        }
10306        break;
10307    case OPC_SDXC1:
10308        check_cop1x(ctx);
10309        check_cp1_registers(ctx, fs);
10310        {
10311            TCGv_i64 fp0 = tcg_temp_new_i64();
10312            gen_load_fpr64(ctx, fp0, fs);
10313            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10314            tcg_temp_free_i64(fp0);
10315        }
10316        break;
10317    case OPC_SUXC1:
10318        check_cp1_64bitmode(ctx);
10319        tcg_gen_andi_tl(t0, t0, ~0x7);
10320        {
10321            TCGv_i64 fp0 = tcg_temp_new_i64();
10322            gen_load_fpr64(ctx, fp0, fs);
10323            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10324            tcg_temp_free_i64(fp0);
10325        }
10326        break;
10327    }
10328    tcg_temp_free(t0);
10329}
10330
10331static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10332                            int fd, int fr, int fs, int ft)
10333{
10334    switch (opc) {
10335    case OPC_ALNV_PS:
10336        check_ps(ctx);
10337        {
10338            TCGv t0 = tcg_temp_local_new();
10339            TCGv_i32 fp = tcg_temp_new_i32();
10340            TCGv_i32 fph = tcg_temp_new_i32();
10341            TCGLabel *l1 = gen_new_label();
10342            TCGLabel *l2 = gen_new_label();
10343
10344            gen_load_gpr(t0, fr);
10345            tcg_gen_andi_tl(t0, t0, 0x7);
10346
10347            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10348            gen_load_fpr32(ctx, fp, fs);
10349            gen_load_fpr32h(ctx, fph, fs);
10350            gen_store_fpr32(ctx, fp, fd);
10351            gen_store_fpr32h(ctx, fph, fd);
10352            tcg_gen_br(l2);
10353            gen_set_label(l1);
10354            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10355            tcg_temp_free(t0);
10356#ifdef TARGET_WORDS_BIGENDIAN
10357            gen_load_fpr32(ctx, fp, fs);
10358            gen_load_fpr32h(ctx, fph, ft);
10359            gen_store_fpr32h(ctx, fp, fd);
10360            gen_store_fpr32(ctx, fph, fd);
10361#else
10362            gen_load_fpr32h(ctx, fph, fs);
10363            gen_load_fpr32(ctx, fp, ft);
10364            gen_store_fpr32(ctx, fph, fd);
10365            gen_store_fpr32h(ctx, fp, fd);
10366#endif
10367            gen_set_label(l2);
10368            tcg_temp_free_i32(fp);
10369            tcg_temp_free_i32(fph);
10370        }
10371        break;
10372    case OPC_MADD_S:
10373        check_cop1x(ctx);
10374        {
10375            TCGv_i32 fp0 = tcg_temp_new_i32();
10376            TCGv_i32 fp1 = tcg_temp_new_i32();
10377            TCGv_i32 fp2 = tcg_temp_new_i32();
10378
10379            gen_load_fpr32(ctx, fp0, fs);
10380            gen_load_fpr32(ctx, fp1, ft);
10381            gen_load_fpr32(ctx, fp2, fr);
10382            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10383            tcg_temp_free_i32(fp0);
10384            tcg_temp_free_i32(fp1);
10385            gen_store_fpr32(ctx, fp2, fd);
10386            tcg_temp_free_i32(fp2);
10387        }
10388        break;
10389    case OPC_MADD_D:
10390        check_cop1x(ctx);
10391        check_cp1_registers(ctx, fd | fs | ft | fr);
10392        {
10393            TCGv_i64 fp0 = tcg_temp_new_i64();
10394            TCGv_i64 fp1 = tcg_temp_new_i64();
10395            TCGv_i64 fp2 = tcg_temp_new_i64();
10396
10397            gen_load_fpr64(ctx, fp0, fs);
10398            gen_load_fpr64(ctx, fp1, ft);
10399            gen_load_fpr64(ctx, fp2, fr);
10400            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10401            tcg_temp_free_i64(fp0);
10402            tcg_temp_free_i64(fp1);
10403            gen_store_fpr64(ctx, fp2, fd);
10404            tcg_temp_free_i64(fp2);
10405        }
10406        break;
10407    case OPC_MADD_PS:
10408        check_ps(ctx);
10409        {
10410            TCGv_i64 fp0 = tcg_temp_new_i64();
10411            TCGv_i64 fp1 = tcg_temp_new_i64();
10412            TCGv_i64 fp2 = tcg_temp_new_i64();
10413
10414            gen_load_fpr64(ctx, fp0, fs);
10415            gen_load_fpr64(ctx, fp1, ft);
10416            gen_load_fpr64(ctx, fp2, fr);
10417            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10418            tcg_temp_free_i64(fp0);
10419            tcg_temp_free_i64(fp1);
10420            gen_store_fpr64(ctx, fp2, fd);
10421            tcg_temp_free_i64(fp2);
10422        }
10423        break;
10424    case OPC_MSUB_S:
10425        check_cop1x(ctx);
10426        {
10427            TCGv_i32 fp0 = tcg_temp_new_i32();
10428            TCGv_i32 fp1 = tcg_temp_new_i32();
10429            TCGv_i32 fp2 = tcg_temp_new_i32();
10430
10431            gen_load_fpr32(ctx, fp0, fs);
10432            gen_load_fpr32(ctx, fp1, ft);
10433            gen_load_fpr32(ctx, fp2, fr);
10434            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10435            tcg_temp_free_i32(fp0);
10436            tcg_temp_free_i32(fp1);
10437            gen_store_fpr32(ctx, fp2, fd);
10438            tcg_temp_free_i32(fp2);
10439        }
10440        break;
10441    case OPC_MSUB_D:
10442        check_cop1x(ctx);
10443        check_cp1_registers(ctx, fd | fs | ft | fr);
10444        {
10445            TCGv_i64 fp0 = tcg_temp_new_i64();
10446            TCGv_i64 fp1 = tcg_temp_new_i64();
10447            TCGv_i64 fp2 = tcg_temp_new_i64();
10448
10449            gen_load_fpr64(ctx, fp0, fs);
10450            gen_load_fpr64(ctx, fp1, ft);
10451            gen_load_fpr64(ctx, fp2, fr);
10452            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10453            tcg_temp_free_i64(fp0);
10454            tcg_temp_free_i64(fp1);
10455            gen_store_fpr64(ctx, fp2, fd);
10456            tcg_temp_free_i64(fp2);
10457        }
10458        break;
10459    case OPC_MSUB_PS:
10460        check_ps(ctx);
10461        {
10462            TCGv_i64 fp0 = tcg_temp_new_i64();
10463            TCGv_i64 fp1 = tcg_temp_new_i64();
10464            TCGv_i64 fp2 = tcg_temp_new_i64();
10465
10466            gen_load_fpr64(ctx, fp0, fs);
10467            gen_load_fpr64(ctx, fp1, ft);
10468            gen_load_fpr64(ctx, fp2, fr);
10469            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10470            tcg_temp_free_i64(fp0);
10471            tcg_temp_free_i64(fp1);
10472            gen_store_fpr64(ctx, fp2, fd);
10473            tcg_temp_free_i64(fp2);
10474        }
10475        break;
10476    case OPC_NMADD_S:
10477        check_cop1x(ctx);
10478        {
10479            TCGv_i32 fp0 = tcg_temp_new_i32();
10480            TCGv_i32 fp1 = tcg_temp_new_i32();
10481            TCGv_i32 fp2 = tcg_temp_new_i32();
10482
10483            gen_load_fpr32(ctx, fp0, fs);
10484            gen_load_fpr32(ctx, fp1, ft);
10485            gen_load_fpr32(ctx, fp2, fr);
10486            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10487            tcg_temp_free_i32(fp0);
10488            tcg_temp_free_i32(fp1);
10489            gen_store_fpr32(ctx, fp2, fd);
10490            tcg_temp_free_i32(fp2);
10491        }
10492        break;
10493    case OPC_NMADD_D:
10494        check_cop1x(ctx);
10495        check_cp1_registers(ctx, fd | fs | ft | fr);
10496        {
10497            TCGv_i64 fp0 = tcg_temp_new_i64();
10498            TCGv_i64 fp1 = tcg_temp_new_i64();
10499            TCGv_i64 fp2 = tcg_temp_new_i64();
10500
10501            gen_load_fpr64(ctx, fp0, fs);
10502            gen_load_fpr64(ctx, fp1, ft);
10503            gen_load_fpr64(ctx, fp2, fr);
10504            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10505            tcg_temp_free_i64(fp0);
10506            tcg_temp_free_i64(fp1);
10507            gen_store_fpr64(ctx, fp2, fd);
10508            tcg_temp_free_i64(fp2);
10509        }
10510        break;
10511    case OPC_NMADD_PS:
10512        check_ps(ctx);
10513        {
10514            TCGv_i64 fp0 = tcg_temp_new_i64();
10515            TCGv_i64 fp1 = tcg_temp_new_i64();
10516            TCGv_i64 fp2 = tcg_temp_new_i64();
10517
10518            gen_load_fpr64(ctx, fp0, fs);
10519            gen_load_fpr64(ctx, fp1, ft);
10520            gen_load_fpr64(ctx, fp2, fr);
10521            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10522            tcg_temp_free_i64(fp0);
10523            tcg_temp_free_i64(fp1);
10524            gen_store_fpr64(ctx, fp2, fd);
10525            tcg_temp_free_i64(fp2);
10526        }
10527        break;
10528    case OPC_NMSUB_S:
10529        check_cop1x(ctx);
10530        {
10531            TCGv_i32 fp0 = tcg_temp_new_i32();
10532            TCGv_i32 fp1 = tcg_temp_new_i32();
10533            TCGv_i32 fp2 = tcg_temp_new_i32();
10534
10535            gen_load_fpr32(ctx, fp0, fs);
10536            gen_load_fpr32(ctx, fp1, ft);
10537            gen_load_fpr32(ctx, fp2, fr);
10538            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10539            tcg_temp_free_i32(fp0);
10540            tcg_temp_free_i32(fp1);
10541            gen_store_fpr32(ctx, fp2, fd);
10542            tcg_temp_free_i32(fp2);
10543        }
10544        break;
10545    case OPC_NMSUB_D:
10546        check_cop1x(ctx);
10547        check_cp1_registers(ctx, fd | fs | ft | fr);
10548        {
10549            TCGv_i64 fp0 = tcg_temp_new_i64();
10550            TCGv_i64 fp1 = tcg_temp_new_i64();
10551            TCGv_i64 fp2 = tcg_temp_new_i64();
10552
10553            gen_load_fpr64(ctx, fp0, fs);
10554            gen_load_fpr64(ctx, fp1, ft);
10555            gen_load_fpr64(ctx, fp2, fr);
10556            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10557            tcg_temp_free_i64(fp0);
10558            tcg_temp_free_i64(fp1);
10559            gen_store_fpr64(ctx, fp2, fd);
10560            tcg_temp_free_i64(fp2);
10561        }
10562        break;
10563    case OPC_NMSUB_PS:
10564        check_ps(ctx);
10565        {
10566            TCGv_i64 fp0 = tcg_temp_new_i64();
10567            TCGv_i64 fp1 = tcg_temp_new_i64();
10568            TCGv_i64 fp2 = tcg_temp_new_i64();
10569
10570            gen_load_fpr64(ctx, fp0, fs);
10571            gen_load_fpr64(ctx, fp1, ft);
10572            gen_load_fpr64(ctx, fp2, fr);
10573            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10574            tcg_temp_free_i64(fp0);
10575            tcg_temp_free_i64(fp1);
10576            gen_store_fpr64(ctx, fp2, fd);
10577            tcg_temp_free_i64(fp2);
10578        }
10579        break;
10580    default:
10581        MIPS_INVAL("flt3_arith");
10582        generate_exception_end(ctx, EXCP_RI);
10583        return;
10584    }
10585}
10586
10587static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10588{
10589    TCGv t0;
10590
10591#if !defined(CONFIG_USER_ONLY)
10592    /* The Linux kernel will emulate rdhwr if it's not supported natively.
10593       Therefore only check the ISA in system mode.  */
10594    check_insn(ctx, ISA_MIPS32R2);
10595#endif
10596    t0 = tcg_temp_new();
10597
10598    switch (rd) {
10599    case 0:
10600        gen_helper_rdhwr_cpunum(t0, cpu_env);
10601        gen_store_gpr(t0, rt);
10602        break;
10603    case 1:
10604        gen_helper_rdhwr_synci_step(t0, cpu_env);
10605        gen_store_gpr(t0, rt);
10606        break;
10607    case 2:
10608        gen_helper_rdhwr_cc(t0, cpu_env);
10609        gen_store_gpr(t0, rt);
10610        break;
10611    case 3:
10612        gen_helper_rdhwr_ccres(t0, cpu_env);
10613        gen_store_gpr(t0, rt);
10614        break;
10615    case 4:
10616        check_insn(ctx, ISA_MIPS32R6);
10617        if (sel != 0) {
10618            /* Performance counter registers are not implemented other than
10619             * control register 0.
10620             */
10621            generate_exception(ctx, EXCP_RI);
10622        }
10623        gen_helper_rdhwr_performance(t0, cpu_env);
10624        gen_store_gpr(t0, rt);
10625        break;
10626    case 5:
10627        check_insn(ctx, ISA_MIPS32R6);
10628        gen_helper_rdhwr_xnp(t0, cpu_env);
10629        gen_store_gpr(t0, rt);
10630        break;
10631    case 29:
10632#if defined(CONFIG_USER_ONLY)
10633        tcg_gen_ld_tl(t0, cpu_env,
10634                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10635        gen_store_gpr(t0, rt);
10636        break;
10637#else
10638        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10639            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10640            tcg_gen_ld_tl(t0, cpu_env,
10641                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10642            gen_store_gpr(t0, rt);
10643        } else {
10644            generate_exception_end(ctx, EXCP_RI);
10645        }
10646        break;
10647#endif
10648    default:            /* Invalid */
10649        MIPS_INVAL("rdhwr");
10650        generate_exception_end(ctx, EXCP_RI);
10651        break;
10652    }
10653    tcg_temp_free(t0);
10654}
10655
10656static inline void clear_branch_hflags(DisasContext *ctx)
10657{
10658    ctx->hflags &= ~MIPS_HFLAG_BMASK;
10659    if (ctx->bstate == BS_NONE) {
10660        save_cpu_state(ctx, 0);
10661    } else {
10662        /* it is not safe to save ctx->hflags as hflags may be changed
10663           in execution time by the instruction in delay / forbidden slot. */
10664        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10665    }
10666}
10667
10668static void gen_branch(DisasContext *ctx, int insn_bytes)
10669{
10670    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10671        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10672        /* Branches completion */
10673        clear_branch_hflags(ctx);
10674        ctx->bstate = BS_BRANCH;
10675        /* FIXME: Need to clear can_do_io.  */
10676        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10677        case MIPS_HFLAG_FBNSLOT:
10678            gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10679            break;
10680        case MIPS_HFLAG_B:
10681            /* unconditional branch */
10682            if (proc_hflags & MIPS_HFLAG_BX) {
10683                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10684            }
10685            gen_goto_tb(ctx, 0, ctx->btarget);
10686            break;
10687        case MIPS_HFLAG_BL:
10688            /* blikely taken case */
10689            gen_goto_tb(ctx, 0, ctx->btarget);
10690            break;
10691        case MIPS_HFLAG_BC:
10692            /* Conditional branch */
10693            {
10694                TCGLabel *l1 = gen_new_label();
10695
10696                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10697                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10698                gen_set_label(l1);
10699                gen_goto_tb(ctx, 0, ctx->btarget);
10700            }
10701            break;
10702        case MIPS_HFLAG_BR:
10703            /* unconditional branch to register */
10704            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10705                TCGv t0 = tcg_temp_new();
10706                TCGv_i32 t1 = tcg_temp_new_i32();
10707
10708                tcg_gen_andi_tl(t0, btarget, 0x1);
10709                tcg_gen_trunc_tl_i32(t1, t0);
10710                tcg_temp_free(t0);
10711                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10712                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10713                tcg_gen_or_i32(hflags, hflags, t1);
10714                tcg_temp_free_i32(t1);
10715
10716                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10717            } else {
10718                tcg_gen_mov_tl(cpu_PC, btarget);
10719            }
10720            if (ctx->singlestep_enabled) {
10721                save_cpu_state(ctx, 0);
10722                gen_helper_raise_exception_debug(cpu_env);
10723            }
10724            tcg_gen_exit_tb(0);
10725            break;
10726        default:
10727            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10728            abort();
10729        }
10730    }
10731}
10732
10733/* Compact Branches */
10734static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10735                                       int rs, int rt, int32_t offset)
10736{
10737    int bcond_compute = 0;
10738    TCGv t0 = tcg_temp_new();
10739    TCGv t1 = tcg_temp_new();
10740    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10741
10742    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10743#ifdef MIPS_DEBUG_DISAS
10744        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10745                  "\n", ctx->pc);
10746#endif
10747        generate_exception_end(ctx, EXCP_RI);
10748        goto out;
10749    }
10750
10751    /* Load needed operands and calculate btarget */
10752    switch (opc) {
10753    /* compact branch */
10754    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10755    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10756        gen_load_gpr(t0, rs);
10757        gen_load_gpr(t1, rt);
10758        bcond_compute = 1;
10759        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10760        if (rs <= rt && rs == 0) {
10761            /* OPC_BEQZALC, OPC_BNEZALC */
10762            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10763        }
10764        break;
10765    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10766    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10767        gen_load_gpr(t0, rs);
10768        gen_load_gpr(t1, rt);
10769        bcond_compute = 1;
10770        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10771        break;
10772    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10773    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10774        if (rs == 0 || rs == rt) {
10775            /* OPC_BLEZALC, OPC_BGEZALC */
10776            /* OPC_BGTZALC, OPC_BLTZALC */
10777            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10778        }
10779        gen_load_gpr(t0, rs);
10780        gen_load_gpr(t1, rt);
10781        bcond_compute = 1;
10782        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10783        break;
10784    case OPC_BC:
10785    case OPC_BALC:
10786        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10787        break;
10788    case OPC_BEQZC:
10789    case OPC_BNEZC:
10790        if (rs != 0) {
10791            /* OPC_BEQZC, OPC_BNEZC */
10792            gen_load_gpr(t0, rs);
10793            bcond_compute = 1;
10794            ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10795        } else {
10796            /* OPC_JIC, OPC_JIALC */
10797            TCGv tbase = tcg_temp_new();
10798            TCGv toffset = tcg_temp_new();
10799
10800            gen_load_gpr(tbase, rt);
10801            tcg_gen_movi_tl(toffset, offset);
10802            gen_op_addr_add(ctx, btarget, tbase, toffset);
10803            tcg_temp_free(tbase);
10804            tcg_temp_free(toffset);
10805        }
10806        break;
10807    default:
10808        MIPS_INVAL("Compact branch/jump");
10809        generate_exception_end(ctx, EXCP_RI);
10810        goto out;
10811    }
10812
10813    if (bcond_compute == 0) {
10814        /* Uncoditional compact branch */
10815        switch (opc) {
10816        case OPC_JIALC:
10817            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10818            /* Fallthrough */
10819        case OPC_JIC:
10820            ctx->hflags |= MIPS_HFLAG_BR;
10821            break;
10822        case OPC_BALC:
10823            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10824            /* Fallthrough */
10825        case OPC_BC:
10826            ctx->hflags |= MIPS_HFLAG_B;
10827            break;
10828        default:
10829            MIPS_INVAL("Compact branch/jump");
10830            generate_exception_end(ctx, EXCP_RI);
10831            goto out;
10832        }
10833
10834        /* Generating branch here as compact branches don't have delay slot */
10835        gen_branch(ctx, 4);
10836    } else {
10837        /* Conditional compact branch */
10838        TCGLabel *fs = gen_new_label();
10839        save_cpu_state(ctx, 0);
10840
10841        switch (opc) {
10842        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10843            if (rs == 0 && rt != 0) {
10844                /* OPC_BLEZALC */
10845                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10846            } else if (rs != 0 && rt != 0 && rs == rt) {
10847                /* OPC_BGEZALC */
10848                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10849            } else {
10850                /* OPC_BGEUC */
10851                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10852            }
10853            break;
10854        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10855            if (rs == 0 && rt != 0) {
10856                /* OPC_BGTZALC */
10857                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10858            } else if (rs != 0 && rt != 0 && rs == rt) {
10859                /* OPC_BLTZALC */
10860                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10861            } else {
10862                /* OPC_BLTUC */
10863                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10864            }
10865            break;
10866        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10867            if (rs == 0 && rt != 0) {
10868                /* OPC_BLEZC */
10869                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10870            } else if (rs != 0 && rt != 0 && rs == rt) {
10871                /* OPC_BGEZC */
10872                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10873            } else {
10874                /* OPC_BGEC */
10875                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10876            }
10877            break;
10878        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10879            if (rs == 0 && rt != 0) {
10880                /* OPC_BGTZC */
10881                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10882            } else if (rs != 0 && rt != 0 && rs == rt) {
10883                /* OPC_BLTZC */
10884                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10885            } else {
10886                /* OPC_BLTC */
10887                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10888            }
10889            break;
10890        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10891        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10892            if (rs >= rt) {
10893                /* OPC_BOVC, OPC_BNVC */
10894                TCGv t2 = tcg_temp_new();
10895                TCGv t3 = tcg_temp_new();
10896                TCGv t4 = tcg_temp_new();
10897                TCGv input_overflow = tcg_temp_new();
10898
10899                gen_load_gpr(t0, rs);
10900                gen_load_gpr(t1, rt);
10901                tcg_gen_ext32s_tl(t2, t0);
10902                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10903                tcg_gen_ext32s_tl(t3, t1);
10904                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10905                tcg_gen_or_tl(input_overflow, input_overflow, t4);
10906
10907                tcg_gen_add_tl(t4, t2, t3);
10908                tcg_gen_ext32s_tl(t4, t4);
10909                tcg_gen_xor_tl(t2, t2, t3);
10910                tcg_gen_xor_tl(t3, t4, t3);
10911                tcg_gen_andc_tl(t2, t3, t2);
10912                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10913                tcg_gen_or_tl(t4, t4, input_overflow);
10914                if (opc == OPC_BOVC) {
10915                    /* OPC_BOVC */
10916                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10917                } else {
10918                    /* OPC_BNVC */
10919                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10920                }
10921                tcg_temp_free(input_overflow);
10922                tcg_temp_free(t4);
10923                tcg_temp_free(t3);
10924                tcg_temp_free(t2);
10925            } else if (rs < rt && rs == 0) {
10926                /* OPC_BEQZALC, OPC_BNEZALC */
10927                if (opc == OPC_BEQZALC) {
10928                    /* OPC_BEQZALC */
10929                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10930                } else {
10931                    /* OPC_BNEZALC */
10932                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10933                }
10934            } else {
10935                /* OPC_BEQC, OPC_BNEC */
10936                if (opc == OPC_BEQC) {
10937                    /* OPC_BEQC */
10938                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10939                } else {
10940                    /* OPC_BNEC */
10941                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10942                }
10943            }
10944            break;
10945        case OPC_BEQZC:
10946            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10947            break;
10948        case OPC_BNEZC:
10949            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10950            break;
10951        default:
10952            MIPS_INVAL("Compact conditional branch/jump");
10953            generate_exception_end(ctx, EXCP_RI);
10954            goto out;
10955        }
10956
10957        /* Generating branch here as compact branches don't have delay slot */
10958        gen_goto_tb(ctx, 1, ctx->btarget);
10959        gen_set_label(fs);
10960
10961        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10962    }
10963
10964out:
10965    tcg_temp_free(t0);
10966    tcg_temp_free(t1);
10967}
10968
10969/* ISA extensions (ASEs) */
10970/* MIPS16 extension to MIPS32 */
10971
10972/* MIPS16 major opcodes */
10973enum {
10974  M16_OPC_ADDIUSP = 0x00,
10975  M16_OPC_ADDIUPC = 0x01,
10976  M16_OPC_B = 0x02,
10977  M16_OPC_JAL = 0x03,
10978  M16_OPC_BEQZ = 0x04,
10979  M16_OPC_BNEQZ = 0x05,
10980  M16_OPC_SHIFT = 0x06,
10981  M16_OPC_LD = 0x07,
10982  M16_OPC_RRIA = 0x08,
10983  M16_OPC_ADDIU8 = 0x09,
10984  M16_OPC_SLTI = 0x0a,
10985  M16_OPC_SLTIU = 0x0b,
10986  M16_OPC_I8 = 0x0c,
10987  M16_OPC_LI = 0x0d,
10988  M16_OPC_CMPI = 0x0e,
10989  M16_OPC_SD = 0x0f,
10990  M16_OPC_LB = 0x10,
10991  M16_OPC_LH = 0x11,
10992  M16_OPC_LWSP = 0x12,
10993  M16_OPC_LW = 0x13,
10994  M16_OPC_LBU = 0x14,
10995  M16_OPC_LHU = 0x15,
10996  M16_OPC_LWPC = 0x16,
10997  M16_OPC_LWU = 0x17,
10998  M16_OPC_SB = 0x18,
10999  M16_OPC_SH = 0x19,
11000  M16_OPC_SWSP = 0x1a,
11001  M16_OPC_SW = 0x1b,
11002  M16_OPC_RRR = 0x1c,
11003  M16_OPC_RR = 0x1d,
11004  M16_OPC_EXTEND = 0x1e,
11005  M16_OPC_I64 = 0x1f
11006};
11007
11008/* I8 funct field */
11009enum {
11010  I8_BTEQZ = 0x0,
11011  I8_BTNEZ = 0x1,
11012  I8_SWRASP = 0x2,
11013  I8_ADJSP = 0x3,
11014  I8_SVRS = 0x4,
11015  I8_MOV32R = 0x5,
11016  I8_MOVR32 = 0x7
11017};
11018
11019/* RRR f field */
11020enum {
11021  RRR_DADDU = 0x0,
11022  RRR_ADDU = 0x1,
11023  RRR_DSUBU = 0x2,
11024  RRR_SUBU = 0x3
11025};
11026
11027/* RR funct field */
11028enum {
11029  RR_JR = 0x00,
11030  RR_SDBBP = 0x01,
11031  RR_SLT = 0x02,
11032  RR_SLTU = 0x03,
11033  RR_SLLV = 0x04,
11034  RR_BREAK = 0x05,
11035  RR_SRLV = 0x06,
11036  RR_SRAV = 0x07,
11037  RR_DSRL = 0x08,
11038  RR_CMP = 0x0a,
11039  RR_NEG = 0x0b,
11040  RR_AND = 0x0c,
11041  RR_OR = 0x0d,
11042  RR_XOR = 0x0e,
11043  RR_NOT = 0x0f,
11044  RR_MFHI = 0x10,
11045  RR_CNVT = 0x11,
11046  RR_MFLO = 0x12,
11047  RR_DSRA = 0x13,
11048  RR_DSLLV = 0x14,
11049  RR_DSRLV = 0x16,
11050  RR_DSRAV = 0x17,
11051  RR_MULT = 0x18,
11052  RR_MULTU = 0x19,
11053  RR_DIV = 0x1a,
11054  RR_DIVU = 0x1b,
11055  RR_DMULT = 0x1c,
11056  RR_DMULTU = 0x1d,
11057  RR_DDIV = 0x1e,
11058  RR_DDIVU = 0x1f
11059};
11060
11061/* I64 funct field */
11062enum {
11063  I64_LDSP = 0x0,
11064  I64_SDSP = 0x1,
11065  I64_SDRASP = 0x2,
11066  I64_DADJSP = 0x3,
11067  I64_LDPC = 0x4,
11068  I64_DADDIU5 = 0x5,
11069  I64_DADDIUPC = 0x6,
11070  I64_DADDIUSP = 0x7
11071};
11072
11073/* RR ry field for CNVT */
11074enum {
11075  RR_RY_CNVT_ZEB = 0x0,
11076  RR_RY_CNVT_ZEH = 0x1,
11077  RR_RY_CNVT_ZEW = 0x2,
11078  RR_RY_CNVT_SEB = 0x4,
11079  RR_RY_CNVT_SEH = 0x5,
11080  RR_RY_CNVT_SEW = 0x6,
11081};
11082
11083static int xlat (int r)
11084{
11085  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11086
11087  return map[r];
11088}
11089
11090static void gen_mips16_save (DisasContext *ctx,
11091                             int xsregs, int aregs,
11092                             int do_ra, int do_s0, int do_s1,
11093                             int framesize)
11094{
11095    TCGv t0 = tcg_temp_new();
11096    TCGv t1 = tcg_temp_new();
11097    TCGv t2 = tcg_temp_new();
11098    int args, astatic;
11099
11100    switch (aregs) {
11101    case 0:
11102    case 1:
11103    case 2:
11104    case 3:
11105    case 11:
11106        args = 0;
11107        break;
11108    case 4:
11109    case 5:
11110    case 6:
11111    case 7:
11112        args = 1;
11113        break;
11114    case 8:
11115    case 9:
11116    case 10:
11117        args = 2;
11118        break;
11119    case 12:
11120    case 13:
11121        args = 3;
11122        break;
11123    case 14:
11124        args = 4;
11125        break;
11126    default:
11127        generate_exception_end(ctx, EXCP_RI);
11128        return;
11129    }
11130
11131    switch (args) {
11132    case 4:
11133        gen_base_offset_addr(ctx, t0, 29, 12);
11134        gen_load_gpr(t1, 7);
11135        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11136        /* Fall through */
11137    case 3:
11138        gen_base_offset_addr(ctx, t0, 29, 8);
11139        gen_load_gpr(t1, 6);
11140        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11141        /* Fall through */
11142    case 2:
11143        gen_base_offset_addr(ctx, t0, 29, 4);
11144        gen_load_gpr(t1, 5);
11145        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11146        /* Fall through */
11147    case 1:
11148        gen_base_offset_addr(ctx, t0, 29, 0);
11149        gen_load_gpr(t1, 4);
11150        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11151    }
11152
11153    gen_load_gpr(t0, 29);
11154
11155#define DECR_AND_STORE(reg) do {                                 \
11156        tcg_gen_movi_tl(t2, -4);                                 \
11157        gen_op_addr_add(ctx, t0, t0, t2);                        \
11158        gen_load_gpr(t1, reg);                                   \
11159        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11160    } while (0)
11161
11162    if (do_ra) {
11163        DECR_AND_STORE(31);
11164    }
11165
11166    switch (xsregs) {
11167    case 7:
11168        DECR_AND_STORE(30);
11169        /* Fall through */
11170    case 6:
11171        DECR_AND_STORE(23);
11172        /* Fall through */
11173    case 5:
11174        DECR_AND_STORE(22);
11175        /* Fall through */
11176    case 4:
11177        DECR_AND_STORE(21);
11178        /* Fall through */
11179    case 3:
11180        DECR_AND_STORE(20);
11181        /* Fall through */
11182    case 2:
11183        DECR_AND_STORE(19);
11184        /* Fall through */
11185    case 1:
11186        DECR_AND_STORE(18);
11187    }
11188
11189    if (do_s1) {
11190        DECR_AND_STORE(17);
11191    }
11192    if (do_s0) {
11193        DECR_AND_STORE(16);
11194    }
11195
11196    switch (aregs) {
11197    case 0:
11198    case 4:
11199    case 8:
11200    case 12:
11201    case 14:
11202        astatic = 0;
11203        break;
11204    case 1:
11205    case 5:
11206    case 9:
11207    case 13:
11208        astatic = 1;
11209        break;
11210    case 2:
11211    case 6:
11212    case 10:
11213        astatic = 2;
11214        break;
11215    case 3:
11216    case 7:
11217        astatic = 3;
11218        break;
11219    case 11:
11220        astatic = 4;
11221        break;
11222    default:
11223        generate_exception_end(ctx, EXCP_RI);
11224        return;
11225    }
11226
11227    if (astatic > 0) {
11228        DECR_AND_STORE(7);
11229        if (astatic > 1) {
11230            DECR_AND_STORE(6);
11231            if (astatic > 2) {
11232                DECR_AND_STORE(5);
11233                if (astatic > 3) {
11234                    DECR_AND_STORE(4);
11235                }
11236            }
11237        }
11238    }
11239#undef DECR_AND_STORE
11240
11241    tcg_gen_movi_tl(t2, -framesize);
11242    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11243    tcg_temp_free(t0);
11244    tcg_temp_free(t1);
11245    tcg_temp_free(t2);
11246}
11247
11248static void gen_mips16_restore (DisasContext *ctx,
11249                                int xsregs, int aregs,
11250                                int do_ra, int do_s0, int do_s1,
11251                                int framesize)
11252{
11253    int astatic;
11254    TCGv t0 = tcg_temp_new();
11255    TCGv t1 = tcg_temp_new();
11256    TCGv t2 = tcg_temp_new();
11257
11258    tcg_gen_movi_tl(t2, framesize);
11259    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11260
11261#define DECR_AND_LOAD(reg) do {                            \
11262        tcg_gen_movi_tl(t2, -4);                           \
11263        gen_op_addr_add(ctx, t0, t0, t2);                  \
11264        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11265        gen_store_gpr(t1, reg);                            \
11266    } while (0)
11267
11268    if (do_ra) {
11269        DECR_AND_LOAD(31);
11270    }
11271
11272    switch (xsregs) {
11273    case 7:
11274        DECR_AND_LOAD(30);
11275        /* Fall through */
11276    case 6:
11277        DECR_AND_LOAD(23);
11278        /* Fall through */
11279    case 5:
11280        DECR_AND_LOAD(22);
11281        /* Fall through */
11282    case 4:
11283        DECR_AND_LOAD(21);
11284        /* Fall through */
11285    case 3:
11286        DECR_AND_LOAD(20);
11287        /* Fall through */
11288    case 2:
11289        DECR_AND_LOAD(19);
11290        /* Fall through */
11291    case 1:
11292        DECR_AND_LOAD(18);
11293    }
11294
11295    if (do_s1) {
11296        DECR_AND_LOAD(17);
11297    }
11298    if (do_s0) {
11299        DECR_AND_LOAD(16);
11300    }
11301
11302    switch (aregs) {
11303    case 0:
11304    case 4:
11305    case 8:
11306    case 12:
11307    case 14:
11308        astatic = 0;
11309        break;
11310    case 1:
11311    case 5:
11312    case 9:
11313    case 13:
11314        astatic = 1;
11315        break;
11316    case 2:
11317    case 6:
11318    case 10:
11319        astatic = 2;
11320        break;
11321    case 3:
11322    case 7:
11323        astatic = 3;
11324        break;
11325    case 11:
11326        astatic = 4;
11327        break;
11328    default:
11329        generate_exception_end(ctx, EXCP_RI);
11330        return;
11331    }
11332
11333    if (astatic > 0) {
11334        DECR_AND_LOAD(7);
11335        if (astatic > 1) {
11336            DECR_AND_LOAD(6);
11337            if (astatic > 2) {
11338                DECR_AND_LOAD(5);
11339                if (astatic > 3) {
11340                    DECR_AND_LOAD(4);
11341                }
11342            }
11343        }
11344    }
11345#undef DECR_AND_LOAD
11346
11347    tcg_gen_movi_tl(t2, framesize);
11348    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11349    tcg_temp_free(t0);
11350    tcg_temp_free(t1);
11351    tcg_temp_free(t2);
11352}
11353
11354static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11355                         int is_64_bit, int extended)
11356{
11357    TCGv t0;
11358
11359    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11360        generate_exception_end(ctx, EXCP_RI);
11361        return;
11362    }
11363
11364    t0 = tcg_temp_new();
11365
11366    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11367    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11368    if (!is_64_bit) {
11369        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11370    }
11371
11372    tcg_temp_free(t0);
11373}
11374
11375static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11376                                int16_t offset)
11377{
11378    TCGv_i32 t0 = tcg_const_i32(op);
11379    TCGv t1 = tcg_temp_new();
11380    gen_base_offset_addr(ctx, t1, base, offset);
11381    gen_helper_cache(cpu_env, t1, t0);
11382}
11383
11384#if defined(TARGET_MIPS64)
11385static void decode_i64_mips16 (DisasContext *ctx,
11386                               int ry, int funct, int16_t offset,
11387                               int extended)
11388{
11389    switch (funct) {
11390    case I64_LDSP:
11391        check_insn(ctx, ISA_MIPS3);
11392        check_mips_64(ctx);
11393        offset = extended ? offset : offset << 3;
11394        gen_ld(ctx, OPC_LD, ry, 29, offset);
11395        break;
11396    case I64_SDSP:
11397        check_insn(ctx, ISA_MIPS3);
11398        check_mips_64(ctx);
11399        offset = extended ? offset : offset << 3;
11400        gen_st(ctx, OPC_SD, ry, 29, offset);
11401        break;
11402    case I64_SDRASP:
11403        check_insn(ctx, ISA_MIPS3);
11404        check_mips_64(ctx);
11405        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11406        gen_st(ctx, OPC_SD, 31, 29, offset);
11407        break;
11408    case I64_DADJSP:
11409        check_insn(ctx, ISA_MIPS3);
11410        check_mips_64(ctx);
11411        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11412        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11413        break;
11414    case I64_LDPC:
11415        check_insn(ctx, ISA_MIPS3);
11416        check_mips_64(ctx);
11417        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11418            generate_exception_end(ctx, EXCP_RI);
11419        } else {
11420            offset = extended ? offset : offset << 3;
11421            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11422        }
11423        break;
11424    case I64_DADDIU5:
11425        check_insn(ctx, ISA_MIPS3);
11426        check_mips_64(ctx);
11427        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11428        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11429        break;
11430    case I64_DADDIUPC:
11431        check_insn(ctx, ISA_MIPS3);
11432        check_mips_64(ctx);
11433        offset = extended ? offset : offset << 2;
11434        gen_addiupc(ctx, ry, offset, 1, extended);
11435        break;
11436    case I64_DADDIUSP:
11437        check_insn(ctx, ISA_MIPS3);
11438        check_mips_64(ctx);
11439        offset = extended ? offset : offset << 2;
11440        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11441        break;
11442    }
11443}
11444#endif
11445
11446static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11447{
11448    int extend = cpu_lduw_code(env, ctx->pc + 2);
11449    int op, rx, ry, funct, sa;
11450    int16_t imm, offset;
11451
11452    ctx->opcode = (ctx->opcode << 16) | extend;
11453    op = (ctx->opcode >> 11) & 0x1f;
11454    sa = (ctx->opcode >> 22) & 0x1f;
11455    funct = (ctx->opcode >> 8) & 0x7;
11456    rx = xlat((ctx->opcode >> 8) & 0x7);
11457    ry = xlat((ctx->opcode >> 5) & 0x7);
11458    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11459                              | ((ctx->opcode >> 21) & 0x3f) << 5
11460                              | (ctx->opcode & 0x1f));
11461
11462    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11463       counterparts.  */
11464    switch (op) {
11465    case M16_OPC_ADDIUSP:
11466        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11467        break;
11468    case M16_OPC_ADDIUPC:
11469        gen_addiupc(ctx, rx, imm, 0, 1);
11470        break;
11471    case M16_OPC_B:
11472        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11473        /* No delay slot, so just process as a normal instruction */
11474        break;
11475    case M16_OPC_BEQZ:
11476        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11477        /* No delay slot, so just process as a normal instruction */
11478        break;
11479    case M16_OPC_BNEQZ:
11480        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11481        /* No delay slot, so just process as a normal instruction */
11482        break;
11483    case M16_OPC_SHIFT:
11484        switch (ctx->opcode & 0x3) {
11485        case 0x0:
11486            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11487            break;
11488        case 0x1:
11489#if defined(TARGET_MIPS64)
11490            check_mips_64(ctx);
11491            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11492#else
11493            generate_exception_end(ctx, EXCP_RI);
11494#endif
11495            break;
11496        case 0x2:
11497            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11498            break;
11499        case 0x3:
11500            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11501            break;
11502        }
11503        break;
11504#if defined(TARGET_MIPS64)
11505    case M16_OPC_LD:
11506        check_insn(ctx, ISA_MIPS3);
11507        check_mips_64(ctx);
11508        gen_ld(ctx, OPC_LD, ry, rx, offset);
11509        break;
11510#endif
11511    case M16_OPC_RRIA:
11512        imm = ctx->opcode & 0xf;
11513        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11514        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11515        imm = (int16_t) (imm << 1) >> 1;
11516        if ((ctx->opcode >> 4) & 0x1) {
11517#if defined(TARGET_MIPS64)
11518            check_mips_64(ctx);
11519            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11520#else
11521            generate_exception_end(ctx, EXCP_RI);
11522#endif
11523        } else {
11524            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11525        }
11526        break;
11527    case M16_OPC_ADDIU8:
11528        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11529        break;
11530    case M16_OPC_SLTI:
11531        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11532        break;
11533    case M16_OPC_SLTIU:
11534        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11535        break;
11536    case M16_OPC_I8:
11537        switch (funct) {
11538        case I8_BTEQZ:
11539            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11540            break;
11541        case I8_BTNEZ:
11542            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11543            break;
11544        case I8_SWRASP:
11545            gen_st(ctx, OPC_SW, 31, 29, imm);
11546            break;
11547        case I8_ADJSP:
11548            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11549            break;
11550        case I8_SVRS:
11551            check_insn(ctx, ISA_MIPS32);
11552            {
11553                int xsregs = (ctx->opcode >> 24) & 0x7;
11554                int aregs = (ctx->opcode >> 16) & 0xf;
11555                int do_ra = (ctx->opcode >> 6) & 0x1;
11556                int do_s0 = (ctx->opcode >> 5) & 0x1;
11557                int do_s1 = (ctx->opcode >> 4) & 0x1;
11558                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11559                                 | (ctx->opcode & 0xf)) << 3;
11560
11561                if (ctx->opcode & (1 << 7)) {
11562                    gen_mips16_save(ctx, xsregs, aregs,
11563                                    do_ra, do_s0, do_s1,
11564                                    framesize);
11565                } else {
11566                    gen_mips16_restore(ctx, xsregs, aregs,
11567                                       do_ra, do_s0, do_s1,
11568                                       framesize);
11569                }
11570            }
11571            break;
11572        default:
11573            generate_exception_end(ctx, EXCP_RI);
11574            break;
11575        }
11576        break;
11577    case M16_OPC_LI:
11578        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11579        break;
11580    case M16_OPC_CMPI:
11581        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11582        break;
11583#if defined(TARGET_MIPS64)
11584    case M16_OPC_SD:
11585        check_insn(ctx, ISA_MIPS3);
11586        check_mips_64(ctx);
11587        gen_st(ctx, OPC_SD, ry, rx, offset);
11588        break;
11589#endif
11590    case M16_OPC_LB:
11591        gen_ld(ctx, OPC_LB, ry, rx, offset);
11592        break;
11593    case M16_OPC_LH:
11594        gen_ld(ctx, OPC_LH, ry, rx, offset);
11595        break;
11596    case M16_OPC_LWSP:
11597        gen_ld(ctx, OPC_LW, rx, 29, offset);
11598        break;
11599    case M16_OPC_LW:
11600        gen_ld(ctx, OPC_LW, ry, rx, offset);
11601        break;
11602    case M16_OPC_LBU:
11603        gen_ld(ctx, OPC_LBU, ry, rx, offset);
11604        break;
11605    case M16_OPC_LHU:
11606        gen_ld(ctx, OPC_LHU, ry, rx, offset);
11607        break;
11608    case M16_OPC_LWPC:
11609        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11610        break;
11611#if defined(TARGET_MIPS64)
11612    case M16_OPC_LWU:
11613        check_insn(ctx, ISA_MIPS3);
11614        check_mips_64(ctx);
11615        gen_ld(ctx, OPC_LWU, ry, rx, offset);
11616        break;
11617#endif
11618    case M16_OPC_SB:
11619        gen_st(ctx, OPC_SB, ry, rx, offset);
11620        break;
11621    case M16_OPC_SH:
11622        gen_st(ctx, OPC_SH, ry, rx, offset);
11623        break;
11624    case M16_OPC_SWSP:
11625        gen_st(ctx, OPC_SW, rx, 29, offset);
11626        break;
11627    case M16_OPC_SW:
11628        gen_st(ctx, OPC_SW, ry, rx, offset);
11629        break;
11630#if defined(TARGET_MIPS64)
11631    case M16_OPC_I64:
11632        decode_i64_mips16(ctx, ry, funct, offset, 1);
11633        break;
11634#endif
11635    default:
11636        generate_exception_end(ctx, EXCP_RI);
11637        break;
11638    }
11639
11640    return 4;
11641}
11642
11643static inline bool is_uhi(int sdbbp_code)
11644{
11645#ifdef CONFIG_USER_ONLY
11646    return false;
11647#else
11648    return semihosting_enabled() && sdbbp_code == 1;
11649#endif
11650}
11651
11652static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11653{
11654    int rx, ry;
11655    int sa;
11656    int op, cnvt_op, op1, offset;
11657    int funct;
11658    int n_bytes;
11659
11660    op = (ctx->opcode >> 11) & 0x1f;
11661    sa = (ctx->opcode >> 2) & 0x7;
11662    sa = sa == 0 ? 8 : sa;
11663    rx = xlat((ctx->opcode >> 8) & 0x7);
11664    cnvt_op = (ctx->opcode >> 5) & 0x7;
11665    ry = xlat((ctx->opcode >> 5) & 0x7);
11666    op1 = offset = ctx->opcode & 0x1f;
11667
11668    n_bytes = 2;
11669
11670    switch (op) {
11671    case M16_OPC_ADDIUSP:
11672        {
11673            int16_t imm = ((uint8_t) ctx->opcode) << 2;
11674
11675            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11676        }
11677        break;
11678    case M16_OPC_ADDIUPC:
11679        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11680        break;
11681    case M16_OPC_B:
11682        offset = (ctx->opcode & 0x7ff) << 1;
11683        offset = (int16_t)(offset << 4) >> 4;
11684        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11685        /* No delay slot, so just process as a normal instruction */
11686        break;
11687    case M16_OPC_JAL:
11688        offset = cpu_lduw_code(env, ctx->pc + 2);
11689        offset = (((ctx->opcode & 0x1f) << 21)
11690                  | ((ctx->opcode >> 5) & 0x1f) << 16
11691                  | offset) << 2;
11692        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11693        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11694        n_bytes = 4;
11695        break;
11696    case M16_OPC_BEQZ:
11697        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11698                           ((int8_t)ctx->opcode) << 1, 0);
11699        /* No delay slot, so just process as a normal instruction */
11700        break;
11701    case M16_OPC_BNEQZ:
11702        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11703                           ((int8_t)ctx->opcode) << 1, 0);
11704        /* No delay slot, so just process as a normal instruction */
11705        break;
11706    case M16_OPC_SHIFT:
11707        switch (ctx->opcode & 0x3) {
11708        case 0x0:
11709            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11710            break;
11711        case 0x1:
11712#if defined(TARGET_MIPS64)
11713            check_insn(ctx, ISA_MIPS3);
11714            check_mips_64(ctx);
11715            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11716#else
11717            generate_exception_end(ctx, EXCP_RI);
11718#endif
11719            break;
11720        case 0x2:
11721            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11722            break;
11723        case 0x3:
11724            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11725            break;
11726        }
11727        break;
11728#if defined(TARGET_MIPS64)
11729    case M16_OPC_LD:
11730        check_insn(ctx, ISA_MIPS3);
11731        check_mips_64(ctx);
11732        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11733        break;
11734#endif
11735    case M16_OPC_RRIA:
11736        {
11737            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11738
11739            if ((ctx->opcode >> 4) & 1) {
11740#if defined(TARGET_MIPS64)
11741                check_insn(ctx, ISA_MIPS3);
11742                check_mips_64(ctx);
11743                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11744#else
11745                generate_exception_end(ctx, EXCP_RI);
11746#endif
11747            } else {
11748                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11749            }
11750        }
11751        break;
11752    case M16_OPC_ADDIU8:
11753        {
11754            int16_t imm = (int8_t) ctx->opcode;
11755
11756            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11757        }
11758        break;
11759    case M16_OPC_SLTI:
11760        {
11761            int16_t imm = (uint8_t) ctx->opcode;
11762            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11763        }
11764        break;
11765    case M16_OPC_SLTIU:
11766        {
11767            int16_t imm = (uint8_t) ctx->opcode;
11768            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11769        }
11770        break;
11771    case M16_OPC_I8:
11772        {
11773            int reg32;
11774
11775            funct = (ctx->opcode >> 8) & 0x7;
11776            switch (funct) {
11777            case I8_BTEQZ:
11778                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11779                                   ((int8_t)ctx->opcode) << 1, 0);
11780                break;
11781            case I8_BTNEZ:
11782                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11783                                   ((int8_t)ctx->opcode) << 1, 0);
11784                break;
11785            case I8_SWRASP:
11786                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11787                break;
11788            case I8_ADJSP:
11789                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11790                              ((int8_t)ctx->opcode) << 3);
11791                break;
11792            case I8_SVRS:
11793                check_insn(ctx, ISA_MIPS32);
11794                {
11795                    int do_ra = ctx->opcode & (1 << 6);
11796                    int do_s0 = ctx->opcode & (1 << 5);
11797                    int do_s1 = ctx->opcode & (1 << 4);
11798                    int framesize = ctx->opcode & 0xf;
11799
11800                    if (framesize == 0) {
11801                        framesize = 128;
11802                    } else {
11803                        framesize = framesize << 3;
11804                    }
11805
11806                    if (ctx->opcode & (1 << 7)) {
11807                        gen_mips16_save(ctx, 0, 0,
11808                                        do_ra, do_s0, do_s1, framesize);
11809                    } else {
11810                        gen_mips16_restore(ctx, 0, 0,
11811                                           do_ra, do_s0, do_s1, framesize);
11812                    }
11813                }
11814                break;
11815            case I8_MOV32R:
11816                {
11817                    int rz = xlat(ctx->opcode & 0x7);
11818
11819                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11820                        ((ctx->opcode >> 5) & 0x7);
11821                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11822                }
11823                break;
11824            case I8_MOVR32:
11825                reg32 = ctx->opcode & 0x1f;
11826                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11827                break;
11828            default:
11829                generate_exception_end(ctx, EXCP_RI);
11830                break;
11831            }
11832        }
11833        break;
11834    case M16_OPC_LI:
11835        {
11836            int16_t imm = (uint8_t) ctx->opcode;
11837
11838            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11839        }
11840        break;
11841    case M16_OPC_CMPI:
11842        {
11843            int16_t imm = (uint8_t) ctx->opcode;
11844            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11845        }
11846        break;
11847#if defined(TARGET_MIPS64)
11848    case M16_OPC_SD:
11849        check_insn(ctx, ISA_MIPS3);
11850        check_mips_64(ctx);
11851        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11852        break;
11853#endif
11854    case M16_OPC_LB:
11855        gen_ld(ctx, OPC_LB, ry, rx, offset);
11856        break;
11857    case M16_OPC_LH:
11858        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11859        break;
11860    case M16_OPC_LWSP:
11861        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11862        break;
11863    case M16_OPC_LW:
11864        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11865        break;
11866    case M16_OPC_LBU:
11867        gen_ld(ctx, OPC_LBU, ry, rx, offset);
11868        break;
11869    case M16_OPC_LHU:
11870        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11871        break;
11872    case M16_OPC_LWPC:
11873        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11874        break;
11875#if defined (TARGET_MIPS64)
11876    case M16_OPC_LWU:
11877        check_insn(ctx, ISA_MIPS3);
11878        check_mips_64(ctx);
11879        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11880        break;
11881#endif
11882    case M16_OPC_SB:
11883        gen_st(ctx, OPC_SB, ry, rx, offset);
11884        break;
11885    case M16_OPC_SH:
11886        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11887        break;
11888    case M16_OPC_SWSP:
11889        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11890        break;
11891    case M16_OPC_SW:
11892        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11893        break;
11894    case M16_OPC_RRR:
11895        {
11896            int rz = xlat((ctx->opcode >> 2) & 0x7);
11897            int mips32_op;
11898
11899            switch (ctx->opcode & 0x3) {
11900            case RRR_ADDU:
11901                mips32_op = OPC_ADDU;
11902                break;
11903            case RRR_SUBU:
11904                mips32_op = OPC_SUBU;
11905                break;
11906#if defined(TARGET_MIPS64)
11907            case RRR_DADDU:
11908                mips32_op = OPC_DADDU;
11909                check_insn(ctx, ISA_MIPS3);
11910                check_mips_64(ctx);
11911                break;
11912            case RRR_DSUBU:
11913                mips32_op = OPC_DSUBU;
11914                check_insn(ctx, ISA_MIPS3);
11915                check_mips_64(ctx);
11916                break;
11917#endif
11918            default:
11919                generate_exception_end(ctx, EXCP_RI);
11920                goto done;
11921            }
11922
11923            gen_arith(ctx, mips32_op, rz, rx, ry);
11924        done:
11925            ;
11926        }
11927        break;
11928    case M16_OPC_RR:
11929        switch (op1) {
11930        case RR_JR:
11931            {
11932                int nd = (ctx->opcode >> 7) & 0x1;
11933                int link = (ctx->opcode >> 6) & 0x1;
11934                int ra = (ctx->opcode >> 5) & 0x1;
11935
11936                if (nd) {
11937                    check_insn(ctx, ISA_MIPS32);
11938                }
11939
11940                if (link) {
11941                    op = OPC_JALR;
11942                } else {
11943                    op = OPC_JR;
11944                }
11945
11946                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11947                                   (nd ? 0 : 2));
11948            }
11949            break;
11950        case RR_SDBBP:
11951            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11952                gen_helper_do_semihosting(cpu_env);
11953            } else {
11954                /* XXX: not clear which exception should be raised
11955                 *      when in debug mode...
11956                 */
11957                check_insn(ctx, ISA_MIPS32);
11958                generate_exception_end(ctx, EXCP_DBp);
11959            }
11960            break;
11961        case RR_SLT:
11962            gen_slt(ctx, OPC_SLT, 24, rx, ry);
11963            break;
11964        case RR_SLTU:
11965            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11966            break;
11967        case RR_BREAK:
11968            generate_exception_end(ctx, EXCP_BREAK);
11969            break;
11970        case RR_SLLV:
11971            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11972            break;
11973        case RR_SRLV:
11974            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11975            break;
11976        case RR_SRAV:
11977            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11978            break;
11979#if defined (TARGET_MIPS64)
11980        case RR_DSRL:
11981            check_insn(ctx, ISA_MIPS3);
11982            check_mips_64(ctx);
11983            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11984            break;
11985#endif
11986        case RR_CMP:
11987            gen_logic(ctx, OPC_XOR, 24, rx, ry);
11988            break;
11989        case RR_NEG:
11990            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11991            break;
11992        case RR_AND:
11993            gen_logic(ctx, OPC_AND, rx, rx, ry);
11994            break;
11995        case RR_OR:
11996            gen_logic(ctx, OPC_OR, rx, rx, ry);
11997            break;
11998        case RR_XOR:
11999            gen_logic(ctx, OPC_XOR, rx, rx, ry);
12000            break;
12001        case RR_NOT:
12002            gen_logic(ctx, OPC_NOR, rx, ry, 0);
12003            break;
12004        case RR_MFHI:
12005            gen_HILO(ctx, OPC_MFHI, 0, rx);
12006            break;
12007        case RR_CNVT:
12008            check_insn(ctx, ISA_MIPS32);
12009            switch (cnvt_op) {
12010            case RR_RY_CNVT_ZEB:
12011                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12012                break;
12013            case RR_RY_CNVT_ZEH:
12014                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12015                break;
12016            case RR_RY_CNVT_SEB:
12017                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12018                break;
12019            case RR_RY_CNVT_SEH:
12020                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12021                break;
12022#if defined (TARGET_MIPS64)
12023            case RR_RY_CNVT_ZEW:
12024                check_insn(ctx, ISA_MIPS64);
12025                check_mips_64(ctx);
12026                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12027                break;
12028            case RR_RY_CNVT_SEW:
12029                check_insn(ctx, ISA_MIPS64);
12030                check_mips_64(ctx);
12031                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12032                break;
12033#endif
12034            default:
12035                generate_exception_end(ctx, EXCP_RI);
12036                break;
12037            }
12038            break;
12039        case RR_MFLO:
12040            gen_HILO(ctx, OPC_MFLO, 0, rx);
12041            break;
12042#if defined (TARGET_MIPS64)
12043        case RR_DSRA:
12044            check_insn(ctx, ISA_MIPS3);
12045            check_mips_64(ctx);
12046            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
12047            break;
12048        case RR_DSLLV:
12049            check_insn(ctx, ISA_MIPS3);
12050            check_mips_64(ctx);
12051            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
12052            break;
12053        case RR_DSRLV:
12054            check_insn(ctx, ISA_MIPS3);
12055            check_mips_64(ctx);
12056            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
12057            break;
12058        case RR_DSRAV:
12059            check_insn(ctx, ISA_MIPS3);
12060            check_mips_64(ctx);
12061            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
12062            break;
12063#endif
12064        case RR_MULT:
12065            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
12066            break;
12067        case RR_MULTU:
12068            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
12069            break;
12070        case RR_DIV:
12071            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
12072            break;
12073        case RR_DIVU:
12074            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
12075            break;
12076#if defined (TARGET_MIPS64)
12077        case RR_DMULT:
12078            check_insn(ctx, ISA_MIPS3);
12079            check_mips_64(ctx);
12080            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
12081            break;
12082        case RR_DMULTU:
12083            check_insn(ctx, ISA_MIPS3);
12084            check_mips_64(ctx);
12085            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
12086            break;
12087        case RR_DDIV:
12088            check_insn(ctx, ISA_MIPS3);
12089            check_mips_64(ctx);
12090            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
12091            break;
12092        case RR_DDIVU:
12093            check_insn(ctx, ISA_MIPS3);
12094            check_mips_64(ctx);
12095            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
12096            break;
12097#endif
12098        default:
12099            generate_exception_end(ctx, EXCP_RI);
12100            break;
12101        }
12102        break;
12103    case M16_OPC_EXTEND:
12104        decode_extended_mips16_opc(env, ctx);
12105        n_bytes = 4;
12106        break;
12107#if defined(TARGET_MIPS64)
12108    case M16_OPC_I64:
12109        funct = (ctx->opcode >> 8) & 0x7;
12110        decode_i64_mips16(ctx, ry, funct, offset, 0);
12111        break;
12112#endif
12113    default:
12114        generate_exception_end(ctx, EXCP_RI);
12115        break;
12116    }
12117
12118    return n_bytes;
12119}
12120
12121/* microMIPS extension to MIPS32/MIPS64 */
12122
12123/*
12124 * microMIPS32/microMIPS64 major opcodes
12125 *
12126 * 1. MIPS Architecture for Programmers Volume II-B:
12127 *      The microMIPS32 Instruction Set (Revision 3.05)
12128 *
12129 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
12130 *
12131 * 2. MIPS Architecture For Programmers Volume II-A:
12132 *      The MIPS64 Instruction Set (Revision 3.51)
12133 */
12134
12135enum {
12136    POOL32A = 0x00,
12137    POOL16A = 0x01,
12138    LBU16 = 0x02,
12139    MOVE16 = 0x03,
12140    ADDI32 = 0x04,
12141    R6_LUI = 0x04,
12142    AUI = 0x04,
12143    LBU32 = 0x05,
12144    SB32 = 0x06,
12145    LB32 = 0x07,
12146
12147    POOL32B = 0x08,
12148    POOL16B = 0x09,
12149    LHU16 = 0x0a,
12150    ANDI16 = 0x0b,
12151    ADDIU32 = 0x0c,
12152    LHU32 = 0x0d,
12153    SH32 = 0x0e,
12154    LH32 = 0x0f,
12155
12156    POOL32I = 0x10,
12157    POOL16C = 0x11,
12158    LWSP16 = 0x12,
12159    POOL16D = 0x13,
12160    ORI32 = 0x14,
12161    POOL32F = 0x15,
12162    POOL32S = 0x16,  /* MIPS64 */
12163    DADDIU32 = 0x17, /* MIPS64 */
12164
12165    POOL32C = 0x18,
12166    LWGP16 = 0x19,
12167    LW16 = 0x1a,
12168    POOL16E = 0x1b,
12169    XORI32 = 0x1c,
12170    JALS32 = 0x1d,
12171    BOVC = 0x1d,
12172    BEQC = 0x1d,
12173    BEQZALC = 0x1d,
12174    ADDIUPC = 0x1e,
12175    PCREL = 0x1e,
12176    BNVC = 0x1f,
12177    BNEC = 0x1f,
12178    BNEZALC = 0x1f,
12179
12180    R6_BEQZC = 0x20,
12181    JIC = 0x20,
12182    POOL16F = 0x21,
12183    SB16 = 0x22,
12184    BEQZ16 = 0x23,
12185    BEQZC16 = 0x23,
12186    SLTI32 = 0x24,
12187    BEQ32 = 0x25,
12188    BC = 0x25,
12189    SWC132 = 0x26,
12190    LWC132 = 0x27,
12191
12192    /* 0x29 is reserved */
12193    RES_29 = 0x29,
12194    R6_BNEZC = 0x28,
12195    JIALC = 0x28,
12196    SH16 = 0x2a,
12197    BNEZ16 = 0x2b,
12198    BNEZC16 = 0x2b,
12199    SLTIU32 = 0x2c,
12200    BNE32 = 0x2d,
12201    BALC = 0x2d,
12202    SDC132 = 0x2e,
12203    LDC132 = 0x2f,
12204
12205    /* 0x31 is reserved */
12206    RES_31 = 0x31,
12207    BLEZALC = 0x30,
12208    BGEZALC = 0x30,
12209    BGEUC = 0x30,
12210    SWSP16 = 0x32,
12211    B16 = 0x33,
12212    BC16 = 0x33,
12213    ANDI32 = 0x34,
12214    J32 = 0x35,
12215    BGTZC = 0x35,
12216    BLTZC = 0x35,
12217    BLTC = 0x35,
12218    SD32 = 0x36, /* MIPS64 */
12219    LD32 = 0x37, /* MIPS64 */
12220
12221    /* 0x39 is reserved */
12222    RES_39 = 0x39,
12223    BGTZALC = 0x38,
12224    BLTZALC = 0x38,
12225    BLTUC = 0x38,
12226    SW16 = 0x3a,
12227    LI16 = 0x3b,
12228    JALX32 = 0x3c,
12229    JAL32 = 0x3d,
12230    BLEZC = 0x3d,
12231    BGEZC = 0x3d,
12232    BGEC = 0x3d,
12233    SW32 = 0x3e,
12234    LW32 = 0x3f
12235};
12236
12237/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12238enum {
12239    ADDIUPC_00 = 0x00,
12240    ADDIUPC_07 = 0x07,
12241    AUIPC = 0x1e,
12242    ALUIPC = 0x1f,
12243    LWPC_08 = 0x08,
12244    LWPC_0F = 0x0F,
12245};
12246
12247/* POOL32A encoding of minor opcode field */
12248
12249enum {
12250    /* These opcodes are distinguished only by bits 9..6; those bits are
12251     * what are recorded below. */
12252    SLL32 = 0x0,
12253    SRL32 = 0x1,
12254    SRA = 0x2,
12255    ROTR = 0x3,
12256    SELEQZ = 0x5,
12257    SELNEZ = 0x6,
12258    R6_RDHWR = 0x7,
12259
12260    SLLV = 0x0,
12261    SRLV = 0x1,
12262    SRAV = 0x2,
12263    ROTRV = 0x3,
12264    ADD = 0x4,
12265    ADDU32 = 0x5,
12266    SUB = 0x6,
12267    SUBU32 = 0x7,
12268    MUL = 0x8,
12269    AND = 0x9,
12270    OR32 = 0xa,
12271    NOR = 0xb,
12272    XOR32 = 0xc,
12273    SLT = 0xd,
12274    SLTU = 0xe,
12275
12276    MOVN = 0x0,
12277    R6_MUL  = 0x0,
12278    MOVZ = 0x1,
12279    MUH  = 0x1,
12280    MULU = 0x2,
12281    MUHU = 0x3,
12282    LWXS = 0x4,
12283    R6_DIV  = 0x4,
12284    MOD  = 0x5,
12285    R6_DIVU = 0x6,
12286    MODU = 0x7,
12287
12288    /* The following can be distinguished by their lower 6 bits. */
12289    BREAK32 = 0x07,
12290    INS = 0x0c,
12291    LSA = 0x0f,
12292    ALIGN = 0x1f,
12293    EXT = 0x2c,
12294    POOL32AXF = 0x3c,
12295    SIGRIE = 0x3f
12296};
12297
12298/* POOL32AXF encoding of minor opcode field extension */
12299
12300/*
12301 * 1. MIPS Architecture for Programmers Volume II-B:
12302 *      The microMIPS32 Instruction Set (Revision 3.05)
12303 *
12304 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12305 *
12306 * 2. MIPS Architecture for Programmers VolumeIV-e:
12307 *      The MIPS DSP Application-Specific Extension
12308 *        to the microMIPS32 Architecture (Revision 2.34)
12309 *
12310 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12311 */
12312
12313enum {
12314    /* bits 11..6 */
12315    TEQ = 0x00,
12316    TGE = 0x08,
12317    TGEU = 0x10,
12318    TLT = 0x20,
12319    TLTU = 0x28,
12320    TNE = 0x30,
12321
12322    MFC0 = 0x03,
12323    MTC0 = 0x0b,
12324
12325    /* begin of microMIPS32 DSP */
12326
12327    /* bits 13..12 for 0x01 */
12328    MFHI_ACC = 0x0,
12329    MFLO_ACC = 0x1,
12330    MTHI_ACC = 0x2,
12331    MTLO_ACC = 0x3,
12332
12333    /* bits 13..12 for 0x2a */
12334    MADD_ACC = 0x0,
12335    MADDU_ACC = 0x1,
12336    MSUB_ACC = 0x2,
12337    MSUBU_ACC = 0x3,
12338
12339    /* bits 13..12 for 0x32 */
12340    MULT_ACC = 0x0,
12341    MULTU_ACC = 0x1,
12342
12343    /* end of microMIPS32 DSP */
12344
12345    /* bits 15..12 for 0x2c */
12346    BITSWAP = 0x0,
12347    SEB = 0x2,
12348    SEH = 0x3,
12349    CLO = 0x4,
12350    CLZ = 0x5,
12351    RDHWR = 0x6,
12352    WSBH = 0x7,
12353    MULT = 0x8,
12354    MULTU = 0x9,
12355    DIV = 0xa,
12356    DIVU = 0xb,
12357    MADD = 0xc,
12358    MADDU = 0xd,
12359    MSUB = 0xe,
12360    MSUBU = 0xf,
12361
12362    /* bits 15..12 for 0x34 */
12363    MFC2 = 0x4,
12364    MTC2 = 0x5,
12365    MFHC2 = 0x8,
12366    MTHC2 = 0x9,
12367    CFC2 = 0xc,
12368    CTC2 = 0xd,
12369
12370    /* bits 15..12 for 0x3c */
12371    JALR = 0x0,
12372    JR = 0x0,                   /* alias */
12373    JALRC = 0x0,
12374    JRC = 0x0,
12375    JALR_HB = 0x1,
12376    JALRC_HB = 0x1,
12377    JALRS = 0x4,
12378    JALRS_HB = 0x5,
12379
12380    /* bits 15..12 for 0x05 */
12381    RDPGPR = 0xe,
12382    WRPGPR = 0xf,
12383
12384    /* bits 15..12 for 0x0d */
12385    TLBP = 0x0,
12386    TLBR = 0x1,
12387    TLBWI = 0x2,
12388    TLBWR = 0x3,
12389    TLBINV = 0x4,
12390    TLBINVF = 0x5,
12391    WAIT = 0x9,
12392    IRET = 0xd,
12393    DERET = 0xe,
12394    ERET = 0xf,
12395
12396    /* bits 15..12 for 0x15 */
12397    DMT = 0x0,
12398    DVPE = 0x1,
12399    EMT = 0x2,
12400    EVPE = 0x3,
12401
12402    /* bits 15..12 for 0x1d */
12403    DI = 0x4,
12404    EI = 0x5,
12405
12406    /* bits 15..12 for 0x2d */
12407    SYNC = 0x6,
12408    SYSCALL = 0x8,
12409    SDBBP = 0xd,
12410
12411    /* bits 15..12 for 0x35 */
12412    MFHI32 = 0x0,
12413    MFLO32 = 0x1,
12414    MTHI32 = 0x2,
12415    MTLO32 = 0x3,
12416};
12417
12418/* POOL32B encoding of minor opcode field (bits 15..12) */
12419
12420enum {
12421    LWC2 = 0x0,
12422    LWP = 0x1,
12423    LDP = 0x4,
12424    LWM32 = 0x5,
12425    CACHE = 0x6,
12426    LDM = 0x7,
12427    SWC2 = 0x8,
12428    SWP = 0x9,
12429    SDP = 0xc,
12430    SWM32 = 0xd,
12431    SDM = 0xf
12432};
12433
12434/* POOL32C encoding of minor opcode field (bits 15..12) */
12435
12436enum {
12437    LWL = 0x0,
12438    SWL = 0x8,
12439    LWR = 0x1,
12440    SWR = 0x9,
12441    PREF = 0x2,
12442    /* 0xa is reserved */
12443    LL = 0x3,
12444    SC = 0xb,
12445    LDL = 0x4,
12446    SDL = 0xc,
12447    LDR = 0x5,
12448    SDR = 0xd,
12449    /* 0x6 is reserved */
12450    LWU = 0xe,
12451    LLD = 0x7,
12452    SCD = 0xf
12453};
12454
12455/* POOL32F encoding of minor opcode field (bits 5..0) */
12456
12457enum {
12458    /* These are the bit 7..6 values */
12459    ADD_FMT = 0x0,
12460
12461    SUB_FMT = 0x1,
12462
12463    MUL_FMT = 0x2,
12464
12465    DIV_FMT = 0x3,
12466
12467    /* These are the bit 8..6 values */
12468    MOVN_FMT = 0x0,
12469    RSQRT2_FMT = 0x0,
12470    MOVF_FMT = 0x0,
12471    RINT_FMT = 0x0,
12472    SELNEZ_FMT = 0x0,
12473
12474    MOVZ_FMT = 0x1,
12475    LWXC1 = 0x1,
12476    MOVT_FMT = 0x1,
12477    CLASS_FMT = 0x1,
12478    SELEQZ_FMT = 0x1,
12479
12480    PLL_PS = 0x2,
12481    SWXC1 = 0x2,
12482    SEL_FMT = 0x2,
12483
12484    PLU_PS = 0x3,
12485    LDXC1 = 0x3,
12486
12487    MOVN_FMT_04 = 0x4,
12488    PUL_PS = 0x4,
12489    SDXC1 = 0x4,
12490    RECIP2_FMT = 0x4,
12491
12492    MOVZ_FMT_05 = 0x05,
12493    PUU_PS = 0x5,
12494    LUXC1 = 0x5,
12495
12496    CVT_PS_S = 0x6,
12497    SUXC1 = 0x6,
12498    ADDR_PS = 0x6,
12499    PREFX = 0x6,
12500    MADDF_FMT = 0x6,
12501
12502    MULR_PS = 0x7,
12503    MSUBF_FMT = 0x7,
12504
12505    MADD_S = 0x01,
12506    MADD_D = 0x09,
12507    MADD_PS = 0x11,
12508    ALNV_PS = 0x19,
12509    MSUB_S = 0x21,
12510    MSUB_D = 0x29,
12511    MSUB_PS = 0x31,
12512
12513    NMADD_S = 0x02,
12514    NMADD_D = 0x0a,
12515    NMADD_PS = 0x12,
12516    NMSUB_S = 0x22,
12517    NMSUB_D = 0x2a,
12518    NMSUB_PS = 0x32,
12519
12520    MIN_FMT = 0x3,
12521    MAX_FMT = 0xb,
12522    MINA_FMT = 0x23,
12523    MAXA_FMT = 0x2b,
12524    POOL32FXF = 0x3b,
12525
12526    CABS_COND_FMT = 0x1c,              /* MIPS3D */
12527    C_COND_FMT = 0x3c,
12528
12529    CMP_CONDN_S = 0x5,
12530    CMP_CONDN_D = 0x15
12531};
12532
12533/* POOL32Fxf encoding of minor opcode extension field */
12534
12535enum {
12536    CVT_L = 0x04,
12537    RSQRT_FMT = 0x08,
12538    FLOOR_L = 0x0c,
12539    CVT_PW_PS = 0x1c,
12540    CVT_W = 0x24,
12541    SQRT_FMT = 0x28,
12542    FLOOR_W = 0x2c,
12543    CVT_PS_PW = 0x3c,
12544    CFC1 = 0x40,
12545    RECIP_FMT = 0x48,
12546    CEIL_L = 0x4c,
12547    CTC1 = 0x60,
12548    CEIL_W = 0x6c,
12549    MFC1 = 0x80,
12550    CVT_S_PL = 0x84,
12551    TRUNC_L = 0x8c,
12552    MTC1 = 0xa0,
12553    CVT_S_PU = 0xa4,
12554    TRUNC_W = 0xac,
12555    MFHC1 = 0xc0,
12556    ROUND_L = 0xcc,
12557    MTHC1 = 0xe0,
12558    ROUND_W = 0xec,
12559
12560    MOV_FMT = 0x01,
12561    MOVF = 0x05,
12562    ABS_FMT = 0x0d,
12563    RSQRT1_FMT = 0x1d,
12564    MOVT = 0x25,
12565    NEG_FMT = 0x2d,
12566    CVT_D = 0x4d,
12567    RECIP1_FMT = 0x5d,
12568    CVT_S = 0x6d
12569};
12570
12571/* POOL32I encoding of minor opcode field (bits 25..21) */
12572
12573enum {
12574    BLTZ = 0x00,
12575    BLTZAL = 0x01,
12576    BGEZ = 0x02,
12577    BGEZAL = 0x03,
12578    BLEZ = 0x04,
12579    BNEZC = 0x05,
12580    BGTZ = 0x06,
12581    BEQZC = 0x07,
12582    TLTI = 0x08,
12583    BC1EQZC = 0x08,
12584    TGEI = 0x09,
12585    BC1NEZC = 0x09,
12586    TLTIU = 0x0a,
12587    BC2EQZC = 0x0a,
12588    TGEIU = 0x0b,
12589    BC2NEZC = 0x0a,
12590    TNEI = 0x0c,
12591    R6_SYNCI = 0x0c,
12592    LUI = 0x0d,
12593    TEQI = 0x0e,
12594    SYNCI = 0x10,
12595    BLTZALS = 0x11,
12596    BGEZALS = 0x13,
12597    BC2F = 0x14,
12598    BC2T = 0x15,
12599    BPOSGE64 = 0x1a,
12600    BPOSGE32 = 0x1b,
12601    /* These overlap and are distinguished by bit16 of the instruction */
12602    BC1F = 0x1c,
12603    BC1T = 0x1d,
12604    BC1ANY2F = 0x1c,
12605    BC1ANY2T = 0x1d,
12606    BC1ANY4F = 0x1e,
12607    BC1ANY4T = 0x1f
12608};
12609
12610/* POOL16A encoding of minor opcode field */
12611
12612enum {
12613    ADDU16 = 0x0,
12614    SUBU16 = 0x1
12615};
12616
12617/* POOL16B encoding of minor opcode field */
12618
12619enum {
12620    SLL16 = 0x0,
12621    SRL16 = 0x1
12622};
12623
12624/* POOL16C encoding of minor opcode field */
12625
12626enum {
12627    NOT16 = 0x00,
12628    XOR16 = 0x04,
12629    AND16 = 0x08,
12630    OR16 = 0x0c,
12631    LWM16 = 0x10,
12632    SWM16 = 0x14,
12633    JR16 = 0x18,
12634    JRC16 = 0x1a,
12635    JALR16 = 0x1c,
12636    JALR16S = 0x1e,
12637    MFHI16 = 0x20,
12638    MFLO16 = 0x24,
12639    BREAK16 = 0x28,
12640    SDBBP16 = 0x2c,
12641    JRADDIUSP = 0x30
12642};
12643
12644/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12645
12646enum {
12647    R6_NOT16    = 0x00,
12648    R6_AND16    = 0x01,
12649    R6_LWM16    = 0x02,
12650    R6_JRC16    = 0x03,
12651    MOVEP       = 0x04,
12652    MOVEP_07    = 0x07,
12653    R6_XOR16    = 0x08,
12654    R6_OR16     = 0x09,
12655    R6_SWM16    = 0x0a,
12656    JALRC16     = 0x0b,
12657    MOVEP_0C    = 0x0c,
12658    MOVEP_0F    = 0x0f,
12659    JRCADDIUSP  = 0x13,
12660    R6_BREAK16  = 0x1b,
12661    R6_SDBBP16  = 0x3b
12662};
12663
12664/* POOL16D encoding of minor opcode field */
12665
12666enum {
12667    ADDIUS5 = 0x0,
12668    ADDIUSP = 0x1
12669};
12670
12671/* POOL16E encoding of minor opcode field */
12672
12673enum {
12674    ADDIUR2 = 0x0,
12675    ADDIUR1SP = 0x1
12676};
12677
12678static int mmreg (int r)
12679{
12680    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12681
12682    return map[r];
12683}
12684
12685/* Used for 16-bit store instructions.  */
12686static int mmreg2 (int r)
12687{
12688    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12689
12690    return map[r];
12691}
12692
12693#define uMIPS_RD(op) ((op >> 7) & 0x7)
12694#define uMIPS_RS(op) ((op >> 4) & 0x7)
12695#define uMIPS_RS2(op) uMIPS_RS(op)
12696#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12697#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12698#define uMIPS_RS5(op) (op & 0x1f)
12699
12700/* Signed immediate */
12701#define SIMM(op, start, width)                                          \
12702    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
12703               << (32-width))                                           \
12704     >> (32-width))
12705/* Zero-extended immediate */
12706#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12707
12708static void gen_addiur1sp(DisasContext *ctx)
12709{
12710    int rd = mmreg(uMIPS_RD(ctx->opcode));
12711
12712    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12713}
12714
12715static void gen_addiur2(DisasContext *ctx)
12716{
12717    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12718    int rd = mmreg(uMIPS_RD(ctx->opcode));
12719    int rs = mmreg(uMIPS_RS(ctx->opcode));
12720
12721    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12722}
12723
12724static void gen_addiusp(DisasContext *ctx)
12725{
12726    int encoded = ZIMM(ctx->opcode, 1, 9);
12727    int decoded;
12728
12729    if (encoded <= 1) {
12730        decoded = 256 + encoded;
12731    } else if (encoded <= 255) {
12732        decoded = encoded;
12733    } else if (encoded <= 509) {
12734        decoded = encoded - 512;
12735    } else {
12736        decoded = encoded - 768;
12737    }
12738
12739    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12740}
12741
12742static void gen_addius5(DisasContext *ctx)
12743{
12744    int imm = SIMM(ctx->opcode, 1, 4);
12745    int rd = (ctx->opcode >> 5) & 0x1f;
12746
12747    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12748}
12749
12750static void gen_andi16(DisasContext *ctx)
12751{
12752    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12753                                 31, 32, 63, 64, 255, 32768, 65535 };
12754    int rd = mmreg(uMIPS_RD(ctx->opcode));
12755    int rs = mmreg(uMIPS_RS(ctx->opcode));
12756    int encoded = ZIMM(ctx->opcode, 0, 4);
12757
12758    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12759}
12760
12761static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12762                               int base, int16_t offset)
12763{
12764    TCGv t0, t1;
12765    TCGv_i32 t2;
12766
12767    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12768        generate_exception_end(ctx, EXCP_RI);
12769        return;
12770    }
12771
12772    t0 = tcg_temp_new();
12773
12774    gen_base_offset_addr(ctx, t0, base, offset);
12775
12776    t1 = tcg_const_tl(reglist);
12777    t2 = tcg_const_i32(ctx->mem_idx);
12778
12779    save_cpu_state(ctx, 1);
12780    switch (opc) {
12781    case LWM32:
12782        gen_helper_lwm(cpu_env, t0, t1, t2);
12783        break;
12784    case SWM32:
12785        gen_helper_swm(cpu_env, t0, t1, t2);
12786        break;
12787#ifdef TARGET_MIPS64
12788    case LDM:
12789        gen_helper_ldm(cpu_env, t0, t1, t2);
12790        break;
12791    case SDM:
12792        gen_helper_sdm(cpu_env, t0, t1, t2);
12793        break;
12794#endif
12795    }
12796    tcg_temp_free(t0);
12797    tcg_temp_free(t1);
12798    tcg_temp_free_i32(t2);
12799}
12800
12801
12802static void gen_pool16c_insn(DisasContext *ctx)
12803{
12804    int rd = mmreg((ctx->opcode >> 3) & 0x7);
12805    int rs = mmreg(ctx->opcode & 0x7);
12806
12807    switch (((ctx->opcode) >> 4) & 0x3f) {
12808    case NOT16 + 0:
12809    case NOT16 + 1:
12810    case NOT16 + 2:
12811    case NOT16 + 3:
12812        gen_logic(ctx, OPC_NOR, rd, rs, 0);
12813        break;
12814    case XOR16 + 0:
12815    case XOR16 + 1:
12816    case XOR16 + 2:
12817    case XOR16 + 3:
12818        gen_logic(ctx, OPC_XOR, rd, rd, rs);
12819        break;
12820    case AND16 + 0:
12821    case AND16 + 1:
12822    case AND16 + 2:
12823    case AND16 + 3:
12824        gen_logic(ctx, OPC_AND, rd, rd, rs);
12825        break;
12826    case OR16 + 0:
12827    case OR16 + 1:
12828    case OR16 + 2:
12829    case OR16 + 3:
12830        gen_logic(ctx, OPC_OR, rd, rd, rs);
12831        break;
12832    case LWM16 + 0:
12833    case LWM16 + 1:
12834    case LWM16 + 2:
12835    case LWM16 + 3:
12836        {
12837            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12838            int offset = ZIMM(ctx->opcode, 0, 4);
12839
12840            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12841                              29, offset << 2);
12842        }
12843        break;
12844    case SWM16 + 0:
12845    case SWM16 + 1:
12846    case SWM16 + 2:
12847    case SWM16 + 3:
12848        {
12849            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12850            int offset = ZIMM(ctx->opcode, 0, 4);
12851
12852            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12853                              29, offset << 2);
12854        }
12855        break;
12856    case JR16 + 0:
12857    case JR16 + 1:
12858        {
12859            int reg = ctx->opcode & 0x1f;
12860
12861            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12862        }
12863        break;
12864    case JRC16 + 0:
12865    case JRC16 + 1:
12866        {
12867            int reg = ctx->opcode & 0x1f;
12868            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12869            /* Let normal delay slot handling in our caller take us
12870               to the branch target.  */
12871        }
12872        break;
12873    case JALR16 + 0:
12874    case JALR16 + 1:
12875        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12876        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12877        break;
12878    case JALR16S + 0:
12879    case JALR16S + 1:
12880        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12881        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12882        break;
12883    case MFHI16 + 0:
12884    case MFHI16 + 1:
12885        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12886        break;
12887    case MFLO16 + 0:
12888    case MFLO16 + 1:
12889        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12890        break;
12891    case BREAK16:
12892        generate_exception_end(ctx, EXCP_BREAK);
12893        break;
12894    case SDBBP16:
12895        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12896            gen_helper_do_semihosting(cpu_env);
12897        } else {
12898            /* XXX: not clear which exception should be raised
12899             *      when in debug mode...
12900             */
12901            check_insn(ctx, ISA_MIPS32);
12902            generate_exception_end(ctx, EXCP_DBp);
12903        }
12904        break;
12905    case JRADDIUSP + 0:
12906    case JRADDIUSP + 1:
12907        {
12908            int imm = ZIMM(ctx->opcode, 0, 5);
12909            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12910            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12911            /* Let normal delay slot handling in our caller take us
12912               to the branch target.  */
12913        }
12914        break;
12915    default:
12916        generate_exception_end(ctx, EXCP_RI);
12917        break;
12918    }
12919}
12920
12921static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12922                             int enc_rs)
12923{
12924    int rd, rs, re, rt;
12925    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12926    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12927    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12928    rd = rd_enc[enc_dest];
12929    re = re_enc[enc_dest];
12930    rs = rs_rt_enc[enc_rs];
12931    rt = rs_rt_enc[enc_rt];
12932    if (rs) {
12933        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12934    } else {
12935        tcg_gen_movi_tl(cpu_gpr[rd], 0);
12936    }
12937    if (rt) {
12938        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12939    } else {
12940        tcg_gen_movi_tl(cpu_gpr[re], 0);
12941    }
12942}
12943
12944static void gen_pool16c_r6_insn(DisasContext *ctx)
12945{
12946    int rt = mmreg((ctx->opcode >> 7) & 0x7);
12947    int rs = mmreg((ctx->opcode >> 4) & 0x7);
12948
12949    switch (ctx->opcode & 0xf) {
12950    case R6_NOT16:
12951        gen_logic(ctx, OPC_NOR, rt, rs, 0);
12952        break;
12953    case R6_AND16:
12954        gen_logic(ctx, OPC_AND, rt, rt, rs);
12955        break;
12956    case R6_LWM16:
12957        {
12958            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12959            int offset = extract32(ctx->opcode, 4, 4);
12960            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12961        }
12962        break;
12963    case R6_JRC16: /* JRCADDIUSP */
12964        if ((ctx->opcode >> 4) & 1) {
12965            /* JRCADDIUSP */
12966            int imm = extract32(ctx->opcode, 5, 5);
12967            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12968            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12969        } else {
12970            /* JRC16 */
12971            int rs = extract32(ctx->opcode, 5, 5);
12972            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12973        }
12974        break;
12975    case MOVEP ... MOVEP_07:
12976    case MOVEP_0C ... MOVEP_0F:
12977        {
12978            int enc_dest = uMIPS_RD(ctx->opcode);
12979            int enc_rt = uMIPS_RS2(ctx->opcode);
12980            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12981            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12982        }
12983        break;
12984    case R6_XOR16:
12985        gen_logic(ctx, OPC_XOR, rt, rt, rs);
12986        break;
12987    case R6_OR16:
12988        gen_logic(ctx, OPC_OR, rt, rt, rs);
12989        break;
12990    case R6_SWM16:
12991        {
12992            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12993            int offset = extract32(ctx->opcode, 4, 4);
12994            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12995        }
12996        break;
12997    case JALRC16: /* BREAK16, SDBBP16 */
12998        switch (ctx->opcode & 0x3f) {
12999        case JALRC16:
13000        case JALRC16 + 0x20:
13001            /* JALRC16 */
13002            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13003                               31, 0, 0);
13004            break;
13005        case R6_BREAK16:
13006            /* BREAK16 */
13007            generate_exception(ctx, EXCP_BREAK);
13008            break;
13009        case R6_SDBBP16:
13010            /* SDBBP16 */
13011            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13012                gen_helper_do_semihosting(cpu_env);
13013            } else {
13014                if (ctx->hflags & MIPS_HFLAG_SBRI) {
13015                    generate_exception(ctx, EXCP_RI);
13016                } else {
13017                    generate_exception(ctx, EXCP_DBp);
13018                }
13019            }
13020            break;
13021        }
13022        break;
13023    default:
13024        generate_exception(ctx, EXCP_RI);
13025        break;
13026    }
13027}
13028
13029static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13030{
13031    TCGv t0 = tcg_temp_new();
13032    TCGv t1 = tcg_temp_new();
13033
13034    gen_load_gpr(t0, base);
13035
13036    if (index != 0) {
13037        gen_load_gpr(t1, index);
13038        tcg_gen_shli_tl(t1, t1, 2);
13039        gen_op_addr_add(ctx, t0, t1, t0);
13040    }
13041
13042    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13043    gen_store_gpr(t1, rd);
13044
13045    tcg_temp_free(t0);
13046    tcg_temp_free(t1);
13047}
13048
13049static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13050                           int base, int16_t offset)
13051{
13052    TCGv t0, t1;
13053
13054    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
13055        generate_exception_end(ctx, EXCP_RI);
13056        return;
13057    }
13058
13059    t0 = tcg_temp_new();
13060    t1 = tcg_temp_new();
13061
13062    gen_base_offset_addr(ctx, t0, base, offset);
13063
13064    switch (opc) {
13065    case LWP:
13066        if (rd == base) {
13067            generate_exception_end(ctx, EXCP_RI);
13068            return;
13069        }
13070        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13071        gen_store_gpr(t1, rd);
13072        tcg_gen_movi_tl(t1, 4);
13073        gen_op_addr_add(ctx, t0, t0, t1);
13074        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13075        gen_store_gpr(t1, rd+1);
13076        break;
13077    case SWP:
13078        gen_load_gpr(t1, rd);
13079        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13080        tcg_gen_movi_tl(t1, 4);
13081        gen_op_addr_add(ctx, t0, t0, t1);
13082        gen_load_gpr(t1, rd+1);
13083        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13084        break;
13085#ifdef TARGET_MIPS64
13086    case LDP:
13087        if (rd == base) {
13088            generate_exception_end(ctx, EXCP_RI);
13089            return;
13090        }
13091        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13092        gen_store_gpr(t1, rd);
13093        tcg_gen_movi_tl(t1, 8);
13094        gen_op_addr_add(ctx, t0, t0, t1);
13095        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13096        gen_store_gpr(t1, rd+1);
13097        break;
13098    case SDP:
13099        gen_load_gpr(t1, rd);
13100        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13101        tcg_gen_movi_tl(t1, 8);
13102        gen_op_addr_add(ctx, t0, t0, t1);
13103        gen_load_gpr(t1, rd+1);
13104        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13105        break;
13106#endif
13107    }
13108    tcg_temp_free(t0);
13109    tcg_temp_free(t1);
13110}
13111
13112static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13113{
13114    int extension = (ctx->opcode >> 6) & 0x3f;
13115    int minor = (ctx->opcode >> 12) & 0xf;
13116    uint32_t mips32_op;
13117
13118    switch (extension) {
13119    case TEQ:
13120        mips32_op = OPC_TEQ;
13121        goto do_trap;
13122    case TGE:
13123        mips32_op = OPC_TGE;
13124        goto do_trap;
13125    case TGEU:
13126        mips32_op = OPC_TGEU;
13127        goto do_trap;
13128    case TLT:
13129        mips32_op = OPC_TLT;
13130        goto do_trap;
13131    case TLTU:
13132        mips32_op = OPC_TLTU;
13133        goto do_trap;
13134    case TNE:
13135        mips32_op = OPC_TNE;
13136    do_trap:
13137        gen_trap(ctx, mips32_op, rs, rt, -1);
13138        break;
13139#ifndef CONFIG_USER_ONLY
13140    case MFC0:
13141    case MFC0 + 32:
13142        check_cp0_enabled(ctx);
13143        if (rt == 0) {
13144            /* Treat as NOP. */
13145            break;
13146        }
13147        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13148        break;
13149    case MTC0:
13150    case MTC0 + 32:
13151        check_cp0_enabled(ctx);
13152        {
13153            TCGv t0 = tcg_temp_new();
13154
13155            gen_load_gpr(t0, rt);
13156            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13157            tcg_temp_free(t0);
13158        }
13159        break;
13160#endif
13161    case 0x2a:
13162        switch (minor & 3) {
13163        case MADD_ACC:
13164            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13165            break;
13166        case MADDU_ACC:
13167            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13168            break;
13169        case MSUB_ACC:
13170            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13171            break;
13172        case MSUBU_ACC:
13173            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13174            break;
13175        default:
13176            goto pool32axf_invalid;
13177        }
13178        break;
13179    case 0x32:
13180        switch (minor & 3) {
13181        case MULT_ACC:
13182            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13183            break;
13184        case MULTU_ACC:
13185            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13186            break;
13187        default:
13188            goto pool32axf_invalid;
13189        }
13190        break;
13191    case 0x2c:
13192        switch (minor) {
13193        case BITSWAP:
13194            check_insn(ctx, ISA_MIPS32R6);
13195            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13196            break;
13197        case SEB:
13198            gen_bshfl(ctx, OPC_SEB, rs, rt);
13199            break;
13200        case SEH:
13201            gen_bshfl(ctx, OPC_SEH, rs, rt);
13202            break;
13203        case CLO:
13204            mips32_op = OPC_CLO;
13205            goto do_cl;
13206        case CLZ:
13207            mips32_op = OPC_CLZ;
13208        do_cl:
13209            check_insn(ctx, ISA_MIPS32);
13210            gen_cl(ctx, mips32_op, rt, rs);
13211            break;
13212        case RDHWR:
13213            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13214            gen_rdhwr(ctx, rt, rs, 0);
13215            break;
13216        case WSBH:
13217            gen_bshfl(ctx, OPC_WSBH, rs, rt);
13218            break;
13219        case MULT:
13220            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13221            mips32_op = OPC_MULT;
13222            goto do_mul;
13223        case MULTU:
13224            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13225            mips32_op = OPC_MULTU;
13226            goto do_mul;
13227        case DIV:
13228            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13229            mips32_op = OPC_DIV;
13230            goto do_div;
13231        case DIVU:
13232            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13233            mips32_op = OPC_DIVU;
13234            goto do_div;
13235        do_div:
13236            check_insn(ctx, ISA_MIPS32);
13237            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13238            break;
13239        case MADD:
13240            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13241            mips32_op = OPC_MADD;
13242            goto do_mul;
13243        case MADDU:
13244            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13245            mips32_op = OPC_MADDU;
13246            goto do_mul;
13247        case MSUB:
13248            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13249            mips32_op = OPC_MSUB;
13250            goto do_mul;
13251        case MSUBU:
13252            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13253            mips32_op = OPC_MSUBU;
13254        do_mul:
13255            check_insn(ctx, ISA_MIPS32);
13256            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13257            break;
13258        default:
13259            goto pool32axf_invalid;
13260        }
13261        break;
13262    case 0x34:
13263        switch (minor) {
13264        case MFC2:
13265        case MTC2:
13266        case MFHC2:
13267        case MTHC2:
13268        case CFC2:
13269        case CTC2:
13270            generate_exception_err(ctx, EXCP_CpU, 2);
13271            break;
13272        default:
13273            goto pool32axf_invalid;
13274        }
13275        break;
13276    case 0x3c:
13277        switch (minor) {
13278        case JALR:    /* JALRC */
13279        case JALR_HB: /* JALRC_HB */
13280            if (ctx->insn_flags & ISA_MIPS32R6) {
13281                /* JALRC, JALRC_HB */
13282                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13283            } else {
13284                /* JALR, JALR_HB */
13285                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13286                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13287            }
13288            break;
13289        case JALRS:
13290        case JALRS_HB:
13291            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13292            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13293            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13294            break;
13295        default:
13296            goto pool32axf_invalid;
13297        }
13298        break;
13299    case 0x05:
13300        switch (minor) {
13301        case RDPGPR:
13302            check_cp0_enabled(ctx);
13303            check_insn(ctx, ISA_MIPS32R2);
13304            gen_load_srsgpr(rs, rt);
13305            break;
13306        case WRPGPR:
13307            check_cp0_enabled(ctx);
13308            check_insn(ctx, ISA_MIPS32R2);
13309            gen_store_srsgpr(rs, rt);
13310            break;
13311        default:
13312            goto pool32axf_invalid;
13313        }
13314        break;
13315#ifndef CONFIG_USER_ONLY
13316    case 0x0d:
13317        switch (minor) {
13318        case TLBP:
13319            mips32_op = OPC_TLBP;
13320            goto do_cp0;
13321        case TLBR:
13322            mips32_op = OPC_TLBR;
13323            goto do_cp0;
13324        case TLBWI:
13325            mips32_op = OPC_TLBWI;
13326            goto do_cp0;
13327        case TLBWR:
13328            mips32_op = OPC_TLBWR;
13329            goto do_cp0;
13330        case TLBINV:
13331            mips32_op = OPC_TLBINV;
13332            goto do_cp0;
13333        case TLBINVF:
13334            mips32_op = OPC_TLBINVF;
13335            goto do_cp0;
13336        case WAIT:
13337            mips32_op = OPC_WAIT;
13338            goto do_cp0;
13339        case DERET:
13340            mips32_op = OPC_DERET;
13341            goto do_cp0;
13342        case ERET:
13343            mips32_op = OPC_ERET;
13344        do_cp0:
13345            gen_cp0(env, ctx, mips32_op, rt, rs);
13346            break;
13347        default:
13348            goto pool32axf_invalid;
13349        }
13350        break;
13351    case 0x1d:
13352        switch (minor) {
13353        case DI:
13354            check_cp0_enabled(ctx);
13355            {
13356                TCGv t0 = tcg_temp_new();
13357
13358                save_cpu_state(ctx, 1);
13359                gen_helper_di(t0, cpu_env);
13360                gen_store_gpr(t0, rs);
13361                /* Stop translation as we may have switched the execution mode */
13362                ctx->bstate = BS_STOP;
13363                tcg_temp_free(t0);
13364            }
13365            break;
13366        case EI:
13367            check_cp0_enabled(ctx);
13368            {
13369                TCGv t0 = tcg_temp_new();
13370
13371                save_cpu_state(ctx, 1);
13372                gen_helper_ei(t0, cpu_env);
13373                gen_store_gpr(t0, rs);
13374                /* Stop translation as we may have switched the execution mode */
13375                ctx->bstate = BS_STOP;
13376                tcg_temp_free(t0);
13377            }
13378            break;
13379        default:
13380            goto pool32axf_invalid;
13381        }
13382        break;
13383#endif
13384    case 0x2d:
13385        switch (minor) {
13386        case SYNC:
13387            /* NOP */
13388            break;
13389        case SYSCALL:
13390            generate_exception_end(ctx, EXCP_SYSCALL);
13391            break;
13392        case SDBBP:
13393            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13394                gen_helper_do_semihosting(cpu_env);
13395            } else {
13396                check_insn(ctx, ISA_MIPS32);
13397                if (ctx->hflags & MIPS_HFLAG_SBRI) {
13398                    generate_exception_end(ctx, EXCP_RI);
13399                } else {
13400                    generate_exception_end(ctx, EXCP_DBp);
13401                }
13402            }
13403            break;
13404        default:
13405            goto pool32axf_invalid;
13406        }
13407        break;
13408    case 0x01:
13409        switch (minor & 3) {
13410        case MFHI_ACC:
13411            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13412            break;
13413        case MFLO_ACC:
13414            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13415            break;
13416        case MTHI_ACC:
13417            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13418            break;
13419        case MTLO_ACC:
13420            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13421            break;
13422        default:
13423            goto pool32axf_invalid;
13424        }
13425        break;
13426    case 0x35:
13427        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13428        switch (minor) {
13429        case MFHI32:
13430            gen_HILO(ctx, OPC_MFHI, 0, rs);
13431            break;
13432        case MFLO32:
13433            gen_HILO(ctx, OPC_MFLO, 0, rs);
13434            break;
13435        case MTHI32:
13436            gen_HILO(ctx, OPC_MTHI, 0, rs);
13437            break;
13438        case MTLO32:
13439            gen_HILO(ctx, OPC_MTLO, 0, rs);
13440            break;
13441        default:
13442            goto pool32axf_invalid;
13443        }
13444        break;
13445    default:
13446    pool32axf_invalid:
13447        MIPS_INVAL("pool32axf");
13448        generate_exception_end(ctx, EXCP_RI);
13449        break;
13450    }
13451}
13452
13453/* Values for microMIPS fmt field.  Variable-width, depending on which
13454   formats the instruction supports.  */
13455
13456enum {
13457    FMT_SD_S = 0,
13458    FMT_SD_D = 1,
13459
13460    FMT_SDPS_S = 0,
13461    FMT_SDPS_D = 1,
13462    FMT_SDPS_PS = 2,
13463
13464    FMT_SWL_S = 0,
13465    FMT_SWL_W = 1,
13466    FMT_SWL_L = 2,
13467
13468    FMT_DWL_D = 0,
13469    FMT_DWL_W = 1,
13470    FMT_DWL_L = 2
13471};
13472
13473static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13474{
13475    int extension = (ctx->opcode >> 6) & 0x3ff;
13476    uint32_t mips32_op;
13477
13478#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13479#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13480#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13481
13482    switch (extension) {
13483    case FLOAT_1BIT_FMT(CFC1, 0):
13484        mips32_op = OPC_CFC1;
13485        goto do_cp1;
13486    case FLOAT_1BIT_FMT(CTC1, 0):
13487        mips32_op = OPC_CTC1;
13488        goto do_cp1;
13489    case FLOAT_1BIT_FMT(MFC1, 0):
13490        mips32_op = OPC_MFC1;
13491        goto do_cp1;
13492    case FLOAT_1BIT_FMT(MTC1, 0):
13493        mips32_op = OPC_MTC1;
13494        goto do_cp1;
13495    case FLOAT_1BIT_FMT(MFHC1, 0):
13496        mips32_op = OPC_MFHC1;
13497        goto do_cp1;
13498    case FLOAT_1BIT_FMT(MTHC1, 0):
13499        mips32_op = OPC_MTHC1;
13500    do_cp1:
13501        gen_cp1(ctx, mips32_op, rt, rs);
13502        break;
13503
13504        /* Reciprocal square root */
13505    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13506        mips32_op = OPC_RSQRT_S;
13507        goto do_unaryfp;
13508    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13509        mips32_op = OPC_RSQRT_D;
13510        goto do_unaryfp;
13511
13512        /* Square root */
13513    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13514        mips32_op = OPC_SQRT_S;
13515        goto do_unaryfp;
13516    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13517        mips32_op = OPC_SQRT_D;
13518        goto do_unaryfp;
13519
13520        /* Reciprocal */
13521    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13522        mips32_op = OPC_RECIP_S;
13523        goto do_unaryfp;
13524    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13525        mips32_op = OPC_RECIP_D;
13526        goto do_unaryfp;
13527
13528        /* Floor */
13529    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13530        mips32_op = OPC_FLOOR_L_S;
13531        goto do_unaryfp;
13532    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13533        mips32_op = OPC_FLOOR_L_D;
13534        goto do_unaryfp;
13535    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13536        mips32_op = OPC_FLOOR_W_S;
13537        goto do_unaryfp;
13538    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13539        mips32_op = OPC_FLOOR_W_D;
13540        goto do_unaryfp;
13541
13542        /* Ceiling */
13543    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13544        mips32_op = OPC_CEIL_L_S;
13545        goto do_unaryfp;
13546    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13547        mips32_op = OPC_CEIL_L_D;
13548        goto do_unaryfp;
13549    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13550        mips32_op = OPC_CEIL_W_S;
13551        goto do_unaryfp;
13552    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13553        mips32_op = OPC_CEIL_W_D;
13554        goto do_unaryfp;
13555
13556        /* Truncation */
13557    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13558        mips32_op = OPC_TRUNC_L_S;
13559        goto do_unaryfp;
13560    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13561        mips32_op = OPC_TRUNC_L_D;
13562        goto do_unaryfp;
13563    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13564        mips32_op = OPC_TRUNC_W_S;
13565        goto do_unaryfp;
13566    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13567        mips32_op = OPC_TRUNC_W_D;
13568        goto do_unaryfp;
13569
13570        /* Round */
13571    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13572        mips32_op = OPC_ROUND_L_S;
13573        goto do_unaryfp;
13574    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13575        mips32_op = OPC_ROUND_L_D;
13576        goto do_unaryfp;
13577    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13578        mips32_op = OPC_ROUND_W_S;
13579        goto do_unaryfp;
13580    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13581        mips32_op = OPC_ROUND_W_D;
13582        goto do_unaryfp;
13583
13584        /* Integer to floating-point conversion */
13585    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13586        mips32_op = OPC_CVT_L_S;
13587        goto do_unaryfp;
13588    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13589        mips32_op = OPC_CVT_L_D;
13590        goto do_unaryfp;
13591    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13592        mips32_op = OPC_CVT_W_S;
13593        goto do_unaryfp;
13594    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13595        mips32_op = OPC_CVT_W_D;
13596        goto do_unaryfp;
13597
13598        /* Paired-foo conversions */
13599    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13600        mips32_op = OPC_CVT_S_PL;
13601        goto do_unaryfp;
13602    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13603        mips32_op = OPC_CVT_S_PU;
13604        goto do_unaryfp;
13605    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13606        mips32_op = OPC_CVT_PW_PS;
13607        goto do_unaryfp;
13608    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13609        mips32_op = OPC_CVT_PS_PW;
13610        goto do_unaryfp;
13611
13612        /* Floating-point moves */
13613    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13614        mips32_op = OPC_MOV_S;
13615        goto do_unaryfp;
13616    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13617        mips32_op = OPC_MOV_D;
13618        goto do_unaryfp;
13619    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13620        mips32_op = OPC_MOV_PS;
13621        goto do_unaryfp;
13622
13623        /* Absolute value */
13624    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13625        mips32_op = OPC_ABS_S;
13626        goto do_unaryfp;
13627    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13628        mips32_op = OPC_ABS_D;
13629        goto do_unaryfp;
13630    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13631        mips32_op = OPC_ABS_PS;
13632        goto do_unaryfp;
13633
13634        /* Negation */
13635    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13636        mips32_op = OPC_NEG_S;
13637        goto do_unaryfp;
13638    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13639        mips32_op = OPC_NEG_D;
13640        goto do_unaryfp;
13641    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13642        mips32_op = OPC_NEG_PS;
13643        goto do_unaryfp;
13644
13645        /* Reciprocal square root step */
13646    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13647        mips32_op = OPC_RSQRT1_S;
13648        goto do_unaryfp;
13649    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13650        mips32_op = OPC_RSQRT1_D;
13651        goto do_unaryfp;
13652    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13653        mips32_op = OPC_RSQRT1_PS;
13654        goto do_unaryfp;
13655
13656        /* Reciprocal step */
13657    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13658        mips32_op = OPC_RECIP1_S;
13659        goto do_unaryfp;
13660    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13661        mips32_op = OPC_RECIP1_S;
13662        goto do_unaryfp;
13663    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13664        mips32_op = OPC_RECIP1_PS;
13665        goto do_unaryfp;
13666
13667        /* Conversions from double */
13668    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13669        mips32_op = OPC_CVT_D_S;
13670        goto do_unaryfp;
13671    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13672        mips32_op = OPC_CVT_D_W;
13673        goto do_unaryfp;
13674    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13675        mips32_op = OPC_CVT_D_L;
13676        goto do_unaryfp;
13677
13678        /* Conversions from single */
13679    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13680        mips32_op = OPC_CVT_S_D;
13681        goto do_unaryfp;
13682    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13683        mips32_op = OPC_CVT_S_W;
13684        goto do_unaryfp;
13685    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13686        mips32_op = OPC_CVT_S_L;
13687    do_unaryfp:
13688        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13689        break;
13690
13691        /* Conditional moves on floating-point codes */
13692    case COND_FLOAT_MOV(MOVT, 0):
13693    case COND_FLOAT_MOV(MOVT, 1):
13694    case COND_FLOAT_MOV(MOVT, 2):
13695    case COND_FLOAT_MOV(MOVT, 3):
13696    case COND_FLOAT_MOV(MOVT, 4):
13697    case COND_FLOAT_MOV(MOVT, 5):
13698    case COND_FLOAT_MOV(MOVT, 6):
13699    case COND_FLOAT_MOV(MOVT, 7):
13700        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13701        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13702        break;
13703    case COND_FLOAT_MOV(MOVF, 0):
13704    case COND_FLOAT_MOV(MOVF, 1):
13705    case COND_FLOAT_MOV(MOVF, 2):
13706    case COND_FLOAT_MOV(MOVF, 3):
13707    case COND_FLOAT_MOV(MOVF, 4):
13708    case COND_FLOAT_MOV(MOVF, 5):
13709    case COND_FLOAT_MOV(MOVF, 6):
13710    case COND_FLOAT_MOV(MOVF, 7):
13711        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13712        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13713        break;
13714    default:
13715        MIPS_INVAL("pool32fxf");
13716        generate_exception_end(ctx, EXCP_RI);
13717        break;
13718    }
13719}
13720
13721static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13722{
13723    int32_t offset;
13724    uint16_t insn;
13725    int rt, rs, rd, rr;
13726    int16_t imm;
13727    uint32_t op, minor, mips32_op;
13728    uint32_t cond, fmt, cc;
13729
13730    insn = cpu_lduw_code(env, ctx->pc + 2);
13731    ctx->opcode = (ctx->opcode << 16) | insn;
13732
13733    rt = (ctx->opcode >> 21) & 0x1f;
13734    rs = (ctx->opcode >> 16) & 0x1f;
13735    rd = (ctx->opcode >> 11) & 0x1f;
13736    rr = (ctx->opcode >> 6) & 0x1f;
13737    imm = (int16_t) ctx->opcode;
13738
13739    op = (ctx->opcode >> 26) & 0x3f;
13740    switch (op) {
13741    case POOL32A:
13742        minor = ctx->opcode & 0x3f;
13743        switch (minor) {
13744        case 0x00:
13745            minor = (ctx->opcode >> 6) & 0xf;
13746            switch (minor) {
13747            case SLL32:
13748                mips32_op = OPC_SLL;
13749                goto do_shifti;
13750            case SRA:
13751                mips32_op = OPC_SRA;
13752                goto do_shifti;
13753            case SRL32:
13754                mips32_op = OPC_SRL;
13755                goto do_shifti;
13756            case ROTR:
13757                mips32_op = OPC_ROTR;
13758            do_shifti:
13759                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13760                break;
13761            case SELEQZ:
13762                check_insn(ctx, ISA_MIPS32R6);
13763                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13764                break;
13765            case SELNEZ:
13766                check_insn(ctx, ISA_MIPS32R6);
13767                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13768                break;
13769            case R6_RDHWR:
13770                check_insn(ctx, ISA_MIPS32R6);
13771                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13772                break;
13773            default:
13774                goto pool32a_invalid;
13775            }
13776            break;
13777        case 0x10:
13778            minor = (ctx->opcode >> 6) & 0xf;
13779            switch (minor) {
13780                /* Arithmetic */
13781            case ADD:
13782                mips32_op = OPC_ADD;
13783                goto do_arith;
13784            case ADDU32:
13785                mips32_op = OPC_ADDU;
13786                goto do_arith;
13787            case SUB:
13788                mips32_op = OPC_SUB;
13789                goto do_arith;
13790            case SUBU32:
13791                mips32_op = OPC_SUBU;
13792                goto do_arith;
13793            case MUL:
13794                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13795                mips32_op = OPC_MUL;
13796            do_arith:
13797                gen_arith(ctx, mips32_op, rd, rs, rt);
13798                break;
13799                /* Shifts */
13800            case SLLV:
13801                mips32_op = OPC_SLLV;
13802                goto do_shift;
13803            case SRLV:
13804                mips32_op = OPC_SRLV;
13805                goto do_shift;
13806            case SRAV:
13807                mips32_op = OPC_SRAV;
13808                goto do_shift;
13809            case ROTRV:
13810                mips32_op = OPC_ROTRV;
13811            do_shift:
13812                gen_shift(ctx, mips32_op, rd, rs, rt);
13813                break;
13814                /* Logical operations */
13815            case AND:
13816                mips32_op = OPC_AND;
13817                goto do_logic;
13818            case OR32:
13819                mips32_op = OPC_OR;
13820                goto do_logic;
13821            case NOR:
13822                mips32_op = OPC_NOR;
13823                goto do_logic;
13824            case XOR32:
13825                mips32_op = OPC_XOR;
13826            do_logic:
13827                gen_logic(ctx, mips32_op, rd, rs, rt);
13828                break;
13829                /* Set less than */
13830            case SLT:
13831                mips32_op = OPC_SLT;
13832                goto do_slt;
13833            case SLTU:
13834                mips32_op = OPC_SLTU;
13835            do_slt:
13836                gen_slt(ctx, mips32_op, rd, rs, rt);
13837                break;
13838            default:
13839                goto pool32a_invalid;
13840            }
13841            break;
13842        case 0x18:
13843            minor = (ctx->opcode >> 6) & 0xf;
13844            switch (minor) {
13845                /* Conditional moves */
13846            case MOVN: /* MUL */
13847                if (ctx->insn_flags & ISA_MIPS32R6) {
13848                    /* MUL */
13849                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13850                } else {
13851                    /* MOVN */
13852                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13853                }
13854                break;
13855            case MOVZ: /* MUH */
13856                if (ctx->insn_flags & ISA_MIPS32R6) {
13857                    /* MUH */
13858                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13859                } else {
13860                    /* MOVZ */
13861                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13862                }
13863                break;
13864            case MULU:
13865                check_insn(ctx, ISA_MIPS32R6);
13866                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13867                break;
13868            case MUHU:
13869                check_insn(ctx, ISA_MIPS32R6);
13870                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13871                break;
13872            case LWXS: /* DIV */
13873                if (ctx->insn_flags & ISA_MIPS32R6) {
13874                    /* DIV */
13875                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13876                } else {
13877                    /* LWXS */
13878                    gen_ldxs(ctx, rs, rt, rd);
13879                }
13880                break;
13881            case MOD:
13882                check_insn(ctx, ISA_MIPS32R6);
13883                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13884                break;
13885            case R6_DIVU:
13886                check_insn(ctx, ISA_MIPS32R6);
13887                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13888                break;
13889            case MODU:
13890                check_insn(ctx, ISA_MIPS32R6);
13891                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13892                break;
13893            default:
13894                goto pool32a_invalid;
13895            }
13896            break;
13897        case INS:
13898            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13899            return;
13900        case LSA:
13901            check_insn(ctx, ISA_MIPS32R6);
13902            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13903                    extract32(ctx->opcode, 9, 2));
13904            break;
13905        case ALIGN:
13906            check_insn(ctx, ISA_MIPS32R6);
13907            gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13908                      extract32(ctx->opcode, 9, 2));
13909            break;
13910        case EXT:
13911            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13912            return;
13913        case POOL32AXF:
13914            gen_pool32axf(env, ctx, rt, rs);
13915            break;
13916        case BREAK32:
13917            generate_exception_end(ctx, EXCP_BREAK);
13918            break;
13919        case SIGRIE:
13920            check_insn(ctx, ISA_MIPS32R6);
13921            generate_exception_end(ctx, EXCP_RI);
13922            break;
13923        default:
13924        pool32a_invalid:
13925                MIPS_INVAL("pool32a");
13926                generate_exception_end(ctx, EXCP_RI);
13927                break;
13928        }
13929        break;
13930    case POOL32B:
13931        minor = (ctx->opcode >> 12) & 0xf;
13932        switch (minor) {
13933        case CACHE:
13934            check_cp0_enabled(ctx);
13935            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13936                gen_cache_operation(ctx, rt, rs, imm);
13937            }
13938            break;
13939        case LWC2:
13940        case SWC2:
13941            /* COP2: Not implemented. */
13942            generate_exception_err(ctx, EXCP_CpU, 2);
13943            break;
13944#ifdef TARGET_MIPS64
13945        case LDP:
13946        case SDP:
13947            check_insn(ctx, ISA_MIPS3);
13948            check_mips_64(ctx);
13949            /* Fallthrough */
13950#endif
13951        case LWP:
13952        case SWP:
13953            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13954            break;
13955#ifdef TARGET_MIPS64
13956        case LDM:
13957        case SDM:
13958            check_insn(ctx, ISA_MIPS3);
13959            check_mips_64(ctx);
13960            /* Fallthrough */
13961#endif
13962        case LWM32:
13963        case SWM32:
13964            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13965            break;
13966        default:
13967            MIPS_INVAL("pool32b");
13968            generate_exception_end(ctx, EXCP_RI);
13969            break;
13970        }
13971        break;
13972    case POOL32F:
13973        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13974            minor = ctx->opcode & 0x3f;
13975            check_cp1_enabled(ctx);
13976            switch (minor) {
13977            case ALNV_PS:
13978                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13979                mips32_op = OPC_ALNV_PS;
13980                goto do_madd;
13981            case MADD_S:
13982                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13983                mips32_op = OPC_MADD_S;
13984                goto do_madd;
13985            case MADD_D:
13986                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13987                mips32_op = OPC_MADD_D;
13988                goto do_madd;
13989            case MADD_PS:
13990                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13991                mips32_op = OPC_MADD_PS;
13992                goto do_madd;
13993            case MSUB_S:
13994                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13995                mips32_op = OPC_MSUB_S;
13996                goto do_madd;
13997            case MSUB_D:
13998                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13999                mips32_op = OPC_MSUB_D;
14000                goto do_madd;
14001            case MSUB_PS:
14002                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14003                mips32_op = OPC_MSUB_PS;
14004                goto do_madd;
14005            case NMADD_S:
14006                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14007                mips32_op = OPC_NMADD_S;
14008                goto do_madd;
14009            case NMADD_D:
14010                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14011                mips32_op = OPC_NMADD_D;
14012                goto do_madd;
14013            case NMADD_PS:
14014                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14015                mips32_op = OPC_NMADD_PS;
14016                goto do_madd;
14017            case NMSUB_S:
14018                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14019                mips32_op = OPC_NMSUB_S;
14020                goto do_madd;
14021            case NMSUB_D:
14022                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14023                mips32_op = OPC_NMSUB_D;
14024                goto do_madd;
14025            case NMSUB_PS:
14026                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14027                mips32_op = OPC_NMSUB_PS;
14028            do_madd:
14029                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14030                break;
14031            case CABS_COND_FMT:
14032                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14033                cond = (ctx->opcode >> 6) & 0xf;
14034                cc = (ctx->opcode >> 13) & 0x7;
14035                fmt = (ctx->opcode >> 10) & 0x3;
14036                switch (fmt) {
14037                case 0x0:
14038                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
14039                    break;
14040                case 0x1:
14041                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
14042                    break;
14043                case 0x2:
14044                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14045                    break;
14046                default:
14047                    goto pool32f_invalid;
14048                }
14049                break;
14050            case C_COND_FMT:
14051                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14052                cond = (ctx->opcode >> 6) & 0xf;
14053                cc = (ctx->opcode >> 13) & 0x7;
14054                fmt = (ctx->opcode >> 10) & 0x3;
14055                switch (fmt) {
14056                case 0x0:
14057                    gen_cmp_s(ctx, cond, rt, rs, cc);
14058                    break;
14059                case 0x1:
14060                    gen_cmp_d(ctx, cond, rt, rs, cc);
14061                    break;
14062                case 0x2:
14063                    gen_cmp_ps(ctx, cond, rt, rs, cc);
14064                    break;
14065                default:
14066                    goto pool32f_invalid;
14067                }
14068                break;
14069            case CMP_CONDN_S:
14070                check_insn(ctx, ISA_MIPS32R6);
14071                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14072                break;
14073            case CMP_CONDN_D:
14074                check_insn(ctx, ISA_MIPS32R6);
14075                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14076                break;
14077            case POOL32FXF:
14078                gen_pool32fxf(ctx, rt, rs);
14079                break;
14080            case 0x00:
14081                /* PLL foo */
14082                switch ((ctx->opcode >> 6) & 0x7) {
14083                case PLL_PS:
14084                    mips32_op = OPC_PLL_PS;
14085                    goto do_ps;
14086                case PLU_PS:
14087                    mips32_op = OPC_PLU_PS;
14088                    goto do_ps;
14089                case PUL_PS:
14090                    mips32_op = OPC_PUL_PS;
14091                    goto do_ps;
14092                case PUU_PS:
14093                    mips32_op = OPC_PUU_PS;
14094                    goto do_ps;
14095                case CVT_PS_S:
14096                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14097                    mips32_op = OPC_CVT_PS_S;
14098                do_ps:
14099                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14100                    break;
14101                default:
14102                    goto pool32f_invalid;
14103                }
14104                break;
14105            case MIN_FMT:
14106                check_insn(ctx, ISA_MIPS32R6);
14107                switch ((ctx->opcode >> 9) & 0x3) {
14108                case FMT_SDPS_S:
14109                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14110                    break;
14111                case FMT_SDPS_D:
14112                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14113                    break;
14114                default:
14115                    goto pool32f_invalid;
14116                }
14117                break;
14118            case 0x08:
14119                /* [LS][WDU]XC1 */
14120                switch ((ctx->opcode >> 6) & 0x7) {
14121                case LWXC1:
14122                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14123                    mips32_op = OPC_LWXC1;
14124                    goto do_ldst_cp1;
14125                case SWXC1:
14126                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14127                    mips32_op = OPC_SWXC1;
14128                    goto do_ldst_cp1;
14129                case LDXC1:
14130                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14131                    mips32_op = OPC_LDXC1;
14132                    goto do_ldst_cp1;
14133                case SDXC1:
14134                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14135                    mips32_op = OPC_SDXC1;
14136                    goto do_ldst_cp1;
14137                case LUXC1:
14138                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14139                    mips32_op = OPC_LUXC1;
14140                    goto do_ldst_cp1;
14141                case SUXC1:
14142                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14143                    mips32_op = OPC_SUXC1;
14144                do_ldst_cp1:
14145                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14146                    break;
14147                default:
14148                    goto pool32f_invalid;
14149                }
14150                break;
14151            case MAX_FMT:
14152                check_insn(ctx, ISA_MIPS32R6);
14153                switch ((ctx->opcode >> 9) & 0x3) {
14154                case FMT_SDPS_S:
14155                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14156                    break;
14157                case FMT_SDPS_D:
14158                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14159                    break;
14160                default:
14161                    goto pool32f_invalid;
14162                }
14163                break;
14164            case 0x18:
14165                /* 3D insns */
14166                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14167                fmt = (ctx->opcode >> 9) & 0x3;
14168                switch ((ctx->opcode >> 6) & 0x7) {
14169                case RSQRT2_FMT:
14170                    switch (fmt) {
14171                    case FMT_SDPS_S:
14172                        mips32_op = OPC_RSQRT2_S;
14173                        goto do_3d;
14174                    case FMT_SDPS_D:
14175                        mips32_op = OPC_RSQRT2_D;
14176                        goto do_3d;
14177                    case FMT_SDPS_PS:
14178                        mips32_op = OPC_RSQRT2_PS;
14179                        goto do_3d;
14180                    default:
14181                        goto pool32f_invalid;
14182                    }
14183                    break;
14184                case RECIP2_FMT:
14185                    switch (fmt) {
14186                    case FMT_SDPS_S:
14187                        mips32_op = OPC_RECIP2_S;
14188                        goto do_3d;
14189                    case FMT_SDPS_D:
14190                        mips32_op = OPC_RECIP2_D;
14191                        goto do_3d;
14192                    case FMT_SDPS_PS:
14193                        mips32_op = OPC_RECIP2_PS;
14194                        goto do_3d;
14195                    default:
14196                        goto pool32f_invalid;
14197                    }
14198                    break;
14199                case ADDR_PS:
14200                    mips32_op = OPC_ADDR_PS;
14201                    goto do_3d;
14202                case MULR_PS:
14203                    mips32_op = OPC_MULR_PS;
14204                do_3d:
14205                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14206                    break;
14207                default:
14208                    goto pool32f_invalid;
14209                }
14210                break;
14211            case 0x20:
14212                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14213                cc = (ctx->opcode >> 13) & 0x7;
14214                fmt = (ctx->opcode >> 9) & 0x3;
14215                switch ((ctx->opcode >> 6) & 0x7) {
14216                case MOVF_FMT: /* RINT_FMT */
14217                    if (ctx->insn_flags & ISA_MIPS32R6) {
14218                        /* RINT_FMT */
14219                        switch (fmt) {
14220                        case FMT_SDPS_S:
14221                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14222                            break;
14223                        case FMT_SDPS_D:
14224                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14225                            break;
14226                        default:
14227                            goto pool32f_invalid;
14228                        }
14229                    } else {
14230                        /* MOVF_FMT */
14231                        switch (fmt) {
14232                        case FMT_SDPS_S:
14233                            gen_movcf_s(ctx, rs, rt, cc, 0);
14234                            break;
14235                        case FMT_SDPS_D:
14236                            gen_movcf_d(ctx, rs, rt, cc, 0);
14237                            break;
14238                        case FMT_SDPS_PS:
14239                            check_ps(ctx);
14240                            gen_movcf_ps(ctx, rs, rt, cc, 0);
14241                            break;
14242                        default:
14243                            goto pool32f_invalid;
14244                        }
14245                    }
14246                    break;
14247                case MOVT_FMT: /* CLASS_FMT */
14248                    if (ctx->insn_flags & ISA_MIPS32R6) {
14249                        /* CLASS_FMT */
14250                        switch (fmt) {
14251                        case FMT_SDPS_S:
14252                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14253                            break;
14254                        case FMT_SDPS_D:
14255                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14256                            break;
14257                        default:
14258                            goto pool32f_invalid;
14259                        }
14260                    } else {
14261                        /* MOVT_FMT */
14262                        switch (fmt) {
14263                        case FMT_SDPS_S:
14264                            gen_movcf_s(ctx, rs, rt, cc, 1);
14265                            break;
14266                        case FMT_SDPS_D:
14267                            gen_movcf_d(ctx, rs, rt, cc, 1);
14268                            break;
14269                        case FMT_SDPS_PS:
14270                            check_ps(ctx);
14271                            gen_movcf_ps(ctx, rs, rt, cc, 1);
14272                            break;
14273                        default:
14274                            goto pool32f_invalid;
14275                        }
14276                    }
14277                    break;
14278                case PREFX:
14279                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14280                    break;
14281                default:
14282                    goto pool32f_invalid;
14283                }
14284                break;
14285#define FINSN_3ARG_SDPS(prfx)                           \
14286                switch ((ctx->opcode >> 8) & 0x3) {     \
14287                case FMT_SDPS_S:                        \
14288                    mips32_op = OPC_##prfx##_S;         \
14289                    goto do_fpop;                       \
14290                case FMT_SDPS_D:                        \
14291                    mips32_op = OPC_##prfx##_D;         \
14292                    goto do_fpop;                       \
14293                case FMT_SDPS_PS:                       \
14294                    check_ps(ctx);                      \
14295                    mips32_op = OPC_##prfx##_PS;        \
14296                    goto do_fpop;                       \
14297                default:                                \
14298                    goto pool32f_invalid;               \
14299                }
14300            case MINA_FMT:
14301                check_insn(ctx, ISA_MIPS32R6);
14302                switch ((ctx->opcode >> 9) & 0x3) {
14303                case FMT_SDPS_S:
14304                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14305                    break;
14306                case FMT_SDPS_D:
14307                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14308                    break;
14309                default:
14310                    goto pool32f_invalid;
14311                }
14312                break;
14313            case MAXA_FMT:
14314                check_insn(ctx, ISA_MIPS32R6);
14315                switch ((ctx->opcode >> 9) & 0x3) {
14316                case FMT_SDPS_S:
14317                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14318                    break;
14319                case FMT_SDPS_D:
14320                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14321                    break;
14322                default:
14323                    goto pool32f_invalid;
14324                }
14325                break;
14326            case 0x30:
14327                /* regular FP ops */
14328                switch ((ctx->opcode >> 6) & 0x3) {
14329                case ADD_FMT:
14330                    FINSN_3ARG_SDPS(ADD);
14331                    break;
14332                case SUB_FMT:
14333                    FINSN_3ARG_SDPS(SUB);
14334                    break;
14335                case MUL_FMT:
14336                    FINSN_3ARG_SDPS(MUL);
14337                    break;
14338                case DIV_FMT:
14339                    fmt = (ctx->opcode >> 8) & 0x3;
14340                    if (fmt == 1) {
14341                        mips32_op = OPC_DIV_D;
14342                    } else if (fmt == 0) {
14343                        mips32_op = OPC_DIV_S;
14344                    } else {
14345                        goto pool32f_invalid;
14346                    }
14347                    goto do_fpop;
14348                default:
14349                    goto pool32f_invalid;
14350                }
14351                break;
14352            case 0x38:
14353                /* cmovs */
14354                switch ((ctx->opcode >> 6) & 0x7) {
14355                case MOVN_FMT: /* SELNEZ_FMT */
14356                    if (ctx->insn_flags & ISA_MIPS32R6) {
14357                        /* SELNEZ_FMT */
14358                        switch ((ctx->opcode >> 9) & 0x3) {
14359                        case FMT_SDPS_S:
14360                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14361                            break;
14362                        case FMT_SDPS_D:
14363                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14364                            break;
14365                        default:
14366                            goto pool32f_invalid;
14367                        }
14368                    } else {
14369                        /* MOVN_FMT */
14370                        FINSN_3ARG_SDPS(MOVN);
14371                    }
14372                    break;
14373                case MOVN_FMT_04:
14374                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14375                    FINSN_3ARG_SDPS(MOVN);
14376                    break;
14377                case MOVZ_FMT: /* SELEQZ_FMT */
14378                    if (ctx->insn_flags & ISA_MIPS32R6) {
14379                        /* SELEQZ_FMT */
14380                        switch ((ctx->opcode >> 9) & 0x3) {
14381                        case FMT_SDPS_S:
14382                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14383                            break;
14384                        case FMT_SDPS_D:
14385                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14386                            break;
14387                        default:
14388                            goto pool32f_invalid;
14389                        }
14390                    } else {
14391                        /* MOVZ_FMT */
14392                        FINSN_3ARG_SDPS(MOVZ);
14393                    }
14394                    break;
14395                case MOVZ_FMT_05:
14396                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14397                    FINSN_3ARG_SDPS(MOVZ);
14398                    break;
14399                case SEL_FMT:
14400                    check_insn(ctx, ISA_MIPS32R6);
14401                    switch ((ctx->opcode >> 9) & 0x3) {
14402                    case FMT_SDPS_S:
14403                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14404                        break;
14405                    case FMT_SDPS_D:
14406                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14407                        break;
14408                    default:
14409                        goto pool32f_invalid;
14410                    }
14411                    break;
14412                case MADDF_FMT:
14413                    check_insn(ctx, ISA_MIPS32R6);
14414                    switch ((ctx->opcode >> 9) & 0x3) {
14415                    case FMT_SDPS_S:
14416                        mips32_op = OPC_MADDF_S;
14417                        goto do_fpop;
14418                    case FMT_SDPS_D:
14419                        mips32_op = OPC_MADDF_D;
14420                        goto do_fpop;
14421                    default:
14422                        goto pool32f_invalid;
14423                    }
14424                    break;
14425                case MSUBF_FMT:
14426                    check_insn(ctx, ISA_MIPS32R6);
14427                    switch ((ctx->opcode >> 9) & 0x3) {
14428                    case FMT_SDPS_S:
14429                        mips32_op = OPC_MSUBF_S;
14430                        goto do_fpop;
14431                    case FMT_SDPS_D:
14432                        mips32_op = OPC_MSUBF_D;
14433                        goto do_fpop;
14434                    default:
14435                        goto pool32f_invalid;
14436                    }
14437                    break;
14438                default:
14439                    goto pool32f_invalid;
14440                }
14441                break;
14442            do_fpop:
14443                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14444                break;
14445            default:
14446            pool32f_invalid:
14447                MIPS_INVAL("pool32f");
14448                generate_exception_end(ctx, EXCP_RI);
14449                break;
14450            }
14451        } else {
14452            generate_exception_err(ctx, EXCP_CpU, 1);
14453        }
14454        break;
14455    case POOL32I:
14456        minor = (ctx->opcode >> 21) & 0x1f;
14457        switch (minor) {
14458        case BLTZ:
14459            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14460            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14461            break;
14462        case BLTZAL:
14463            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14464            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14465            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14466            break;
14467        case BLTZALS:
14468            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14469            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14470            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14471            break;
14472        case BGEZ:
14473            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14474            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14475            break;
14476        case BGEZAL:
14477            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14478            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14479            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14480            break;
14481        case BGEZALS:
14482            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14483            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14484            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14485            break;
14486        case BLEZ:
14487            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14488            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14489            break;
14490        case BGTZ:
14491            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14492            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14493            break;
14494
14495            /* Traps */
14496        case TLTI: /* BC1EQZC */
14497            if (ctx->insn_flags & ISA_MIPS32R6) {
14498                /* BC1EQZC */
14499                check_cp1_enabled(ctx);
14500                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14501            } else {
14502                /* TLTI */
14503                mips32_op = OPC_TLTI;
14504                goto do_trapi;
14505            }
14506            break;
14507        case TGEI: /* BC1NEZC */
14508            if (ctx->insn_flags & ISA_MIPS32R6) {
14509                /* BC1NEZC */
14510                check_cp1_enabled(ctx);
14511                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14512            } else {
14513                /* TGEI */
14514                mips32_op = OPC_TGEI;
14515                goto do_trapi;
14516            }
14517            break;
14518        case TLTIU:
14519            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14520            mips32_op = OPC_TLTIU;
14521            goto do_trapi;
14522        case TGEIU:
14523            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14524            mips32_op = OPC_TGEIU;
14525            goto do_trapi;
14526        case TNEI: /* SYNCI */
14527            if (ctx->insn_flags & ISA_MIPS32R6) {
14528                /* SYNCI */
14529                /* Break the TB to be able to sync copied instructions
14530                   immediately */
14531                ctx->bstate = BS_STOP;
14532            } else {
14533                /* TNEI */
14534                mips32_op = OPC_TNEI;
14535                goto do_trapi;
14536            }
14537            break;
14538        case TEQI:
14539            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14540            mips32_op = OPC_TEQI;
14541        do_trapi:
14542            gen_trap(ctx, mips32_op, rs, -1, imm);
14543            break;
14544
14545        case BNEZC:
14546        case BEQZC:
14547            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14548            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14549                               4, rs, 0, imm << 1, 0);
14550            /* Compact branches don't have a delay slot, so just let
14551               the normal delay slot handling take us to the branch
14552               target. */
14553            break;
14554        case LUI:
14555            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14556            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14557            break;
14558        case SYNCI:
14559            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14560            /* Break the TB to be able to sync copied instructions
14561               immediately */
14562            ctx->bstate = BS_STOP;
14563            break;
14564        case BC2F:
14565        case BC2T:
14566            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14567            /* COP2: Not implemented. */
14568            generate_exception_err(ctx, EXCP_CpU, 2);
14569            break;
14570        case BC1F:
14571            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14572            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14573            goto do_cp1branch;
14574        case BC1T:
14575            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14576            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14577            goto do_cp1branch;
14578        case BC1ANY4F:
14579            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14580            mips32_op = OPC_BC1FANY4;
14581            goto do_cp1mips3d;
14582        case BC1ANY4T:
14583            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14584            mips32_op = OPC_BC1TANY4;
14585        do_cp1mips3d:
14586            check_cop1x(ctx);
14587            check_insn(ctx, ASE_MIPS3D);
14588            /* Fall through */
14589        do_cp1branch:
14590            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14591                check_cp1_enabled(ctx);
14592                gen_compute_branch1(ctx, mips32_op,
14593                                    (ctx->opcode >> 18) & 0x7, imm << 1);
14594            } else {
14595                generate_exception_err(ctx, EXCP_CpU, 1);
14596            }
14597            break;
14598        case BPOSGE64:
14599        case BPOSGE32:
14600            /* MIPS DSP: not implemented */
14601            /* Fall through */
14602        default:
14603            MIPS_INVAL("pool32i");
14604            generate_exception_end(ctx, EXCP_RI);
14605            break;
14606        }
14607        break;
14608    case POOL32C:
14609        minor = (ctx->opcode >> 12) & 0xf;
14610        offset = sextract32(ctx->opcode, 0,
14611                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14612        switch (minor) {
14613        case LWL:
14614            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14615            mips32_op = OPC_LWL;
14616            goto do_ld_lr;
14617        case SWL:
14618            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14619            mips32_op = OPC_SWL;
14620            goto do_st_lr;
14621        case LWR:
14622            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14623            mips32_op = OPC_LWR;
14624            goto do_ld_lr;
14625        case SWR:
14626            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14627            mips32_op = OPC_SWR;
14628            goto do_st_lr;
14629#if defined(TARGET_MIPS64)
14630        case LDL:
14631            check_insn(ctx, ISA_MIPS3);
14632            check_mips_64(ctx);
14633            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14634            mips32_op = OPC_LDL;
14635            goto do_ld_lr;
14636        case SDL:
14637            check_insn(ctx, ISA_MIPS3);
14638            check_mips_64(ctx);
14639            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14640            mips32_op = OPC_SDL;
14641            goto do_st_lr;
14642        case LDR:
14643            check_insn(ctx, ISA_MIPS3);
14644            check_mips_64(ctx);
14645            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14646            mips32_op = OPC_LDR;
14647            goto do_ld_lr;
14648        case SDR:
14649            check_insn(ctx, ISA_MIPS3);
14650            check_mips_64(ctx);
14651            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14652            mips32_op = OPC_SDR;
14653            goto do_st_lr;
14654        case LWU:
14655            check_insn(ctx, ISA_MIPS3);
14656            check_mips_64(ctx);
14657            mips32_op = OPC_LWU;
14658            goto do_ld_lr;
14659        case LLD:
14660            check_insn(ctx, ISA_MIPS3);
14661            check_mips_64(ctx);
14662            mips32_op = OPC_LLD;
14663            goto do_ld_lr;
14664#endif
14665        case LL:
14666            mips32_op = OPC_LL;
14667            goto do_ld_lr;
14668        do_ld_lr:
14669            gen_ld(ctx, mips32_op, rt, rs, offset);
14670            break;
14671        do_st_lr:
14672            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14673            break;
14674        case SC:
14675            gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14676            break;
14677#if defined(TARGET_MIPS64)
14678        case SCD:
14679            check_insn(ctx, ISA_MIPS3);
14680            check_mips_64(ctx);
14681            gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14682            break;
14683#endif
14684        case PREF:
14685            /* Treat as no-op */
14686            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14687                /* hint codes 24-31 are reserved and signal RI */
14688                generate_exception(ctx, EXCP_RI);
14689            }
14690            break;
14691        default:
14692            MIPS_INVAL("pool32c");
14693            generate_exception_end(ctx, EXCP_RI);
14694            break;
14695        }
14696        break;
14697    case ADDI32: /* AUI, LUI */
14698        if (ctx->insn_flags & ISA_MIPS32R6) {
14699            /* AUI, LUI */
14700            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14701        } else {
14702            /* ADDI32 */
14703            mips32_op = OPC_ADDI;
14704            goto do_addi;
14705        }
14706        break;
14707    case ADDIU32:
14708        mips32_op = OPC_ADDIU;
14709    do_addi:
14710        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14711        break;
14712
14713        /* Logical operations */
14714    case ORI32:
14715        mips32_op = OPC_ORI;
14716        goto do_logici;
14717    case XORI32:
14718        mips32_op = OPC_XORI;
14719        goto do_logici;
14720    case ANDI32:
14721        mips32_op = OPC_ANDI;
14722    do_logici:
14723        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14724        break;
14725
14726        /* Set less than immediate */
14727    case SLTI32:
14728        mips32_op = OPC_SLTI;
14729        goto do_slti;
14730    case SLTIU32:
14731        mips32_op = OPC_SLTIU;
14732    do_slti:
14733        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14734        break;
14735    case JALX32:
14736        check_insn_opc_removed(ctx, ISA_MIPS32R6);
14737        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14738        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14739        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14740        break;
14741    case JALS32: /* BOVC, BEQC, BEQZALC */
14742        if (ctx->insn_flags & ISA_MIPS32R6) {
14743            if (rs >= rt) {
14744                /* BOVC */
14745                mips32_op = OPC_BOVC;
14746            } else if (rs < rt && rs == 0) {
14747                /* BEQZALC */
14748                mips32_op = OPC_BEQZALC;
14749            } else {
14750                /* BEQC */
14751                mips32_op = OPC_BEQC;
14752            }
14753            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14754        } else {
14755            /* JALS32 */
14756            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14757            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14758            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14759        }
14760        break;
14761    case BEQ32: /* BC */
14762        if (ctx->insn_flags & ISA_MIPS32R6) {
14763            /* BC */
14764            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14765                                       sextract32(ctx->opcode << 1, 0, 27));
14766        } else {
14767            /* BEQ32 */
14768            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14769        }
14770        break;
14771    case BNE32: /* BALC */
14772        if (ctx->insn_flags & ISA_MIPS32R6) {
14773            /* BALC */
14774            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14775                                       sextract32(ctx->opcode << 1, 0, 27));
14776        } else {
14777            /* BNE32 */
14778            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14779        }
14780        break;
14781    case J32: /* BGTZC, BLTZC, BLTC */
14782        if (ctx->insn_flags & ISA_MIPS32R6) {
14783            if (rs == 0 && rt != 0) {
14784                /* BGTZC */
14785                mips32_op = OPC_BGTZC;
14786            } else if (rs != 0 && rt != 0 && rs == rt) {
14787                /* BLTZC */
14788                mips32_op = OPC_BLTZC;
14789            } else {
14790                /* BLTC */
14791                mips32_op = OPC_BLTC;
14792            }
14793            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14794        } else {
14795            /* J32 */
14796            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14797                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14798        }
14799        break;
14800    case JAL32: /* BLEZC, BGEZC, BGEC */
14801        if (ctx->insn_flags & ISA_MIPS32R6) {
14802            if (rs == 0 && rt != 0) {
14803                /* BLEZC */
14804                mips32_op = OPC_BLEZC;
14805            } else if (rs != 0 && rt != 0 && rs == rt) {
14806                /* BGEZC */
14807                mips32_op = OPC_BGEZC;
14808            } else {
14809                /* BGEC */
14810                mips32_op = OPC_BGEC;
14811            }
14812            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14813        } else {
14814            /* JAL32 */
14815            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14816                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14817            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14818        }
14819        break;
14820        /* Floating point (COP1) */
14821    case LWC132:
14822        mips32_op = OPC_LWC1;
14823        goto do_cop1;
14824    case LDC132:
14825        mips32_op = OPC_LDC1;
14826        goto do_cop1;
14827    case SWC132:
14828        mips32_op = OPC_SWC1;
14829        goto do_cop1;
14830    case SDC132:
14831        mips32_op = OPC_SDC1;
14832    do_cop1:
14833        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14834        break;
14835    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14836        if (ctx->insn_flags & ISA_MIPS32R6) {
14837            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14838            switch ((ctx->opcode >> 16) & 0x1f) {
14839            case ADDIUPC_00 ... ADDIUPC_07:
14840                gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14841                break;
14842            case AUIPC:
14843                gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14844                break;
14845            case ALUIPC:
14846                gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14847                break;
14848            case LWPC_08 ... LWPC_0F:
14849                gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14850                break;
14851            default:
14852                generate_exception(ctx, EXCP_RI);
14853                break;
14854            }
14855        } else {
14856            /* ADDIUPC */
14857            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14858            int offset = SIMM(ctx->opcode, 0, 23) << 2;
14859
14860            gen_addiupc(ctx, reg, offset, 0, 0);
14861        }
14862        break;
14863    case BNVC: /* BNEC, BNEZALC */
14864        check_insn(ctx, ISA_MIPS32R6);
14865        if (rs >= rt) {
14866            /* BNVC */
14867            mips32_op = OPC_BNVC;
14868        } else if (rs < rt && rs == 0) {
14869            /* BNEZALC */
14870            mips32_op = OPC_BNEZALC;
14871        } else {
14872            /* BNEC */
14873            mips32_op = OPC_BNEC;
14874        }
14875        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14876        break;
14877    case R6_BNEZC: /* JIALC */
14878        check_insn(ctx, ISA_MIPS32R6);
14879        if (rt != 0) {
14880            /* BNEZC */
14881            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14882                                       sextract32(ctx->opcode << 1, 0, 22));
14883        } else {
14884            /* JIALC */
14885            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14886        }
14887        break;
14888    case R6_BEQZC: /* JIC */
14889        check_insn(ctx, ISA_MIPS32R6);
14890        if (rt != 0) {
14891            /* BEQZC */
14892            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14893                                       sextract32(ctx->opcode << 1, 0, 22));
14894        } else {
14895            /* JIC */
14896            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14897        }
14898        break;
14899    case BLEZALC: /* BGEZALC, BGEUC */
14900        check_insn(ctx, ISA_MIPS32R6);
14901        if (rs == 0 && rt != 0) {
14902            /* BLEZALC */
14903            mips32_op = OPC_BLEZALC;
14904        } else if (rs != 0 && rt != 0 && rs == rt) {
14905            /* BGEZALC */
14906            mips32_op = OPC_BGEZALC;
14907        } else {
14908            /* BGEUC */
14909            mips32_op = OPC_BGEUC;
14910        }
14911        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14912        break;
14913    case BGTZALC: /* BLTZALC, BLTUC */
14914        check_insn(ctx, ISA_MIPS32R6);
14915        if (rs == 0 && rt != 0) {
14916            /* BGTZALC */
14917            mips32_op = OPC_BGTZALC;
14918        } else if (rs != 0 && rt != 0 && rs == rt) {
14919            /* BLTZALC */
14920            mips32_op = OPC_BLTZALC;
14921        } else {
14922            /* BLTUC */
14923            mips32_op = OPC_BLTUC;
14924        }
14925        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14926        break;
14927        /* Loads and stores */
14928    case LB32:
14929        mips32_op = OPC_LB;
14930        goto do_ld;
14931    case LBU32:
14932        mips32_op = OPC_LBU;
14933        goto do_ld;
14934    case LH32:
14935        mips32_op = OPC_LH;
14936        goto do_ld;
14937    case LHU32:
14938        mips32_op = OPC_LHU;
14939        goto do_ld;
14940    case LW32:
14941        mips32_op = OPC_LW;
14942        goto do_ld;
14943#ifdef TARGET_MIPS64
14944    case LD32:
14945        check_insn(ctx, ISA_MIPS3);
14946        check_mips_64(ctx);
14947        mips32_op = OPC_LD;
14948        goto do_ld;
14949    case SD32:
14950        check_insn(ctx, ISA_MIPS3);
14951        check_mips_64(ctx);
14952        mips32_op = OPC_SD;
14953        goto do_st;
14954#endif
14955    case SB32:
14956        mips32_op = OPC_SB;
14957        goto do_st;
14958    case SH32:
14959        mips32_op = OPC_SH;
14960        goto do_st;
14961    case SW32:
14962        mips32_op = OPC_SW;
14963        goto do_st;
14964    do_ld:
14965        gen_ld(ctx, mips32_op, rt, rs, imm);
14966        break;
14967    do_st:
14968        gen_st(ctx, mips32_op, rt, rs, imm);
14969        break;
14970    default:
14971        generate_exception_end(ctx, EXCP_RI);
14972        break;
14973    }
14974}
14975
14976static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
14977{
14978    uint32_t op;
14979
14980    /* make sure instructions are on a halfword boundary */
14981    if (ctx->pc & 0x1) {
14982        env->CP0_BadVAddr = ctx->pc;
14983        generate_exception_end(ctx, EXCP_AdEL);
14984        return 2;
14985    }
14986
14987    op = (ctx->opcode >> 10) & 0x3f;
14988    /* Enforce properly-sized instructions in a delay slot */
14989    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14990        switch (op & 0x7) { /* MSB-3..MSB-5 */
14991        case 0:
14992        /* POOL32A, POOL32B, POOL32I, POOL32C */
14993        case 4:
14994        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14995        case 5:
14996        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14997        case 6:
14998        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14999        case 7:
15000        /* LB32, LH32, LWC132, LDC132, LW32 */
15001            if (ctx->hflags & MIPS_HFLAG_BDS16) {
15002                generate_exception_end(ctx, EXCP_RI);
15003                return 2;
15004            }
15005            break;
15006        case 1:
15007        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15008        case 2:
15009        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15010        case 3:
15011        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15012            if (ctx->hflags & MIPS_HFLAG_BDS32) {
15013                generate_exception_end(ctx, EXCP_RI);
15014                return 2;
15015            }
15016            break;
15017        }
15018    }
15019
15020    switch (op) {
15021    case POOL16A:
15022        {
15023            int rd = mmreg(uMIPS_RD(ctx->opcode));
15024            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15025            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15026            uint32_t opc = 0;
15027
15028            switch (ctx->opcode & 0x1) {
15029            case ADDU16:
15030                opc = OPC_ADDU;
15031                break;
15032            case SUBU16:
15033                opc = OPC_SUBU;
15034                break;
15035            }
15036            if (ctx->insn_flags & ISA_MIPS32R6) {
15037                /* In the Release 6 the register number location in
15038                 * the instruction encoding has changed.
15039                 */
15040                gen_arith(ctx, opc, rs1, rd, rs2);
15041            } else {
15042                gen_arith(ctx, opc, rd, rs1, rs2);
15043            }
15044        }
15045        break;
15046    case POOL16B:
15047        {
15048            int rd = mmreg(uMIPS_RD(ctx->opcode));
15049            int rs = mmreg(uMIPS_RS(ctx->opcode));
15050            int amount = (ctx->opcode >> 1) & 0x7;
15051            uint32_t opc = 0;
15052            amount = amount == 0 ? 8 : amount;
15053
15054            switch (ctx->opcode & 0x1) {
15055            case SLL16:
15056                opc = OPC_SLL;
15057                break;
15058            case SRL16:
15059                opc = OPC_SRL;
15060                break;
15061            }
15062
15063            gen_shift_imm(ctx, opc, rd, rs, amount);
15064        }
15065        break;
15066    case POOL16C:
15067        if (ctx->insn_flags & ISA_MIPS32R6) {
15068            gen_pool16c_r6_insn(ctx);
15069        } else {
15070            gen_pool16c_insn(ctx);
15071        }
15072        break;
15073    case LWGP16:
15074        {
15075            int rd = mmreg(uMIPS_RD(ctx->opcode));
15076            int rb = 28;            /* GP */
15077            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15078
15079            gen_ld(ctx, OPC_LW, rd, rb, offset);
15080        }
15081        break;
15082    case POOL16F:
15083        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15084        if (ctx->opcode & 1) {
15085            generate_exception_end(ctx, EXCP_RI);
15086        } else {
15087            /* MOVEP */
15088            int enc_dest = uMIPS_RD(ctx->opcode);
15089            int enc_rt = uMIPS_RS2(ctx->opcode);
15090            int enc_rs = uMIPS_RS1(ctx->opcode);
15091            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15092        }
15093        break;
15094    case LBU16:
15095        {
15096            int rd = mmreg(uMIPS_RD(ctx->opcode));
15097            int rb = mmreg(uMIPS_RS(ctx->opcode));
15098            int16_t offset = ZIMM(ctx->opcode, 0, 4);
15099            offset = (offset == 0xf ? -1 : offset);
15100
15101            gen_ld(ctx, OPC_LBU, rd, rb, offset);
15102        }
15103        break;
15104    case LHU16:
15105        {
15106            int rd = mmreg(uMIPS_RD(ctx->opcode));
15107            int rb = mmreg(uMIPS_RS(ctx->opcode));
15108            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15109
15110            gen_ld(ctx, OPC_LHU, rd, rb, offset);
15111        }
15112        break;
15113    case LWSP16:
15114        {
15115            int rd = (ctx->opcode >> 5) & 0x1f;
15116            int rb = 29;            /* SP */
15117            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15118
15119            gen_ld(ctx, OPC_LW, rd, rb, offset);
15120        }
15121        break;
15122    case LW16:
15123        {
15124            int rd = mmreg(uMIPS_RD(ctx->opcode));
15125            int rb = mmreg(uMIPS_RS(ctx->opcode));
15126            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15127
15128            gen_ld(ctx, OPC_LW, rd, rb, offset);
15129        }
15130        break;
15131    case SB16:
15132        {
15133            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15134            int rb = mmreg(uMIPS_RS(ctx->opcode));
15135            int16_t offset = ZIMM(ctx->opcode, 0, 4);
15136
15137            gen_st(ctx, OPC_SB, rd, rb, offset);
15138        }
15139        break;
15140    case SH16:
15141        {
15142            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15143            int rb = mmreg(uMIPS_RS(ctx->opcode));
15144            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15145
15146            gen_st(ctx, OPC_SH, rd, rb, offset);
15147        }
15148        break;
15149    case SWSP16:
15150        {
15151            int rd = (ctx->opcode >> 5) & 0x1f;
15152            int rb = 29;            /* SP */
15153            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15154
15155            gen_st(ctx, OPC_SW, rd, rb, offset);
15156        }
15157        break;
15158    case SW16:
15159        {
15160            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15161            int rb = mmreg(uMIPS_RS(ctx->opcode));
15162            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15163
15164            gen_st(ctx, OPC_SW, rd, rb, offset);
15165        }
15166        break;
15167    case MOVE16:
15168        {
15169            int rd = uMIPS_RD5(ctx->opcode);
15170            int rs = uMIPS_RS5(ctx->opcode);
15171
15172            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15173        }
15174        break;
15175    case ANDI16:
15176        gen_andi16(ctx);
15177        break;
15178    case POOL16D:
15179        switch (ctx->opcode & 0x1) {
15180        case ADDIUS5:
15181            gen_addius5(ctx);
15182            break;
15183        case ADDIUSP:
15184            gen_addiusp(ctx);
15185            break;
15186        }
15187        break;
15188    case POOL16E:
15189        switch (ctx->opcode & 0x1) {
15190        case ADDIUR2:
15191            gen_addiur2(ctx);
15192            break;
15193        case ADDIUR1SP:
15194            gen_addiur1sp(ctx);
15195            break;
15196        }
15197        break;
15198    case B16: /* BC16 */
15199        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15200                           sextract32(ctx->opcode, 0, 10) << 1,
15201                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15202        break;
15203    case BNEZ16: /* BNEZC16 */
15204    case BEQZ16: /* BEQZC16 */
15205        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15206                           mmreg(uMIPS_RD(ctx->opcode)),
15207                           0, sextract32(ctx->opcode, 0, 7) << 1,
15208                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15209
15210        break;
15211    case LI16:
15212        {
15213            int reg = mmreg(uMIPS_RD(ctx->opcode));
15214            int imm = ZIMM(ctx->opcode, 0, 7);
15215
15216            imm = (imm == 0x7f ? -1 : imm);
15217            tcg_gen_movi_tl(cpu_gpr[reg], imm);
15218        }
15219        break;
15220    case RES_29:
15221    case RES_31:
15222    case RES_39:
15223        generate_exception_end(ctx, EXCP_RI);
15224        break;
15225    default:
15226        decode_micromips32_opc(env, ctx);
15227        return 4;
15228    }
15229
15230    return 2;
15231}
15232
15233/* SmartMIPS extension to MIPS32 */
15234
15235#if defined(TARGET_MIPS64)
15236
15237/* MDMX extension to MIPS64 */
15238
15239#endif
15240
15241/* MIPSDSP functions. */
15242static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15243                           int rd, int base, int offset)
15244{
15245    TCGv t0;
15246
15247    check_dsp(ctx);
15248    t0 = tcg_temp_new();
15249
15250    if (base == 0) {
15251        gen_load_gpr(t0, offset);
15252    } else if (offset == 0) {
15253        gen_load_gpr(t0, base);
15254    } else {
15255        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15256    }
15257
15258    switch (opc) {
15259    case OPC_LBUX:
15260        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15261        gen_store_gpr(t0, rd);
15262        break;
15263    case OPC_LHX:
15264        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15265        gen_store_gpr(t0, rd);
15266        break;
15267    case OPC_LWX:
15268        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15269        gen_store_gpr(t0, rd);
15270        break;
15271#if defined(TARGET_MIPS64)
15272    case OPC_LDX:
15273        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15274        gen_store_gpr(t0, rd);
15275        break;
15276#endif
15277    }
15278    tcg_temp_free(t0);
15279}
15280
15281static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15282                              int ret, int v1, int v2)
15283{
15284    TCGv v1_t;
15285    TCGv v2_t;
15286
15287    if (ret == 0) {
15288        /* Treat as NOP. */
15289        return;
15290    }
15291
15292    v1_t = tcg_temp_new();
15293    v2_t = tcg_temp_new();
15294
15295    gen_load_gpr(v1_t, v1);
15296    gen_load_gpr(v2_t, v2);
15297
15298    switch (op1) {
15299    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15300    case OPC_MULT_G_2E:
15301        check_dspr2(ctx);
15302        switch (op2) {
15303        case OPC_ADDUH_QB:
15304            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15305            break;
15306        case OPC_ADDUH_R_QB:
15307            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15308            break;
15309        case OPC_ADDQH_PH:
15310            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15311            break;
15312        case OPC_ADDQH_R_PH:
15313            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15314            break;
15315        case OPC_ADDQH_W:
15316            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15317            break;
15318        case OPC_ADDQH_R_W:
15319            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15320            break;
15321        case OPC_SUBUH_QB:
15322            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15323            break;
15324        case OPC_SUBUH_R_QB:
15325            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15326            break;
15327        case OPC_SUBQH_PH:
15328            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15329            break;
15330        case OPC_SUBQH_R_PH:
15331            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15332            break;
15333        case OPC_SUBQH_W:
15334            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15335            break;
15336        case OPC_SUBQH_R_W:
15337            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15338            break;
15339        }
15340        break;
15341    case OPC_ABSQ_S_PH_DSP:
15342        switch (op2) {
15343        case OPC_ABSQ_S_QB:
15344            check_dspr2(ctx);
15345            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15346            break;
15347        case OPC_ABSQ_S_PH:
15348            check_dsp(ctx);
15349            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15350            break;
15351        case OPC_ABSQ_S_W:
15352            check_dsp(ctx);
15353            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15354            break;
15355        case OPC_PRECEQ_W_PHL:
15356            check_dsp(ctx);
15357            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15358            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15359            break;
15360        case OPC_PRECEQ_W_PHR:
15361            check_dsp(ctx);
15362            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15363            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15364            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15365            break;
15366        case OPC_PRECEQU_PH_QBL:
15367            check_dsp(ctx);
15368            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15369            break;
15370        case OPC_PRECEQU_PH_QBR:
15371            check_dsp(ctx);
15372            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15373            break;
15374        case OPC_PRECEQU_PH_QBLA:
15375            check_dsp(ctx);
15376            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15377            break;
15378        case OPC_PRECEQU_PH_QBRA:
15379            check_dsp(ctx);
15380            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15381            break;
15382        case OPC_PRECEU_PH_QBL:
15383            check_dsp(ctx);
15384            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15385            break;
15386        case OPC_PRECEU_PH_QBR:
15387            check_dsp(ctx);
15388            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15389            break;
15390        case OPC_PRECEU_PH_QBLA:
15391            check_dsp(ctx);
15392            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15393            break;
15394        case OPC_PRECEU_PH_QBRA:
15395            check_dsp(ctx);
15396            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15397            break;
15398        }
15399        break;
15400    case OPC_ADDU_QB_DSP:
15401        switch (op2) {
15402        case OPC_ADDQ_PH:
15403            check_dsp(ctx);
15404            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15405            break;
15406        case OPC_ADDQ_S_PH:
15407            check_dsp(ctx);
15408            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15409            break;
15410        case OPC_ADDQ_S_W:
15411            check_dsp(ctx);
15412            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15413            break;
15414        case OPC_ADDU_QB:
15415            check_dsp(ctx);
15416            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15417            break;
15418        case OPC_ADDU_S_QB:
15419            check_dsp(ctx);
15420            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15421            break;
15422        case OPC_ADDU_PH:
15423            check_dspr2(ctx);
15424            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15425            break;
15426        case OPC_ADDU_S_PH:
15427            check_dspr2(ctx);
15428            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15429            break;
15430        case OPC_SUBQ_PH:
15431            check_dsp(ctx);
15432            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15433            break;
15434        case OPC_SUBQ_S_PH:
15435            check_dsp(ctx);
15436            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15437            break;
15438        case OPC_SUBQ_S_W:
15439            check_dsp(ctx);
15440            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15441            break;
15442        case OPC_SUBU_QB:
15443            check_dsp(ctx);
15444            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15445            break;
15446        case OPC_SUBU_S_QB:
15447            check_dsp(ctx);
15448            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15449            break;
15450        case OPC_SUBU_PH:
15451            check_dspr2(ctx);
15452            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15453            break;
15454        case OPC_SUBU_S_PH:
15455            check_dspr2(ctx);
15456            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15457            break;
15458        case OPC_ADDSC:
15459            check_dsp(ctx);
15460            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15461            break;
15462        case OPC_ADDWC:
15463            check_dsp(ctx);
15464            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15465            break;
15466        case OPC_MODSUB:
15467            check_dsp(ctx);
15468            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15469            break;
15470        case OPC_RADDU_W_QB:
15471            check_dsp(ctx);
15472            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15473            break;
15474        }
15475        break;
15476    case OPC_CMPU_EQ_QB_DSP:
15477        switch (op2) {
15478        case OPC_PRECR_QB_PH:
15479            check_dspr2(ctx);
15480            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15481            break;
15482        case OPC_PRECRQ_QB_PH:
15483            check_dsp(ctx);
15484            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15485            break;
15486        case OPC_PRECR_SRA_PH_W:
15487            check_dspr2(ctx);
15488            {
15489                TCGv_i32 sa_t = tcg_const_i32(v2);
15490                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15491                                          cpu_gpr[ret]);
15492                tcg_temp_free_i32(sa_t);
15493                break;
15494            }
15495        case OPC_PRECR_SRA_R_PH_W:
15496            check_dspr2(ctx);
15497            {
15498                TCGv_i32 sa_t = tcg_const_i32(v2);
15499                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15500                                            cpu_gpr[ret]);
15501                tcg_temp_free_i32(sa_t);
15502                break;
15503            }
15504        case OPC_PRECRQ_PH_W:
15505            check_dsp(ctx);
15506            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15507            break;
15508        case OPC_PRECRQ_RS_PH_W:
15509            check_dsp(ctx);
15510            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15511            break;
15512        case OPC_PRECRQU_S_QB_PH:
15513            check_dsp(ctx);
15514            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15515            break;
15516        }
15517        break;
15518#ifdef TARGET_MIPS64
15519    case OPC_ABSQ_S_QH_DSP:
15520        switch (op2) {
15521        case OPC_PRECEQ_L_PWL:
15522            check_dsp(ctx);
15523            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15524            break;
15525        case OPC_PRECEQ_L_PWR:
15526            check_dsp(ctx);
15527            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15528            break;
15529        case OPC_PRECEQ_PW_QHL:
15530            check_dsp(ctx);
15531            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15532            break;
15533        case OPC_PRECEQ_PW_QHR:
15534            check_dsp(ctx);
15535            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15536            break;
15537        case OPC_PRECEQ_PW_QHLA:
15538            check_dsp(ctx);
15539            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15540            break;
15541        case OPC_PRECEQ_PW_QHRA:
15542            check_dsp(ctx);
15543            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15544            break;
15545        case OPC_PRECEQU_QH_OBL:
15546            check_dsp(ctx);
15547            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15548            break;
15549        case OPC_PRECEQU_QH_OBR:
15550            check_dsp(ctx);
15551            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15552            break;
15553        case OPC_PRECEQU_QH_OBLA:
15554            check_dsp(ctx);
15555            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15556            break;
15557        case OPC_PRECEQU_QH_OBRA:
15558            check_dsp(ctx);
15559            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15560            break;
15561        case OPC_PRECEU_QH_OBL:
15562            check_dsp(ctx);
15563            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15564            break;
15565        case OPC_PRECEU_QH_OBR:
15566            check_dsp(ctx);
15567            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15568            break;
15569        case OPC_PRECEU_QH_OBLA:
15570            check_dsp(ctx);
15571            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15572            break;
15573        case OPC_PRECEU_QH_OBRA:
15574            check_dsp(ctx);
15575            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15576            break;
15577        case OPC_ABSQ_S_OB:
15578            check_dspr2(ctx);
15579            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15580            break;
15581        case OPC_ABSQ_S_PW:
15582            check_dsp(ctx);
15583            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15584            break;
15585        case OPC_ABSQ_S_QH:
15586            check_dsp(ctx);
15587            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15588            break;
15589        }
15590        break;
15591    case OPC_ADDU_OB_DSP:
15592        switch (op2) {
15593        case OPC_RADDU_L_OB:
15594            check_dsp(ctx);
15595            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15596            break;
15597        case OPC_SUBQ_PW:
15598            check_dsp(ctx);
15599            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15600            break;
15601        case OPC_SUBQ_S_PW:
15602            check_dsp(ctx);
15603            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15604            break;
15605        case OPC_SUBQ_QH:
15606            check_dsp(ctx);
15607            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15608            break;
15609        case OPC_SUBQ_S_QH:
15610            check_dsp(ctx);
15611            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15612            break;
15613        case OPC_SUBU_OB:
15614            check_dsp(ctx);
15615            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15616            break;
15617        case OPC_SUBU_S_OB:
15618            check_dsp(ctx);
15619            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15620            break;
15621        case OPC_SUBU_QH:
15622            check_dspr2(ctx);
15623            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15624            break;
15625        case OPC_SUBU_S_QH:
15626            check_dspr2(ctx);
15627            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15628            break;
15629        case OPC_SUBUH_OB:
15630            check_dspr2(ctx);
15631            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15632            break;
15633        case OPC_SUBUH_R_OB:
15634            check_dspr2(ctx);
15635            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15636            break;
15637        case OPC_ADDQ_PW:
15638            check_dsp(ctx);
15639            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15640            break;
15641        case OPC_ADDQ_S_PW:
15642            check_dsp(ctx);
15643            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15644            break;
15645        case OPC_ADDQ_QH:
15646            check_dsp(ctx);
15647            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15648            break;
15649        case OPC_ADDQ_S_QH:
15650            check_dsp(ctx);
15651            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15652            break;
15653        case OPC_ADDU_OB:
15654            check_dsp(ctx);
15655            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15656            break;
15657        case OPC_ADDU_S_OB:
15658            check_dsp(ctx);
15659            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15660            break;
15661        case OPC_ADDU_QH:
15662            check_dspr2(ctx);
15663            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15664            break;
15665        case OPC_ADDU_S_QH:
15666            check_dspr2(ctx);
15667            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15668            break;
15669        case OPC_ADDUH_OB:
15670            check_dspr2(ctx);
15671            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15672            break;
15673        case OPC_ADDUH_R_OB:
15674            check_dspr2(ctx);
15675            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15676            break;
15677        }
15678        break;
15679    case OPC_CMPU_EQ_OB_DSP:
15680        switch (op2) {
15681        case OPC_PRECR_OB_QH:
15682            check_dspr2(ctx);
15683            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15684            break;
15685        case OPC_PRECR_SRA_QH_PW:
15686            check_dspr2(ctx);
15687            {
15688                TCGv_i32 ret_t = tcg_const_i32(ret);
15689                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15690                tcg_temp_free_i32(ret_t);
15691                break;
15692            }
15693        case OPC_PRECR_SRA_R_QH_PW:
15694            check_dspr2(ctx);
15695            {
15696                TCGv_i32 sa_v = tcg_const_i32(ret);
15697                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15698                tcg_temp_free_i32(sa_v);
15699                break;
15700            }
15701        case OPC_PRECRQ_OB_QH:
15702            check_dsp(ctx);
15703            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15704            break;
15705        case OPC_PRECRQ_PW_L:
15706            check_dsp(ctx);
15707            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15708            break;
15709        case OPC_PRECRQ_QH_PW:
15710            check_dsp(ctx);
15711            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15712            break;
15713        case OPC_PRECRQ_RS_QH_PW:
15714            check_dsp(ctx);
15715            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15716            break;
15717        case OPC_PRECRQU_S_OB_QH:
15718            check_dsp(ctx);
15719            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15720            break;
15721        }
15722        break;
15723#endif
15724    }
15725
15726    tcg_temp_free(v1_t);
15727    tcg_temp_free(v2_t);
15728}
15729
15730static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15731                              int ret, int v1, int v2)
15732{
15733    uint32_t op2;
15734    TCGv t0;
15735    TCGv v1_t;
15736    TCGv v2_t;
15737
15738    if (ret == 0) {
15739        /* Treat as NOP. */
15740        return;
15741    }
15742
15743    t0 = tcg_temp_new();
15744    v1_t = tcg_temp_new();
15745    v2_t = tcg_temp_new();
15746
15747    tcg_gen_movi_tl(t0, v1);
15748    gen_load_gpr(v1_t, v1);
15749    gen_load_gpr(v2_t, v2);
15750
15751    switch (opc) {
15752    case OPC_SHLL_QB_DSP:
15753        {
15754            op2 = MASK_SHLL_QB(ctx->opcode);
15755            switch (op2) {
15756            case OPC_SHLL_QB:
15757                check_dsp(ctx);
15758                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15759                break;
15760            case OPC_SHLLV_QB:
15761                check_dsp(ctx);
15762                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15763                break;
15764            case OPC_SHLL_PH:
15765                check_dsp(ctx);
15766                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15767                break;
15768            case OPC_SHLLV_PH:
15769                check_dsp(ctx);
15770                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15771                break;
15772            case OPC_SHLL_S_PH:
15773                check_dsp(ctx);
15774                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15775                break;
15776            case OPC_SHLLV_S_PH:
15777                check_dsp(ctx);
15778                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15779                break;
15780            case OPC_SHLL_S_W:
15781                check_dsp(ctx);
15782                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15783                break;
15784            case OPC_SHLLV_S_W:
15785                check_dsp(ctx);
15786                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15787                break;
15788            case OPC_SHRL_QB:
15789                check_dsp(ctx);
15790                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15791                break;
15792            case OPC_SHRLV_QB:
15793                check_dsp(ctx);
15794                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15795                break;
15796            case OPC_SHRL_PH:
15797                check_dspr2(ctx);
15798                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15799                break;
15800            case OPC_SHRLV_PH:
15801                check_dspr2(ctx);
15802                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15803                break;
15804            case OPC_SHRA_QB:
15805                check_dspr2(ctx);
15806                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15807                break;
15808            case OPC_SHRA_R_QB:
15809                check_dspr2(ctx);
15810                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15811                break;
15812            case OPC_SHRAV_QB:
15813                check_dspr2(ctx);
15814                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15815                break;
15816            case OPC_SHRAV_R_QB:
15817                check_dspr2(ctx);
15818                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15819                break;
15820            case OPC_SHRA_PH:
15821                check_dsp(ctx);
15822                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15823                break;
15824            case OPC_SHRA_R_PH:
15825                check_dsp(ctx);
15826                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15827                break;
15828            case OPC_SHRAV_PH:
15829                check_dsp(ctx);
15830                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15831                break;
15832            case OPC_SHRAV_R_PH:
15833                check_dsp(ctx);
15834                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15835                break;
15836            case OPC_SHRA_R_W:
15837                check_dsp(ctx);
15838                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15839                break;
15840            case OPC_SHRAV_R_W:
15841                check_dsp(ctx);
15842                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15843                break;
15844            default:            /* Invalid */
15845                MIPS_INVAL("MASK SHLL.QB");
15846                generate_exception_end(ctx, EXCP_RI);
15847                break;
15848            }
15849            break;
15850        }
15851#ifdef TARGET_MIPS64
15852    case OPC_SHLL_OB_DSP:
15853        op2 = MASK_SHLL_OB(ctx->opcode);
15854        switch (op2) {
15855        case OPC_SHLL_PW:
15856            check_dsp(ctx);
15857            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15858            break;
15859        case OPC_SHLLV_PW:
15860            check_dsp(ctx);
15861            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15862            break;
15863        case OPC_SHLL_S_PW:
15864            check_dsp(ctx);
15865            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15866            break;
15867        case OPC_SHLLV_S_PW:
15868            check_dsp(ctx);
15869            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15870            break;
15871        case OPC_SHLL_OB:
15872            check_dsp(ctx);
15873            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15874            break;
15875        case OPC_SHLLV_OB:
15876            check_dsp(ctx);
15877            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15878            break;
15879        case OPC_SHLL_QH:
15880            check_dsp(ctx);
15881            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15882            break;
15883        case OPC_SHLLV_QH:
15884            check_dsp(ctx);
15885            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15886            break;
15887        case OPC_SHLL_S_QH:
15888            check_dsp(ctx);
15889            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15890            break;
15891        case OPC_SHLLV_S_QH:
15892            check_dsp(ctx);
15893            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15894            break;
15895        case OPC_SHRA_OB:
15896            check_dspr2(ctx);
15897            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15898            break;
15899        case OPC_SHRAV_OB:
15900            check_dspr2(ctx);
15901            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15902            break;
15903        case OPC_SHRA_R_OB:
15904            check_dspr2(ctx);
15905            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15906            break;
15907        case OPC_SHRAV_R_OB:
15908            check_dspr2(ctx);
15909            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15910            break;
15911        case OPC_SHRA_PW:
15912            check_dsp(ctx);
15913            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15914            break;
15915        case OPC_SHRAV_PW:
15916            check_dsp(ctx);
15917            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15918            break;
15919        case OPC_SHRA_R_PW:
15920            check_dsp(ctx);
15921            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15922            break;
15923        case OPC_SHRAV_R_PW:
15924            check_dsp(ctx);
15925            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15926            break;
15927        case OPC_SHRA_QH:
15928            check_dsp(ctx);
15929            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15930            break;
15931        case OPC_SHRAV_QH:
15932            check_dsp(ctx);
15933            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15934            break;
15935        case OPC_SHRA_R_QH:
15936            check_dsp(ctx);
15937            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15938            break;
15939        case OPC_SHRAV_R_QH:
15940            check_dsp(ctx);
15941            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15942            break;
15943        case OPC_SHRL_OB:
15944            check_dsp(ctx);
15945            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15946            break;
15947        case OPC_SHRLV_OB:
15948            check_dsp(ctx);
15949            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15950            break;
15951        case OPC_SHRL_QH:
15952            check_dspr2(ctx);
15953            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15954            break;
15955        case OPC_SHRLV_QH:
15956            check_dspr2(ctx);
15957            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15958            break;
15959        default:            /* Invalid */
15960            MIPS_INVAL("MASK SHLL.OB");
15961            generate_exception_end(ctx, EXCP_RI);
15962            break;
15963        }
15964        break;
15965#endif
15966    }
15967
15968    tcg_temp_free(t0);
15969    tcg_temp_free(v1_t);
15970    tcg_temp_free(v2_t);
15971}
15972
15973static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15974                                 int ret, int v1, int v2, int check_ret)
15975{
15976    TCGv_i32 t0;
15977    TCGv v1_t;
15978    TCGv v2_t;
15979
15980    if ((ret == 0) && (check_ret == 1)) {
15981        /* Treat as NOP. */
15982        return;
15983    }
15984
15985    t0 = tcg_temp_new_i32();
15986    v1_t = tcg_temp_new();
15987    v2_t = tcg_temp_new();
15988
15989    tcg_gen_movi_i32(t0, ret);
15990    gen_load_gpr(v1_t, v1);
15991    gen_load_gpr(v2_t, v2);
15992
15993    switch (op1) {
15994    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15995     * the same mask and op1. */
15996    case OPC_MULT_G_2E:
15997        check_dspr2(ctx);
15998        switch (op2) {
15999        case  OPC_MUL_PH:
16000            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16001            break;
16002        case  OPC_MUL_S_PH:
16003            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16004            break;
16005        case OPC_MULQ_S_W:
16006            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16007            break;
16008        case OPC_MULQ_RS_W:
16009            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16010            break;
16011        }
16012        break;
16013    case OPC_DPA_W_PH_DSP:
16014        switch (op2) {
16015        case OPC_DPAU_H_QBL:
16016            check_dsp(ctx);
16017            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16018            break;
16019        case OPC_DPAU_H_QBR:
16020            check_dsp(ctx);
16021            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16022            break;
16023        case OPC_DPSU_H_QBL:
16024            check_dsp(ctx);
16025            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16026            break;
16027        case OPC_DPSU_H_QBR:
16028            check_dsp(ctx);
16029            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16030            break;
16031        case OPC_DPA_W_PH:
16032            check_dspr2(ctx);
16033            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16034            break;
16035        case OPC_DPAX_W_PH:
16036            check_dspr2(ctx);
16037            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16038            break;
16039        case OPC_DPAQ_S_W_PH:
16040            check_dsp(ctx);
16041            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16042            break;
16043        case OPC_DPAQX_S_W_PH:
16044            check_dspr2(ctx);
16045            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16046            break;
16047        case OPC_DPAQX_SA_W_PH:
16048            check_dspr2(ctx);
16049            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16050            break;
16051        case OPC_DPS_W_PH:
16052            check_dspr2(ctx);
16053            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16054            break;
16055        case OPC_DPSX_W_PH:
16056            check_dspr2(ctx);
16057            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16058            break;
16059        case OPC_DPSQ_S_W_PH:
16060            check_dsp(ctx);
16061            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16062            break;
16063        case OPC_DPSQX_S_W_PH:
16064            check_dspr2(ctx);
16065            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16066            break;
16067        case OPC_DPSQX_SA_W_PH:
16068            check_dspr2(ctx);
16069            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16070            break;
16071        case OPC_MULSAQ_S_W_PH:
16072            check_dsp(ctx);
16073            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16074            break;
16075        case OPC_DPAQ_SA_L_W:
16076            check_dsp(ctx);
16077            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16078            break;
16079        case OPC_DPSQ_SA_L_W:
16080            check_dsp(ctx);
16081            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16082            break;
16083        case OPC_MAQ_S_W_PHL:
16084            check_dsp(ctx);
16085            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16086            break;
16087        case OPC_MAQ_S_W_PHR:
16088            check_dsp(ctx);
16089            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16090            break;
16091        case OPC_MAQ_SA_W_PHL:
16092            check_dsp(ctx);
16093            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16094            break;
16095        case OPC_MAQ_SA_W_PHR:
16096            check_dsp(ctx);
16097            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16098            break;
16099        case OPC_MULSA_W_PH:
16100            check_dspr2(ctx);
16101            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16102            break;
16103        }
16104        break;
16105#ifdef TARGET_MIPS64
16106    case OPC_DPAQ_W_QH_DSP:
16107        {
16108            int ac = ret & 0x03;
16109            tcg_gen_movi_i32(t0, ac);
16110
16111            switch (op2) {
16112            case OPC_DMADD:
16113                check_dsp(ctx);
16114                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16115                break;
16116            case OPC_DMADDU:
16117                check_dsp(ctx);
16118                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16119                break;
16120            case OPC_DMSUB:
16121                check_dsp(ctx);
16122                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16123                break;
16124            case OPC_DMSUBU:
16125                check_dsp(ctx);
16126                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16127                break;
16128            case OPC_DPA_W_QH:
16129                check_dspr2(ctx);
16130                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16131                break;
16132            case OPC_DPAQ_S_W_QH:
16133                check_dsp(ctx);
16134                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16135                break;
16136            case OPC_DPAQ_SA_L_PW:
16137                check_dsp(ctx);
16138                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16139                break;
16140            case OPC_DPAU_H_OBL:
16141                check_dsp(ctx);
16142                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16143                break;
16144            case OPC_DPAU_H_OBR:
16145                check_dsp(ctx);
16146                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16147                break;
16148            case OPC_DPS_W_QH:
16149                check_dspr2(ctx);
16150                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16151                break;
16152            case OPC_DPSQ_S_W_QH:
16153                check_dsp(ctx);
16154                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16155                break;
16156            case OPC_DPSQ_SA_L_PW:
16157                check_dsp(ctx);
16158                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16159                break;
16160            case OPC_DPSU_H_OBL:
16161                check_dsp(ctx);
16162                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16163                break;
16164            case OPC_DPSU_H_OBR:
16165                check_dsp(ctx);
16166                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16167                break;
16168            case OPC_MAQ_S_L_PWL:
16169                check_dsp(ctx);
16170                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16171                break;
16172            case OPC_MAQ_S_L_PWR:
16173                check_dsp(ctx);
16174                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16175                break;
16176            case OPC_MAQ_S_W_QHLL:
16177                check_dsp(ctx);
16178                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16179                break;
16180            case OPC_MAQ_SA_W_QHLL:
16181                check_dsp(ctx);
16182                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16183                break;
16184            case OPC_MAQ_S_W_QHLR:
16185                check_dsp(ctx);
16186                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16187                break;
16188            case OPC_MAQ_SA_W_QHLR:
16189                check_dsp(ctx);
16190                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16191                break;
16192            case OPC_MAQ_S_W_QHRL:
16193                check_dsp(ctx);
16194                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16195                break;
16196            case OPC_MAQ_SA_W_QHRL:
16197                check_dsp(ctx);
16198                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16199                break;
16200            case OPC_MAQ_S_W_QHRR:
16201                check_dsp(ctx);
16202                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16203                break;
16204            case OPC_MAQ_SA_W_QHRR:
16205                check_dsp(ctx);
16206                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16207                break;
16208            case OPC_MULSAQ_S_L_PW:
16209                check_dsp(ctx);
16210                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16211                break;
16212            case OPC_MULSAQ_S_W_QH:
16213                check_dsp(ctx);
16214                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16215                break;
16216            }
16217        }
16218        break;
16219#endif
16220    case OPC_ADDU_QB_DSP:
16221        switch (op2) {
16222        case OPC_MULEU_S_PH_QBL:
16223            check_dsp(ctx);
16224            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16225            break;
16226        case OPC_MULEU_S_PH_QBR:
16227            check_dsp(ctx);
16228            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16229            break;
16230        case OPC_MULQ_RS_PH:
16231            check_dsp(ctx);
16232            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16233            break;
16234        case OPC_MULEQ_S_W_PHL:
16235            check_dsp(ctx);
16236            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16237            break;
16238        case OPC_MULEQ_S_W_PHR:
16239            check_dsp(ctx);
16240            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16241            break;
16242        case OPC_MULQ_S_PH:
16243            check_dspr2(ctx);
16244            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16245            break;
16246        }
16247        break;
16248#ifdef TARGET_MIPS64
16249    case OPC_ADDU_OB_DSP:
16250        switch (op2) {
16251        case OPC_MULEQ_S_PW_QHL:
16252            check_dsp(ctx);
16253            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16254            break;
16255        case OPC_MULEQ_S_PW_QHR:
16256            check_dsp(ctx);
16257            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16258            break;
16259        case OPC_MULEU_S_QH_OBL:
16260            check_dsp(ctx);
16261            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16262            break;
16263        case OPC_MULEU_S_QH_OBR:
16264            check_dsp(ctx);
16265            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16266            break;
16267        case OPC_MULQ_RS_QH:
16268            check_dsp(ctx);
16269            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16270            break;
16271        }
16272        break;
16273#endif
16274    }
16275
16276    tcg_temp_free_i32(t0);
16277    tcg_temp_free(v1_t);
16278    tcg_temp_free(v2_t);
16279}
16280
16281static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16282                                int ret, int val)
16283{
16284    int16_t imm;
16285    TCGv t0;
16286    TCGv val_t;
16287
16288    if (ret == 0) {
16289        /* Treat as NOP. */
16290        return;
16291    }
16292
16293    t0 = tcg_temp_new();
16294    val_t = tcg_temp_new();
16295    gen_load_gpr(val_t, val);
16296
16297    switch (op1) {
16298    case OPC_ABSQ_S_PH_DSP:
16299        switch (op2) {
16300        case OPC_BITREV:
16301            check_dsp(ctx);
16302            gen_helper_bitrev(cpu_gpr[ret], val_t);
16303            break;
16304        case OPC_REPL_QB:
16305            check_dsp(ctx);
16306            {
16307                target_long result;
16308                imm = (ctx->opcode >> 16) & 0xFF;
16309                result = (uint32_t)imm << 24 |
16310                         (uint32_t)imm << 16 |
16311                         (uint32_t)imm << 8  |
16312                         (uint32_t)imm;
16313                result = (int32_t)result;
16314                tcg_gen_movi_tl(cpu_gpr[ret], result);
16315            }
16316            break;
16317        case OPC_REPLV_QB:
16318            check_dsp(ctx);
16319            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16320            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16321            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16322            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16323            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16324            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16325            break;
16326        case OPC_REPL_PH:
16327            check_dsp(ctx);
16328            {
16329                imm = (ctx->opcode >> 16) & 0x03FF;
16330                imm = (int16_t)(imm << 6) >> 6;
16331                tcg_gen_movi_tl(cpu_gpr[ret], \
16332                                (target_long)((int32_t)imm << 16 | \
16333                                (uint16_t)imm));
16334            }
16335            break;
16336        case OPC_REPLV_PH:
16337            check_dsp(ctx);
16338            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16339            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16340            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16341            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16342            break;
16343        }
16344        break;
16345#ifdef TARGET_MIPS64
16346    case OPC_ABSQ_S_QH_DSP:
16347        switch (op2) {
16348        case OPC_REPL_OB:
16349            check_dsp(ctx);
16350            {
16351                target_long temp;
16352
16353                imm = (ctx->opcode >> 16) & 0xFF;
16354                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16355                temp = (temp << 16) | temp;
16356                temp = (temp << 32) | temp;
16357                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16358                break;
16359            }
16360        case OPC_REPL_PW:
16361            check_dsp(ctx);
16362            {
16363                target_long temp;
16364
16365                imm = (ctx->opcode >> 16) & 0x03FF;
16366                imm = (int16_t)(imm << 6) >> 6;
16367                temp = ((target_long)imm << 32) \
16368                       | ((target_long)imm & 0xFFFFFFFF);
16369                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16370                break;
16371            }
16372        case OPC_REPL_QH:
16373            check_dsp(ctx);
16374            {
16375                target_long temp;
16376
16377                imm = (ctx->opcode >> 16) & 0x03FF;
16378                imm = (int16_t)(imm << 6) >> 6;
16379
16380                temp = ((uint64_t)(uint16_t)imm << 48) |
16381                       ((uint64_t)(uint16_t)imm << 32) |
16382                       ((uint64_t)(uint16_t)imm << 16) |
16383                       (uint64_t)(uint16_t)imm;
16384                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16385                break;
16386            }
16387        case OPC_REPLV_OB:
16388            check_dsp(ctx);
16389            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16390            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16391            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16392            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16393            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16394            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16395            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16396            break;
16397        case OPC_REPLV_PW:
16398            check_dsp(ctx);
16399            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16400            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16401            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16402            break;
16403        case OPC_REPLV_QH:
16404            check_dsp(ctx);
16405            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16406            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16407            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16408            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16409            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16410            break;
16411        }
16412        break;
16413#endif
16414    }
16415    tcg_temp_free(t0);
16416    tcg_temp_free(val_t);
16417}
16418
16419static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16420                                     uint32_t op1, uint32_t op2,
16421                                     int ret, int v1, int v2, int check_ret)
16422{
16423    TCGv t1;
16424    TCGv v1_t;
16425    TCGv v2_t;
16426
16427    if ((ret == 0) && (check_ret == 1)) {
16428        /* Treat as NOP. */
16429        return;
16430    }
16431
16432    t1 = tcg_temp_new();
16433    v1_t = tcg_temp_new();
16434    v2_t = tcg_temp_new();
16435
16436    gen_load_gpr(v1_t, v1);
16437    gen_load_gpr(v2_t, v2);
16438
16439    switch (op1) {
16440    case OPC_CMPU_EQ_QB_DSP:
16441        switch (op2) {
16442        case OPC_CMPU_EQ_QB:
16443            check_dsp(ctx);
16444            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16445            break;
16446        case OPC_CMPU_LT_QB:
16447            check_dsp(ctx);
16448            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16449            break;
16450        case OPC_CMPU_LE_QB:
16451            check_dsp(ctx);
16452            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16453            break;
16454        case OPC_CMPGU_EQ_QB:
16455            check_dsp(ctx);
16456            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16457            break;
16458        case OPC_CMPGU_LT_QB:
16459            check_dsp(ctx);
16460            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16461            break;
16462        case OPC_CMPGU_LE_QB:
16463            check_dsp(ctx);
16464            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16465            break;
16466        case OPC_CMPGDU_EQ_QB:
16467            check_dspr2(ctx);
16468            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16469            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16470            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16471            tcg_gen_shli_tl(t1, t1, 24);
16472            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16473            break;
16474        case OPC_CMPGDU_LT_QB:
16475            check_dspr2(ctx);
16476            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16477            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16478            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16479            tcg_gen_shli_tl(t1, t1, 24);
16480            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16481            break;
16482        case OPC_CMPGDU_LE_QB:
16483            check_dspr2(ctx);
16484            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16485            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16486            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16487            tcg_gen_shli_tl(t1, t1, 24);
16488            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16489            break;
16490        case OPC_CMP_EQ_PH:
16491            check_dsp(ctx);
16492            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16493            break;
16494        case OPC_CMP_LT_PH:
16495            check_dsp(ctx);
16496            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16497            break;
16498        case OPC_CMP_LE_PH:
16499            check_dsp(ctx);
16500            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16501            break;
16502        case OPC_PICK_QB:
16503            check_dsp(ctx);
16504            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16505            break;
16506        case OPC_PICK_PH:
16507            check_dsp(ctx);
16508            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16509            break;
16510        case OPC_PACKRL_PH:
16511            check_dsp(ctx);
16512            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16513            break;
16514        }
16515        break;
16516#ifdef TARGET_MIPS64
16517    case OPC_CMPU_EQ_OB_DSP:
16518        switch (op2) {
16519        case OPC_CMP_EQ_PW:
16520            check_dsp(ctx);
16521            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16522            break;
16523        case OPC_CMP_LT_PW:
16524            check_dsp(ctx);
16525            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16526            break;
16527        case OPC_CMP_LE_PW:
16528            check_dsp(ctx);
16529            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16530            break;
16531        case OPC_CMP_EQ_QH:
16532            check_dsp(ctx);
16533            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16534            break;
16535        case OPC_CMP_LT_QH:
16536            check_dsp(ctx);
16537            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16538            break;
16539        case OPC_CMP_LE_QH:
16540            check_dsp(ctx);
16541            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16542            break;
16543        case OPC_CMPGDU_EQ_OB:
16544            check_dspr2(ctx);
16545            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16546            break;
16547        case OPC_CMPGDU_LT_OB:
16548            check_dspr2(ctx);
16549            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16550            break;
16551        case OPC_CMPGDU_LE_OB:
16552            check_dspr2(ctx);
16553            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16554            break;
16555        case OPC_CMPGU_EQ_OB:
16556            check_dsp(ctx);
16557            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16558            break;
16559        case OPC_CMPGU_LT_OB:
16560            check_dsp(ctx);
16561            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16562            break;
16563        case OPC_CMPGU_LE_OB:
16564            check_dsp(ctx);
16565            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16566            break;
16567        case OPC_CMPU_EQ_OB:
16568            check_dsp(ctx);
16569            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16570            break;
16571        case OPC_CMPU_LT_OB:
16572            check_dsp(ctx);
16573            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16574            break;
16575        case OPC_CMPU_LE_OB:
16576            check_dsp(ctx);
16577            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16578            break;
16579        case OPC_PACKRL_PW:
16580            check_dsp(ctx);
16581            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16582            break;
16583        case OPC_PICK_OB:
16584            check_dsp(ctx);
16585            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16586            break;
16587        case OPC_PICK_PW:
16588            check_dsp(ctx);
16589            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16590            break;
16591        case OPC_PICK_QH:
16592            check_dsp(ctx);
16593            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16594            break;
16595        }
16596        break;
16597#endif
16598    }
16599
16600    tcg_temp_free(t1);
16601    tcg_temp_free(v1_t);
16602    tcg_temp_free(v2_t);
16603}
16604
16605static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16606                               uint32_t op1, int rt, int rs, int sa)
16607{
16608    TCGv t0;
16609
16610    check_dspr2(ctx);
16611
16612    if (rt == 0) {
16613        /* Treat as NOP. */
16614        return;
16615    }
16616
16617    t0 = tcg_temp_new();
16618    gen_load_gpr(t0, rs);
16619
16620    switch (op1) {
16621    case OPC_APPEND_DSP:
16622        switch (MASK_APPEND(ctx->opcode)) {
16623        case OPC_APPEND:
16624            if (sa != 0) {
16625                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16626            }
16627            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16628            break;
16629        case OPC_PREPEND:
16630            if (sa != 0) {
16631                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16632                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16633                tcg_gen_shli_tl(t0, t0, 32 - sa);
16634                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16635            }
16636            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16637            break;
16638        case OPC_BALIGN:
16639            sa &= 3;
16640            if (sa != 0 && sa != 2) {
16641                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16642                tcg_gen_ext32u_tl(t0, t0);
16643                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16644                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16645            }
16646            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16647            break;
16648        default:            /* Invalid */
16649            MIPS_INVAL("MASK APPEND");
16650            generate_exception_end(ctx, EXCP_RI);
16651            break;
16652        }
16653        break;
16654#ifdef TARGET_MIPS64
16655    case OPC_DAPPEND_DSP:
16656        switch (MASK_DAPPEND(ctx->opcode)) {
16657        case OPC_DAPPEND:
16658            if (sa != 0) {
16659                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16660            }
16661            break;
16662        case OPC_PREPENDD:
16663            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16664            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16665            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16666            break;
16667        case OPC_PREPENDW:
16668            if (sa != 0) {
16669                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16670                tcg_gen_shli_tl(t0, t0, 64 - sa);
16671                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16672            }
16673            break;
16674        case OPC_DBALIGN:
16675            sa &= 7;
16676            if (sa != 0 && sa != 2 && sa != 4) {
16677                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16678                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16679                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16680            }
16681            break;
16682        default:            /* Invalid */
16683            MIPS_INVAL("MASK DAPPEND");
16684            generate_exception_end(ctx, EXCP_RI);
16685            break;
16686        }
16687        break;
16688#endif
16689    }
16690    tcg_temp_free(t0);
16691}
16692
16693static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16694                                int ret, int v1, int v2, int check_ret)
16695
16696{
16697    TCGv t0;
16698    TCGv t1;
16699    TCGv v1_t;
16700    TCGv v2_t;
16701    int16_t imm;
16702
16703    if ((ret == 0) && (check_ret == 1)) {
16704        /* Treat as NOP. */
16705        return;
16706    }
16707
16708    t0 = tcg_temp_new();
16709    t1 = tcg_temp_new();
16710    v1_t = tcg_temp_new();
16711    v2_t = tcg_temp_new();
16712
16713    gen_load_gpr(v1_t, v1);
16714    gen_load_gpr(v2_t, v2);
16715
16716    switch (op1) {
16717    case OPC_EXTR_W_DSP:
16718        check_dsp(ctx);
16719        switch (op2) {
16720        case OPC_EXTR_W:
16721            tcg_gen_movi_tl(t0, v2);
16722            tcg_gen_movi_tl(t1, v1);
16723            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16724            break;
16725        case OPC_EXTR_R_W:
16726            tcg_gen_movi_tl(t0, v2);
16727            tcg_gen_movi_tl(t1, v1);
16728            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16729            break;
16730        case OPC_EXTR_RS_W:
16731            tcg_gen_movi_tl(t0, v2);
16732            tcg_gen_movi_tl(t1, v1);
16733            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16734            break;
16735        case OPC_EXTR_S_H:
16736            tcg_gen_movi_tl(t0, v2);
16737            tcg_gen_movi_tl(t1, v1);
16738            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16739            break;
16740        case OPC_EXTRV_S_H:
16741            tcg_gen_movi_tl(t0, v2);
16742            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16743            break;
16744        case OPC_EXTRV_W:
16745            tcg_gen_movi_tl(t0, v2);
16746            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16747            break;
16748        case OPC_EXTRV_R_W:
16749            tcg_gen_movi_tl(t0, v2);
16750            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16751            break;
16752        case OPC_EXTRV_RS_W:
16753            tcg_gen_movi_tl(t0, v2);
16754            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16755            break;
16756        case OPC_EXTP:
16757            tcg_gen_movi_tl(t0, v2);
16758            tcg_gen_movi_tl(t1, v1);
16759            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16760            break;
16761        case OPC_EXTPV:
16762            tcg_gen_movi_tl(t0, v2);
16763            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16764            break;
16765        case OPC_EXTPDP:
16766            tcg_gen_movi_tl(t0, v2);
16767            tcg_gen_movi_tl(t1, v1);
16768            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16769            break;
16770        case OPC_EXTPDPV:
16771            tcg_gen_movi_tl(t0, v2);
16772            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16773            break;
16774        case OPC_SHILO:
16775            imm = (ctx->opcode >> 20) & 0x3F;
16776            tcg_gen_movi_tl(t0, ret);
16777            tcg_gen_movi_tl(t1, imm);
16778            gen_helper_shilo(t0, t1, cpu_env);
16779            break;
16780        case OPC_SHILOV:
16781            tcg_gen_movi_tl(t0, ret);
16782            gen_helper_shilo(t0, v1_t, cpu_env);
16783            break;
16784        case OPC_MTHLIP:
16785            tcg_gen_movi_tl(t0, ret);
16786            gen_helper_mthlip(t0, v1_t, cpu_env);
16787            break;
16788        case OPC_WRDSP:
16789            imm = (ctx->opcode >> 11) & 0x3FF;
16790            tcg_gen_movi_tl(t0, imm);
16791            gen_helper_wrdsp(v1_t, t0, cpu_env);
16792            break;
16793        case OPC_RDDSP:
16794            imm = (ctx->opcode >> 16) & 0x03FF;
16795            tcg_gen_movi_tl(t0, imm);
16796            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16797            break;
16798        }
16799        break;
16800#ifdef TARGET_MIPS64
16801    case OPC_DEXTR_W_DSP:
16802        check_dsp(ctx);
16803        switch (op2) {
16804        case OPC_DMTHLIP:
16805            tcg_gen_movi_tl(t0, ret);
16806            gen_helper_dmthlip(v1_t, t0, cpu_env);
16807            break;
16808        case OPC_DSHILO:
16809            {
16810                int shift = (ctx->opcode >> 19) & 0x7F;
16811                int ac = (ctx->opcode >> 11) & 0x03;
16812                tcg_gen_movi_tl(t0, shift);
16813                tcg_gen_movi_tl(t1, ac);
16814                gen_helper_dshilo(t0, t1, cpu_env);
16815                break;
16816            }
16817        case OPC_DSHILOV:
16818            {
16819                int ac = (ctx->opcode >> 11) & 0x03;
16820                tcg_gen_movi_tl(t0, ac);
16821                gen_helper_dshilo(v1_t, t0, cpu_env);
16822                break;
16823            }
16824        case OPC_DEXTP:
16825            tcg_gen_movi_tl(t0, v2);
16826            tcg_gen_movi_tl(t1, v1);
16827
16828            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16829            break;
16830        case OPC_DEXTPV:
16831            tcg_gen_movi_tl(t0, v2);
16832            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16833            break;
16834        case OPC_DEXTPDP:
16835            tcg_gen_movi_tl(t0, v2);
16836            tcg_gen_movi_tl(t1, v1);
16837            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16838            break;
16839        case OPC_DEXTPDPV:
16840            tcg_gen_movi_tl(t0, v2);
16841            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16842            break;
16843        case OPC_DEXTR_L:
16844            tcg_gen_movi_tl(t0, v2);
16845            tcg_gen_movi_tl(t1, v1);
16846            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16847            break;
16848        case OPC_DEXTR_R_L:
16849            tcg_gen_movi_tl(t0, v2);
16850            tcg_gen_movi_tl(t1, v1);
16851            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16852            break;
16853        case OPC_DEXTR_RS_L:
16854            tcg_gen_movi_tl(t0, v2);
16855            tcg_gen_movi_tl(t1, v1);
16856            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16857            break;
16858        case OPC_DEXTR_W:
16859            tcg_gen_movi_tl(t0, v2);
16860            tcg_gen_movi_tl(t1, v1);
16861            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16862            break;
16863        case OPC_DEXTR_R_W:
16864            tcg_gen_movi_tl(t0, v2);
16865            tcg_gen_movi_tl(t1, v1);
16866            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16867            break;
16868        case OPC_DEXTR_RS_W:
16869            tcg_gen_movi_tl(t0, v2);
16870            tcg_gen_movi_tl(t1, v1);
16871            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16872            break;
16873        case OPC_DEXTR_S_H:
16874            tcg_gen_movi_tl(t0, v2);
16875            tcg_gen_movi_tl(t1, v1);
16876            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16877            break;
16878        case OPC_DEXTRV_S_H:
16879            tcg_gen_movi_tl(t0, v2);
16880            tcg_gen_movi_tl(t1, v1);
16881            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16882            break;
16883        case OPC_DEXTRV_L:
16884            tcg_gen_movi_tl(t0, v2);
16885            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16886            break;
16887        case OPC_DEXTRV_R_L:
16888            tcg_gen_movi_tl(t0, v2);
16889            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16890            break;
16891        case OPC_DEXTRV_RS_L:
16892            tcg_gen_movi_tl(t0, v2);
16893            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16894            break;
16895        case OPC_DEXTRV_W:
16896            tcg_gen_movi_tl(t0, v2);
16897            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16898            break;
16899        case OPC_DEXTRV_R_W:
16900            tcg_gen_movi_tl(t0, v2);
16901            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16902            break;
16903        case OPC_DEXTRV_RS_W:
16904            tcg_gen_movi_tl(t0, v2);
16905            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16906            break;
16907        }
16908        break;
16909#endif
16910    }
16911
16912    tcg_temp_free(t0);
16913    tcg_temp_free(t1);
16914    tcg_temp_free(v1_t);
16915    tcg_temp_free(v2_t);
16916}
16917
16918/* End MIPSDSP functions. */
16919
16920static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16921{
16922    int rs, rt, rd, sa;
16923    uint32_t op1, op2;
16924
16925    rs = (ctx->opcode >> 21) & 0x1f;
16926    rt = (ctx->opcode >> 16) & 0x1f;
16927    rd = (ctx->opcode >> 11) & 0x1f;
16928    sa = (ctx->opcode >> 6) & 0x1f;
16929
16930    op1 = MASK_SPECIAL(ctx->opcode);
16931    switch (op1) {
16932    case OPC_LSA:
16933        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16934        break;
16935    case OPC_MULT ... OPC_DIVU:
16936        op2 = MASK_R6_MULDIV(ctx->opcode);
16937        switch (op2) {
16938        case R6_OPC_MUL:
16939        case R6_OPC_MUH:
16940        case R6_OPC_MULU:
16941        case R6_OPC_MUHU:
16942        case R6_OPC_DIV:
16943        case R6_OPC_MOD:
16944        case R6_OPC_DIVU:
16945        case R6_OPC_MODU:
16946            gen_r6_muldiv(ctx, op2, rd, rs, rt);
16947            break;
16948        default:
16949            MIPS_INVAL("special_r6 muldiv");
16950            generate_exception_end(ctx, EXCP_RI);
16951            break;
16952        }
16953        break;
16954    case OPC_SELEQZ:
16955    case OPC_SELNEZ:
16956        gen_cond_move(ctx, op1, rd, rs, rt);
16957        break;
16958    case R6_OPC_CLO:
16959    case R6_OPC_CLZ:
16960        if (rt == 0 && sa == 1) {
16961            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16962               We need additionally to check other fields */
16963            gen_cl(ctx, op1, rd, rs);
16964        } else {
16965            generate_exception_end(ctx, EXCP_RI);
16966        }
16967        break;
16968    case R6_OPC_SDBBP:
16969        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16970            gen_helper_do_semihosting(cpu_env);
16971        } else {
16972            if (ctx->hflags & MIPS_HFLAG_SBRI) {
16973                generate_exception_end(ctx, EXCP_RI);
16974            } else {
16975                generate_exception_end(ctx, EXCP_DBp);
16976            }
16977        }
16978        break;
16979#if defined(TARGET_MIPS64)
16980    case OPC_DLSA:
16981        check_mips_64(ctx);
16982        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16983        break;
16984    case R6_OPC_DCLO:
16985    case R6_OPC_DCLZ:
16986        if (rt == 0 && sa == 1) {
16987            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16988               We need additionally to check other fields */
16989            check_mips_64(ctx);
16990            gen_cl(ctx, op1, rd, rs);
16991        } else {
16992            generate_exception_end(ctx, EXCP_RI);
16993        }
16994        break;
16995    case OPC_DMULT ... OPC_DDIVU:
16996        op2 = MASK_R6_MULDIV(ctx->opcode);
16997        switch (op2) {
16998        case R6_OPC_DMUL:
16999        case R6_OPC_DMUH:
17000        case R6_OPC_DMULU:
17001        case R6_OPC_DMUHU:
17002        case R6_OPC_DDIV:
17003        case R6_OPC_DMOD:
17004        case R6_OPC_DDIVU:
17005        case R6_OPC_DMODU:
17006            check_mips_64(ctx);
17007            gen_r6_muldiv(ctx, op2, rd, rs, rt);
17008            break;
17009        default:
17010            MIPS_INVAL("special_r6 muldiv");
17011            generate_exception_end(ctx, EXCP_RI);
17012            break;
17013        }
17014        break;
17015#endif
17016    default:            /* Invalid */
17017        MIPS_INVAL("special_r6");
17018        generate_exception_end(ctx, EXCP_RI);
17019        break;
17020    }
17021}
17022
17023static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17024{
17025    int rs, rt, rd, sa;
17026    uint32_t op1;
17027
17028    rs = (ctx->opcode >> 21) & 0x1f;
17029    rt = (ctx->opcode >> 16) & 0x1f;
17030    rd = (ctx->opcode >> 11) & 0x1f;
17031    sa = (ctx->opcode >> 6) & 0x1f;
17032
17033    op1 = MASK_SPECIAL(ctx->opcode);
17034    switch (op1) {
17035    case OPC_MOVN:         /* Conditional move */
17036    case OPC_MOVZ:
17037        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17038                   INSN_LOONGSON2E | INSN_LOONGSON2F);
17039        gen_cond_move(ctx, op1, rd, rs, rt);
17040        break;
17041    case OPC_MFHI:          /* Move from HI/LO */
17042    case OPC_MFLO:
17043        gen_HILO(ctx, op1, rs & 3, rd);
17044        break;
17045    case OPC_MTHI:
17046    case OPC_MTLO:          /* Move to HI/LO */
17047        gen_HILO(ctx, op1, rd & 3, rs);
17048        break;
17049    case OPC_MOVCI:
17050        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17051        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17052            check_cp1_enabled(ctx);
17053            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17054                      (ctx->opcode >> 16) & 1);
17055        } else {
17056            generate_exception_err(ctx, EXCP_CpU, 1);
17057        }
17058        break;
17059    case OPC_MULT:
17060    case OPC_MULTU:
17061        if (sa) {
17062            check_insn(ctx, INSN_VR54XX);
17063            op1 = MASK_MUL_VR54XX(ctx->opcode);
17064            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17065        } else {
17066            gen_muldiv(ctx, op1, rd & 3, rs, rt);
17067        }
17068        break;
17069    case OPC_DIV:
17070    case OPC_DIVU:
17071        gen_muldiv(ctx, op1, 0, rs, rt);
17072        break;
17073#if defined(TARGET_MIPS64)
17074    case OPC_DMULT ... OPC_DDIVU:
17075        check_insn(ctx, ISA_MIPS3);
17076        check_mips_64(ctx);
17077        gen_muldiv(ctx, op1, 0, rs, rt);
17078        break;
17079#endif
17080    case OPC_JR:
17081        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17082        break;
17083    case OPC_SPIM:
17084#ifdef MIPS_STRICT_STANDARD
17085        MIPS_INVAL("SPIM");
17086        generate_exception_end(ctx, EXCP_RI);
17087#else
17088        /* Implemented as RI exception for now. */
17089        MIPS_INVAL("spim (unofficial)");
17090        generate_exception_end(ctx, EXCP_RI);
17091#endif
17092        break;
17093    default:            /* Invalid */
17094        MIPS_INVAL("special_legacy");
17095        generate_exception_end(ctx, EXCP_RI);
17096        break;
17097    }
17098}
17099
17100static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
17101{
17102    int rs, rt, rd, sa;
17103    uint32_t op1;
17104
17105    rs = (ctx->opcode >> 21) & 0x1f;
17106    rt = (ctx->opcode >> 16) & 0x1f;
17107    rd = (ctx->opcode >> 11) & 0x1f;
17108    sa = (ctx->opcode >> 6) & 0x1f;
17109
17110    op1 = MASK_SPECIAL(ctx->opcode);
17111    switch (op1) {
17112    case OPC_SLL:          /* Shift with immediate */
17113        if (sa == 5 && rd == 0 &&
17114            rs == 0 && rt == 0) { /* PAUSE */
17115            if ((ctx->insn_flags & ISA_MIPS32R6) &&
17116                (ctx->hflags & MIPS_HFLAG_BMASK)) {
17117                generate_exception_end(ctx, EXCP_RI);
17118                break;
17119            }
17120        }
17121        /* Fallthrough */
17122    case OPC_SRA:
17123        gen_shift_imm(ctx, op1, rd, rt, sa);
17124        break;
17125    case OPC_SRL:
17126        switch ((ctx->opcode >> 21) & 0x1f) {
17127        case 1:
17128            /* rotr is decoded as srl on non-R2 CPUs */
17129            if (ctx->insn_flags & ISA_MIPS32R2) {
17130                op1 = OPC_ROTR;
17131            }
17132            /* Fallthrough */
17133        case 0:
17134            gen_shift_imm(ctx, op1, rd, rt, sa);
17135            break;
17136        default:
17137            generate_exception_end(ctx, EXCP_RI);
17138            break;
17139        }
17140        break;
17141    case OPC_ADD ... OPC_SUBU:
17142        gen_arith(ctx, op1, rd, rs, rt);
17143        break;
17144    case OPC_SLLV:         /* Shifts */
17145    case OPC_SRAV:
17146        gen_shift(ctx, op1, rd, rs, rt);
17147        break;
17148    case OPC_SRLV:
17149        switch ((ctx->opcode >> 6) & 0x1f) {
17150        case 1:
17151            /* rotrv is decoded as srlv on non-R2 CPUs */
17152            if (ctx->insn_flags & ISA_MIPS32R2) {
17153                op1 = OPC_ROTRV;
17154            }
17155            /* Fallthrough */
17156        case 0:
17157            gen_shift(ctx, op1, rd, rs, rt);
17158            break;
17159        default:
17160            generate_exception_end(ctx, EXCP_RI);
17161            break;
17162        }
17163        break;
17164    case OPC_SLT:          /* Set on less than */
17165    case OPC_SLTU:
17166        gen_slt(ctx, op1, rd, rs, rt);
17167        break;
17168    case OPC_AND:          /* Logic*/
17169    case OPC_OR:
17170    case OPC_NOR:
17171    case OPC_XOR:
17172        gen_logic(ctx, op1, rd, rs, rt);
17173        break;
17174    case OPC_JALR:
17175        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17176        break;
17177    case OPC_TGE ... OPC_TEQ: /* Traps */
17178    case OPC_TNE:
17179        check_insn(ctx, ISA_MIPS2);
17180        gen_trap(ctx, op1, rs, rt, -1);
17181        break;
17182    case OPC_LSA: /* OPC_PMON */
17183        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17184            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17185            decode_opc_special_r6(env, ctx);
17186        } else {
17187            /* Pmon entry point, also R4010 selsl */
17188#ifdef MIPS_STRICT_STANDARD
17189            MIPS_INVAL("PMON / selsl");
17190            generate_exception_end(ctx, EXCP_RI);
17191#else
17192            gen_helper_0e0i(pmon, sa);
17193#endif
17194        }
17195        break;
17196    case OPC_SYSCALL:
17197        generate_exception_end(ctx, EXCP_SYSCALL);
17198        break;
17199    case OPC_BREAK:
17200        generate_exception_end(ctx, EXCP_BREAK);
17201        break;
17202    case OPC_SYNC:
17203        check_insn(ctx, ISA_MIPS2);
17204        /* Treat as NOP. */
17205        break;
17206
17207#if defined(TARGET_MIPS64)
17208        /* MIPS64 specific opcodes */
17209    case OPC_DSLL:
17210    case OPC_DSRA:
17211    case OPC_DSLL32:
17212    case OPC_DSRA32:
17213        check_insn(ctx, ISA_MIPS3);
17214        check_mips_64(ctx);
17215        gen_shift_imm(ctx, op1, rd, rt, sa);
17216        break;
17217    case OPC_DSRL:
17218        switch ((ctx->opcode >> 21) & 0x1f) {
17219        case 1:
17220            /* drotr is decoded as dsrl on non-R2 CPUs */
17221            if (ctx->insn_flags & ISA_MIPS32R2) {
17222                op1 = OPC_DROTR;
17223            }
17224            /* Fallthrough */
17225        case 0:
17226            check_insn(ctx, ISA_MIPS3);
17227            check_mips_64(ctx);
17228            gen_shift_imm(ctx, op1, rd, rt, sa);
17229            break;
17230        default:
17231            generate_exception_end(ctx, EXCP_RI);
17232            break;
17233        }
17234        break;
17235    case OPC_DSRL32:
17236        switch ((ctx->opcode >> 21) & 0x1f) {
17237        case 1:
17238            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17239            if (ctx->insn_flags & ISA_MIPS32R2) {
17240                op1 = OPC_DROTR32;
17241            }
17242            /* Fallthrough */
17243        case 0:
17244            check_insn(ctx, ISA_MIPS3);
17245            check_mips_64(ctx);
17246            gen_shift_imm(ctx, op1, rd, rt, sa);
17247            break;
17248        default:
17249            generate_exception_end(ctx, EXCP_RI);
17250            break;
17251        }
17252        break;
17253    case OPC_DADD ... OPC_DSUBU:
17254        check_insn(ctx, ISA_MIPS3);
17255        check_mips_64(ctx);
17256        gen_arith(ctx, op1, rd, rs, rt);
17257        break;
17258    case OPC_DSLLV:
17259    case OPC_DSRAV:
17260        check_insn(ctx, ISA_MIPS3);
17261        check_mips_64(ctx);
17262        gen_shift(ctx, op1, rd, rs, rt);
17263        break;
17264    case OPC_DSRLV:
17265        switch ((ctx->opcode >> 6) & 0x1f) {
17266        case 1:
17267            /* drotrv is decoded as dsrlv on non-R2 CPUs */
17268            if (ctx->insn_flags & ISA_MIPS32R2) {
17269                op1 = OPC_DROTRV;
17270            }
17271            /* Fallthrough */
17272        case 0:
17273            check_insn(ctx, ISA_MIPS3);
17274            check_mips_64(ctx);
17275            gen_shift(ctx, op1, rd, rs, rt);
17276            break;
17277        default:
17278            generate_exception_end(ctx, EXCP_RI);
17279            break;
17280        }
17281        break;
17282    case OPC_DLSA:
17283        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17284            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17285            decode_opc_special_r6(env, ctx);
17286        }
17287        break;
17288#endif
17289    default:
17290        if (ctx->insn_flags & ISA_MIPS32R6) {
17291            decode_opc_special_r6(env, ctx);
17292        } else {
17293            decode_opc_special_legacy(env, ctx);
17294        }
17295    }
17296}
17297
17298static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17299{
17300    int rs, rt, rd;
17301    uint32_t op1;
17302
17303    check_insn_opc_removed(ctx, ISA_MIPS32R6);
17304
17305    rs = (ctx->opcode >> 21) & 0x1f;
17306    rt = (ctx->opcode >> 16) & 0x1f;
17307    rd = (ctx->opcode >> 11) & 0x1f;
17308
17309    op1 = MASK_SPECIAL2(ctx->opcode);
17310    switch (op1) {
17311    case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17312    case OPC_MSUB ... OPC_MSUBU:
17313        check_insn(ctx, ISA_MIPS32);
17314        gen_muldiv(ctx, op1, rd & 3, rs, rt);
17315        break;
17316    case OPC_MUL:
17317        gen_arith(ctx, op1, rd, rs, rt);
17318        break;
17319    case OPC_DIV_G_2F:
17320    case OPC_DIVU_G_2F:
17321    case OPC_MULT_G_2F:
17322    case OPC_MULTU_G_2F:
17323    case OPC_MOD_G_2F:
17324    case OPC_MODU_G_2F:
17325        check_insn(ctx, INSN_LOONGSON2F);
17326        gen_loongson_integer(ctx, op1, rd, rs, rt);
17327        break;
17328    case OPC_CLO:
17329    case OPC_CLZ:
17330        check_insn(ctx, ISA_MIPS32);
17331        gen_cl(ctx, op1, rd, rs);
17332        break;
17333    case OPC_SDBBP:
17334        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17335            gen_helper_do_semihosting(cpu_env);
17336        } else {
17337            /* XXX: not clear which exception should be raised
17338             *      when in debug mode...
17339             */
17340            check_insn(ctx, ISA_MIPS32);
17341            generate_exception_end(ctx, EXCP_DBp);
17342        }
17343        break;
17344#if defined(TARGET_MIPS64)
17345    case OPC_DCLO:
17346    case OPC_DCLZ:
17347        check_insn(ctx, ISA_MIPS64);
17348        check_mips_64(ctx);
17349        gen_cl(ctx, op1, rd, rs);
17350        break;
17351    case OPC_DMULT_G_2F:
17352    case OPC_DMULTU_G_2F:
17353    case OPC_DDIV_G_2F:
17354    case OPC_DDIVU_G_2F:
17355    case OPC_DMOD_G_2F:
17356    case OPC_DMODU_G_2F:
17357        check_insn(ctx, INSN_LOONGSON2F);
17358        gen_loongson_integer(ctx, op1, rd, rs, rt);
17359        break;
17360#endif
17361    default:            /* Invalid */
17362        MIPS_INVAL("special2_legacy");
17363        generate_exception_end(ctx, EXCP_RI);
17364        break;
17365    }
17366}
17367
17368static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17369{
17370    int rs, rt, rd, sa;
17371    uint32_t op1, op2;
17372    int16_t imm;
17373
17374    rs = (ctx->opcode >> 21) & 0x1f;
17375    rt = (ctx->opcode >> 16) & 0x1f;
17376    rd = (ctx->opcode >> 11) & 0x1f;
17377    sa = (ctx->opcode >> 6) & 0x1f;
17378    imm = (int16_t)ctx->opcode >> 7;
17379
17380    op1 = MASK_SPECIAL3(ctx->opcode);
17381    switch (op1) {
17382    case R6_OPC_PREF:
17383        if (rt >= 24) {
17384            /* hint codes 24-31 are reserved and signal RI */
17385            generate_exception_end(ctx, EXCP_RI);
17386        }
17387        /* Treat as NOP. */
17388        break;
17389    case R6_OPC_CACHE:
17390        check_cp0_enabled(ctx);
17391        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17392            gen_cache_operation(ctx, rt, rs, imm);
17393        }
17394        break;
17395    case R6_OPC_SC:
17396        gen_st_cond(ctx, op1, rt, rs, imm);
17397        break;
17398    case R6_OPC_LL:
17399        gen_ld(ctx, op1, rt, rs, imm);
17400        break;
17401    case OPC_BSHFL:
17402        {
17403            if (rd == 0) {
17404                /* Treat as NOP. */
17405                break;
17406            }
17407            op2 = MASK_BSHFL(ctx->opcode);
17408            switch (op2) {
17409            case OPC_ALIGN ... OPC_ALIGN_END:
17410                gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17411                break;
17412            case OPC_BITSWAP:
17413                gen_bitswap(ctx, op2, rd, rt);
17414                break;
17415            }
17416        }
17417        break;
17418#if defined(TARGET_MIPS64)
17419    case R6_OPC_SCD:
17420        gen_st_cond(ctx, op1, rt, rs, imm);
17421        break;
17422    case R6_OPC_LLD:
17423        gen_ld(ctx, op1, rt, rs, imm);
17424        break;
17425    case OPC_DBSHFL:
17426        check_mips_64(ctx);
17427        {
17428            if (rd == 0) {
17429                /* Treat as NOP. */
17430                break;
17431            }
17432            op2 = MASK_DBSHFL(ctx->opcode);
17433            switch (op2) {
17434            case OPC_DALIGN ... OPC_DALIGN_END:
17435                gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17436                break;
17437            case OPC_DBITSWAP:
17438                gen_bitswap(ctx, op2, rd, rt);
17439                break;
17440            }
17441
17442        }
17443        break;
17444#endif
17445    default:            /* Invalid */
17446        MIPS_INVAL("special3_r6");
17447        generate_exception_end(ctx, EXCP_RI);
17448        break;
17449    }
17450}
17451
17452static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17453{
17454    int rs, rt, rd;
17455    uint32_t op1, op2;
17456
17457    rs = (ctx->opcode >> 21) & 0x1f;
17458    rt = (ctx->opcode >> 16) & 0x1f;
17459    rd = (ctx->opcode >> 11) & 0x1f;
17460
17461    op1 = MASK_SPECIAL3(ctx->opcode);
17462    switch (op1) {
17463    case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17464    case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17465    case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17466        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17467         * the same mask and op1. */
17468        if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17469            op2 = MASK_ADDUH_QB(ctx->opcode);
17470            switch (op2) {
17471            case OPC_ADDUH_QB:
17472            case OPC_ADDUH_R_QB:
17473            case OPC_ADDQH_PH:
17474            case OPC_ADDQH_R_PH:
17475            case OPC_ADDQH_W:
17476            case OPC_ADDQH_R_W:
17477            case OPC_SUBUH_QB:
17478            case OPC_SUBUH_R_QB:
17479            case OPC_SUBQH_PH:
17480            case OPC_SUBQH_R_PH:
17481            case OPC_SUBQH_W:
17482            case OPC_SUBQH_R_W:
17483                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17484                break;
17485            case OPC_MUL_PH:
17486            case OPC_MUL_S_PH:
17487            case OPC_MULQ_S_W:
17488            case OPC_MULQ_RS_W:
17489                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17490                break;
17491            default:
17492                MIPS_INVAL("MASK ADDUH.QB");
17493                generate_exception_end(ctx, EXCP_RI);
17494                break;
17495            }
17496        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17497            gen_loongson_integer(ctx, op1, rd, rs, rt);
17498        } else {
17499            generate_exception_end(ctx, EXCP_RI);
17500        }
17501        break;
17502    case OPC_LX_DSP:
17503        op2 = MASK_LX(ctx->opcode);
17504        switch (op2) {
17505#if defined(TARGET_MIPS64)
17506        case OPC_LDX:
17507#endif
17508        case OPC_LBUX:
17509        case OPC_LHX:
17510        case OPC_LWX:
17511            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17512            break;
17513        default:            /* Invalid */
17514            MIPS_INVAL("MASK LX");
17515            generate_exception_end(ctx, EXCP_RI);
17516            break;
17517        }
17518        break;
17519    case OPC_ABSQ_S_PH_DSP:
17520        op2 = MASK_ABSQ_S_PH(ctx->opcode);
17521        switch (op2) {
17522        case OPC_ABSQ_S_QB:
17523        case OPC_ABSQ_S_PH:
17524        case OPC_ABSQ_S_W:
17525        case OPC_PRECEQ_W_PHL:
17526        case OPC_PRECEQ_W_PHR:
17527        case OPC_PRECEQU_PH_QBL:
17528        case OPC_PRECEQU_PH_QBR:
17529        case OPC_PRECEQU_PH_QBLA:
17530        case OPC_PRECEQU_PH_QBRA:
17531        case OPC_PRECEU_PH_QBL:
17532        case OPC_PRECEU_PH_QBR:
17533        case OPC_PRECEU_PH_QBLA:
17534        case OPC_PRECEU_PH_QBRA:
17535            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17536            break;
17537        case OPC_BITREV:
17538        case OPC_REPL_QB:
17539        case OPC_REPLV_QB:
17540        case OPC_REPL_PH:
17541        case OPC_REPLV_PH:
17542            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17543            break;
17544        default:
17545            MIPS_INVAL("MASK ABSQ_S.PH");
17546            generate_exception_end(ctx, EXCP_RI);
17547            break;
17548        }
17549        break;
17550    case OPC_ADDU_QB_DSP:
17551        op2 = MASK_ADDU_QB(ctx->opcode);
17552        switch (op2) {
17553        case OPC_ADDQ_PH:
17554        case OPC_ADDQ_S_PH:
17555        case OPC_ADDQ_S_W:
17556        case OPC_ADDU_QB:
17557        case OPC_ADDU_S_QB:
17558        case OPC_ADDU_PH:
17559        case OPC_ADDU_S_PH:
17560        case OPC_SUBQ_PH:
17561        case OPC_SUBQ_S_PH:
17562        case OPC_SUBQ_S_W:
17563        case OPC_SUBU_QB:
17564        case OPC_SUBU_S_QB:
17565        case OPC_SUBU_PH:
17566        case OPC_SUBU_S_PH:
17567        case OPC_ADDSC:
17568        case OPC_ADDWC:
17569        case OPC_MODSUB:
17570        case OPC_RADDU_W_QB:
17571            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17572            break;
17573        case OPC_MULEU_S_PH_QBL:
17574        case OPC_MULEU_S_PH_QBR:
17575        case OPC_MULQ_RS_PH:
17576        case OPC_MULEQ_S_W_PHL:
17577        case OPC_MULEQ_S_W_PHR:
17578        case OPC_MULQ_S_PH:
17579            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17580            break;
17581        default:            /* Invalid */
17582            MIPS_INVAL("MASK ADDU.QB");
17583            generate_exception_end(ctx, EXCP_RI);
17584            break;
17585
17586        }
17587        break;
17588    case OPC_CMPU_EQ_QB_DSP:
17589        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17590        switch (op2) {
17591        case OPC_PRECR_SRA_PH_W:
17592        case OPC_PRECR_SRA_R_PH_W:
17593            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17594            break;
17595        case OPC_PRECR_QB_PH:
17596        case OPC_PRECRQ_QB_PH:
17597        case OPC_PRECRQ_PH_W:
17598        case OPC_PRECRQ_RS_PH_W:
17599        case OPC_PRECRQU_S_QB_PH:
17600            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17601            break;
17602        case OPC_CMPU_EQ_QB:
17603        case OPC_CMPU_LT_QB:
17604        case OPC_CMPU_LE_QB:
17605        case OPC_CMP_EQ_PH:
17606        case OPC_CMP_LT_PH:
17607        case OPC_CMP_LE_PH:
17608            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17609            break;
17610        case OPC_CMPGU_EQ_QB:
17611        case OPC_CMPGU_LT_QB:
17612        case OPC_CMPGU_LE_QB:
17613        case OPC_CMPGDU_EQ_QB:
17614        case OPC_CMPGDU_LT_QB:
17615        case OPC_CMPGDU_LE_QB:
17616        case OPC_PICK_QB:
17617        case OPC_PICK_PH:
17618        case OPC_PACKRL_PH:
17619            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17620            break;
17621        default:            /* Invalid */
17622            MIPS_INVAL("MASK CMPU.EQ.QB");
17623            generate_exception_end(ctx, EXCP_RI);
17624            break;
17625        }
17626        break;
17627    case OPC_SHLL_QB_DSP:
17628        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17629        break;
17630    case OPC_DPA_W_PH_DSP:
17631        op2 = MASK_DPA_W_PH(ctx->opcode);
17632        switch (op2) {
17633        case OPC_DPAU_H_QBL:
17634        case OPC_DPAU_H_QBR:
17635        case OPC_DPSU_H_QBL:
17636        case OPC_DPSU_H_QBR:
17637        case OPC_DPA_W_PH:
17638        case OPC_DPAX_W_PH:
17639        case OPC_DPAQ_S_W_PH:
17640        case OPC_DPAQX_S_W_PH:
17641        case OPC_DPAQX_SA_W_PH:
17642        case OPC_DPS_W_PH:
17643        case OPC_DPSX_W_PH:
17644        case OPC_DPSQ_S_W_PH:
17645        case OPC_DPSQX_S_W_PH:
17646        case OPC_DPSQX_SA_W_PH:
17647        case OPC_MULSAQ_S_W_PH:
17648        case OPC_DPAQ_SA_L_W:
17649        case OPC_DPSQ_SA_L_W:
17650        case OPC_MAQ_S_W_PHL:
17651        case OPC_MAQ_S_W_PHR:
17652        case OPC_MAQ_SA_W_PHL:
17653        case OPC_MAQ_SA_W_PHR:
17654        case OPC_MULSA_W_PH:
17655            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17656            break;
17657        default:            /* Invalid */
17658            MIPS_INVAL("MASK DPAW.PH");
17659            generate_exception_end(ctx, EXCP_RI);
17660            break;
17661        }
17662        break;
17663    case OPC_INSV_DSP:
17664        op2 = MASK_INSV(ctx->opcode);
17665        switch (op2) {
17666        case OPC_INSV:
17667            check_dsp(ctx);
17668            {
17669                TCGv t0, t1;
17670
17671                if (rt == 0) {
17672                    break;
17673                }
17674
17675                t0 = tcg_temp_new();
17676                t1 = tcg_temp_new();
17677
17678                gen_load_gpr(t0, rt);
17679                gen_load_gpr(t1, rs);
17680
17681                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17682
17683                tcg_temp_free(t0);
17684                tcg_temp_free(t1);
17685                break;
17686            }
17687        default:            /* Invalid */
17688            MIPS_INVAL("MASK INSV");
17689            generate_exception_end(ctx, EXCP_RI);
17690            break;
17691        }
17692        break;
17693    case OPC_APPEND_DSP:
17694        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17695        break;
17696    case OPC_EXTR_W_DSP:
17697        op2 = MASK_EXTR_W(ctx->opcode);
17698        switch (op2) {
17699        case OPC_EXTR_W:
17700        case OPC_EXTR_R_W:
17701        case OPC_EXTR_RS_W:
17702        case OPC_EXTR_S_H:
17703        case OPC_EXTRV_S_H:
17704        case OPC_EXTRV_W:
17705        case OPC_EXTRV_R_W:
17706        case OPC_EXTRV_RS_W:
17707        case OPC_EXTP:
17708        case OPC_EXTPV:
17709        case OPC_EXTPDP:
17710        case OPC_EXTPDPV:
17711            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17712            break;
17713        case OPC_RDDSP:
17714            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17715            break;
17716        case OPC_SHILO:
17717        case OPC_SHILOV:
17718        case OPC_MTHLIP:
17719        case OPC_WRDSP:
17720            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17721            break;
17722        default:            /* Invalid */
17723            MIPS_INVAL("MASK EXTR.W");
17724            generate_exception_end(ctx, EXCP_RI);
17725            break;
17726        }
17727        break;
17728#if defined(TARGET_MIPS64)
17729    case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17730    case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17731    case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17732        check_insn(ctx, INSN_LOONGSON2E);
17733        gen_loongson_integer(ctx, op1, rd, rs, rt);
17734        break;
17735    case OPC_ABSQ_S_QH_DSP:
17736        op2 = MASK_ABSQ_S_QH(ctx->opcode);
17737        switch (op2) {
17738        case OPC_PRECEQ_L_PWL:
17739        case OPC_PRECEQ_L_PWR:
17740        case OPC_PRECEQ_PW_QHL:
17741        case OPC_PRECEQ_PW_QHR:
17742        case OPC_PRECEQ_PW_QHLA:
17743        case OPC_PRECEQ_PW_QHRA:
17744        case OPC_PRECEQU_QH_OBL:
17745        case OPC_PRECEQU_QH_OBR:
17746        case OPC_PRECEQU_QH_OBLA:
17747        case OPC_PRECEQU_QH_OBRA:
17748        case OPC_PRECEU_QH_OBL:
17749        case OPC_PRECEU_QH_OBR:
17750        case OPC_PRECEU_QH_OBLA:
17751        case OPC_PRECEU_QH_OBRA:
17752        case OPC_ABSQ_S_OB:
17753        case OPC_ABSQ_S_PW:
17754        case OPC_ABSQ_S_QH:
17755            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17756            break;
17757        case OPC_REPL_OB:
17758        case OPC_REPL_PW:
17759        case OPC_REPL_QH:
17760        case OPC_REPLV_OB:
17761        case OPC_REPLV_PW:
17762        case OPC_REPLV_QH:
17763            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17764            break;
17765        default:            /* Invalid */
17766            MIPS_INVAL("MASK ABSQ_S.QH");
17767            generate_exception_end(ctx, EXCP_RI);
17768            break;
17769        }
17770        break;
17771    case OPC_ADDU_OB_DSP:
17772        op2 = MASK_ADDU_OB(ctx->opcode);
17773        switch (op2) {
17774        case OPC_RADDU_L_OB:
17775        case OPC_SUBQ_PW:
17776        case OPC_SUBQ_S_PW:
17777        case OPC_SUBQ_QH:
17778        case OPC_SUBQ_S_QH:
17779        case OPC_SUBU_OB:
17780        case OPC_SUBU_S_OB:
17781        case OPC_SUBU_QH:
17782        case OPC_SUBU_S_QH:
17783        case OPC_SUBUH_OB:
17784        case OPC_SUBUH_R_OB:
17785        case OPC_ADDQ_PW:
17786        case OPC_ADDQ_S_PW:
17787        case OPC_ADDQ_QH:
17788        case OPC_ADDQ_S_QH:
17789        case OPC_ADDU_OB:
17790        case OPC_ADDU_S_OB:
17791        case OPC_ADDU_QH:
17792        case OPC_ADDU_S_QH:
17793        case OPC_ADDUH_OB:
17794        case OPC_ADDUH_R_OB:
17795            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17796            break;
17797        case OPC_MULEQ_S_PW_QHL:
17798        case OPC_MULEQ_S_PW_QHR:
17799        case OPC_MULEU_S_QH_OBL:
17800        case OPC_MULEU_S_QH_OBR:
17801        case OPC_MULQ_RS_QH:
17802            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17803            break;
17804        default:            /* Invalid */
17805            MIPS_INVAL("MASK ADDU.OB");
17806            generate_exception_end(ctx, EXCP_RI);
17807            break;
17808        }
17809        break;
17810    case OPC_CMPU_EQ_OB_DSP:
17811        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17812        switch (op2) {
17813        case OPC_PRECR_SRA_QH_PW:
17814        case OPC_PRECR_SRA_R_QH_PW:
17815            /* Return value is rt. */
17816            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17817            break;
17818        case OPC_PRECR_OB_QH:
17819        case OPC_PRECRQ_OB_QH:
17820        case OPC_PRECRQ_PW_L:
17821        case OPC_PRECRQ_QH_PW:
17822        case OPC_PRECRQ_RS_QH_PW:
17823        case OPC_PRECRQU_S_OB_QH:
17824            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17825            break;
17826        case OPC_CMPU_EQ_OB:
17827        case OPC_CMPU_LT_OB:
17828        case OPC_CMPU_LE_OB:
17829        case OPC_CMP_EQ_QH:
17830        case OPC_CMP_LT_QH:
17831        case OPC_CMP_LE_QH:
17832        case OPC_CMP_EQ_PW:
17833        case OPC_CMP_LT_PW:
17834        case OPC_CMP_LE_PW:
17835            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17836            break;
17837        case OPC_CMPGDU_EQ_OB:
17838        case OPC_CMPGDU_LT_OB:
17839        case OPC_CMPGDU_LE_OB:
17840        case OPC_CMPGU_EQ_OB:
17841        case OPC_CMPGU_LT_OB:
17842        case OPC_CMPGU_LE_OB:
17843        case OPC_PACKRL_PW:
17844        case OPC_PICK_OB:
17845        case OPC_PICK_PW:
17846        case OPC_PICK_QH:
17847            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17848            break;
17849        default:            /* Invalid */
17850            MIPS_INVAL("MASK CMPU_EQ.OB");
17851            generate_exception_end(ctx, EXCP_RI);
17852            break;
17853        }
17854        break;
17855    case OPC_DAPPEND_DSP:
17856        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17857        break;
17858    case OPC_DEXTR_W_DSP:
17859        op2 = MASK_DEXTR_W(ctx->opcode);
17860        switch (op2) {
17861        case OPC_DEXTP:
17862        case OPC_DEXTPDP:
17863        case OPC_DEXTPDPV:
17864        case OPC_DEXTPV:
17865        case OPC_DEXTR_L:
17866        case OPC_DEXTR_R_L:
17867        case OPC_DEXTR_RS_L:
17868        case OPC_DEXTR_W:
17869        case OPC_DEXTR_R_W:
17870        case OPC_DEXTR_RS_W:
17871        case OPC_DEXTR_S_H:
17872        case OPC_DEXTRV_L:
17873        case OPC_DEXTRV_R_L:
17874        case OPC_DEXTRV_RS_L:
17875        case OPC_DEXTRV_S_H:
17876        case OPC_DEXTRV_W:
17877        case OPC_DEXTRV_R_W:
17878        case OPC_DEXTRV_RS_W:
17879            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17880            break;
17881        case OPC_DMTHLIP:
17882        case OPC_DSHILO:
17883        case OPC_DSHILOV:
17884            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17885            break;
17886        default:            /* Invalid */
17887            MIPS_INVAL("MASK EXTR.W");
17888            generate_exception_end(ctx, EXCP_RI);
17889            break;
17890        }
17891        break;
17892    case OPC_DPAQ_W_QH_DSP:
17893        op2 = MASK_DPAQ_W_QH(ctx->opcode);
17894        switch (op2) {
17895        case OPC_DPAU_H_OBL:
17896        case OPC_DPAU_H_OBR:
17897        case OPC_DPSU_H_OBL:
17898        case OPC_DPSU_H_OBR:
17899        case OPC_DPA_W_QH:
17900        case OPC_DPAQ_S_W_QH:
17901        case OPC_DPS_W_QH:
17902        case OPC_DPSQ_S_W_QH:
17903        case OPC_MULSAQ_S_W_QH:
17904        case OPC_DPAQ_SA_L_PW:
17905        case OPC_DPSQ_SA_L_PW:
17906        case OPC_MULSAQ_S_L_PW:
17907            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17908            break;
17909        case OPC_MAQ_S_W_QHLL:
17910        case OPC_MAQ_S_W_QHLR:
17911        case OPC_MAQ_S_W_QHRL:
17912        case OPC_MAQ_S_W_QHRR:
17913        case OPC_MAQ_SA_W_QHLL:
17914        case OPC_MAQ_SA_W_QHLR:
17915        case OPC_MAQ_SA_W_QHRL:
17916        case OPC_MAQ_SA_W_QHRR:
17917        case OPC_MAQ_S_L_PWL:
17918        case OPC_MAQ_S_L_PWR:
17919        case OPC_DMADD:
17920        case OPC_DMADDU:
17921        case OPC_DMSUB:
17922        case OPC_DMSUBU:
17923            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17924            break;
17925        default:            /* Invalid */
17926            MIPS_INVAL("MASK DPAQ.W.QH");
17927            generate_exception_end(ctx, EXCP_RI);
17928            break;
17929        }
17930        break;
17931    case OPC_DINSV_DSP:
17932        op2 = MASK_INSV(ctx->opcode);
17933        switch (op2) {
17934        case OPC_DINSV:
17935        {
17936            TCGv t0, t1;
17937
17938            if (rt == 0) {
17939                break;
17940            }
17941            check_dsp(ctx);
17942
17943            t0 = tcg_temp_new();
17944            t1 = tcg_temp_new();
17945
17946            gen_load_gpr(t0, rt);
17947            gen_load_gpr(t1, rs);
17948
17949            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17950
17951            tcg_temp_free(t0);
17952            tcg_temp_free(t1);
17953            break;
17954        }
17955        default:            /* Invalid */
17956            MIPS_INVAL("MASK DINSV");
17957            generate_exception_end(ctx, EXCP_RI);
17958            break;
17959        }
17960        break;
17961    case OPC_SHLL_OB_DSP:
17962        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17963        break;
17964#endif
17965    default:            /* Invalid */
17966        MIPS_INVAL("special3_legacy");
17967        generate_exception_end(ctx, EXCP_RI);
17968        break;
17969    }
17970}
17971
17972static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17973{
17974    int rs, rt, rd, sa;
17975    uint32_t op1, op2;
17976
17977    rs = (ctx->opcode >> 21) & 0x1f;
17978    rt = (ctx->opcode >> 16) & 0x1f;
17979    rd = (ctx->opcode >> 11) & 0x1f;
17980    sa = (ctx->opcode >> 6) & 0x1f;
17981
17982    op1 = MASK_SPECIAL3(ctx->opcode);
17983    switch (op1) {
17984    case OPC_EXT:
17985    case OPC_INS:
17986        check_insn(ctx, ISA_MIPS32R2);
17987        gen_bitops(ctx, op1, rt, rs, sa, rd);
17988        break;
17989    case OPC_BSHFL:
17990        op2 = MASK_BSHFL(ctx->opcode);
17991        switch (op2) {
17992        case OPC_ALIGN ... OPC_ALIGN_END:
17993        case OPC_BITSWAP:
17994            check_insn(ctx, ISA_MIPS32R6);
17995            decode_opc_special3_r6(env, ctx);
17996            break;
17997        default:
17998            check_insn(ctx, ISA_MIPS32R2);
17999            gen_bshfl(ctx, op2, rt, rd);
18000            break;
18001        }
18002        break;
18003#if defined(TARGET_MIPS64)
18004    case OPC_DEXTM ... OPC_DEXT:
18005    case OPC_DINSM ... OPC_DINS:
18006        check_insn(ctx, ISA_MIPS64R2);
18007        check_mips_64(ctx);
18008        gen_bitops(ctx, op1, rt, rs, sa, rd);
18009        break;
18010    case OPC_DBSHFL:
18011        op2 = MASK_DBSHFL(ctx->opcode);
18012        switch (op2) {
18013        case OPC_DALIGN ... OPC_DALIGN_END:
18014        case OPC_DBITSWAP:
18015            check_insn(ctx, ISA_MIPS32R6);
18016            decode_opc_special3_r6(env, ctx);
18017            break;
18018        default:
18019            check_insn(ctx, ISA_MIPS64R2);
18020            check_mips_64(ctx);
18021            op2 = MASK_DBSHFL(ctx->opcode);
18022            gen_bshfl(ctx, op2, rt, rd);
18023            break;
18024        }
18025        break;
18026#endif
18027    case OPC_RDHWR:
18028        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
18029        break;
18030    case OPC_FORK:
18031        check_insn(ctx, ASE_MT);
18032        {
18033            TCGv t0 = tcg_temp_new();
18034            TCGv t1 = tcg_temp_new();
18035
18036            gen_load_gpr(t0, rt);
18037            gen_load_gpr(t1, rs);
18038            gen_helper_fork(t0, t1);
18039            tcg_temp_free(t0);
18040            tcg_temp_free(t1);
18041        }
18042        break;
18043    case OPC_YIELD:
18044        check_insn(ctx, ASE_MT);
18045        {
18046            TCGv t0 = tcg_temp_new();
18047
18048            gen_load_gpr(t0, rs);
18049            gen_helper_yield(t0, cpu_env, t0);
18050            gen_store_gpr(t0, rd);
18051            tcg_temp_free(t0);
18052        }
18053        break;
18054    default:
18055        if (ctx->insn_flags & ISA_MIPS32R6) {
18056            decode_opc_special3_r6(env, ctx);
18057        } else {
18058            decode_opc_special3_legacy(env, ctx);
18059        }
18060    }
18061}
18062
18063/* MIPS SIMD Architecture (MSA)  */
18064static inline int check_msa_access(DisasContext *ctx)
18065{
18066    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18067                 !(ctx->hflags & MIPS_HFLAG_F64))) {
18068        generate_exception_end(ctx, EXCP_RI);
18069        return 0;
18070    }
18071
18072    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18073        if (ctx->insn_flags & ASE_MSA) {
18074            generate_exception_end(ctx, EXCP_MSADIS);
18075            return 0;
18076        } else {
18077            generate_exception_end(ctx, EXCP_RI);
18078            return 0;
18079        }
18080    }
18081    return 1;
18082}
18083
18084static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18085{
18086    /* generates tcg ops to check if any element is 0 */
18087    /* Note this function only works with MSA_WRLEN = 128 */
18088    uint64_t eval_zero_or_big = 0;
18089    uint64_t eval_big = 0;
18090    TCGv_i64 t0 = tcg_temp_new_i64();
18091    TCGv_i64 t1 = tcg_temp_new_i64();
18092    switch (df) {
18093    case DF_BYTE:
18094        eval_zero_or_big = 0x0101010101010101ULL;
18095        eval_big = 0x8080808080808080ULL;
18096        break;
18097    case DF_HALF:
18098        eval_zero_or_big = 0x0001000100010001ULL;
18099        eval_big = 0x8000800080008000ULL;
18100        break;
18101    case DF_WORD:
18102        eval_zero_or_big = 0x0000000100000001ULL;
18103        eval_big = 0x8000000080000000ULL;
18104        break;
18105    case DF_DOUBLE:
18106        eval_zero_or_big = 0x0000000000000001ULL;
18107        eval_big = 0x8000000000000000ULL;
18108        break;
18109    }
18110    tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18111    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18112    tcg_gen_andi_i64(t0, t0, eval_big);
18113    tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18114    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18115    tcg_gen_andi_i64(t1, t1, eval_big);
18116    tcg_gen_or_i64(t0, t0, t1);
18117    /* if all bits are zero then all elements are not zero */
18118    /* if some bit is non-zero then some element is zero */
18119    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18120    tcg_gen_trunc_i64_tl(tresult, t0);
18121    tcg_temp_free_i64(t0);
18122    tcg_temp_free_i64(t1);
18123}
18124
18125static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18126{
18127    uint8_t df = (ctx->opcode >> 21) & 0x3;
18128    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18129    int64_t s16 = (int16_t)ctx->opcode;
18130
18131    check_msa_access(ctx);
18132
18133    if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
18134        generate_exception_end(ctx, EXCP_RI);
18135        return;
18136    }
18137    switch (op1) {
18138    case OPC_BZ_V:
18139    case OPC_BNZ_V:
18140        {
18141            TCGv_i64 t0 = tcg_temp_new_i64();
18142            tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18143            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18144                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18145            tcg_gen_trunc_i64_tl(bcond, t0);
18146            tcg_temp_free_i64(t0);
18147        }
18148        break;
18149    case OPC_BZ_B:
18150    case OPC_BZ_H:
18151    case OPC_BZ_W:
18152    case OPC_BZ_D:
18153        gen_check_zero_element(bcond, df, wt);
18154        break;
18155    case OPC_BNZ_B:
18156    case OPC_BNZ_H:
18157    case OPC_BNZ_W:
18158    case OPC_BNZ_D:
18159        gen_check_zero_element(bcond, df, wt);
18160        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18161        break;
18162    }
18163
18164    ctx->btarget = ctx->pc + (s16 << 2) + 4;
18165
18166    ctx->hflags |= MIPS_HFLAG_BC;
18167    ctx->hflags |= MIPS_HFLAG_BDS32;
18168}
18169
18170static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18171{
18172#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18173    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18174    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18175    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18176
18177    TCGv_i32 twd = tcg_const_i32(wd);
18178    TCGv_i32 tws = tcg_const_i32(ws);
18179    TCGv_i32 ti8 = tcg_const_i32(i8);
18180
18181    switch (MASK_MSA_I8(ctx->opcode)) {
18182    case OPC_ANDI_B:
18183        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18184        break;
18185    case OPC_ORI_B:
18186        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18187        break;
18188    case OPC_NORI_B:
18189        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18190        break;
18191    case OPC_XORI_B:
18192        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18193        break;
18194    case OPC_BMNZI_B:
18195        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18196        break;
18197    case OPC_BMZI_B:
18198        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18199        break;
18200    case OPC_BSELI_B:
18201        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18202        break;
18203    case OPC_SHF_B:
18204    case OPC_SHF_H:
18205    case OPC_SHF_W:
18206        {
18207            uint8_t df = (ctx->opcode >> 24) & 0x3;
18208            if (df == DF_DOUBLE) {
18209                generate_exception_end(ctx, EXCP_RI);
18210            } else {
18211                TCGv_i32 tdf = tcg_const_i32(df);
18212                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18213                tcg_temp_free_i32(tdf);
18214            }
18215        }
18216        break;
18217    default:
18218        MIPS_INVAL("MSA instruction");
18219        generate_exception_end(ctx, EXCP_RI);
18220        break;
18221    }
18222
18223    tcg_temp_free_i32(twd);
18224    tcg_temp_free_i32(tws);
18225    tcg_temp_free_i32(ti8);
18226}
18227
18228static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18229{
18230#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18231    uint8_t df = (ctx->opcode >> 21) & 0x3;
18232    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18233    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18234    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18235    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18236
18237    TCGv_i32 tdf = tcg_const_i32(df);
18238    TCGv_i32 twd = tcg_const_i32(wd);
18239    TCGv_i32 tws = tcg_const_i32(ws);
18240    TCGv_i32 timm = tcg_temp_new_i32();
18241    tcg_gen_movi_i32(timm, u5);
18242
18243    switch (MASK_MSA_I5(ctx->opcode)) {
18244    case OPC_ADDVI_df:
18245        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18246        break;
18247    case OPC_SUBVI_df:
18248        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18249        break;
18250    case OPC_MAXI_S_df:
18251        tcg_gen_movi_i32(timm, s5);
18252        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18253        break;
18254    case OPC_MAXI_U_df:
18255        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18256        break;
18257    case OPC_MINI_S_df:
18258        tcg_gen_movi_i32(timm, s5);
18259        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18260        break;
18261    case OPC_MINI_U_df:
18262        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18263        break;
18264    case OPC_CEQI_df:
18265        tcg_gen_movi_i32(timm, s5);
18266        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18267        break;
18268    case OPC_CLTI_S_df:
18269        tcg_gen_movi_i32(timm, s5);
18270        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18271        break;
18272    case OPC_CLTI_U_df:
18273        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18274        break;
18275    case OPC_CLEI_S_df:
18276        tcg_gen_movi_i32(timm, s5);
18277        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18278        break;
18279    case OPC_CLEI_U_df:
18280        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18281        break;
18282    case OPC_LDI_df:
18283        {
18284            int32_t s10 = sextract32(ctx->opcode, 11, 10);
18285            tcg_gen_movi_i32(timm, s10);
18286            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18287        }
18288        break;
18289    default:
18290        MIPS_INVAL("MSA instruction");
18291        generate_exception_end(ctx, EXCP_RI);
18292        break;
18293    }
18294
18295    tcg_temp_free_i32(tdf);
18296    tcg_temp_free_i32(twd);
18297    tcg_temp_free_i32(tws);
18298    tcg_temp_free_i32(timm);
18299}
18300
18301static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18302{
18303#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18304    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18305    uint32_t df = 0, m = 0;
18306    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18307    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18308
18309    TCGv_i32 tdf;
18310    TCGv_i32 tm;
18311    TCGv_i32 twd;
18312    TCGv_i32 tws;
18313
18314    if ((dfm & 0x40) == 0x00) {
18315        m = dfm & 0x3f;
18316        df = DF_DOUBLE;
18317    } else if ((dfm & 0x60) == 0x40) {
18318        m = dfm & 0x1f;
18319        df = DF_WORD;
18320    } else if ((dfm & 0x70) == 0x60) {
18321        m = dfm & 0x0f;
18322        df = DF_HALF;
18323    } else if ((dfm & 0x78) == 0x70) {
18324        m = dfm & 0x7;
18325        df = DF_BYTE;
18326    } else {
18327        generate_exception_end(ctx, EXCP_RI);
18328        return;
18329    }
18330
18331    tdf = tcg_const_i32(df);
18332    tm  = tcg_const_i32(m);
18333    twd = tcg_const_i32(wd);
18334    tws = tcg_const_i32(ws);
18335
18336    switch (MASK_MSA_BIT(ctx->opcode)) {
18337    case OPC_SLLI_df:
18338        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18339        break;
18340    case OPC_SRAI_df:
18341        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18342        break;
18343    case OPC_SRLI_df:
18344        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18345        break;
18346    case OPC_BCLRI_df:
18347        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18348        break;
18349    case OPC_BSETI_df:
18350        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18351        break;
18352    case OPC_BNEGI_df:
18353        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18354        break;
18355    case OPC_BINSLI_df:
18356        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18357        break;
18358    case OPC_BINSRI_df:
18359        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18360        break;
18361    case OPC_SAT_S_df:
18362        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18363        break;
18364    case OPC_SAT_U_df:
18365        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18366        break;
18367    case OPC_SRARI_df:
18368        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18369        break;
18370    case OPC_SRLRI_df:
18371        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18372        break;
18373    default:
18374        MIPS_INVAL("MSA instruction");
18375        generate_exception_end(ctx, EXCP_RI);
18376        break;
18377    }
18378
18379    tcg_temp_free_i32(tdf);
18380    tcg_temp_free_i32(tm);
18381    tcg_temp_free_i32(twd);
18382    tcg_temp_free_i32(tws);
18383}
18384
18385static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18386{
18387#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18388    uint8_t df = (ctx->opcode >> 21) & 0x3;
18389    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18390    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18391    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18392
18393    TCGv_i32 tdf = tcg_const_i32(df);
18394    TCGv_i32 twd = tcg_const_i32(wd);
18395    TCGv_i32 tws = tcg_const_i32(ws);
18396    TCGv_i32 twt = tcg_const_i32(wt);
18397
18398    switch (MASK_MSA_3R(ctx->opcode)) {
18399    case OPC_SLL_df:
18400        gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18401        break;
18402    case OPC_ADDV_df:
18403        gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18404        break;
18405    case OPC_CEQ_df:
18406        gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18407        break;
18408    case OPC_ADD_A_df:
18409        gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18410        break;
18411    case OPC_SUBS_S_df:
18412        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18413        break;
18414    case OPC_MULV_df:
18415        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18416        break;
18417    case OPC_SLD_df:
18418        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18419        break;
18420    case OPC_VSHF_df:
18421        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18422        break;
18423    case OPC_SRA_df:
18424        gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18425        break;
18426    case OPC_SUBV_df:
18427        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18428        break;
18429    case OPC_ADDS_A_df:
18430        gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18431        break;
18432    case OPC_SUBS_U_df:
18433        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18434        break;
18435    case OPC_MADDV_df:
18436        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18437        break;
18438    case OPC_SPLAT_df:
18439        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18440        break;
18441    case OPC_SRAR_df:
18442        gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18443        break;
18444    case OPC_SRL_df:
18445        gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18446        break;
18447    case OPC_MAX_S_df:
18448        gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18449        break;
18450    case OPC_CLT_S_df:
18451        gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18452        break;
18453    case OPC_ADDS_S_df:
18454        gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18455        break;
18456    case OPC_SUBSUS_U_df:
18457        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18458        break;
18459    case OPC_MSUBV_df:
18460        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18461        break;
18462    case OPC_PCKEV_df:
18463        gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18464        break;
18465    case OPC_SRLR_df:
18466        gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18467        break;
18468    case OPC_BCLR_df:
18469        gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18470        break;
18471    case OPC_MAX_U_df:
18472        gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18473        break;
18474    case OPC_CLT_U_df:
18475        gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18476        break;
18477    case OPC_ADDS_U_df:
18478        gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18479        break;
18480    case OPC_SUBSUU_S_df:
18481        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18482        break;
18483    case OPC_PCKOD_df:
18484        gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18485        break;
18486    case OPC_BSET_df:
18487        gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18488        break;
18489    case OPC_MIN_S_df:
18490        gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18491        break;
18492    case OPC_CLE_S_df:
18493        gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18494        break;
18495    case OPC_AVE_S_df:
18496        gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18497        break;
18498    case OPC_ASUB_S_df:
18499        gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18500        break;
18501    case OPC_DIV_S_df:
18502        gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18503        break;
18504    case OPC_ILVL_df:
18505        gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18506        break;
18507    case OPC_BNEG_df:
18508        gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18509        break;
18510    case OPC_MIN_U_df:
18511        gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18512        break;
18513    case OPC_CLE_U_df:
18514        gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18515        break;
18516    case OPC_AVE_U_df:
18517        gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18518        break;
18519    case OPC_ASUB_U_df:
18520        gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18521        break;
18522    case OPC_DIV_U_df:
18523        gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18524        break;
18525    case OPC_ILVR_df:
18526        gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18527        break;
18528    case OPC_BINSL_df:
18529        gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18530        break;
18531    case OPC_MAX_A_df:
18532        gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18533        break;
18534    case OPC_AVER_S_df:
18535        gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18536        break;
18537    case OPC_MOD_S_df:
18538        gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18539        break;
18540    case OPC_ILVEV_df:
18541        gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18542        break;
18543    case OPC_BINSR_df:
18544        gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18545        break;
18546    case OPC_MIN_A_df:
18547        gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18548        break;
18549    case OPC_AVER_U_df:
18550        gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18551        break;
18552    case OPC_MOD_U_df:
18553        gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18554        break;
18555    case OPC_ILVOD_df:
18556        gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18557        break;
18558
18559    case OPC_DOTP_S_df:
18560    case OPC_DOTP_U_df:
18561    case OPC_DPADD_S_df:
18562    case OPC_DPADD_U_df:
18563    case OPC_DPSUB_S_df:
18564    case OPC_HADD_S_df:
18565    case OPC_DPSUB_U_df:
18566    case OPC_HADD_U_df:
18567    case OPC_HSUB_S_df:
18568    case OPC_HSUB_U_df:
18569        if (df == DF_BYTE) {
18570            generate_exception_end(ctx, EXCP_RI);
18571            break;
18572        }
18573        switch (MASK_MSA_3R(ctx->opcode)) {
18574        case OPC_DOTP_S_df:
18575            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18576            break;
18577        case OPC_DOTP_U_df:
18578            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18579            break;
18580        case OPC_DPADD_S_df:
18581            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18582            break;
18583        case OPC_DPADD_U_df:
18584            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18585            break;
18586        case OPC_DPSUB_S_df:
18587            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18588            break;
18589        case OPC_HADD_S_df:
18590            gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18591            break;
18592        case OPC_DPSUB_U_df:
18593            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18594            break;
18595        case OPC_HADD_U_df:
18596            gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18597            break;
18598        case OPC_HSUB_S_df:
18599            gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18600            break;
18601        case OPC_HSUB_U_df:
18602            gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18603            break;
18604        }
18605        break;
18606    default:
18607        MIPS_INVAL("MSA instruction");
18608        generate_exception_end(ctx, EXCP_RI);
18609        break;
18610    }
18611    tcg_temp_free_i32(twd);
18612    tcg_temp_free_i32(tws);
18613    tcg_temp_free_i32(twt);
18614    tcg_temp_free_i32(tdf);
18615}
18616
18617static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18618{
18619#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18620    uint8_t source = (ctx->opcode >> 11) & 0x1f;
18621    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18622    TCGv telm = tcg_temp_new();
18623    TCGv_i32 tsr = tcg_const_i32(source);
18624    TCGv_i32 tdt = tcg_const_i32(dest);
18625
18626    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18627    case OPC_CTCMSA:
18628        gen_load_gpr(telm, source);
18629        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18630        break;
18631    case OPC_CFCMSA:
18632        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18633        gen_store_gpr(telm, dest);
18634        break;
18635    case OPC_MOVE_V:
18636        gen_helper_msa_move_v(cpu_env, tdt, tsr);
18637        break;
18638    default:
18639        MIPS_INVAL("MSA instruction");
18640        generate_exception_end(ctx, EXCP_RI);
18641        break;
18642    }
18643
18644    tcg_temp_free(telm);
18645    tcg_temp_free_i32(tdt);
18646    tcg_temp_free_i32(tsr);
18647}
18648
18649static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18650        uint32_t n)
18651{
18652#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18653    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18654    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18655
18656    TCGv_i32 tws = tcg_const_i32(ws);
18657    TCGv_i32 twd = tcg_const_i32(wd);
18658    TCGv_i32 tn  = tcg_const_i32(n);
18659    TCGv_i32 tdf = tcg_const_i32(df);
18660
18661    switch (MASK_MSA_ELM(ctx->opcode)) {
18662    case OPC_SLDI_df:
18663        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18664        break;
18665    case OPC_SPLATI_df:
18666        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18667        break;
18668    case OPC_INSVE_df:
18669        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18670        break;
18671    case OPC_COPY_S_df:
18672    case OPC_COPY_U_df:
18673    case OPC_INSERT_df:
18674#if !defined(TARGET_MIPS64)
18675        /* Double format valid only for MIPS64 */
18676        if (df == DF_DOUBLE) {
18677            generate_exception_end(ctx, EXCP_RI);
18678            break;
18679        }
18680#endif
18681        switch (MASK_MSA_ELM(ctx->opcode)) {
18682        case OPC_COPY_S_df:
18683            gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18684            break;
18685        case OPC_COPY_U_df:
18686            gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18687            break;
18688        case OPC_INSERT_df:
18689            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18690            break;
18691        }
18692        break;
18693    default:
18694        MIPS_INVAL("MSA instruction");
18695        generate_exception_end(ctx, EXCP_RI);
18696    }
18697    tcg_temp_free_i32(twd);
18698    tcg_temp_free_i32(tws);
18699    tcg_temp_free_i32(tn);
18700    tcg_temp_free_i32(tdf);
18701}
18702
18703static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18704{
18705    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18706    uint32_t df = 0, n = 0;
18707
18708    if ((dfn & 0x30) == 0x00) {
18709        n = dfn & 0x0f;
18710        df = DF_BYTE;
18711    } else if ((dfn & 0x38) == 0x20) {
18712        n = dfn & 0x07;
18713        df = DF_HALF;
18714    } else if ((dfn & 0x3c) == 0x30) {
18715        n = dfn & 0x03;
18716        df = DF_WORD;
18717    } else if ((dfn & 0x3e) == 0x38) {
18718        n = dfn & 0x01;
18719        df = DF_DOUBLE;
18720    } else if (dfn == 0x3E) {
18721        /* CTCMSA, CFCMSA, MOVE.V */
18722        gen_msa_elm_3e(env, ctx);
18723        return;
18724    } else {
18725        generate_exception_end(ctx, EXCP_RI);
18726        return;
18727    }
18728
18729    gen_msa_elm_df(env, ctx, df, n);
18730}
18731
18732static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18733{
18734#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18735    uint8_t df = (ctx->opcode >> 21) & 0x1;
18736    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18737    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18738    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18739
18740    TCGv_i32 twd = tcg_const_i32(wd);
18741    TCGv_i32 tws = tcg_const_i32(ws);
18742    TCGv_i32 twt = tcg_const_i32(wt);
18743    TCGv_i32 tdf = tcg_temp_new_i32();
18744
18745    /* adjust df value for floating-point instruction */
18746    tcg_gen_movi_i32(tdf, df + 2);
18747
18748    switch (MASK_MSA_3RF(ctx->opcode)) {
18749    case OPC_FCAF_df:
18750        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18751        break;
18752    case OPC_FADD_df:
18753        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18754        break;
18755    case OPC_FCUN_df:
18756        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18757        break;
18758    case OPC_FSUB_df:
18759        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18760        break;
18761    case OPC_FCOR_df:
18762        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18763        break;
18764    case OPC_FCEQ_df:
18765        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18766        break;
18767    case OPC_FMUL_df:
18768        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18769        break;
18770    case OPC_FCUNE_df:
18771        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18772        break;
18773    case OPC_FCUEQ_df:
18774        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18775        break;
18776    case OPC_FDIV_df:
18777        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18778        break;
18779    case OPC_FCNE_df:
18780        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18781        break;
18782    case OPC_FCLT_df:
18783        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18784        break;
18785    case OPC_FMADD_df:
18786        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18787        break;
18788    case OPC_MUL_Q_df:
18789        tcg_gen_movi_i32(tdf, df + 1);
18790        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18791        break;
18792    case OPC_FCULT_df:
18793        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18794        break;
18795    case OPC_FMSUB_df:
18796        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18797        break;
18798    case OPC_MADD_Q_df:
18799        tcg_gen_movi_i32(tdf, df + 1);
18800        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18801        break;
18802    case OPC_FCLE_df:
18803        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18804        break;
18805    case OPC_MSUB_Q_df:
18806        tcg_gen_movi_i32(tdf, df + 1);
18807        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18808        break;
18809    case OPC_FCULE_df:
18810        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18811        break;
18812    case OPC_FEXP2_df:
18813        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18814        break;
18815    case OPC_FSAF_df:
18816        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18817        break;
18818    case OPC_FEXDO_df:
18819        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18820        break;
18821    case OPC_FSUN_df:
18822        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18823        break;
18824    case OPC_FSOR_df:
18825        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18826        break;
18827    case OPC_FSEQ_df:
18828        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18829        break;
18830    case OPC_FTQ_df:
18831        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18832        break;
18833    case OPC_FSUNE_df:
18834        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18835        break;
18836    case OPC_FSUEQ_df:
18837        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18838        break;
18839    case OPC_FSNE_df:
18840        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18841        break;
18842    case OPC_FSLT_df:
18843        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18844        break;
18845    case OPC_FMIN_df:
18846        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18847        break;
18848    case OPC_MULR_Q_df:
18849        tcg_gen_movi_i32(tdf, df + 1);
18850        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18851        break;
18852    case OPC_FSULT_df:
18853        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18854        break;
18855    case OPC_FMIN_A_df:
18856        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18857        break;
18858    case OPC_MADDR_Q_df:
18859        tcg_gen_movi_i32(tdf, df + 1);
18860        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18861        break;
18862    case OPC_FSLE_df:
18863        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18864        break;
18865    case OPC_FMAX_df:
18866        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18867        break;
18868    case OPC_MSUBR_Q_df:
18869        tcg_gen_movi_i32(tdf, df + 1);
18870        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18871        break;
18872    case OPC_FSULE_df:
18873        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18874        break;
18875    case OPC_FMAX_A_df:
18876        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18877        break;
18878    default:
18879        MIPS_INVAL("MSA instruction");
18880        generate_exception_end(ctx, EXCP_RI);
18881        break;
18882    }
18883
18884    tcg_temp_free_i32(twd);
18885    tcg_temp_free_i32(tws);
18886    tcg_temp_free_i32(twt);
18887    tcg_temp_free_i32(tdf);
18888}
18889
18890static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18891{
18892#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18893                            (op & (0x7 << 18)))
18894    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18895    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18896    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18897    uint8_t df = (ctx->opcode >> 16) & 0x3;
18898    TCGv_i32 twd = tcg_const_i32(wd);
18899    TCGv_i32 tws = tcg_const_i32(ws);
18900    TCGv_i32 twt = tcg_const_i32(wt);
18901    TCGv_i32 tdf = tcg_const_i32(df);
18902
18903    switch (MASK_MSA_2R(ctx->opcode)) {
18904    case OPC_FILL_df:
18905#if !defined(TARGET_MIPS64)
18906        /* Double format valid only for MIPS64 */
18907        if (df == DF_DOUBLE) {
18908            generate_exception_end(ctx, EXCP_RI);
18909            break;
18910        }
18911#endif
18912        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18913        break;
18914    case OPC_PCNT_df:
18915        gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18916        break;
18917    case OPC_NLOC_df:
18918        gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18919        break;
18920    case OPC_NLZC_df:
18921        gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18922        break;
18923    default:
18924        MIPS_INVAL("MSA instruction");
18925        generate_exception_end(ctx, EXCP_RI);
18926        break;
18927    }
18928
18929    tcg_temp_free_i32(twd);
18930    tcg_temp_free_i32(tws);
18931    tcg_temp_free_i32(twt);
18932    tcg_temp_free_i32(tdf);
18933}
18934
18935static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18936{
18937#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18938                            (op & (0xf << 17)))
18939    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18940    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18941    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18942    uint8_t df = (ctx->opcode >> 16) & 0x1;
18943    TCGv_i32 twd = tcg_const_i32(wd);
18944    TCGv_i32 tws = tcg_const_i32(ws);
18945    TCGv_i32 twt = tcg_const_i32(wt);
18946    /* adjust df value for floating-point instruction */
18947    TCGv_i32 tdf = tcg_const_i32(df + 2);
18948
18949    switch (MASK_MSA_2RF(ctx->opcode)) {
18950    case OPC_FCLASS_df:
18951        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18952        break;
18953    case OPC_FTRUNC_S_df:
18954        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18955        break;
18956    case OPC_FTRUNC_U_df:
18957        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18958        break;
18959    case OPC_FSQRT_df:
18960        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18961        break;
18962    case OPC_FRSQRT_df:
18963        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18964        break;
18965    case OPC_FRCP_df:
18966        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18967        break;
18968    case OPC_FRINT_df:
18969        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18970        break;
18971    case OPC_FLOG2_df:
18972        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18973        break;
18974    case OPC_FEXUPL_df:
18975        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18976        break;
18977    case OPC_FEXUPR_df:
18978        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18979        break;
18980    case OPC_FFQL_df:
18981        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18982        break;
18983    case OPC_FFQR_df:
18984        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18985        break;
18986    case OPC_FTINT_S_df:
18987        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18988        break;
18989    case OPC_FTINT_U_df:
18990        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18991        break;
18992    case OPC_FFINT_S_df:
18993        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18994        break;
18995    case OPC_FFINT_U_df:
18996        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18997        break;
18998    }
18999
19000    tcg_temp_free_i32(twd);
19001    tcg_temp_free_i32(tws);
19002    tcg_temp_free_i32(twt);
19003    tcg_temp_free_i32(tdf);
19004}
19005
19006static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19007{
19008#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19009    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19010    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19011    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19012    TCGv_i32 twd = tcg_const_i32(wd);
19013    TCGv_i32 tws = tcg_const_i32(ws);
19014    TCGv_i32 twt = tcg_const_i32(wt);
19015
19016    switch (MASK_MSA_VEC(ctx->opcode)) {
19017    case OPC_AND_V:
19018        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19019        break;
19020    case OPC_OR_V:
19021        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19022        break;
19023    case OPC_NOR_V:
19024        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19025        break;
19026    case OPC_XOR_V:
19027        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19028        break;
19029    case OPC_BMNZ_V:
19030        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19031        break;
19032    case OPC_BMZ_V:
19033        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19034        break;
19035    case OPC_BSEL_V:
19036        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19037        break;
19038    default:
19039        MIPS_INVAL("MSA instruction");
19040        generate_exception_end(ctx, EXCP_RI);
19041        break;
19042    }
19043
19044    tcg_temp_free_i32(twd);
19045    tcg_temp_free_i32(tws);
19046    tcg_temp_free_i32(twt);
19047}
19048
19049static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19050{
19051    switch (MASK_MSA_VEC(ctx->opcode)) {
19052    case OPC_AND_V:
19053    case OPC_OR_V:
19054    case OPC_NOR_V:
19055    case OPC_XOR_V:
19056    case OPC_BMNZ_V:
19057    case OPC_BMZ_V:
19058    case OPC_BSEL_V:
19059        gen_msa_vec_v(env, ctx);
19060        break;
19061    case OPC_MSA_2R:
19062        gen_msa_2r(env, ctx);
19063        break;
19064    case OPC_MSA_2RF:
19065        gen_msa_2rf(env, ctx);
19066        break;
19067    default:
19068        MIPS_INVAL("MSA instruction");
19069        generate_exception_end(ctx, EXCP_RI);
19070        break;
19071    }
19072}
19073
19074static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19075{
19076    uint32_t opcode = ctx->opcode;
19077    check_insn(ctx, ASE_MSA);
19078    check_msa_access(ctx);
19079
19080    switch (MASK_MSA_MINOR(opcode)) {
19081    case OPC_MSA_I8_00:
19082    case OPC_MSA_I8_01:
19083    case OPC_MSA_I8_02:
19084        gen_msa_i8(env, ctx);
19085        break;
19086    case OPC_MSA_I5_06:
19087    case OPC_MSA_I5_07:
19088        gen_msa_i5(env, ctx);
19089        break;
19090    case OPC_MSA_BIT_09:
19091    case OPC_MSA_BIT_0A:
19092        gen_msa_bit(env, ctx);
19093        break;
19094    case OPC_MSA_3R_0D:
19095    case OPC_MSA_3R_0E:
19096    case OPC_MSA_3R_0F:
19097    case OPC_MSA_3R_10:
19098    case OPC_MSA_3R_11:
19099    case OPC_MSA_3R_12:
19100    case OPC_MSA_3R_13:
19101    case OPC_MSA_3R_14:
19102    case OPC_MSA_3R_15:
19103        gen_msa_3r(env, ctx);
19104        break;
19105    case OPC_MSA_ELM:
19106        gen_msa_elm(env, ctx);
19107        break;
19108    case OPC_MSA_3RF_1A:
19109    case OPC_MSA_3RF_1B:
19110    case OPC_MSA_3RF_1C:
19111        gen_msa_3rf(env, ctx);
19112        break;
19113    case OPC_MSA_VEC:
19114        gen_msa_vec(env, ctx);
19115        break;
19116    case OPC_LD_B:
19117    case OPC_LD_H:
19118    case OPC_LD_W:
19119    case OPC_LD_D:
19120    case OPC_ST_B:
19121    case OPC_ST_H:
19122    case OPC_ST_W:
19123    case OPC_ST_D:
19124        {
19125            int32_t s10 = sextract32(ctx->opcode, 16, 10);
19126            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19127            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19128            uint8_t df = (ctx->opcode >> 0) & 0x3;
19129
19130            TCGv_i32 twd = tcg_const_i32(wd);
19131            TCGv taddr = tcg_temp_new();
19132            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19133
19134            switch (MASK_MSA_MINOR(opcode)) {
19135            case OPC_LD_B:
19136                gen_helper_msa_ld_b(cpu_env, twd, taddr);
19137                break;
19138            case OPC_LD_H:
19139                gen_helper_msa_ld_h(cpu_env, twd, taddr);
19140                break;
19141            case OPC_LD_W:
19142                gen_helper_msa_ld_w(cpu_env, twd, taddr);
19143                break;
19144            case OPC_LD_D:
19145                gen_helper_msa_ld_d(cpu_env, twd, taddr);
19146                break;
19147            case OPC_ST_B:
19148                gen_helper_msa_st_b(cpu_env, twd, taddr);
19149                break;
19150            case OPC_ST_H:
19151                gen_helper_msa_st_h(cpu_env, twd, taddr);
19152                break;
19153            case OPC_ST_W:
19154                gen_helper_msa_st_w(cpu_env, twd, taddr);
19155                break;
19156            case OPC_ST_D:
19157                gen_helper_msa_st_d(cpu_env, twd, taddr);
19158                break;
19159            }
19160
19161            tcg_temp_free_i32(twd);
19162            tcg_temp_free(taddr);
19163        }
19164        break;
19165    default:
19166        MIPS_INVAL("MSA instruction");
19167        generate_exception_end(ctx, EXCP_RI);
19168        break;
19169    }
19170
19171}
19172
19173static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19174{
19175    int32_t offset;
19176    int rs, rt, rd, sa;
19177    uint32_t op, op1;
19178    int16_t imm;
19179
19180    /* make sure instructions are on a word boundary */
19181    if (ctx->pc & 0x3) {
19182        env->CP0_BadVAddr = ctx->pc;
19183        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19184        return;
19185    }
19186
19187    /* Handle blikely not taken case */
19188    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19189        TCGLabel *l1 = gen_new_label();
19190
19191        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19192        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19193        gen_goto_tb(ctx, 1, ctx->pc + 4);
19194        gen_set_label(l1);
19195    }
19196
19197    op = MASK_OP_MAJOR(ctx->opcode);
19198    rs = (ctx->opcode >> 21) & 0x1f;
19199    rt = (ctx->opcode >> 16) & 0x1f;
19200    rd = (ctx->opcode >> 11) & 0x1f;
19201    sa = (ctx->opcode >> 6) & 0x1f;
19202    imm = (int16_t)ctx->opcode;
19203    switch (op) {
19204    case OPC_SPECIAL:
19205        decode_opc_special(env, ctx);
19206        break;
19207    case OPC_SPECIAL2:
19208        decode_opc_special2_legacy(env, ctx);
19209        break;
19210    case OPC_SPECIAL3:
19211        decode_opc_special3(env, ctx);
19212        break;
19213    case OPC_REGIMM:
19214        op1 = MASK_REGIMM(ctx->opcode);
19215        switch (op1) {
19216        case OPC_BLTZL: /* REGIMM branches */
19217        case OPC_BGEZL:
19218        case OPC_BLTZALL:
19219        case OPC_BGEZALL:
19220            check_insn(ctx, ISA_MIPS2);
19221            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19222            /* Fallthrough */
19223        case OPC_BLTZ:
19224        case OPC_BGEZ:
19225            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19226            break;
19227        case OPC_BLTZAL:
19228        case OPC_BGEZAL:
19229            if (ctx->insn_flags & ISA_MIPS32R6) {
19230                if (rs == 0) {
19231                    /* OPC_NAL, OPC_BAL */
19232                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19233                } else {
19234                    generate_exception_end(ctx, EXCP_RI);
19235                }
19236            } else {
19237                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19238            }
19239            break;
19240        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19241        case OPC_TNEI:
19242            check_insn(ctx, ISA_MIPS2);
19243            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19244            gen_trap(ctx, op1, rs, -1, imm);
19245            break;
19246        case OPC_SIGRIE:
19247            check_insn(ctx, ISA_MIPS32R6);
19248            generate_exception_end(ctx, EXCP_RI);
19249            break;
19250        case OPC_SYNCI:
19251            check_insn(ctx, ISA_MIPS32R2);
19252            /* Break the TB to be able to sync copied instructions
19253               immediately */
19254            ctx->bstate = BS_STOP;
19255            break;
19256        case OPC_BPOSGE32:    /* MIPS DSP branch */
19257#if defined(TARGET_MIPS64)
19258        case OPC_BPOSGE64:
19259#endif
19260            check_dsp(ctx);
19261            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19262            break;
19263#if defined(TARGET_MIPS64)
19264        case OPC_DAHI:
19265            check_insn(ctx, ISA_MIPS32R6);
19266            check_mips_64(ctx);
19267            if (rs != 0) {
19268                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19269            }
19270            break;
19271        case OPC_DATI:
19272            check_insn(ctx, ISA_MIPS32R6);
19273            check_mips_64(ctx);
19274            if (rs != 0) {
19275                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19276            }
19277            break;
19278#endif
19279        default:            /* Invalid */
19280            MIPS_INVAL("regimm");
19281            generate_exception_end(ctx, EXCP_RI);
19282            break;
19283        }
19284        break;
19285    case OPC_CP0:
19286        check_cp0_enabled(ctx);
19287        op1 = MASK_CP0(ctx->opcode);
19288        switch (op1) {
19289        case OPC_MFC0:
19290        case OPC_MTC0:
19291        case OPC_MFTR:
19292        case OPC_MTTR:
19293        case OPC_MFHC0:
19294        case OPC_MTHC0:
19295#if defined(TARGET_MIPS64)
19296        case OPC_DMFC0:
19297        case OPC_DMTC0:
19298#endif
19299#ifndef CONFIG_USER_ONLY
19300            gen_cp0(env, ctx, op1, rt, rd);
19301#endif /* !CONFIG_USER_ONLY */
19302            break;
19303        case OPC_C0_FIRST ... OPC_C0_LAST:
19304#ifndef CONFIG_USER_ONLY
19305            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19306#endif /* !CONFIG_USER_ONLY */
19307            break;
19308        case OPC_MFMC0:
19309#ifndef CONFIG_USER_ONLY
19310            {
19311                uint32_t op2;
19312                TCGv t0 = tcg_temp_new();
19313
19314                op2 = MASK_MFMC0(ctx->opcode);
19315                switch (op2) {
19316                case OPC_DMT:
19317                    check_insn(ctx, ASE_MT);
19318                    gen_helper_dmt(t0);
19319                    gen_store_gpr(t0, rt);
19320                    break;
19321                case OPC_EMT:
19322                    check_insn(ctx, ASE_MT);
19323                    gen_helper_emt(t0);
19324                    gen_store_gpr(t0, rt);
19325                    break;
19326                case OPC_DVPE:
19327                    check_insn(ctx, ASE_MT);
19328                    gen_helper_dvpe(t0, cpu_env);
19329                    gen_store_gpr(t0, rt);
19330                    break;
19331                case OPC_EVPE:
19332                    check_insn(ctx, ASE_MT);
19333                    gen_helper_evpe(t0, cpu_env);
19334                    gen_store_gpr(t0, rt);
19335                    break;
19336                case OPC_DVP:
19337                    check_insn(ctx, ISA_MIPS32R6);
19338                    if (ctx->vp) {
19339                        gen_helper_dvp(t0, cpu_env);
19340                        gen_store_gpr(t0, rt);
19341                    }
19342                    break;
19343                case OPC_EVP:
19344                    check_insn(ctx, ISA_MIPS32R6);
19345                    if (ctx->vp) {
19346                        gen_helper_evp(t0, cpu_env);
19347                        gen_store_gpr(t0, rt);
19348                    }
19349                    break;
19350                case OPC_DI:
19351                    check_insn(ctx, ISA_MIPS32R2);
19352                    save_cpu_state(ctx, 1);
19353                    gen_helper_di(t0, cpu_env);
19354                    gen_store_gpr(t0, rt);
19355                    /* Stop translation as we may have switched
19356                       the execution mode.  */
19357                    ctx->bstate = BS_STOP;
19358                    break;
19359                case OPC_EI:
19360                    check_insn(ctx, ISA_MIPS32R2);
19361                    save_cpu_state(ctx, 1);
19362                    gen_helper_ei(t0, cpu_env);
19363                    gen_store_gpr(t0, rt);
19364                    /* Stop translation as we may have switched
19365                       the execution mode.  */
19366                    ctx->bstate = BS_STOP;
19367                    break;
19368                default:            /* Invalid */
19369                    MIPS_INVAL("mfmc0");
19370                    generate_exception_end(ctx, EXCP_RI);
19371                    break;
19372                }
19373                tcg_temp_free(t0);
19374            }
19375#endif /* !CONFIG_USER_ONLY */
19376            break;
19377        case OPC_RDPGPR:
19378            check_insn(ctx, ISA_MIPS32R2);
19379            gen_load_srsgpr(rt, rd);
19380            break;
19381        case OPC_WRPGPR:
19382            check_insn(ctx, ISA_MIPS32R2);
19383            gen_store_srsgpr(rt, rd);
19384            break;
19385        default:
19386            MIPS_INVAL("cp0");
19387            generate_exception_end(ctx, EXCP_RI);
19388            break;
19389        }
19390        break;
19391    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19392        if (ctx->insn_flags & ISA_MIPS32R6) {
19393            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19394            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19395        } else {
19396            /* OPC_ADDI */
19397            /* Arithmetic with immediate opcode */
19398            gen_arith_imm(ctx, op, rt, rs, imm);
19399        }
19400        break;
19401    case OPC_ADDIU:
19402         gen_arith_imm(ctx, op, rt, rs, imm);
19403         break;
19404    case OPC_SLTI: /* Set on less than with immediate opcode */
19405    case OPC_SLTIU:
19406         gen_slt_imm(ctx, op, rt, rs, imm);
19407         break;
19408    case OPC_ANDI: /* Arithmetic with immediate opcode */
19409    case OPC_LUI: /* OPC_AUI */
19410    case OPC_ORI:
19411    case OPC_XORI:
19412         gen_logic_imm(ctx, op, rt, rs, imm);
19413         break;
19414    case OPC_J ... OPC_JAL: /* Jump */
19415         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19416         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19417         break;
19418    /* Branch */
19419    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19420        if (ctx->insn_flags & ISA_MIPS32R6) {
19421            if (rt == 0) {
19422                generate_exception_end(ctx, EXCP_RI);
19423                break;
19424            }
19425            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19426            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19427        } else {
19428            /* OPC_BLEZL */
19429            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19430        }
19431        break;
19432    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19433        if (ctx->insn_flags & ISA_MIPS32R6) {
19434            if (rt == 0) {
19435                generate_exception_end(ctx, EXCP_RI);
19436                break;
19437            }
19438            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19439            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19440        } else {
19441            /* OPC_BGTZL */
19442            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19443        }
19444        break;
19445    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19446        if (rt == 0) {
19447            /* OPC_BLEZ */
19448            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19449        } else {
19450            check_insn(ctx, ISA_MIPS32R6);
19451            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19452            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19453        }
19454        break;
19455    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19456        if (rt == 0) {
19457            /* OPC_BGTZ */
19458            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19459        } else {
19460            check_insn(ctx, ISA_MIPS32R6);
19461            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19462            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19463        }
19464        break;
19465    case OPC_BEQL:
19466    case OPC_BNEL:
19467        check_insn(ctx, ISA_MIPS2);
19468         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19469        /* Fallthrough */
19470    case OPC_BEQ:
19471    case OPC_BNE:
19472         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19473         break;
19474    case OPC_LL: /* Load and stores */
19475        check_insn(ctx, ISA_MIPS2);
19476        /* Fallthrough */
19477    case OPC_LWL:
19478    case OPC_LWR:
19479        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19480         /* Fallthrough */
19481    case OPC_LB ... OPC_LH:
19482    case OPC_LW ... OPC_LHU:
19483         gen_ld(ctx, op, rt, rs, imm);
19484         break;
19485    case OPC_SWL:
19486    case OPC_SWR:
19487        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19488        /* fall through */
19489    case OPC_SB ... OPC_SH:
19490    case OPC_SW:
19491         gen_st(ctx, op, rt, rs, imm);
19492         break;
19493    case OPC_SC:
19494        check_insn(ctx, ISA_MIPS2);
19495         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19496         gen_st_cond(ctx, op, rt, rs, imm);
19497         break;
19498    case OPC_CACHE:
19499        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19500        check_cp0_enabled(ctx);
19501        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19502        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19503            gen_cache_operation(ctx, rt, rs, imm);
19504        }
19505        /* Treat as NOP. */
19506        break;
19507    case OPC_PREF:
19508        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19509        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19510        /* Treat as NOP. */
19511        break;
19512
19513    /* Floating point (COP1). */
19514    case OPC_LWC1:
19515    case OPC_LDC1:
19516    case OPC_SWC1:
19517    case OPC_SDC1:
19518        gen_cop1_ldst(ctx, op, rt, rs, imm);
19519        break;
19520
19521    case OPC_CP1:
19522        op1 = MASK_CP1(ctx->opcode);
19523
19524        switch (op1) {
19525        case OPC_MFHC1:
19526        case OPC_MTHC1:
19527            check_cp1_enabled(ctx);
19528            check_insn(ctx, ISA_MIPS32R2);
19529        case OPC_MFC1:
19530        case OPC_CFC1:
19531        case OPC_MTC1:
19532        case OPC_CTC1:
19533            check_cp1_enabled(ctx);
19534            gen_cp1(ctx, op1, rt, rd);
19535            break;
19536#if defined(TARGET_MIPS64)
19537        case OPC_DMFC1:
19538        case OPC_DMTC1:
19539            check_cp1_enabled(ctx);
19540            check_insn(ctx, ISA_MIPS3);
19541            check_mips_64(ctx);
19542            gen_cp1(ctx, op1, rt, rd);
19543            break;
19544#endif
19545        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19546            check_cp1_enabled(ctx);
19547            if (ctx->insn_flags & ISA_MIPS32R6) {
19548                /* OPC_BC1EQZ */
19549                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19550                                       rt, imm << 2, 4);
19551            } else {
19552                /* OPC_BC1ANY2 */
19553                check_cop1x(ctx);
19554                check_insn(ctx, ASE_MIPS3D);
19555                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19556                                    (rt >> 2) & 0x7, imm << 2);
19557            }
19558            break;
19559        case OPC_BC1NEZ:
19560            check_cp1_enabled(ctx);
19561            check_insn(ctx, ISA_MIPS32R6);
19562            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19563                                   rt, imm << 2, 4);
19564            break;
19565        case OPC_BC1ANY4:
19566            check_cp1_enabled(ctx);
19567            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19568            check_cop1x(ctx);
19569            check_insn(ctx, ASE_MIPS3D);
19570            /* fall through */
19571        case OPC_BC1:
19572            check_cp1_enabled(ctx);
19573            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19574            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19575                                (rt >> 2) & 0x7, imm << 2);
19576            break;
19577        case OPC_PS_FMT:
19578            check_ps(ctx);
19579            /* fall through */
19580        case OPC_S_FMT:
19581        case OPC_D_FMT:
19582            check_cp1_enabled(ctx);
19583            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19584                       (imm >> 8) & 0x7);
19585            break;
19586        case OPC_W_FMT:
19587        case OPC_L_FMT:
19588        {
19589            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19590            check_cp1_enabled(ctx);
19591            if (ctx->insn_flags & ISA_MIPS32R6) {
19592                switch (r6_op) {
19593                case R6_OPC_CMP_AF_S:
19594                case R6_OPC_CMP_UN_S:
19595                case R6_OPC_CMP_EQ_S:
19596                case R6_OPC_CMP_UEQ_S:
19597                case R6_OPC_CMP_LT_S:
19598                case R6_OPC_CMP_ULT_S:
19599                case R6_OPC_CMP_LE_S:
19600                case R6_OPC_CMP_ULE_S:
19601                case R6_OPC_CMP_SAF_S:
19602                case R6_OPC_CMP_SUN_S:
19603                case R6_OPC_CMP_SEQ_S:
19604                case R6_OPC_CMP_SEUQ_S:
19605                case R6_OPC_CMP_SLT_S:
19606                case R6_OPC_CMP_SULT_S:
19607                case R6_OPC_CMP_SLE_S:
19608                case R6_OPC_CMP_SULE_S:
19609                case R6_OPC_CMP_OR_S:
19610                case R6_OPC_CMP_UNE_S:
19611                case R6_OPC_CMP_NE_S:
19612                case R6_OPC_CMP_SOR_S:
19613                case R6_OPC_CMP_SUNE_S:
19614                case R6_OPC_CMP_SNE_S:
19615                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19616                    break;
19617                case R6_OPC_CMP_AF_D:
19618                case R6_OPC_CMP_UN_D:
19619                case R6_OPC_CMP_EQ_D:
19620                case R6_OPC_CMP_UEQ_D:
19621                case R6_OPC_CMP_LT_D:
19622                case R6_OPC_CMP_ULT_D:
19623                case R6_OPC_CMP_LE_D:
19624                case R6_OPC_CMP_ULE_D:
19625                case R6_OPC_CMP_SAF_D:
19626                case R6_OPC_CMP_SUN_D:
19627                case R6_OPC_CMP_SEQ_D:
19628                case R6_OPC_CMP_SEUQ_D:
19629                case R6_OPC_CMP_SLT_D:
19630                case R6_OPC_CMP_SULT_D:
19631                case R6_OPC_CMP_SLE_D:
19632                case R6_OPC_CMP_SULE_D:
19633                case R6_OPC_CMP_OR_D:
19634                case R6_OPC_CMP_UNE_D:
19635                case R6_OPC_CMP_NE_D:
19636                case R6_OPC_CMP_SOR_D:
19637                case R6_OPC_CMP_SUNE_D:
19638                case R6_OPC_CMP_SNE_D:
19639                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19640                    break;
19641                default:
19642                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19643                               rt, rd, sa, (imm >> 8) & 0x7);
19644
19645                    break;
19646                }
19647            } else {
19648                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19649                           (imm >> 8) & 0x7);
19650            }
19651            break;
19652        }
19653        case OPC_BZ_V:
19654        case OPC_BNZ_V:
19655        case OPC_BZ_B:
19656        case OPC_BZ_H:
19657        case OPC_BZ_W:
19658        case OPC_BZ_D:
19659        case OPC_BNZ_B:
19660        case OPC_BNZ_H:
19661        case OPC_BNZ_W:
19662        case OPC_BNZ_D:
19663            check_insn(ctx, ASE_MSA);
19664            gen_msa_branch(env, ctx, op1);
19665            break;
19666        default:
19667            MIPS_INVAL("cp1");
19668            generate_exception_end(ctx, EXCP_RI);
19669            break;
19670        }
19671        break;
19672
19673    /* Compact branches [R6] and COP2 [non-R6] */
19674    case OPC_BC: /* OPC_LWC2 */
19675    case OPC_BALC: /* OPC_SWC2 */
19676        if (ctx->insn_flags & ISA_MIPS32R6) {
19677            /* OPC_BC, OPC_BALC */
19678            gen_compute_compact_branch(ctx, op, 0, 0,
19679                                       sextract32(ctx->opcode << 2, 0, 28));
19680        } else {
19681            /* OPC_LWC2, OPC_SWC2 */
19682            /* COP2: Not implemented. */
19683            generate_exception_err(ctx, EXCP_CpU, 2);
19684        }
19685        break;
19686    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19687    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19688        if (ctx->insn_flags & ISA_MIPS32R6) {
19689            if (rs != 0) {
19690                /* OPC_BEQZC, OPC_BNEZC */
19691                gen_compute_compact_branch(ctx, op, rs, 0,
19692                                           sextract32(ctx->opcode << 2, 0, 23));
19693            } else {
19694                /* OPC_JIC, OPC_JIALC */
19695                gen_compute_compact_branch(ctx, op, 0, rt, imm);
19696            }
19697        } else {
19698            /* OPC_LWC2, OPC_SWC2 */
19699            /* COP2: Not implemented. */
19700            generate_exception_err(ctx, EXCP_CpU, 2);
19701        }
19702        break;
19703    case OPC_CP2:
19704        check_insn(ctx, INSN_LOONGSON2F);
19705        /* Note that these instructions use different fields.  */
19706        gen_loongson_multimedia(ctx, sa, rd, rt);
19707        break;
19708
19709    case OPC_CP3:
19710        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19711        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19712            check_cp1_enabled(ctx);
19713            op1 = MASK_CP3(ctx->opcode);
19714            switch (op1) {
19715            case OPC_LUXC1:
19716            case OPC_SUXC1:
19717                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19718                /* Fallthrough */
19719            case OPC_LWXC1:
19720            case OPC_LDXC1:
19721            case OPC_SWXC1:
19722            case OPC_SDXC1:
19723                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19724                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19725                break;
19726            case OPC_PREFX:
19727                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19728                /* Treat as NOP. */
19729                break;
19730            case OPC_ALNV_PS:
19731                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19732                /* Fallthrough */
19733            case OPC_MADD_S:
19734            case OPC_MADD_D:
19735            case OPC_MADD_PS:
19736            case OPC_MSUB_S:
19737            case OPC_MSUB_D:
19738            case OPC_MSUB_PS:
19739            case OPC_NMADD_S:
19740            case OPC_NMADD_D:
19741            case OPC_NMADD_PS:
19742            case OPC_NMSUB_S:
19743            case OPC_NMSUB_D:
19744            case OPC_NMSUB_PS:
19745                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19746                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19747                break;
19748            default:
19749                MIPS_INVAL("cp3");
19750                generate_exception_end(ctx, EXCP_RI);
19751                break;
19752            }
19753        } else {
19754            generate_exception_err(ctx, EXCP_CpU, 1);
19755        }
19756        break;
19757
19758#if defined(TARGET_MIPS64)
19759    /* MIPS64 opcodes */
19760    case OPC_LDL ... OPC_LDR:
19761    case OPC_LLD:
19762        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19763        /* fall through */
19764    case OPC_LWU:
19765    case OPC_LD:
19766        check_insn(ctx, ISA_MIPS3);
19767        check_mips_64(ctx);
19768        gen_ld(ctx, op, rt, rs, imm);
19769        break;
19770    case OPC_SDL ... OPC_SDR:
19771        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19772        /* fall through */
19773    case OPC_SD:
19774        check_insn(ctx, ISA_MIPS3);
19775        check_mips_64(ctx);
19776        gen_st(ctx, op, rt, rs, imm);
19777        break;
19778    case OPC_SCD:
19779        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19780        check_insn(ctx, ISA_MIPS3);
19781        check_mips_64(ctx);
19782        gen_st_cond(ctx, op, rt, rs, imm);
19783        break;
19784    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19785        if (ctx->insn_flags & ISA_MIPS32R6) {
19786            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19787            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19788        } else {
19789            /* OPC_DADDI */
19790            check_insn(ctx, ISA_MIPS3);
19791            check_mips_64(ctx);
19792            gen_arith_imm(ctx, op, rt, rs, imm);
19793        }
19794        break;
19795    case OPC_DADDIU:
19796        check_insn(ctx, ISA_MIPS3);
19797        check_mips_64(ctx);
19798        gen_arith_imm(ctx, op, rt, rs, imm);
19799        break;
19800#else
19801    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19802        if (ctx->insn_flags & ISA_MIPS32R6) {
19803            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19804        } else {
19805            MIPS_INVAL("major opcode");
19806            generate_exception_end(ctx, EXCP_RI);
19807        }
19808        break;
19809#endif
19810    case OPC_DAUI: /* OPC_JALX */
19811        if (ctx->insn_flags & ISA_MIPS32R6) {
19812#if defined(TARGET_MIPS64)
19813            /* OPC_DAUI */
19814            check_mips_64(ctx);
19815            if (rs == 0) {
19816                generate_exception(ctx, EXCP_RI);
19817            } else if (rt != 0) {
19818                TCGv t0 = tcg_temp_new();
19819                gen_load_gpr(t0, rs);
19820                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19821                tcg_temp_free(t0);
19822            }
19823#else
19824            generate_exception_end(ctx, EXCP_RI);
19825            MIPS_INVAL("major opcode");
19826#endif
19827        } else {
19828            /* OPC_JALX */
19829            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19830            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19831            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19832        }
19833        break;
19834    case OPC_MSA: /* OPC_MDMX */
19835        /* MDMX: Not implemented. */
19836        gen_msa(env, ctx);
19837        break;
19838    case OPC_PCREL:
19839        check_insn(ctx, ISA_MIPS32R6);
19840        gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19841        break;
19842    default:            /* Invalid */
19843        MIPS_INVAL("major opcode");
19844        generate_exception_end(ctx, EXCP_RI);
19845        break;
19846    }
19847}
19848
19849void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19850{
19851    MIPSCPU *cpu = mips_env_get_cpu(env);
19852    CPUState *cs = CPU(cpu);
19853    DisasContext ctx;
19854    target_ulong pc_start;
19855    target_ulong next_page_start;
19856    int num_insns;
19857    int max_insns;
19858    int insn_bytes;
19859    int is_slot;
19860
19861    pc_start = tb->pc;
19862    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19863    ctx.pc = pc_start;
19864    ctx.saved_pc = -1;
19865    ctx.singlestep_enabled = cs->singlestep_enabled;
19866    ctx.insn_flags = env->insn_flags;
19867    ctx.CP0_Config1 = env->CP0_Config1;
19868    ctx.tb = tb;
19869    ctx.bstate = BS_NONE;
19870    ctx.btarget = 0;
19871    ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19872    ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19873    ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19874    ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19875    ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19876    ctx.PAMask = env->PAMask;
19877    ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19878    ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19879    ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
19880    /* Restore delay slot state from the tb context.  */
19881    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19882    ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19883    ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19884             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19885    ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
19886    ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
19887    ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
19888    ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
19889    restore_cpu_state(env, &ctx);
19890#ifdef CONFIG_USER_ONLY
19891        ctx.mem_idx = MIPS_HFLAG_UM;
19892#else
19893        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19894#endif
19895    ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19896                                 MO_UNALN : MO_ALIGN;
19897    num_insns = 0;
19898    max_insns = tb->cflags & CF_COUNT_MASK;
19899    if (max_insns == 0) {
19900        max_insns = CF_COUNT_MASK;
19901    }
19902    if (max_insns > TCG_MAX_INSNS) {
19903        max_insns = TCG_MAX_INSNS;
19904    }
19905
19906    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19907    gen_tb_start(tb);
19908    while (ctx.bstate == BS_NONE) {
19909        tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19910        num_insns++;
19911
19912        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19913            save_cpu_state(&ctx, 1);
19914            ctx.bstate = BS_BRANCH;
19915            gen_helper_raise_exception_debug(cpu_env);
19916            /* The address covered by the breakpoint must be included in
19917               [tb->pc, tb->pc + tb->size) in order to for it to be
19918               properly cleared -- thus we increment the PC here so that
19919               the logic setting tb->size below does the right thing.  */
19920            ctx.pc += 4;
19921            goto done_generating;
19922        }
19923
19924        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19925            gen_io_start();
19926        }
19927
19928        is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19929        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19930            ctx.opcode = cpu_ldl_code(env, ctx.pc);
19931            insn_bytes = 4;
19932            decode_opc(env, &ctx);
19933        } else if (ctx.insn_flags & ASE_MICROMIPS) {
19934            ctx.opcode = cpu_lduw_code(env, ctx.pc);
19935            insn_bytes = decode_micromips_opc(env, &ctx);
19936        } else if (ctx.insn_flags & ASE_MIPS16) {
19937            ctx.opcode = cpu_lduw_code(env, ctx.pc);
19938            insn_bytes = decode_mips16_opc(env, &ctx);
19939        } else {
19940            generate_exception_end(&ctx, EXCP_RI);
19941            break;
19942        }
19943
19944        if (ctx.hflags & MIPS_HFLAG_BMASK) {
19945            if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19946                                MIPS_HFLAG_FBNSLOT))) {
19947                /* force to generate branch as there is neither delay nor
19948                   forbidden slot */
19949                is_slot = 1;
19950            }
19951            if ((ctx.hflags & MIPS_HFLAG_M16) &&
19952                (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19953                /* Force to generate branch as microMIPS R6 doesn't restrict
19954                   branches in the forbidden slot. */
19955                is_slot = 1;
19956            }
19957        }
19958        if (is_slot) {
19959            gen_branch(&ctx, insn_bytes);
19960        }
19961        ctx.pc += insn_bytes;
19962
19963        /* Execute a branch and its delay slot as a single instruction.
19964           This is what GDB expects and is consistent with what the
19965           hardware does (e.g. if a delay slot instruction faults, the
19966           reported PC is the PC of the branch).  */
19967        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19968            break;
19969        }
19970
19971        if (ctx.pc >= next_page_start) {
19972            break;
19973        }
19974
19975        if (tcg_op_buf_full()) {
19976            break;
19977        }
19978
19979        if (num_insns >= max_insns)
19980            break;
19981
19982        if (singlestep)
19983            break;
19984    }
19985    if (tb->cflags & CF_LAST_IO) {
19986        gen_io_end();
19987    }
19988    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19989        save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19990        gen_helper_raise_exception_debug(cpu_env);
19991    } else {
19992        switch (ctx.bstate) {
19993        case BS_STOP:
19994            gen_goto_tb(&ctx, 0, ctx.pc);
19995            break;
19996        case BS_NONE:
19997            save_cpu_state(&ctx, 0);
19998            gen_goto_tb(&ctx, 0, ctx.pc);
19999            break;
20000        case BS_EXCP:
20001            tcg_gen_exit_tb(0);
20002            break;
20003        case BS_BRANCH:
20004        default:
20005            break;
20006        }
20007    }
20008done_generating:
20009    gen_tb_end(tb, num_insns);
20010
20011    tb->size = ctx.pc - pc_start;
20012    tb->icount = num_insns;
20013
20014#ifdef DEBUG_DISAS
20015    LOG_DISAS("\n");
20016    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20017        && qemu_log_in_addr_range(pc_start)) {
20018        qemu_log("IN: %s\n", lookup_symbol(pc_start));
20019        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
20020        qemu_log("\n");
20021    }
20022#endif
20023}
20024
20025static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
20026                           int flags)
20027{
20028    int i;
20029    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
20030
20031#define printfpr(fp)                                                    \
20032    do {                                                                \
20033        if (is_fpu64)                                                   \
20034            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
20035                        " fd:%13g fs:%13g psu: %13g\n",                 \
20036                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
20037                        (double)(fp)->fd,                               \
20038                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
20039                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
20040        else {                                                          \
20041            fpr_t tmp;                                                  \
20042            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
20043            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
20044            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
20045                        " fd:%13g fs:%13g psu:%13g\n",                  \
20046                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
20047                        (double)tmp.fd,                                 \
20048                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
20049                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
20050        }                                                               \
20051    } while(0)
20052
20053
20054    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
20055                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
20056                get_float_exception_flags(&env->active_fpu.fp_status));
20057    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20058        fpu_fprintf(f, "%3s: ", fregnames[i]);
20059        printfpr(&env->active_fpu.fpr[i]);
20060    }
20061
20062#undef printfpr
20063}
20064
20065void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20066                         int flags)
20067{
20068    MIPSCPU *cpu = MIPS_CPU(cs);
20069    CPUMIPSState *env = &cpu->env;
20070    int i;
20071
20072    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20073                " LO=0x" TARGET_FMT_lx " ds %04x "
20074                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
20075                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20076                env->hflags, env->btarget, env->bcond);
20077    for (i = 0; i < 32; i++) {
20078        if ((i & 3) == 0)
20079            cpu_fprintf(f, "GPR%02d:", i);
20080        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
20081        if ((i & 3) == 3)
20082            cpu_fprintf(f, "\n");
20083    }
20084
20085    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
20086                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
20087    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20088                PRIx64 "\n",
20089                env->CP0_Config0, env->CP0_Config1, env->lladdr);
20090    cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
20091                env->CP0_Config2, env->CP0_Config3);
20092    cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
20093                env->CP0_Config4, env->CP0_Config5);
20094    if (env->hflags & MIPS_HFLAG_FPU)
20095        fpu_dump_state(env, f, cpu_fprintf, flags);
20096}
20097
20098void mips_tcg_init(void)
20099{
20100    int i;
20101    static int inited;
20102
20103    /* Initialize various static tables. */
20104    if (inited)
20105        return;
20106
20107    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
20108    tcg_ctx.tcg_env = cpu_env;
20109
20110    TCGV_UNUSED(cpu_gpr[0]);
20111    for (i = 1; i < 32; i++)
20112        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20113                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
20114                                        regnames[i]);
20115
20116    for (i = 0; i < 32; i++) {
20117        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20118        msa_wr_d[i * 2] =
20119                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20120        /* The scalar floating-point unit (FPU) registers are mapped on
20121         * the MSA vector registers. */
20122        fpu_f64[i] = msa_wr_d[i * 2];
20123        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20124        msa_wr_d[i * 2 + 1] =
20125                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20126    }
20127
20128    cpu_PC = tcg_global_mem_new(cpu_env,
20129                                offsetof(CPUMIPSState, active_tc.PC), "PC");
20130    for (i = 0; i < MIPS_DSP_ACC; i++) {
20131        cpu_HI[i] = tcg_global_mem_new(cpu_env,
20132                                       offsetof(CPUMIPSState, active_tc.HI[i]),
20133                                       regnames_HI[i]);
20134        cpu_LO[i] = tcg_global_mem_new(cpu_env,
20135                                       offsetof(CPUMIPSState, active_tc.LO[i]),
20136                                       regnames_LO[i]);
20137    }
20138    cpu_dspctrl = tcg_global_mem_new(cpu_env,
20139                                     offsetof(CPUMIPSState, active_tc.DSPControl),
20140                                     "DSPControl");
20141    bcond = tcg_global_mem_new(cpu_env,
20142                               offsetof(CPUMIPSState, bcond), "bcond");
20143    btarget = tcg_global_mem_new(cpu_env,
20144                                 offsetof(CPUMIPSState, btarget), "btarget");
20145    hflags = tcg_global_mem_new_i32(cpu_env,
20146                                    offsetof(CPUMIPSState, hflags), "hflags");
20147
20148    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20149                                      offsetof(CPUMIPSState, active_fpu.fcr0),
20150                                      "fcr0");
20151    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20152                                       offsetof(CPUMIPSState, active_fpu.fcr31),
20153                                       "fcr31");
20154
20155    inited = 1;
20156}
20157
20158#include "translate_init.c"
20159
20160MIPSCPU *cpu_mips_init(const char *cpu_model)
20161{
20162    MIPSCPU *cpu;
20163    CPUMIPSState *env;
20164    const mips_def_t *def;
20165
20166    def = cpu_mips_find_by_name(cpu_model);
20167    if (!def)
20168        return NULL;
20169    cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20170    env = &cpu->env;
20171    env->cpu_model = def;
20172    env->exception_base = (int32_t)0xBFC00000;
20173
20174#ifndef CONFIG_USER_ONLY
20175    mmu_init(env, def);
20176#endif
20177    fpu_init(env, def);
20178    mvp_init(env, def);
20179
20180    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20181
20182    return cpu;
20183}
20184
20185bool cpu_supports_cps_smp(const char *cpu_model)
20186{
20187    const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20188    if (!def) {
20189        return false;
20190    }
20191
20192    return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20193}
20194
20195void cpu_set_exception_base(int vp_index, target_ulong address)
20196{
20197    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20198    vp->env.exception_base = address;
20199}
20200
20201void cpu_state_reset(CPUMIPSState *env)
20202{
20203    MIPSCPU *cpu = mips_env_get_cpu(env);
20204    CPUState *cs = CPU(cpu);
20205
20206    /* Reset registers to their default values */
20207    env->CP0_PRid = env->cpu_model->CP0_PRid;
20208    env->CP0_Config0 = env->cpu_model->CP0_Config0;
20209#ifdef TARGET_WORDS_BIGENDIAN
20210    env->CP0_Config0 |= (1 << CP0C0_BE);
20211#endif
20212    env->CP0_Config1 = env->cpu_model->CP0_Config1;
20213    env->CP0_Config2 = env->cpu_model->CP0_Config2;
20214    env->CP0_Config3 = env->cpu_model->CP0_Config3;
20215    env->CP0_Config4 = env->cpu_model->CP0_Config4;
20216    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20217    env->CP0_Config5 = env->cpu_model->CP0_Config5;
20218    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20219    env->CP0_Config6 = env->cpu_model->CP0_Config6;
20220    env->CP0_Config7 = env->cpu_model->CP0_Config7;
20221    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20222                                 << env->cpu_model->CP0_LLAddr_shift;
20223    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20224    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20225    env->CCRes = env->cpu_model->CCRes;
20226    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20227    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20228    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20229    env->current_tc = 0;
20230    env->SEGBITS = env->cpu_model->SEGBITS;
20231    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20232#if defined(TARGET_MIPS64)
20233    if (env->cpu_model->insn_flags & ISA_MIPS3) {
20234        env->SEGMask |= 3ULL << 62;
20235    }
20236#endif
20237    env->PABITS = env->cpu_model->PABITS;
20238    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20239    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20240    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20241    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20242    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20243    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20244    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20245    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20246    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20247    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20248    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20249    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20250    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20251    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
20252    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20253    env->msair = env->cpu_model->MSAIR;
20254    env->insn_flags = env->cpu_model->insn_flags;
20255
20256#if defined(CONFIG_USER_ONLY)
20257    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20258# ifdef TARGET_MIPS64
20259    /* Enable 64-bit register mode.  */
20260    env->CP0_Status |= (1 << CP0St_PX);
20261# endif
20262# ifdef TARGET_ABI_MIPSN64
20263    /* Enable 64-bit address mode.  */
20264    env->CP0_Status |= (1 << CP0St_UX);
20265# endif
20266    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20267       hardware registers.  */
20268    env->CP0_HWREna |= 0x0000000F;
20269    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20270        env->CP0_Status |= (1 << CP0St_CU1);
20271    }
20272    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20273        env->CP0_Status |= (1 << CP0St_MX);
20274    }
20275# if defined(TARGET_MIPS64)
20276    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20277    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20278        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20279        env->CP0_Status |= (1 << CP0St_FR);
20280    }
20281# endif
20282#else
20283    if (env->hflags & MIPS_HFLAG_BMASK) {
20284        /* If the exception was raised from a delay slot,
20285           come back to the jump.  */
20286        env->CP0_ErrorEPC = (env->active_tc.PC
20287                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20288    } else {
20289        env->CP0_ErrorEPC = env->active_tc.PC;
20290    }
20291    env->active_tc.PC = env->exception_base;
20292    env->CP0_Random = env->tlb->nb_tlb - 1;
20293    env->tlb->tlb_in_use = env->tlb->nb_tlb;
20294    env->CP0_Wired = 0;
20295    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20296    env->CP0_EBase = (cs->cpu_index & 0x3FF);
20297    if (kvm_enabled()) {
20298        env->CP0_EBase |= 0x40000000;
20299    } else {
20300        env->CP0_EBase |= 0x80000000;
20301    }
20302    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20303        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20304    }
20305    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20306                                 0x3ff : 0xff;
20307    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20308    /* vectored interrupts not implemented, timer on int 7,
20309       no performance counters. */
20310    env->CP0_IntCtl = 0xe0000000;
20311    {
20312        int i;
20313
20314        for (i = 0; i < 7; i++) {
20315            env->CP0_WatchLo[i] = 0;
20316            env->CP0_WatchHi[i] = 0x80000000;
20317        }
20318        env->CP0_WatchLo[7] = 0;
20319        env->CP0_WatchHi[7] = 0;
20320    }
20321    /* Count register increments in debug mode, EJTAG version 1 */
20322    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20323
20324    cpu_mips_store_count(env, 1);
20325
20326    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20327        int i;
20328
20329        /* Only TC0 on VPE 0 starts as active.  */
20330        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20331            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20332            env->tcs[i].CP0_TCHalt = 1;
20333        }
20334        env->active_tc.CP0_TCHalt = 1;
20335        cs->halted = 1;
20336
20337        if (cs->cpu_index == 0) {
20338            /* VPE0 starts up enabled.  */
20339            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20340            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20341
20342            /* TC0 starts up unhalted.  */
20343            cs->halted = 0;
20344            env->active_tc.CP0_TCHalt = 0;
20345            env->tcs[0].CP0_TCHalt = 0;
20346            /* With thread 0 active.  */
20347            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20348            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20349        }
20350    }
20351#endif
20352    if ((env->insn_flags & ISA_MIPS32R6) &&
20353        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20354        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20355        env->CP0_Status |= (1 << CP0St_FR);
20356    }
20357
20358    /* MSA */
20359    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20360        msa_reset(env);
20361    }
20362
20363    compute_hflags(env);
20364    restore_fp_status(env);
20365    restore_pamask(env);
20366    cs->exception_index = EXCP_NONE;
20367
20368    if (semihosting_get_argc()) {
20369        /* UHI interface can be used to obtain argc and argv */
20370        env->active_tc.gpr[4] = -1;
20371    }
20372}
20373
20374void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20375                          target_ulong *data)
20376{
20377    env->active_tc.PC = data[0];
20378    env->hflags &= ~MIPS_HFLAG_BMASK;
20379    env->hflags |= data[1];
20380    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20381    case MIPS_HFLAG_BR:
20382        break;
20383    case MIPS_HFLAG_BC:
20384    case MIPS_HFLAG_BL:
20385    case MIPS_HFLAG_B:
20386        env->btarget = data[2];
20387        break;
20388    }
20389}
20390