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    check_cp1_enabled(ctx);
3875    gen_load_fpr64(ctx, t0, rs);
3876    gen_load_fpr64(ctx, t1, rt);
3877
3878#define LMI_HELPER(UP, LO) \
3879    case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3880#define LMI_HELPER_1(UP, LO) \
3881    case OPC_##UP: gen_helper_##LO(t0, t0); break
3882#define LMI_DIRECT(UP, LO, OP) \
3883    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3884
3885    switch (opc) {
3886    LMI_HELPER(PADDSH, paddsh);
3887    LMI_HELPER(PADDUSH, paddush);
3888    LMI_HELPER(PADDH, paddh);
3889    LMI_HELPER(PADDW, paddw);
3890    LMI_HELPER(PADDSB, paddsb);
3891    LMI_HELPER(PADDUSB, paddusb);
3892    LMI_HELPER(PADDB, paddb);
3893
3894    LMI_HELPER(PSUBSH, psubsh);
3895    LMI_HELPER(PSUBUSH, psubush);
3896    LMI_HELPER(PSUBH, psubh);
3897    LMI_HELPER(PSUBW, psubw);
3898    LMI_HELPER(PSUBSB, psubsb);
3899    LMI_HELPER(PSUBUSB, psubusb);
3900    LMI_HELPER(PSUBB, psubb);
3901
3902    LMI_HELPER(PSHUFH, pshufh);
3903    LMI_HELPER(PACKSSWH, packsswh);
3904    LMI_HELPER(PACKSSHB, packsshb);
3905    LMI_HELPER(PACKUSHB, packushb);
3906
3907    LMI_HELPER(PUNPCKLHW, punpcklhw);
3908    LMI_HELPER(PUNPCKHHW, punpckhhw);
3909    LMI_HELPER(PUNPCKLBH, punpcklbh);
3910    LMI_HELPER(PUNPCKHBH, punpckhbh);
3911    LMI_HELPER(PUNPCKLWD, punpcklwd);
3912    LMI_HELPER(PUNPCKHWD, punpckhwd);
3913
3914    LMI_HELPER(PAVGH, pavgh);
3915    LMI_HELPER(PAVGB, pavgb);
3916    LMI_HELPER(PMAXSH, pmaxsh);
3917    LMI_HELPER(PMINSH, pminsh);
3918    LMI_HELPER(PMAXUB, pmaxub);
3919    LMI_HELPER(PMINUB, pminub);
3920
3921    LMI_HELPER(PCMPEQW, pcmpeqw);
3922    LMI_HELPER(PCMPGTW, pcmpgtw);
3923    LMI_HELPER(PCMPEQH, pcmpeqh);
3924    LMI_HELPER(PCMPGTH, pcmpgth);
3925    LMI_HELPER(PCMPEQB, pcmpeqb);
3926    LMI_HELPER(PCMPGTB, pcmpgtb);
3927
3928    LMI_HELPER(PSLLW, psllw);
3929    LMI_HELPER(PSLLH, psllh);
3930    LMI_HELPER(PSRLW, psrlw);
3931    LMI_HELPER(PSRLH, psrlh);
3932    LMI_HELPER(PSRAW, psraw);
3933    LMI_HELPER(PSRAH, psrah);
3934
3935    LMI_HELPER(PMULLH, pmullh);
3936    LMI_HELPER(PMULHH, pmulhh);
3937    LMI_HELPER(PMULHUH, pmulhuh);
3938    LMI_HELPER(PMADDHW, pmaddhw);
3939
3940    LMI_HELPER(PASUBUB, pasubub);
3941    LMI_HELPER_1(BIADD, biadd);
3942    LMI_HELPER_1(PMOVMSKB, pmovmskb);
3943
3944    LMI_DIRECT(PADDD, paddd, add);
3945    LMI_DIRECT(PSUBD, psubd, sub);
3946    LMI_DIRECT(XOR_CP2, xor, xor);
3947    LMI_DIRECT(NOR_CP2, nor, nor);
3948    LMI_DIRECT(AND_CP2, and, and);
3949    LMI_DIRECT(OR_CP2, or, or);
3950
3951    case OPC_PANDN:
3952        tcg_gen_andc_i64(t0, t1, t0);
3953        break;
3954
3955    case OPC_PINSRH_0:
3956        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3957        break;
3958    case OPC_PINSRH_1:
3959        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3960        break;
3961    case OPC_PINSRH_2:
3962        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3963        break;
3964    case OPC_PINSRH_3:
3965        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3966        break;
3967
3968    case OPC_PEXTRH:
3969        tcg_gen_andi_i64(t1, t1, 3);
3970        tcg_gen_shli_i64(t1, t1, 4);
3971        tcg_gen_shr_i64(t0, t0, t1);
3972        tcg_gen_ext16u_i64(t0, t0);
3973        break;
3974
3975    case OPC_ADDU_CP2:
3976        tcg_gen_add_i64(t0, t0, t1);
3977        tcg_gen_ext32s_i64(t0, t0);
3978        break;
3979    case OPC_SUBU_CP2:
3980        tcg_gen_sub_i64(t0, t0, t1);
3981        tcg_gen_ext32s_i64(t0, t0);
3982        break;
3983
3984    case OPC_SLL_CP2:
3985        shift_max = 32;
3986        goto do_shift;
3987    case OPC_SRL_CP2:
3988        shift_max = 32;
3989        goto do_shift;
3990    case OPC_SRA_CP2:
3991        shift_max = 32;
3992        goto do_shift;
3993    case OPC_DSLL_CP2:
3994        shift_max = 64;
3995        goto do_shift;
3996    case OPC_DSRL_CP2:
3997        shift_max = 64;
3998        goto do_shift;
3999    case OPC_DSRA_CP2:
4000        shift_max = 64;
4001        goto do_shift;
4002    do_shift:
4003        /* Make sure shift count isn't TCG undefined behaviour.  */
4004        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4005
4006        switch (opc) {
4007        case OPC_SLL_CP2:
4008        case OPC_DSLL_CP2:
4009            tcg_gen_shl_i64(t0, t0, t1);
4010            break;
4011        case OPC_SRA_CP2:
4012        case OPC_DSRA_CP2:
4013            /* Since SRA is UndefinedResult without sign-extended inputs,
4014               we can treat SRA and DSRA the same.  */
4015            tcg_gen_sar_i64(t0, t0, t1);
4016            break;
4017        case OPC_SRL_CP2:
4018            /* We want to shift in zeros for SRL; zero-extend first.  */
4019            tcg_gen_ext32u_i64(t0, t0);
4020            /* FALLTHRU */
4021        case OPC_DSRL_CP2:
4022            tcg_gen_shr_i64(t0, t0, t1);
4023            break;
4024        }
4025
4026        if (shift_max == 32) {
4027            tcg_gen_ext32s_i64(t0, t0);
4028        }
4029
4030        /* Shifts larger than MAX produce zero.  */
4031        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4032        tcg_gen_neg_i64(t1, t1);
4033        tcg_gen_and_i64(t0, t0, t1);
4034        break;
4035
4036    case OPC_ADD_CP2:
4037    case OPC_DADD_CP2:
4038        {
4039            TCGv_i64 t2 = tcg_temp_new_i64();
4040            TCGLabel *lab = gen_new_label();
4041
4042            tcg_gen_mov_i64(t2, t0);
4043            tcg_gen_add_i64(t0, t1, t2);
4044            if (opc == OPC_ADD_CP2) {
4045                tcg_gen_ext32s_i64(t0, t0);
4046            }
4047            tcg_gen_xor_i64(t1, t1, t2);
4048            tcg_gen_xor_i64(t2, t2, t0);
4049            tcg_gen_andc_i64(t1, t2, t1);
4050            tcg_temp_free_i64(t2);
4051            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4052            generate_exception(ctx, EXCP_OVERFLOW);
4053            gen_set_label(lab);
4054            break;
4055        }
4056
4057    case OPC_SUB_CP2:
4058    case OPC_DSUB_CP2:
4059        {
4060            TCGv_i64 t2 = tcg_temp_new_i64();
4061            TCGLabel *lab = gen_new_label();
4062
4063            tcg_gen_mov_i64(t2, t0);
4064            tcg_gen_sub_i64(t0, t1, t2);
4065            if (opc == OPC_SUB_CP2) {
4066                tcg_gen_ext32s_i64(t0, t0);
4067            }
4068            tcg_gen_xor_i64(t1, t1, t2);
4069            tcg_gen_xor_i64(t2, t2, t0);
4070            tcg_gen_and_i64(t1, t1, t2);
4071            tcg_temp_free_i64(t2);
4072            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4073            generate_exception(ctx, EXCP_OVERFLOW);
4074            gen_set_label(lab);
4075            break;
4076        }
4077
4078    case OPC_PMULUW:
4079        tcg_gen_ext32u_i64(t0, t0);
4080        tcg_gen_ext32u_i64(t1, t1);
4081        tcg_gen_mul_i64(t0, t0, t1);
4082        break;
4083
4084    case OPC_SEQU_CP2:
4085    case OPC_SEQ_CP2:
4086    case OPC_SLTU_CP2:
4087    case OPC_SLT_CP2:
4088    case OPC_SLEU_CP2:
4089    case OPC_SLE_CP2:
4090        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4091           FD field is the CC field?  */
4092    default:
4093        MIPS_INVAL("loongson_cp2");
4094        generate_exception_end(ctx, EXCP_RI);
4095        return;
4096    }
4097
4098#undef LMI_HELPER
4099#undef LMI_DIRECT
4100
4101    gen_store_fpr64(ctx, t0, rd);
4102
4103    tcg_temp_free_i64(t0);
4104    tcg_temp_free_i64(t1);
4105}
4106
4107/* Traps */
4108static void gen_trap (DisasContext *ctx, uint32_t opc,
4109                      int rs, int rt, int16_t imm)
4110{
4111    int cond;
4112    TCGv t0 = tcg_temp_new();
4113    TCGv t1 = tcg_temp_new();
4114
4115    cond = 0;
4116    /* Load needed operands */
4117    switch (opc) {
4118    case OPC_TEQ:
4119    case OPC_TGE:
4120    case OPC_TGEU:
4121    case OPC_TLT:
4122    case OPC_TLTU:
4123    case OPC_TNE:
4124        /* Compare two registers */
4125        if (rs != rt) {
4126            gen_load_gpr(t0, rs);
4127            gen_load_gpr(t1, rt);
4128            cond = 1;
4129        }
4130        break;
4131    case OPC_TEQI:
4132    case OPC_TGEI:
4133    case OPC_TGEIU:
4134    case OPC_TLTI:
4135    case OPC_TLTIU:
4136    case OPC_TNEI:
4137        /* Compare register to immediate */
4138        if (rs != 0 || imm != 0) {
4139            gen_load_gpr(t0, rs);
4140            tcg_gen_movi_tl(t1, (int32_t)imm);
4141            cond = 1;
4142        }
4143        break;
4144    }
4145    if (cond == 0) {
4146        switch (opc) {
4147        case OPC_TEQ:   /* rs == rs */
4148        case OPC_TEQI:  /* r0 == 0  */
4149        case OPC_TGE:   /* rs >= rs */
4150        case OPC_TGEI:  /* r0 >= 0  */
4151        case OPC_TGEU:  /* rs >= rs unsigned */
4152        case OPC_TGEIU: /* r0 >= 0  unsigned */
4153            /* Always trap */
4154            generate_exception_end(ctx, EXCP_TRAP);
4155            break;
4156        case OPC_TLT:   /* rs < rs           */
4157        case OPC_TLTI:  /* r0 < 0            */
4158        case OPC_TLTU:  /* rs < rs unsigned  */
4159        case OPC_TLTIU: /* r0 < 0  unsigned  */
4160        case OPC_TNE:   /* rs != rs          */
4161        case OPC_TNEI:  /* r0 != 0           */
4162            /* Never trap: treat as NOP. */
4163            break;
4164        }
4165    } else {
4166        TCGLabel *l1 = gen_new_label();
4167
4168        switch (opc) {
4169        case OPC_TEQ:
4170        case OPC_TEQI:
4171            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4172            break;
4173        case OPC_TGE:
4174        case OPC_TGEI:
4175            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4176            break;
4177        case OPC_TGEU:
4178        case OPC_TGEIU:
4179            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4180            break;
4181        case OPC_TLT:
4182        case OPC_TLTI:
4183            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4184            break;
4185        case OPC_TLTU:
4186        case OPC_TLTIU:
4187            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4188            break;
4189        case OPC_TNE:
4190        case OPC_TNEI:
4191            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4192            break;
4193        }
4194        generate_exception(ctx, EXCP_TRAP);
4195        gen_set_label(l1);
4196    }
4197    tcg_temp_free(t0);
4198    tcg_temp_free(t1);
4199}
4200
4201static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4202{
4203    if (unlikely(ctx->singlestep_enabled)) {
4204        return false;
4205    }
4206
4207#ifndef CONFIG_USER_ONLY
4208    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4209#else
4210    return true;
4211#endif
4212}
4213
4214static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4215{
4216    if (use_goto_tb(ctx, dest)) {
4217        tcg_gen_goto_tb(n);
4218        gen_save_pc(dest);
4219        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4220    } else {
4221        gen_save_pc(dest);
4222        if (ctx->singlestep_enabled) {
4223            save_cpu_state(ctx, 0);
4224            gen_helper_raise_exception_debug(cpu_env);
4225        }
4226        tcg_gen_exit_tb(0);
4227    }
4228}
4229
4230/* Branches (before delay slot) */
4231static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4232                                int insn_bytes,
4233                                int rs, int rt, int32_t offset,
4234                                int delayslot_size)
4235{
4236    target_ulong btgt = -1;
4237    int blink = 0;
4238    int bcond_compute = 0;
4239    TCGv t0 = tcg_temp_new();
4240    TCGv t1 = tcg_temp_new();
4241
4242    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4243#ifdef MIPS_DEBUG_DISAS
4244        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4245                  TARGET_FMT_lx "\n", ctx->pc);
4246#endif
4247        generate_exception_end(ctx, EXCP_RI);
4248        goto out;
4249    }
4250
4251    /* Load needed operands */
4252    switch (opc) {
4253    case OPC_BEQ:
4254    case OPC_BEQL:
4255    case OPC_BNE:
4256    case OPC_BNEL:
4257        /* Compare two registers */
4258        if (rs != rt) {
4259            gen_load_gpr(t0, rs);
4260            gen_load_gpr(t1, rt);
4261            bcond_compute = 1;
4262        }
4263        btgt = ctx->pc + insn_bytes + offset;
4264        break;
4265    case OPC_BGEZ:
4266    case OPC_BGEZAL:
4267    case OPC_BGEZALL:
4268    case OPC_BGEZL:
4269    case OPC_BGTZ:
4270    case OPC_BGTZL:
4271    case OPC_BLEZ:
4272    case OPC_BLEZL:
4273    case OPC_BLTZ:
4274    case OPC_BLTZAL:
4275    case OPC_BLTZALL:
4276    case OPC_BLTZL:
4277        /* Compare to zero */
4278        if (rs != 0) {
4279            gen_load_gpr(t0, rs);
4280            bcond_compute = 1;
4281        }
4282        btgt = ctx->pc + insn_bytes + offset;
4283        break;
4284    case OPC_BPOSGE32:
4285#if defined(TARGET_MIPS64)
4286    case OPC_BPOSGE64:
4287        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4288#else
4289        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4290#endif
4291        bcond_compute = 1;
4292        btgt = ctx->pc + insn_bytes + offset;
4293        break;
4294    case OPC_J:
4295    case OPC_JAL:
4296    case OPC_JALX:
4297        /* Jump to immediate */
4298        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4299        break;
4300    case OPC_JR:
4301    case OPC_JALR:
4302        /* Jump to register */
4303        if (offset != 0 && offset != 16) {
4304            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4305               others are reserved. */
4306            MIPS_INVAL("jump hint");
4307            generate_exception_end(ctx, EXCP_RI);
4308            goto out;
4309        }
4310        gen_load_gpr(btarget, rs);
4311        break;
4312    default:
4313        MIPS_INVAL("branch/jump");
4314        generate_exception_end(ctx, EXCP_RI);
4315        goto out;
4316    }
4317    if (bcond_compute == 0) {
4318        /* No condition to be computed */
4319        switch (opc) {
4320        case OPC_BEQ:     /* rx == rx        */
4321        case OPC_BEQL:    /* rx == rx likely */
4322        case OPC_BGEZ:    /* 0 >= 0          */
4323        case OPC_BGEZL:   /* 0 >= 0 likely   */
4324        case OPC_BLEZ:    /* 0 <= 0          */
4325        case OPC_BLEZL:   /* 0 <= 0 likely   */
4326            /* Always take */
4327            ctx->hflags |= MIPS_HFLAG_B;
4328            break;
4329        case OPC_BGEZAL:  /* 0 >= 0          */
4330        case OPC_BGEZALL: /* 0 >= 0 likely   */
4331            /* Always take and link */
4332            blink = 31;
4333            ctx->hflags |= MIPS_HFLAG_B;
4334            break;
4335        case OPC_BNE:     /* rx != rx        */
4336        case OPC_BGTZ:    /* 0 > 0           */
4337        case OPC_BLTZ:    /* 0 < 0           */
4338            /* Treat as NOP. */
4339            goto out;
4340        case OPC_BLTZAL:  /* 0 < 0           */
4341            /* Handle as an unconditional branch to get correct delay
4342               slot checking.  */
4343            blink = 31;
4344            btgt = ctx->pc + insn_bytes + delayslot_size;
4345            ctx->hflags |= MIPS_HFLAG_B;
4346            break;
4347        case OPC_BLTZALL: /* 0 < 0 likely */
4348            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4349            /* Skip the instruction in the delay slot */
4350            ctx->pc += 4;
4351            goto out;
4352        case OPC_BNEL:    /* rx != rx likely */
4353        case OPC_BGTZL:   /* 0 > 0 likely */
4354        case OPC_BLTZL:   /* 0 < 0 likely */
4355            /* Skip the instruction in the delay slot */
4356            ctx->pc += 4;
4357            goto out;
4358        case OPC_J:
4359            ctx->hflags |= MIPS_HFLAG_B;
4360            break;
4361        case OPC_JALX:
4362            ctx->hflags |= MIPS_HFLAG_BX;
4363            /* Fallthrough */
4364        case OPC_JAL:
4365            blink = 31;
4366            ctx->hflags |= MIPS_HFLAG_B;
4367            break;
4368        case OPC_JR:
4369            ctx->hflags |= MIPS_HFLAG_BR;
4370            break;
4371        case OPC_JALR:
4372            blink = rt;
4373            ctx->hflags |= MIPS_HFLAG_BR;
4374            break;
4375        default:
4376            MIPS_INVAL("branch/jump");
4377            generate_exception_end(ctx, EXCP_RI);
4378            goto out;
4379        }
4380    } else {
4381        switch (opc) {
4382        case OPC_BEQ:
4383            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4384            goto not_likely;
4385        case OPC_BEQL:
4386            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4387            goto likely;
4388        case OPC_BNE:
4389            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4390            goto not_likely;
4391        case OPC_BNEL:
4392            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4393            goto likely;
4394        case OPC_BGEZ:
4395            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4396            goto not_likely;
4397        case OPC_BGEZL:
4398            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4399            goto likely;
4400        case OPC_BGEZAL:
4401            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4402            blink = 31;
4403            goto not_likely;
4404        case OPC_BGEZALL:
4405            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4406            blink = 31;
4407            goto likely;
4408        case OPC_BGTZ:
4409            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4410            goto not_likely;
4411        case OPC_BGTZL:
4412            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4413            goto likely;
4414        case OPC_BLEZ:
4415            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4416            goto not_likely;
4417        case OPC_BLEZL:
4418            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4419            goto likely;
4420        case OPC_BLTZ:
4421            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4422            goto not_likely;
4423        case OPC_BLTZL:
4424            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4425            goto likely;
4426        case OPC_BPOSGE32:
4427            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4428            goto not_likely;
4429#if defined(TARGET_MIPS64)
4430        case OPC_BPOSGE64:
4431            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4432            goto not_likely;
4433#endif
4434        case OPC_BLTZAL:
4435            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4436            blink = 31;
4437        not_likely:
4438            ctx->hflags |= MIPS_HFLAG_BC;
4439            break;
4440        case OPC_BLTZALL:
4441            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4442            blink = 31;
4443        likely:
4444            ctx->hflags |= MIPS_HFLAG_BL;
4445            break;
4446        default:
4447            MIPS_INVAL("conditional branch/jump");
4448            generate_exception_end(ctx, EXCP_RI);
4449            goto out;
4450        }
4451    }
4452
4453    ctx->btarget = btgt;
4454
4455    switch (delayslot_size) {
4456    case 2:
4457        ctx->hflags |= MIPS_HFLAG_BDS16;
4458        break;
4459    case 4:
4460        ctx->hflags |= MIPS_HFLAG_BDS32;
4461        break;
4462    }
4463
4464    if (blink > 0) {
4465        int post_delay = insn_bytes + delayslot_size;
4466        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4467
4468        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4469    }
4470
4471 out:
4472    if (insn_bytes == 2)
4473        ctx->hflags |= MIPS_HFLAG_B16;
4474    tcg_temp_free(t0);
4475    tcg_temp_free(t1);
4476}
4477
4478/* special3 bitfield operations */
4479static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4480                        int rs, int lsb, int msb)
4481{
4482    TCGv t0 = tcg_temp_new();
4483    TCGv t1 = tcg_temp_new();
4484
4485    gen_load_gpr(t1, rs);
4486    switch (opc) {
4487    case OPC_EXT:
4488        if (lsb + msb > 31) {
4489            goto fail;
4490        }
4491        tcg_gen_shri_tl(t0, t1, lsb);
4492        if (msb != 31) {
4493            tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4494        } else {
4495            tcg_gen_ext32s_tl(t0, t0);
4496        }
4497        break;
4498#if defined(TARGET_MIPS64)
4499    case OPC_DEXTU:
4500        lsb += 32;
4501        goto do_dext;
4502    case OPC_DEXTM:
4503        msb += 32;
4504        goto do_dext;
4505    case OPC_DEXT:
4506    do_dext:
4507        if (lsb + msb > 63) {
4508            goto fail;
4509        }
4510        tcg_gen_shri_tl(t0, t1, lsb);
4511        if (msb != 63) {
4512            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4513        }
4514        break;
4515#endif
4516    case OPC_INS:
4517        if (lsb > msb) {
4518            goto fail;
4519        }
4520        gen_load_gpr(t0, rt);
4521        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4522        tcg_gen_ext32s_tl(t0, t0);
4523        break;
4524#if defined(TARGET_MIPS64)
4525    case OPC_DINSU:
4526        lsb += 32;
4527        /* FALLTHRU */
4528    case OPC_DINSM:
4529        msb += 32;
4530        /* FALLTHRU */
4531    case OPC_DINS:
4532        if (lsb > msb) {
4533            goto fail;
4534        }
4535        gen_load_gpr(t0, rt);
4536        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4537        break;
4538#endif
4539    default:
4540fail:
4541        MIPS_INVAL("bitops");
4542        generate_exception_end(ctx, EXCP_RI);
4543        tcg_temp_free(t0);
4544        tcg_temp_free(t1);
4545        return;
4546    }
4547    gen_store_gpr(t0, rt);
4548    tcg_temp_free(t0);
4549    tcg_temp_free(t1);
4550}
4551
4552static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4553{
4554    TCGv t0;
4555
4556    if (rd == 0) {
4557        /* If no destination, treat it as a NOP. */
4558        return;
4559    }
4560
4561    t0 = tcg_temp_new();
4562    gen_load_gpr(t0, rt);
4563    switch (op2) {
4564    case OPC_WSBH:
4565        {
4566            TCGv t1 = tcg_temp_new();
4567
4568            tcg_gen_shri_tl(t1, t0, 8);
4569            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4570            tcg_gen_shli_tl(t0, t0, 8);
4571            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4572            tcg_gen_or_tl(t0, t0, t1);
4573            tcg_temp_free(t1);
4574            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4575        }
4576        break;
4577    case OPC_SEB:
4578        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4579        break;
4580    case OPC_SEH:
4581        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4582        break;
4583#if defined(TARGET_MIPS64)
4584    case OPC_DSBH:
4585        {
4586            TCGv t1 = tcg_temp_new();
4587
4588            tcg_gen_shri_tl(t1, t0, 8);
4589            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4590            tcg_gen_shli_tl(t0, t0, 8);
4591            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4592            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4593            tcg_temp_free(t1);
4594        }
4595        break;
4596    case OPC_DSHD:
4597        {
4598            TCGv t1 = tcg_temp_new();
4599
4600            tcg_gen_shri_tl(t1, t0, 16);
4601            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4602            tcg_gen_shli_tl(t0, t0, 16);
4603            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4604            tcg_gen_or_tl(t0, t0, t1);
4605            tcg_gen_shri_tl(t1, t0, 32);
4606            tcg_gen_shli_tl(t0, t0, 32);
4607            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4608            tcg_temp_free(t1);
4609        }
4610        break;
4611#endif
4612    default:
4613        MIPS_INVAL("bsfhl");
4614        generate_exception_end(ctx, EXCP_RI);
4615        tcg_temp_free(t0);
4616        return;
4617    }
4618    tcg_temp_free(t0);
4619}
4620
4621static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4622                    int imm2)
4623{
4624    TCGv t0;
4625    TCGv t1;
4626    if (rd == 0) {
4627        /* Treat as NOP. */
4628        return;
4629    }
4630    t0 = tcg_temp_new();
4631    t1 = tcg_temp_new();
4632    gen_load_gpr(t0, rs);
4633    gen_load_gpr(t1, rt);
4634    tcg_gen_shli_tl(t0, t0, imm2 + 1);
4635    tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4636    if (opc == OPC_LSA) {
4637        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4638    }
4639
4640    tcg_temp_free(t1);
4641    tcg_temp_free(t0);
4642
4643    return;
4644}
4645
4646static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4647                      int bp)
4648{
4649    TCGv t0;
4650    if (rd == 0) {
4651        /* Treat as NOP. */
4652        return;
4653    }
4654    t0 = tcg_temp_new();
4655    gen_load_gpr(t0, rt);
4656    if (bp == 0) {
4657        switch (opc) {
4658        case OPC_ALIGN:
4659            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4660            break;
4661#if defined(TARGET_MIPS64)
4662        case OPC_DALIGN:
4663            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4664            break;
4665#endif
4666        }
4667    } else {
4668        TCGv t1 = tcg_temp_new();
4669        gen_load_gpr(t1, rs);
4670        switch (opc) {
4671        case OPC_ALIGN:
4672            {
4673                TCGv_i64 t2 = tcg_temp_new_i64();
4674                tcg_gen_concat_tl_i64(t2, t1, t0);
4675                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4676                gen_move_low32(cpu_gpr[rd], t2);
4677                tcg_temp_free_i64(t2);
4678            }
4679            break;
4680#if defined(TARGET_MIPS64)
4681        case OPC_DALIGN:
4682            tcg_gen_shli_tl(t0, t0, 8 * bp);
4683            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4684            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4685            break;
4686#endif
4687        }
4688        tcg_temp_free(t1);
4689    }
4690
4691    tcg_temp_free(t0);
4692}
4693
4694static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4695{
4696    TCGv t0;
4697    if (rd == 0) {
4698        /* Treat as NOP. */
4699        return;
4700    }
4701    t0 = tcg_temp_new();
4702    gen_load_gpr(t0, rt);
4703    switch (opc) {
4704    case OPC_BITSWAP:
4705        gen_helper_bitswap(cpu_gpr[rd], t0);
4706        break;
4707#if defined(TARGET_MIPS64)
4708    case OPC_DBITSWAP:
4709        gen_helper_dbitswap(cpu_gpr[rd], t0);
4710        break;
4711#endif
4712    }
4713    tcg_temp_free(t0);
4714}
4715
4716#ifndef CONFIG_USER_ONLY
4717/* CP0 (MMU and control) */
4718static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4719{
4720    TCGv_i64 t0 = tcg_temp_new_i64();
4721    TCGv_i64 t1 = tcg_temp_new_i64();
4722
4723    tcg_gen_ext_tl_i64(t0, arg);
4724    tcg_gen_ld_i64(t1, cpu_env, off);
4725#if defined(TARGET_MIPS64)
4726    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4727#else
4728    tcg_gen_concat32_i64(t1, t1, t0);
4729#endif
4730    tcg_gen_st_i64(t1, cpu_env, off);
4731    tcg_temp_free_i64(t1);
4732    tcg_temp_free_i64(t0);
4733}
4734
4735static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4736{
4737    TCGv_i64 t0 = tcg_temp_new_i64();
4738    TCGv_i64 t1 = tcg_temp_new_i64();
4739
4740    tcg_gen_ext_tl_i64(t0, arg);
4741    tcg_gen_ld_i64(t1, cpu_env, off);
4742    tcg_gen_concat32_i64(t1, t1, t0);
4743    tcg_gen_st_i64(t1, cpu_env, off);
4744    tcg_temp_free_i64(t1);
4745    tcg_temp_free_i64(t0);
4746}
4747
4748static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4749{
4750    TCGv_i64 t0 = tcg_temp_new_i64();
4751
4752    tcg_gen_ld_i64(t0, cpu_env, off);
4753#if defined(TARGET_MIPS64)
4754    tcg_gen_shri_i64(t0, t0, 30);
4755#else
4756    tcg_gen_shri_i64(t0, t0, 32);
4757#endif
4758    gen_move_low32(arg, t0);
4759    tcg_temp_free_i64(t0);
4760}
4761
4762static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4763{
4764    TCGv_i64 t0 = tcg_temp_new_i64();
4765
4766    tcg_gen_ld_i64(t0, cpu_env, off);
4767    tcg_gen_shri_i64(t0, t0, 32 + shift);
4768    gen_move_low32(arg, t0);
4769    tcg_temp_free_i64(t0);
4770}
4771
4772static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4773{
4774    TCGv_i32 t0 = tcg_temp_new_i32();
4775
4776    tcg_gen_ld_i32(t0, cpu_env, off);
4777    tcg_gen_ext_i32_tl(arg, t0);
4778    tcg_temp_free_i32(t0);
4779}
4780
4781static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4782{
4783    tcg_gen_ld_tl(arg, cpu_env, off);
4784    tcg_gen_ext32s_tl(arg, arg);
4785}
4786
4787static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4788{
4789    TCGv_i32 t0 = tcg_temp_new_i32();
4790
4791    tcg_gen_trunc_tl_i32(t0, arg);
4792    tcg_gen_st_i32(t0, cpu_env, off);
4793    tcg_temp_free_i32(t0);
4794}
4795
4796#define CP0_CHECK(c)                            \
4797    do {                                        \
4798        if (!(c)) {                             \
4799            goto cp0_unimplemented;             \
4800        }                                       \
4801    } while (0)
4802
4803static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4804{
4805    const char *rn = "invalid";
4806
4807    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4808
4809    switch (reg) {
4810    case 2:
4811        switch (sel) {
4812        case 0:
4813            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4814            rn = "EntryLo0";
4815            break;
4816        default:
4817            goto cp0_unimplemented;
4818        }
4819        break;
4820    case 3:
4821        switch (sel) {
4822        case 0:
4823            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4824            rn = "EntryLo1";
4825            break;
4826        default:
4827            goto cp0_unimplemented;
4828        }
4829        break;
4830    case 17:
4831        switch (sel) {
4832        case 0:
4833            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4834                             ctx->CP0_LLAddr_shift);
4835            rn = "LLAddr";
4836            break;
4837        case 1:
4838            CP0_CHECK(ctx->mrp);
4839            gen_helper_mfhc0_maar(arg, cpu_env);
4840            rn = "MAAR";
4841            break;
4842        default:
4843            goto cp0_unimplemented;
4844        }
4845        break;
4846    case 28:
4847        switch (sel) {
4848        case 0:
4849        case 2:
4850        case 4:
4851        case 6:
4852            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4853            rn = "TagLo";
4854            break;
4855        default:
4856            goto cp0_unimplemented;
4857        }
4858        break;
4859    default:
4860        goto cp0_unimplemented;
4861    }
4862
4863    (void)rn; /* avoid a compiler warning */
4864    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4865    return;
4866
4867cp0_unimplemented:
4868    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4869    tcg_gen_movi_tl(arg, 0);
4870}
4871
4872static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4873{
4874    const char *rn = "invalid";
4875    uint64_t mask = ctx->PAMask >> 36;
4876
4877    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4878
4879    switch (reg) {
4880    case 2:
4881        switch (sel) {
4882        case 0:
4883            tcg_gen_andi_tl(arg, arg, mask);
4884            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4885            rn = "EntryLo0";
4886            break;
4887        default:
4888            goto cp0_unimplemented;
4889        }
4890        break;
4891    case 3:
4892        switch (sel) {
4893        case 0:
4894            tcg_gen_andi_tl(arg, arg, mask);
4895            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4896            rn = "EntryLo1";
4897            break;
4898        default:
4899            goto cp0_unimplemented;
4900        }
4901        break;
4902    case 17:
4903        switch (sel) {
4904        case 0:
4905            /* LLAddr is read-only (the only exception is bit 0 if LLB is
4906               supported); the CP0_LLAddr_rw_bitmask does not seem to be
4907               relevant for modern MIPS cores supporting MTHC0, therefore
4908               treating MTHC0 to LLAddr as NOP. */
4909            rn = "LLAddr";
4910            break;
4911        case 1:
4912            CP0_CHECK(ctx->mrp);
4913            gen_helper_mthc0_maar(cpu_env, arg);
4914            rn = "MAAR";
4915            break;
4916        default:
4917            goto cp0_unimplemented;
4918        }
4919        break;
4920    case 28:
4921        switch (sel) {
4922        case 0:
4923        case 2:
4924        case 4:
4925        case 6:
4926            tcg_gen_andi_tl(arg, arg, mask);
4927            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4928            rn = "TagLo";
4929            break;
4930        default:
4931            goto cp0_unimplemented;
4932        }
4933        break;
4934    default:
4935        goto cp0_unimplemented;
4936    }
4937
4938    (void)rn; /* avoid a compiler warning */
4939cp0_unimplemented:
4940    LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4941}
4942
4943static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4944{
4945    if (ctx->insn_flags & ISA_MIPS32R6) {
4946        tcg_gen_movi_tl(arg, 0);
4947    } else {
4948        tcg_gen_movi_tl(arg, ~0);
4949    }
4950}
4951
4952static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4953{
4954    const char *rn = "invalid";
4955
4956    if (sel != 0)
4957        check_insn(ctx, ISA_MIPS32);
4958
4959    switch (reg) {
4960    case 0:
4961        switch (sel) {
4962        case 0:
4963            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4964            rn = "Index";
4965            break;
4966        case 1:
4967            CP0_CHECK(ctx->insn_flags & ASE_MT);
4968            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4969            rn = "MVPControl";
4970            break;
4971        case 2:
4972            CP0_CHECK(ctx->insn_flags & ASE_MT);
4973            gen_helper_mfc0_mvpconf0(arg, cpu_env);
4974            rn = "MVPConf0";
4975            break;
4976        case 3:
4977            CP0_CHECK(ctx->insn_flags & ASE_MT);
4978            gen_helper_mfc0_mvpconf1(arg, cpu_env);
4979            rn = "MVPConf1";
4980            break;
4981        case 4:
4982            CP0_CHECK(ctx->vp);
4983            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4984            rn = "VPControl";
4985            break;
4986        default:
4987            goto cp0_unimplemented;
4988        }
4989        break;
4990    case 1:
4991        switch (sel) {
4992        case 0:
4993            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4994            gen_helper_mfc0_random(arg, cpu_env);
4995            rn = "Random";
4996            break;
4997        case 1:
4998            CP0_CHECK(ctx->insn_flags & ASE_MT);
4999            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5000            rn = "VPEControl";
5001            break;
5002        case 2:
5003            CP0_CHECK(ctx->insn_flags & ASE_MT);
5004            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5005            rn = "VPEConf0";
5006            break;
5007        case 3:
5008            CP0_CHECK(ctx->insn_flags & ASE_MT);
5009            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5010            rn = "VPEConf1";
5011            break;
5012        case 4:
5013            CP0_CHECK(ctx->insn_flags & ASE_MT);
5014            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5015            rn = "YQMask";
5016            break;
5017        case 5:
5018            CP0_CHECK(ctx->insn_flags & ASE_MT);
5019            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5020            rn = "VPESchedule";
5021            break;
5022        case 6:
5023            CP0_CHECK(ctx->insn_flags & ASE_MT);
5024            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5025            rn = "VPEScheFBack";
5026            break;
5027        case 7:
5028            CP0_CHECK(ctx->insn_flags & ASE_MT);
5029            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5030            rn = "VPEOpt";
5031            break;
5032        default:
5033            goto cp0_unimplemented;
5034        }
5035        break;
5036    case 2:
5037        switch (sel) {
5038        case 0:
5039            {
5040                TCGv_i64 tmp = tcg_temp_new_i64();
5041                tcg_gen_ld_i64(tmp, cpu_env,
5042                               offsetof(CPUMIPSState, CP0_EntryLo0));
5043#if defined(TARGET_MIPS64)
5044                if (ctx->rxi) {
5045                    /* Move RI/XI fields to bits 31:30 */
5046                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5047                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5048                }
5049#endif
5050                gen_move_low32(arg, tmp);
5051                tcg_temp_free_i64(tmp);
5052            }
5053            rn = "EntryLo0";
5054            break;
5055        case 1:
5056            CP0_CHECK(ctx->insn_flags & ASE_MT);
5057            gen_helper_mfc0_tcstatus(arg, cpu_env);
5058            rn = "TCStatus";
5059            break;
5060        case 2:
5061            CP0_CHECK(ctx->insn_flags & ASE_MT);
5062            gen_helper_mfc0_tcbind(arg, cpu_env);
5063            rn = "TCBind";
5064            break;
5065        case 3:
5066            CP0_CHECK(ctx->insn_flags & ASE_MT);
5067            gen_helper_mfc0_tcrestart(arg, cpu_env);
5068            rn = "TCRestart";
5069            break;
5070        case 4:
5071            CP0_CHECK(ctx->insn_flags & ASE_MT);
5072            gen_helper_mfc0_tchalt(arg, cpu_env);
5073            rn = "TCHalt";
5074            break;
5075        case 5:
5076            CP0_CHECK(ctx->insn_flags & ASE_MT);
5077            gen_helper_mfc0_tccontext(arg, cpu_env);
5078            rn = "TCContext";
5079            break;
5080        case 6:
5081            CP0_CHECK(ctx->insn_flags & ASE_MT);
5082            gen_helper_mfc0_tcschedule(arg, cpu_env);
5083            rn = "TCSchedule";
5084            break;
5085        case 7:
5086            CP0_CHECK(ctx->insn_flags & ASE_MT);
5087            gen_helper_mfc0_tcschefback(arg, cpu_env);
5088            rn = "TCScheFBack";
5089            break;
5090        default:
5091            goto cp0_unimplemented;
5092        }
5093        break;
5094    case 3:
5095        switch (sel) {
5096        case 0:
5097            {
5098                TCGv_i64 tmp = tcg_temp_new_i64();
5099                tcg_gen_ld_i64(tmp, cpu_env,
5100                               offsetof(CPUMIPSState, CP0_EntryLo1));
5101#if defined(TARGET_MIPS64)
5102                if (ctx->rxi) {
5103                    /* Move RI/XI fields to bits 31:30 */
5104                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5105                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5106                }
5107#endif
5108                gen_move_low32(arg, tmp);
5109                tcg_temp_free_i64(tmp);
5110            }
5111            rn = "EntryLo1";
5112            break;
5113        case 1:
5114            CP0_CHECK(ctx->vp);
5115            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5116            rn = "GlobalNumber";
5117            break;
5118        default:
5119            goto cp0_unimplemented;
5120        }
5121        break;
5122    case 4:
5123        switch (sel) {
5124        case 0:
5125            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5126            tcg_gen_ext32s_tl(arg, arg);
5127            rn = "Context";
5128            break;
5129        case 1:
5130//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5131            rn = "ContextConfig";
5132            goto cp0_unimplemented;
5133//            break;
5134        case 2:
5135            CP0_CHECK(ctx->ulri);
5136            tcg_gen_ld32s_tl(arg, cpu_env,
5137                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5138            rn = "UserLocal";
5139            break;
5140        default:
5141            goto cp0_unimplemented;
5142        }
5143        break;
5144    case 5:
5145        switch (sel) {
5146        case 0:
5147            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5148            rn = "PageMask";
5149            break;
5150        case 1:
5151            check_insn(ctx, ISA_MIPS32R2);
5152            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5153            rn = "PageGrain";
5154            break;
5155        default:
5156            goto cp0_unimplemented;
5157        }
5158        break;
5159    case 6:
5160        switch (sel) {
5161        case 0:
5162            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5163            rn = "Wired";
5164            break;
5165        case 1:
5166            check_insn(ctx, ISA_MIPS32R2);
5167            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5168            rn = "SRSConf0";
5169            break;
5170        case 2:
5171            check_insn(ctx, ISA_MIPS32R2);
5172            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5173            rn = "SRSConf1";
5174            break;
5175        case 3:
5176            check_insn(ctx, ISA_MIPS32R2);
5177            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5178            rn = "SRSConf2";
5179            break;
5180        case 4:
5181            check_insn(ctx, ISA_MIPS32R2);
5182            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5183            rn = "SRSConf3";
5184            break;
5185        case 5:
5186            check_insn(ctx, ISA_MIPS32R2);
5187            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5188            rn = "SRSConf4";
5189            break;
5190        default:
5191            goto cp0_unimplemented;
5192        }
5193        break;
5194    case 7:
5195        switch (sel) {
5196        case 0:
5197            check_insn(ctx, ISA_MIPS32R2);
5198            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5199            rn = "HWREna";
5200            break;
5201        default:
5202            goto cp0_unimplemented;
5203        }
5204        break;
5205    case 8:
5206        switch (sel) {
5207        case 0:
5208            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5209            tcg_gen_ext32s_tl(arg, arg);
5210            rn = "BadVAddr";
5211            break;
5212        case 1:
5213            CP0_CHECK(ctx->bi);
5214            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5215            rn = "BadInstr";
5216            break;
5217        case 2:
5218            CP0_CHECK(ctx->bp);
5219            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5220            rn = "BadInstrP";
5221            break;
5222        default:
5223            goto cp0_unimplemented;
5224        }
5225        break;
5226    case 9:
5227        switch (sel) {
5228        case 0:
5229            /* Mark as an IO operation because we read the time.  */
5230            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5231                gen_io_start();
5232            }
5233            gen_helper_mfc0_count(arg, cpu_env);
5234            if (ctx->tb->cflags & CF_USE_ICOUNT) {
5235                gen_io_end();
5236            }
5237            /* Break the TB to be able to take timer interrupts immediately
5238               after reading count.  */
5239            ctx->bstate = BS_STOP;
5240            rn = "Count";
5241            break;
5242        /* 6,7 are implementation dependent */
5243        default:
5244            goto cp0_unimplemented;
5245        }
5246        break;
5247    case 10:
5248        switch (sel) {
5249        case 0:
5250            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5251            tcg_gen_ext32s_tl(arg, arg);
5252            rn = "EntryHi";
5253            break;
5254        default:
5255            goto cp0_unimplemented;
5256        }
5257        break;
5258    case 11:
5259        switch (sel) {
5260        case 0:
5261            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5262            rn = "Compare";
5263            break;
5264        /* 6,7 are implementation dependent */
5265        default:
5266            goto cp0_unimplemented;
5267        }
5268        break;
5269    case 12:
5270        switch (sel) {
5271        case 0:
5272            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5273            rn = "Status";
5274            break;
5275        case 1:
5276            check_insn(ctx, ISA_MIPS32R2);
5277            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5278            rn = "IntCtl";
5279            break;
5280        case 2:
5281            check_insn(ctx, ISA_MIPS32R2);
5282            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5283            rn = "SRSCtl";
5284            break;
5285        case 3:
5286            check_insn(ctx, ISA_MIPS32R2);
5287            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5288            rn = "SRSMap";
5289            break;
5290        default:
5291            goto cp0_unimplemented;
5292       }
5293        break;
5294    case 13:
5295        switch (sel) {
5296        case 0:
5297            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5298            rn = "Cause";
5299            break;
5300        default:
5301            goto cp0_unimplemented;
5302       }
5303        break;
5304    case 14:
5305        switch (sel) {
5306        case 0:
5307            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5308            tcg_gen_ext32s_tl(arg, arg);
5309            rn = "EPC";
5310            break;
5311        default:
5312            goto cp0_unimplemented;
5313        }
5314        break;
5315    case 15:
5316        switch (sel) {
5317        case 0:
5318            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5319            rn = "PRid";
5320            break;
5321        case 1:
5322            check_insn(ctx, ISA_MIPS32R2);
5323            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5324            rn = "EBase";
5325            break;
5326        case 3:
5327            check_insn(ctx, ISA_MIPS32R2);
5328            CP0_CHECK(ctx->cmgcr);
5329            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5330            tcg_gen_ext32s_tl(arg, arg);
5331            rn = "CMGCRBase";
5332            break;
5333        default:
5334            goto cp0_unimplemented;
5335       }
5336        break;
5337    case 16:
5338        switch (sel) {
5339        case 0:
5340            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5341            rn = "Config";
5342            break;
5343        case 1:
5344            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5345            rn = "Config1";
5346            break;
5347        case 2:
5348            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5349            rn = "Config2";
5350            break;
5351        case 3:
5352            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5353            rn = "Config3";
5354            break;
5355        case 4:
5356            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5357            rn = "Config4";
5358            break;
5359        case 5:
5360            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5361            rn = "Config5";
5362            break;
5363        /* 6,7 are implementation dependent */
5364        case 6:
5365            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5366            rn = "Config6";
5367            break;
5368        case 7:
5369            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5370            rn = "Config7";
5371            break;
5372        default:
5373            goto cp0_unimplemented;
5374        }
5375        break;
5376    case 17:
5377        switch (sel) {
5378        case 0:
5379            gen_helper_mfc0_lladdr(arg, cpu_env);
5380            rn = "LLAddr";
5381            break;
5382        case 1:
5383            CP0_CHECK(ctx->mrp);
5384            gen_helper_mfc0_maar(arg, cpu_env);
5385            rn = "MAAR";
5386            break;
5387        case 2:
5388            CP0_CHECK(ctx->mrp);
5389            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5390            rn = "MAARI";
5391            break;
5392        default:
5393            goto cp0_unimplemented;
5394        }
5395        break;
5396    case 18:
5397        switch (sel) {
5398        case 0 ... 7:
5399            gen_helper_1e0i(mfc0_watchlo, arg, sel);
5400            rn = "WatchLo";
5401            break;
5402        default:
5403            goto cp0_unimplemented;
5404        }
5405        break;
5406    case 19:
5407        switch (sel) {
5408        case 0 ...7:
5409            gen_helper_1e0i(mfc0_watchhi, arg, sel);
5410            rn = "WatchHi";
5411            break;
5412        default:
5413            goto cp0_unimplemented;
5414        }
5415        break;
5416    case 20:
5417        switch (sel) {
5418        case 0:
5419#if defined(TARGET_MIPS64)
5420            check_insn(ctx, ISA_MIPS3);
5421            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5422            tcg_gen_ext32s_tl(arg, arg);
5423            rn = "XContext";
5424            break;
5425#endif
5426        default:
5427            goto cp0_unimplemented;
5428        }
5429        break;
5430    case 21:
5431       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5432        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5433        switch (sel) {
5434        case 0:
5435            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5436            rn = "Framemask";
5437            break;
5438        default:
5439            goto cp0_unimplemented;
5440        }
5441        break;
5442    case 22:
5443        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5444        rn = "'Diagnostic"; /* implementation dependent */
5445        break;
5446    case 23:
5447        switch (sel) {
5448        case 0:
5449            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5450            rn = "Debug";
5451            break;
5452        case 1:
5453//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5454            rn = "TraceControl";
5455//            break;
5456        case 2:
5457//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5458            rn = "TraceControl2";
5459//            break;
5460        case 3:
5461//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5462            rn = "UserTraceData";
5463//            break;
5464        case 4:
5465//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5466            rn = "TraceBPC";
5467//            break;
5468        default:
5469            goto cp0_unimplemented;
5470        }
5471        break;
5472    case 24:
5473        switch (sel) {
5474        case 0:
5475            /* EJTAG support */
5476            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5477            tcg_gen_ext32s_tl(arg, arg);
5478            rn = "DEPC";
5479            break;
5480        default:
5481            goto cp0_unimplemented;
5482        }
5483        break;
5484    case 25:
5485        switch (sel) {
5486        case 0:
5487            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5488            rn = "Performance0";
5489            break;
5490        case 1:
5491//            gen_helper_mfc0_performance1(arg);
5492            rn = "Performance1";
5493//            break;
5494        case 2:
5495//            gen_helper_mfc0_performance2(arg);
5496            rn = "Performance2";
5497//            break;
5498        case 3:
5499//            gen_helper_mfc0_performance3(arg);
5500            rn = "Performance3";
5501//            break;
5502        case 4:
5503//            gen_helper_mfc0_performance4(arg);
5504            rn = "Performance4";
5505//            break;
5506        case 5:
5507//            gen_helper_mfc0_performance5(arg);
5508            rn = "Performance5";
5509//            break;
5510        case 6:
5511//            gen_helper_mfc0_performance6(arg);
5512            rn = "Performance6";
5513//            break;
5514        case 7:
5515//            gen_helper_mfc0_performance7(arg);
5516            rn = "Performance7";
5517//            break;
5518        default:
5519            goto cp0_unimplemented;
5520        }
5521        break;
5522    case 26:
5523        switch (sel) {
5524        case 0:
5525            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5526            rn = "ErrCtl";
5527            break;
5528        default:
5529            goto cp0_unimplemented;
5530        }
5531        break;
5532    case 27:
5533        switch (sel) {
5534        case 0 ... 3:
5535            tcg_gen_movi_tl(arg, 0); /* unimplemented */
5536            rn = "CacheErr";
5537            break;
5538        default:
5539            goto cp0_unimplemented;
5540        }
5541        break;
5542    case 28:
5543        switch (sel) {
5544        case 0:
5545        case 2:
5546        case 4:
5547        case 6:
5548            {
5549                TCGv_i64 tmp = tcg_temp_new_i64();
5550                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5551                gen_move_low32(arg, tmp);
5552                tcg_temp_free_i64(tmp);
5553            }
5554            rn = "TagLo";
5555            break;
5556        case 1:
5557        case 3:
5558        case 5:
5559        case 7:
5560            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5561            rn = "DataLo";
5562            break;
5563        default:
5564            goto cp0_unimplemented;
5565        }
5566        break;
5567    case 29:
5568        switch (sel) {
5569        case 0:
5570        case 2:
5571        case 4:
5572        case 6:
5573            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5574            rn = "TagHi";
5575            break;
5576        case 1:
5577        case 3:
5578        case 5:
5579        case 7:
5580            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5581            rn = "DataHi";
5582            break;
5583        default:
5584            goto cp0_unimplemented;
5585        }
5586        break;
5587    case 30:
5588        switch (sel) {
5589        case 0:
5590            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5591            tcg_gen_ext32s_tl(arg, arg);
5592            rn = "ErrorEPC";
5593            break;
5594        default:
5595            goto cp0_unimplemented;
5596        }
5597        break;
5598    case 31:
5599        switch (sel) {
5600        case 0:
5601            /* EJTAG support */
5602            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5603            rn = "DESAVE";
5604            break;
5605        case 2 ... 7:
5606            CP0_CHECK(ctx->kscrexist & (1 << sel));
5607            tcg_gen_ld_tl(arg, cpu_env,
5608                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5609            tcg_gen_ext32s_tl(arg, arg);
5610            rn = "KScratch";
5611            break;
5612        default:
5613            goto cp0_unimplemented;
5614        }
5615        break;
5616    default:
5617       goto cp0_unimplemented;
5618    }
5619    (void)rn; /* avoid a compiler warning */
5620    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5621    return;
5622
5623cp0_unimplemented:
5624    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5625    gen_mfc0_unimplemented(ctx, arg);
5626}
5627
5628static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5629{
5630    const char *rn = "invalid";
5631
5632    if (sel != 0)
5633        check_insn(ctx, ISA_MIPS32);
5634
5635    if (ctx->tb->cflags & CF_USE_ICOUNT) {
5636        gen_io_start();
5637    }
5638
5639    switch (reg) {
5640    case 0:
5641        switch (sel) {
5642        case 0:
5643            gen_helper_mtc0_index(cpu_env, arg);
5644            rn = "Index";
5645            break;
5646        case 1:
5647            CP0_CHECK(ctx->insn_flags & ASE_MT);
5648            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5649            rn = "MVPControl";
5650            break;
5651        case 2:
5652            CP0_CHECK(ctx->insn_flags & ASE_MT);
5653            /* ignored */
5654            rn = "MVPConf0";
5655            break;
5656        case 3:
5657            CP0_CHECK(ctx->insn_flags & ASE_MT);
5658            /* ignored */
5659            rn = "MVPConf1";
5660            break;
5661        case 4:
5662            CP0_CHECK(ctx->vp);
5663            /* ignored */
5664            rn = "VPControl";
5665            break;
5666        default:
5667            goto cp0_unimplemented;
5668        }
5669        break;
5670    case 1:
5671        switch (sel) {
5672        case 0:
5673            /* ignored */
5674            rn = "Random";
5675            break;
5676        case 1:
5677            CP0_CHECK(ctx->insn_flags & ASE_MT);
5678            gen_helper_mtc0_vpecontrol(cpu_env, arg);
5679            rn = "VPEControl";
5680            break;
5681        case 2:
5682            CP0_CHECK(ctx->insn_flags & ASE_MT);
5683            gen_helper_mtc0_vpeconf0(cpu_env, arg);
5684            rn = "VPEConf0";
5685            break;
5686        case 3:
5687            CP0_CHECK(ctx->insn_flags & ASE_MT);
5688            gen_helper_mtc0_vpeconf1(cpu_env, arg);
5689            rn = "VPEConf1";
5690            break;
5691        case 4:
5692            CP0_CHECK(ctx->insn_flags & ASE_MT);
5693            gen_helper_mtc0_yqmask(cpu_env, arg);
5694            rn = "YQMask";
5695            break;
5696        case 5:
5697            CP0_CHECK(ctx->insn_flags & ASE_MT);
5698            tcg_gen_st_tl(arg, cpu_env,
5699                          offsetof(CPUMIPSState, CP0_VPESchedule));
5700            rn = "VPESchedule";
5701            break;
5702        case 6:
5703            CP0_CHECK(ctx->insn_flags & ASE_MT);
5704            tcg_gen_st_tl(arg, cpu_env,
5705                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
5706            rn = "VPEScheFBack";
5707            break;
5708        case 7:
5709            CP0_CHECK(ctx->insn_flags & ASE_MT);
5710            gen_helper_mtc0_vpeopt(cpu_env, arg);
5711            rn = "VPEOpt";
5712            break;
5713        default:
5714            goto cp0_unimplemented;
5715        }
5716        break;
5717    case 2:
5718        switch (sel) {
5719        case 0:
5720            gen_helper_mtc0_entrylo0(cpu_env, arg);
5721            rn = "EntryLo0";
5722            break;
5723        case 1:
5724            CP0_CHECK(ctx->insn_flags & ASE_MT);
5725            gen_helper_mtc0_tcstatus(cpu_env, arg);
5726            rn = "TCStatus";
5727            break;
5728        case 2:
5729            CP0_CHECK(ctx->insn_flags & ASE_MT);
5730            gen_helper_mtc0_tcbind(cpu_env, arg);
5731            rn = "TCBind";
5732            break;
5733        case 3:
5734            CP0_CHECK(ctx->insn_flags & ASE_MT);
5735            gen_helper_mtc0_tcrestart(cpu_env, arg);
5736            rn = "TCRestart";
5737            break;
5738        case 4:
5739            CP0_CHECK(ctx->insn_flags & ASE_MT);
5740            gen_helper_mtc0_tchalt(cpu_env, arg);
5741            rn = "TCHalt";
5742            break;
5743        case 5:
5744            CP0_CHECK(ctx->insn_flags & ASE_MT);
5745            gen_helper_mtc0_tccontext(cpu_env, arg);
5746            rn = "TCContext";
5747            break;
5748        case 6:
5749            CP0_CHECK(ctx->insn_flags & ASE_MT);
5750            gen_helper_mtc0_tcschedule(cpu_env, arg);
5751            rn = "TCSchedule";
5752            break;
5753        case 7:
5754            CP0_CHECK(ctx->insn_flags & ASE_MT);
5755            gen_helper_mtc0_tcschefback(cpu_env, arg);
5756            rn = "TCScheFBack";
5757            break;
5758        default:
5759            goto cp0_unimplemented;
5760        }
5761        break;
5762    case 3:
5763        switch (sel) {
5764        case 0:
5765            gen_helper_mtc0_entrylo1(cpu_env, arg);
5766            rn = "EntryLo1";
5767            break;
5768        case 1:
5769            CP0_CHECK(ctx->vp);
5770            /* ignored */
5771            rn = "GlobalNumber";
5772            break;
5773        default:
5774            goto cp0_unimplemented;
5775        }
5776        break;
5777    case 4:
5778        switch (sel) {
5779        case 0:
5780            gen_helper_mtc0_context(cpu_env, arg);
5781            rn = "Context";
5782            break;
5783        case 1:
5784//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5785            rn = "ContextConfig";
5786            goto cp0_unimplemented;
5787//            break;
5788        case 2:
5789            CP0_CHECK(ctx->ulri);
5790            tcg_gen_st_tl(arg, cpu_env,
5791                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5792            rn = "UserLocal";
5793            break;
5794        default:
5795            goto cp0_unimplemented;
5796        }
5797        break;
5798    case 5:
5799        switch (sel) {
5800        case 0:
5801            gen_helper_mtc0_pagemask(cpu_env, arg);
5802            rn = "PageMask";
5803            break;
5804        case 1:
5805            check_insn(ctx, ISA_MIPS32R2);
5806            gen_helper_mtc0_pagegrain(cpu_env, arg);
5807            rn = "PageGrain";
5808            ctx->bstate = BS_STOP;
5809            break;
5810        default:
5811            goto cp0_unimplemented;
5812        }
5813        break;
5814    case 6:
5815        switch (sel) {
5816        case 0:
5817            gen_helper_mtc0_wired(cpu_env, arg);
5818            rn = "Wired";
5819            break;
5820        case 1:
5821            check_insn(ctx, ISA_MIPS32R2);
5822            gen_helper_mtc0_srsconf0(cpu_env, arg);
5823            rn = "SRSConf0";
5824            break;
5825        case 2:
5826            check_insn(ctx, ISA_MIPS32R2);
5827            gen_helper_mtc0_srsconf1(cpu_env, arg);
5828            rn = "SRSConf1";
5829            break;
5830        case 3:
5831            check_insn(ctx, ISA_MIPS32R2);
5832            gen_helper_mtc0_srsconf2(cpu_env, arg);
5833            rn = "SRSConf2";
5834            break;
5835        case 4:
5836            check_insn(ctx, ISA_MIPS32R2);
5837            gen_helper_mtc0_srsconf3(cpu_env, arg);
5838            rn = "SRSConf3";
5839            break;
5840        case 5:
5841            check_insn(ctx, ISA_MIPS32R2);
5842            gen_helper_mtc0_srsconf4(cpu_env, arg);
5843            rn = "SRSConf4";
5844            break;
5845        default:
5846            goto cp0_unimplemented;
5847        }
5848        break;
5849    case 7:
5850        switch (sel) {
5851        case 0:
5852            check_insn(ctx, ISA_MIPS32R2);
5853            gen_helper_mtc0_hwrena(cpu_env, arg);
5854            ctx->bstate = BS_STOP;
5855            rn = "HWREna";
5856            break;
5857        default:
5858            goto cp0_unimplemented;
5859        }
5860        break;
5861    case 8:
5862        switch (sel) {
5863        case 0:
5864            /* ignored */
5865            rn = "BadVAddr";
5866            break;
5867        case 1:
5868            /* ignored */
5869            rn = "BadInstr";
5870            break;
5871        case 2:
5872            /* ignored */
5873            rn = "BadInstrP";
5874            break;
5875        default:
5876            goto cp0_unimplemented;
5877        }
5878        break;
5879    case 9:
5880        switch (sel) {
5881        case 0:
5882            gen_helper_mtc0_count(cpu_env, arg);
5883            rn = "Count";
5884            break;
5885        /* 6,7 are implementation dependent */
5886        default:
5887            goto cp0_unimplemented;
5888        }
5889        break;
5890    case 10:
5891        switch (sel) {
5892        case 0:
5893            gen_helper_mtc0_entryhi(cpu_env, arg);
5894            rn = "EntryHi";
5895            break;
5896        default:
5897            goto cp0_unimplemented;
5898        }
5899        break;
5900    case 11:
5901        switch (sel) {
5902        case 0:
5903            gen_helper_mtc0_compare(cpu_env, arg);
5904            rn = "Compare";
5905            break;
5906        /* 6,7 are implementation dependent */
5907        default:
5908            goto cp0_unimplemented;
5909        }
5910        break;
5911    case 12:
5912        switch (sel) {
5913        case 0:
5914            save_cpu_state(ctx, 1);
5915            gen_helper_mtc0_status(cpu_env, arg);
5916            /* BS_STOP isn't good enough here, hflags may have changed. */
5917            gen_save_pc(ctx->pc + 4);
5918            ctx->bstate = BS_EXCP;
5919            rn = "Status";
5920            break;
5921        case 1:
5922            check_insn(ctx, ISA_MIPS32R2);
5923            gen_helper_mtc0_intctl(cpu_env, arg);
5924            /* Stop translation as we may have switched the execution mode */
5925            ctx->bstate = BS_STOP;
5926            rn = "IntCtl";
5927            break;
5928        case 2:
5929            check_insn(ctx, ISA_MIPS32R2);
5930            gen_helper_mtc0_srsctl(cpu_env, arg);
5931            /* Stop translation as we may have switched the execution mode */
5932            ctx->bstate = BS_STOP;
5933            rn = "SRSCtl";
5934            break;
5935        case 3:
5936            check_insn(ctx, ISA_MIPS32R2);
5937            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5938            /* Stop translation as we may have switched the execution mode */
5939            ctx->bstate = BS_STOP;
5940            rn = "SRSMap";
5941            break;
5942        default:
5943            goto cp0_unimplemented;
5944        }
5945        break;
5946    case 13:
5947        switch (sel) {
5948        case 0:
5949            save_cpu_state(ctx, 1);
5950            gen_helper_mtc0_cause(cpu_env, arg);
5951            rn = "Cause";
5952            break;
5953        default:
5954            goto cp0_unimplemented;
5955        }
5956        break;
5957    case 14:
5958        switch (sel) {
5959        case 0:
5960            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5961            rn = "EPC";
5962            break;
5963        default:
5964            goto cp0_unimplemented;
5965        }
5966        break;
5967    case 15:
5968        switch (sel) {
5969        case 0:
5970            /* ignored */
5971            rn = "PRid";
5972            break;
5973        case 1:
5974            check_insn(ctx, ISA_MIPS32R2);
5975            gen_helper_mtc0_ebase(cpu_env, arg);
5976            rn = "EBase";
5977            break;
5978        default:
5979            goto cp0_unimplemented;
5980        }
5981        break;
5982    case 16:
5983        switch (sel) {
5984        case 0:
5985            gen_helper_mtc0_config0(cpu_env, arg);
5986            rn = "Config";
5987            /* Stop translation as we may have switched the execution mode */
5988            ctx->bstate = BS_STOP;
5989            break;
5990        case 1:
5991            /* ignored, read only */
5992            rn = "Config1";
5993            break;
5994        case 2:
5995            gen_helper_mtc0_config2(cpu_env, arg);
5996            rn = "Config2";
5997            /* Stop translation as we may have switched the execution mode */
5998            ctx->bstate = BS_STOP;
5999            break;
6000        case 3:
6001            gen_helper_mtc0_config3(cpu_env, arg);
6002            rn = "Config3";
6003            /* Stop translation as we may have switched the execution mode */
6004            ctx->bstate = BS_STOP;
6005            break;
6006        case 4:
6007            gen_helper_mtc0_config4(cpu_env, arg);
6008            rn = "Config4";
6009            ctx->bstate = BS_STOP;
6010            break;
6011        case 5:
6012            gen_helper_mtc0_config5(cpu_env, arg);
6013            rn = "Config5";
6014            /* Stop translation as we may have switched the execution mode */
6015            ctx->bstate = BS_STOP;
6016            break;
6017        /* 6,7 are implementation dependent */
6018        case 6:
6019            /* ignored */
6020            rn = "Config6";
6021            break;
6022        case 7:
6023            /* ignored */
6024            rn = "Config7";
6025            break;
6026        default:
6027            rn = "Invalid config selector";
6028            goto cp0_unimplemented;
6029        }
6030        break;
6031    case 17:
6032        switch (sel) {
6033        case 0:
6034            gen_helper_mtc0_lladdr(cpu_env, arg);
6035            rn = "LLAddr";
6036            break;
6037        case 1:
6038            CP0_CHECK(ctx->mrp);
6039            gen_helper_mtc0_maar(cpu_env, arg);
6040            rn = "MAAR";
6041            break;
6042        case 2:
6043            CP0_CHECK(ctx->mrp);
6044            gen_helper_mtc0_maari(cpu_env, arg);
6045            rn = "MAARI";
6046            break;
6047        default:
6048            goto cp0_unimplemented;
6049        }
6050        break;
6051    case 18:
6052        switch (sel) {
6053        case 0 ... 7:
6054            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6055            rn = "WatchLo";
6056            break;
6057        default:
6058            goto cp0_unimplemented;
6059        }
6060        break;
6061    case 19:
6062        switch (sel) {
6063        case 0 ... 7:
6064            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6065            rn = "WatchHi";
6066            break;
6067        default:
6068            goto cp0_unimplemented;
6069        }
6070        break;
6071    case 20:
6072        switch (sel) {
6073        case 0:
6074#if defined(TARGET_MIPS64)
6075            check_insn(ctx, ISA_MIPS3);
6076            gen_helper_mtc0_xcontext(cpu_env, arg);
6077            rn = "XContext";
6078            break;
6079#endif
6080        default:
6081            goto cp0_unimplemented;
6082        }
6083        break;
6084    case 21:
6085       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6086        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6087        switch (sel) {
6088        case 0:
6089            gen_helper_mtc0_framemask(cpu_env, arg);
6090            rn = "Framemask";
6091            break;
6092        default:
6093            goto cp0_unimplemented;
6094        }
6095        break;
6096    case 22:
6097        /* ignored */
6098        rn = "Diagnostic"; /* implementation dependent */
6099        break;
6100    case 23:
6101        switch (sel) {
6102        case 0:
6103            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6104            /* BS_STOP isn't good enough here, hflags may have changed. */
6105            gen_save_pc(ctx->pc + 4);
6106            ctx->bstate = BS_EXCP;
6107            rn = "Debug";
6108            break;
6109        case 1:
6110//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6111            rn = "TraceControl";
6112            /* Stop translation as we may have switched the execution mode */
6113            ctx->bstate = BS_STOP;
6114//            break;
6115        case 2:
6116//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6117            rn = "TraceControl2";
6118            /* Stop translation as we may have switched the execution mode */
6119            ctx->bstate = BS_STOP;
6120//            break;
6121        case 3:
6122            /* Stop translation as we may have switched the execution mode */
6123            ctx->bstate = BS_STOP;
6124//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6125            rn = "UserTraceData";
6126            /* Stop translation as we may have switched the execution mode */
6127            ctx->bstate = BS_STOP;
6128//            break;
6129        case 4:
6130//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6131            /* Stop translation as we may have switched the execution mode */
6132            ctx->bstate = BS_STOP;
6133            rn = "TraceBPC";
6134//            break;
6135        default:
6136            goto cp0_unimplemented;
6137        }
6138        break;
6139    case 24:
6140        switch (sel) {
6141        case 0:
6142            /* EJTAG support */
6143            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6144            rn = "DEPC";
6145            break;
6146        default:
6147            goto cp0_unimplemented;
6148        }
6149        break;
6150    case 25:
6151        switch (sel) {
6152        case 0:
6153            gen_helper_mtc0_performance0(cpu_env, arg);
6154            rn = "Performance0";
6155            break;
6156        case 1:
6157//            gen_helper_mtc0_performance1(arg);
6158            rn = "Performance1";
6159//            break;
6160        case 2:
6161//            gen_helper_mtc0_performance2(arg);
6162            rn = "Performance2";
6163//            break;
6164        case 3:
6165//            gen_helper_mtc0_performance3(arg);
6166            rn = "Performance3";
6167//            break;
6168        case 4:
6169//            gen_helper_mtc0_performance4(arg);
6170            rn = "Performance4";
6171//            break;
6172        case 5:
6173//            gen_helper_mtc0_performance5(arg);
6174            rn = "Performance5";
6175//            break;
6176        case 6:
6177//            gen_helper_mtc0_performance6(arg);
6178            rn = "Performance6";
6179//            break;
6180        case 7:
6181//            gen_helper_mtc0_performance7(arg);
6182            rn = "Performance7";
6183//            break;
6184        default:
6185            goto cp0_unimplemented;
6186        }
6187       break;
6188    case 26:
6189        switch (sel) {
6190        case 0:
6191            gen_helper_mtc0_errctl(cpu_env, arg);
6192            ctx->bstate = BS_STOP;
6193            rn = "ErrCtl";
6194            break;
6195        default:
6196            goto cp0_unimplemented;
6197        }
6198        break;
6199    case 27:
6200        switch (sel) {
6201        case 0 ... 3:
6202            /* ignored */
6203            rn = "CacheErr";
6204            break;
6205        default:
6206            goto cp0_unimplemented;
6207        }
6208       break;
6209    case 28:
6210        switch (sel) {
6211        case 0:
6212        case 2:
6213        case 4:
6214        case 6:
6215            gen_helper_mtc0_taglo(cpu_env, arg);
6216            rn = "TagLo";
6217            break;
6218        case 1:
6219        case 3:
6220        case 5:
6221        case 7:
6222            gen_helper_mtc0_datalo(cpu_env, arg);
6223            rn = "DataLo";
6224            break;
6225        default:
6226            goto cp0_unimplemented;
6227        }
6228        break;
6229    case 29:
6230        switch (sel) {
6231        case 0:
6232        case 2:
6233        case 4:
6234        case 6:
6235            gen_helper_mtc0_taghi(cpu_env, arg);
6236            rn = "TagHi";
6237            break;
6238        case 1:
6239        case 3:
6240        case 5:
6241        case 7:
6242            gen_helper_mtc0_datahi(cpu_env, arg);
6243            rn = "DataHi";
6244            break;
6245        default:
6246            rn = "invalid sel";
6247            goto cp0_unimplemented;
6248        }
6249       break;
6250    case 30:
6251        switch (sel) {
6252        case 0:
6253            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6254            rn = "ErrorEPC";
6255            break;
6256        default:
6257            goto cp0_unimplemented;
6258        }
6259        break;
6260    case 31:
6261        switch (sel) {
6262        case 0:
6263            /* EJTAG support */
6264            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6265            rn = "DESAVE";
6266            break;
6267        case 2 ... 7:
6268            CP0_CHECK(ctx->kscrexist & (1 << sel));
6269            tcg_gen_st_tl(arg, cpu_env,
6270                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6271            rn = "KScratch";
6272            break;
6273        default:
6274            goto cp0_unimplemented;
6275        }
6276        /* Stop translation as we may have switched the execution mode */
6277        ctx->bstate = BS_STOP;
6278        break;
6279    default:
6280       goto cp0_unimplemented;
6281    }
6282    (void)rn; /* avoid a compiler warning */
6283    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6284    /* For simplicity assume that all writes can cause interrupts.  */
6285    if (ctx->tb->cflags & CF_USE_ICOUNT) {
6286        gen_io_end();
6287        ctx->bstate = BS_STOP;
6288    }
6289    return;
6290
6291cp0_unimplemented:
6292    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6293}
6294
6295#if defined(TARGET_MIPS64)
6296static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6297{
6298    const char *rn = "invalid";
6299
6300    if (sel != 0)
6301        check_insn(ctx, ISA_MIPS64);
6302
6303    switch (reg) {
6304    case 0:
6305        switch (sel) {
6306        case 0:
6307            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6308            rn = "Index";
6309            break;
6310        case 1:
6311            CP0_CHECK(ctx->insn_flags & ASE_MT);
6312            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6313            rn = "MVPControl";
6314            break;
6315        case 2:
6316            CP0_CHECK(ctx->insn_flags & ASE_MT);
6317            gen_helper_mfc0_mvpconf0(arg, cpu_env);
6318            rn = "MVPConf0";
6319            break;
6320        case 3:
6321            CP0_CHECK(ctx->insn_flags & ASE_MT);
6322            gen_helper_mfc0_mvpconf1(arg, cpu_env);
6323            rn = "MVPConf1";
6324            break;
6325        case 4:
6326            CP0_CHECK(ctx->vp);
6327            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6328            rn = "VPControl";
6329            break;
6330        default:
6331            goto cp0_unimplemented;
6332        }
6333        break;
6334    case 1:
6335        switch (sel) {
6336        case 0:
6337            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6338            gen_helper_mfc0_random(arg, cpu_env);
6339            rn = "Random";
6340            break;
6341        case 1:
6342            CP0_CHECK(ctx->insn_flags & ASE_MT);
6343            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6344            rn = "VPEControl";
6345            break;
6346        case 2:
6347            CP0_CHECK(ctx->insn_flags & ASE_MT);
6348            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6349            rn = "VPEConf0";
6350            break;
6351        case 3:
6352            CP0_CHECK(ctx->insn_flags & ASE_MT);
6353            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6354            rn = "VPEConf1";
6355            break;
6356        case 4:
6357            CP0_CHECK(ctx->insn_flags & ASE_MT);
6358            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6359            rn = "YQMask";
6360            break;
6361        case 5:
6362            CP0_CHECK(ctx->insn_flags & ASE_MT);
6363            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6364            rn = "VPESchedule";
6365            break;
6366        case 6:
6367            CP0_CHECK(ctx->insn_flags & ASE_MT);
6368            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6369            rn = "VPEScheFBack";
6370            break;
6371        case 7:
6372            CP0_CHECK(ctx->insn_flags & ASE_MT);
6373            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6374            rn = "VPEOpt";
6375            break;
6376        default:
6377            goto cp0_unimplemented;
6378        }
6379        break;
6380    case 2:
6381        switch (sel) {
6382        case 0:
6383            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6384            rn = "EntryLo0";
6385            break;
6386        case 1:
6387            CP0_CHECK(ctx->insn_flags & ASE_MT);
6388            gen_helper_mfc0_tcstatus(arg, cpu_env);
6389            rn = "TCStatus";
6390            break;
6391        case 2:
6392            CP0_CHECK(ctx->insn_flags & ASE_MT);
6393            gen_helper_mfc0_tcbind(arg, cpu_env);
6394            rn = "TCBind";
6395            break;
6396        case 3:
6397            CP0_CHECK(ctx->insn_flags & ASE_MT);
6398            gen_helper_dmfc0_tcrestart(arg, cpu_env);
6399            rn = "TCRestart";
6400            break;
6401        case 4:
6402            CP0_CHECK(ctx->insn_flags & ASE_MT);
6403            gen_helper_dmfc0_tchalt(arg, cpu_env);
6404            rn = "TCHalt";
6405            break;
6406        case 5:
6407            CP0_CHECK(ctx->insn_flags & ASE_MT);
6408            gen_helper_dmfc0_tccontext(arg, cpu_env);
6409            rn = "TCContext";
6410            break;
6411        case 6:
6412            CP0_CHECK(ctx->insn_flags & ASE_MT);
6413            gen_helper_dmfc0_tcschedule(arg, cpu_env);
6414            rn = "TCSchedule";
6415            break;
6416        case 7:
6417            CP0_CHECK(ctx->insn_flags & ASE_MT);
6418            gen_helper_dmfc0_tcschefback(arg, cpu_env);
6419            rn = "TCScheFBack";
6420            break;
6421        default:
6422            goto cp0_unimplemented;
6423        }
6424        break;
6425    case 3:
6426        switch (sel) {
6427        case 0:
6428            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6429            rn = "EntryLo1";
6430            break;
6431        case 1:
6432            CP0_CHECK(ctx->vp);
6433            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6434            rn = "GlobalNumber";
6435            break;
6436        default:
6437            goto cp0_unimplemented;
6438        }
6439        break;
6440    case 4:
6441        switch (sel) {
6442        case 0:
6443            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6444            rn = "Context";
6445            break;
6446        case 1:
6447//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6448            rn = "ContextConfig";
6449            goto cp0_unimplemented;
6450//            break;
6451        case 2:
6452            CP0_CHECK(ctx->ulri);
6453            tcg_gen_ld_tl(arg, cpu_env,
6454                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6455            rn = "UserLocal";
6456            break;
6457        default:
6458            goto cp0_unimplemented;
6459        }
6460        break;
6461    case 5:
6462        switch (sel) {
6463        case 0:
6464            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6465            rn = "PageMask";
6466            break;
6467        case 1:
6468            check_insn(ctx, ISA_MIPS32R2);
6469            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6470            rn = "PageGrain";
6471            break;
6472        default:
6473            goto cp0_unimplemented;
6474        }
6475        break;
6476    case 6:
6477        switch (sel) {
6478        case 0:
6479            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6480            rn = "Wired";
6481            break;
6482        case 1:
6483            check_insn(ctx, ISA_MIPS32R2);
6484            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6485            rn = "SRSConf0";
6486            break;
6487        case 2:
6488            check_insn(ctx, ISA_MIPS32R2);
6489            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6490            rn = "SRSConf1";
6491            break;
6492        case 3:
6493            check_insn(ctx, ISA_MIPS32R2);
6494            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6495            rn = "SRSConf2";
6496            break;
6497        case 4:
6498            check_insn(ctx, ISA_MIPS32R2);
6499            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6500            rn = "SRSConf3";
6501            break;
6502        case 5:
6503            check_insn(ctx, ISA_MIPS32R2);
6504            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6505            rn = "SRSConf4";
6506            break;
6507        default:
6508            goto cp0_unimplemented;
6509        }
6510        break;
6511    case 7:
6512        switch (sel) {
6513        case 0:
6514            check_insn(ctx, ISA_MIPS32R2);
6515            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6516            rn = "HWREna";
6517            break;
6518        default:
6519            goto cp0_unimplemented;
6520        }
6521        break;
6522    case 8:
6523        switch (sel) {
6524        case 0:
6525            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6526            rn = "BadVAddr";
6527            break;
6528        case 1:
6529            CP0_CHECK(ctx->bi);
6530            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6531            rn = "BadInstr";
6532            break;
6533        case 2:
6534            CP0_CHECK(ctx->bp);
6535            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6536            rn = "BadInstrP";
6537            break;
6538        default:
6539            goto cp0_unimplemented;
6540        }
6541        break;
6542    case 9:
6543        switch (sel) {
6544        case 0:
6545            /* Mark as an IO operation because we read the time.  */
6546            if (ctx->tb->cflags & CF_USE_ICOUNT) {
6547                gen_io_start();
6548            }
6549            gen_helper_mfc0_count(arg, cpu_env);
6550            if (ctx->tb->cflags & CF_USE_ICOUNT) {
6551                gen_io_end();
6552            }
6553            /* Break the TB to be able to take timer interrupts immediately
6554               after reading count.  */
6555            ctx->bstate = BS_STOP;
6556            rn = "Count";
6557            break;
6558        /* 6,7 are implementation dependent */
6559        default:
6560            goto cp0_unimplemented;
6561        }
6562        break;
6563    case 10:
6564        switch (sel) {
6565        case 0:
6566            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6567            rn = "EntryHi";
6568            break;
6569        default:
6570            goto cp0_unimplemented;
6571        }
6572        break;
6573    case 11:
6574        switch (sel) {
6575        case 0:
6576            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6577            rn = "Compare";
6578            break;
6579        /* 6,7 are implementation dependent */
6580        default:
6581            goto cp0_unimplemented;
6582        }
6583        break;
6584    case 12:
6585        switch (sel) {
6586        case 0:
6587            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6588            rn = "Status";
6589            break;
6590        case 1:
6591            check_insn(ctx, ISA_MIPS32R2);
6592            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6593            rn = "IntCtl";
6594            break;
6595        case 2:
6596            check_insn(ctx, ISA_MIPS32R2);
6597            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6598            rn = "SRSCtl";
6599            break;
6600        case 3:
6601            check_insn(ctx, ISA_MIPS32R2);
6602            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6603            rn = "SRSMap";
6604            break;
6605        default:
6606            goto cp0_unimplemented;
6607        }
6608        break;
6609    case 13:
6610        switch (sel) {
6611        case 0:
6612            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6613            rn = "Cause";
6614            break;
6615        default:
6616            goto cp0_unimplemented;
6617        }
6618        break;
6619    case 14:
6620        switch (sel) {
6621        case 0:
6622            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6623            rn = "EPC";
6624            break;
6625        default:
6626            goto cp0_unimplemented;
6627        }
6628        break;
6629    case 15:
6630        switch (sel) {
6631        case 0:
6632            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6633            rn = "PRid";
6634            break;
6635        case 1:
6636            check_insn(ctx, ISA_MIPS32R2);
6637            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6638            rn = "EBase";
6639            break;
6640        case 3:
6641            check_insn(ctx, ISA_MIPS32R2);
6642            CP0_CHECK(ctx->cmgcr);
6643            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6644            rn = "CMGCRBase";
6645            break;
6646        default:
6647            goto cp0_unimplemented;
6648        }
6649        break;
6650    case 16:
6651        switch (sel) {
6652        case 0:
6653            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6654            rn = "Config";
6655            break;
6656        case 1:
6657            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6658            rn = "Config1";
6659            break;
6660        case 2:
6661            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6662            rn = "Config2";
6663            break;
6664        case 3:
6665            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6666            rn = "Config3";
6667            break;
6668        case 4:
6669            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6670            rn = "Config4";
6671            break;
6672        case 5:
6673            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6674            rn = "Config5";
6675            break;
6676       /* 6,7 are implementation dependent */
6677        case 6:
6678            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6679            rn = "Config6";
6680            break;
6681        case 7:
6682            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6683            rn = "Config7";
6684            break;
6685        default:
6686            goto cp0_unimplemented;
6687        }
6688        break;
6689    case 17:
6690        switch (sel) {
6691        case 0:
6692            gen_helper_dmfc0_lladdr(arg, cpu_env);
6693            rn = "LLAddr";
6694            break;
6695        case 1:
6696            CP0_CHECK(ctx->mrp);
6697            gen_helper_dmfc0_maar(arg, cpu_env);
6698            rn = "MAAR";
6699            break;
6700        case 2:
6701            CP0_CHECK(ctx->mrp);
6702            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6703            rn = "MAARI";
6704            break;
6705        default:
6706            goto cp0_unimplemented;
6707        }
6708        break;
6709    case 18:
6710        switch (sel) {
6711        case 0 ... 7:
6712            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6713            rn = "WatchLo";
6714            break;
6715        default:
6716            goto cp0_unimplemented;
6717        }
6718        break;
6719    case 19:
6720        switch (sel) {
6721        case 0 ... 7:
6722            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6723            rn = "WatchHi";
6724            break;
6725        default:
6726            goto cp0_unimplemented;
6727        }
6728        break;
6729    case 20:
6730        switch (sel) {
6731        case 0:
6732            check_insn(ctx, ISA_MIPS3);
6733            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6734            rn = "XContext";
6735            break;
6736        default:
6737            goto cp0_unimplemented;
6738        }
6739        break;
6740    case 21:
6741       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6742        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6743        switch (sel) {
6744        case 0:
6745            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6746            rn = "Framemask";
6747            break;
6748        default:
6749            goto cp0_unimplemented;
6750        }
6751        break;
6752    case 22:
6753        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6754        rn = "'Diagnostic"; /* implementation dependent */
6755        break;
6756    case 23:
6757        switch (sel) {
6758        case 0:
6759            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6760            rn = "Debug";
6761            break;
6762        case 1:
6763//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6764            rn = "TraceControl";
6765//            break;
6766        case 2:
6767//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6768            rn = "TraceControl2";
6769//            break;
6770        case 3:
6771//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6772            rn = "UserTraceData";
6773//            break;
6774        case 4:
6775//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6776            rn = "TraceBPC";
6777//            break;
6778        default:
6779            goto cp0_unimplemented;
6780        }
6781        break;
6782    case 24:
6783        switch (sel) {
6784        case 0:
6785            /* EJTAG support */
6786            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6787            rn = "DEPC";
6788            break;
6789        default:
6790            goto cp0_unimplemented;
6791        }
6792        break;
6793    case 25:
6794        switch (sel) {
6795        case 0:
6796            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6797            rn = "Performance0";
6798            break;
6799        case 1:
6800//            gen_helper_dmfc0_performance1(arg);
6801            rn = "Performance1";
6802//            break;
6803        case 2:
6804//            gen_helper_dmfc0_performance2(arg);
6805            rn = "Performance2";
6806//            break;
6807        case 3:
6808//            gen_helper_dmfc0_performance3(arg);
6809            rn = "Performance3";
6810//            break;
6811        case 4:
6812//            gen_helper_dmfc0_performance4(arg);
6813            rn = "Performance4";
6814//            break;
6815        case 5:
6816//            gen_helper_dmfc0_performance5(arg);
6817            rn = "Performance5";
6818//            break;
6819        case 6:
6820//            gen_helper_dmfc0_performance6(arg);
6821            rn = "Performance6";
6822//            break;
6823        case 7:
6824//            gen_helper_dmfc0_performance7(arg);
6825            rn = "Performance7";
6826//            break;
6827        default:
6828            goto cp0_unimplemented;
6829        }
6830        break;
6831    case 26:
6832        switch (sel) {
6833        case 0:
6834            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6835            rn = "ErrCtl";
6836            break;
6837        default:
6838            goto cp0_unimplemented;
6839        }
6840        break;
6841    case 27:
6842        switch (sel) {
6843        /* ignored */
6844        case 0 ... 3:
6845            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6846            rn = "CacheErr";
6847            break;
6848        default:
6849            goto cp0_unimplemented;
6850        }
6851        break;
6852    case 28:
6853        switch (sel) {
6854        case 0:
6855        case 2:
6856        case 4:
6857        case 6:
6858            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6859            rn = "TagLo";
6860            break;
6861        case 1:
6862        case 3:
6863        case 5:
6864        case 7:
6865            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6866            rn = "DataLo";
6867            break;
6868        default:
6869            goto cp0_unimplemented;
6870        }
6871        break;
6872    case 29:
6873        switch (sel) {
6874        case 0:
6875        case 2:
6876        case 4:
6877        case 6:
6878            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6879            rn = "TagHi";
6880            break;
6881        case 1:
6882        case 3:
6883        case 5:
6884        case 7:
6885            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6886            rn = "DataHi";
6887            break;
6888        default:
6889            goto cp0_unimplemented;
6890        }
6891        break;
6892    case 30:
6893        switch (sel) {
6894        case 0:
6895            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6896            rn = "ErrorEPC";
6897            break;
6898        default:
6899            goto cp0_unimplemented;
6900        }
6901        break;
6902    case 31:
6903        switch (sel) {
6904        case 0:
6905            /* EJTAG support */
6906            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6907            rn = "DESAVE";
6908            break;
6909        case 2 ... 7:
6910            CP0_CHECK(ctx->kscrexist & (1 << sel));
6911            tcg_gen_ld_tl(arg, cpu_env,
6912                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6913            rn = "KScratch";
6914            break;
6915        default:
6916            goto cp0_unimplemented;
6917        }
6918        break;
6919    default:
6920        goto cp0_unimplemented;
6921    }
6922    (void)rn; /* avoid a compiler warning */
6923    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6924    return;
6925
6926cp0_unimplemented:
6927    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6928    gen_mfc0_unimplemented(ctx, arg);
6929}
6930
6931static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6932{
6933    const char *rn = "invalid";
6934
6935    if (sel != 0)
6936        check_insn(ctx, ISA_MIPS64);
6937
6938    if (ctx->tb->cflags & CF_USE_ICOUNT) {
6939        gen_io_start();
6940    }
6941
6942    switch (reg) {
6943    case 0:
6944        switch (sel) {
6945        case 0:
6946            gen_helper_mtc0_index(cpu_env, arg);
6947            rn = "Index";
6948            break;
6949        case 1:
6950            CP0_CHECK(ctx->insn_flags & ASE_MT);
6951            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6952            rn = "MVPControl";
6953            break;
6954        case 2:
6955            CP0_CHECK(ctx->insn_flags & ASE_MT);
6956            /* ignored */
6957            rn = "MVPConf0";
6958            break;
6959        case 3:
6960            CP0_CHECK(ctx->insn_flags & ASE_MT);
6961            /* ignored */
6962            rn = "MVPConf1";
6963            break;
6964        case 4:
6965            CP0_CHECK(ctx->vp);
6966            /* ignored */
6967            rn = "VPControl";
6968            break;
6969        default:
6970            goto cp0_unimplemented;
6971        }
6972        break;
6973    case 1:
6974        switch (sel) {
6975        case 0:
6976            /* ignored */
6977            rn = "Random";
6978            break;
6979        case 1:
6980            CP0_CHECK(ctx->insn_flags & ASE_MT);
6981            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6982            rn = "VPEControl";
6983            break;
6984        case 2:
6985            CP0_CHECK(ctx->insn_flags & ASE_MT);
6986            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6987            rn = "VPEConf0";
6988            break;
6989        case 3:
6990            CP0_CHECK(ctx->insn_flags & ASE_MT);
6991            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6992            rn = "VPEConf1";
6993            break;
6994        case 4:
6995            CP0_CHECK(ctx->insn_flags & ASE_MT);
6996            gen_helper_mtc0_yqmask(cpu_env, arg);
6997            rn = "YQMask";
6998            break;
6999        case 5:
7000            CP0_CHECK(ctx->insn_flags & ASE_MT);
7001            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7002            rn = "VPESchedule";
7003            break;
7004        case 6:
7005            CP0_CHECK(ctx->insn_flags & ASE_MT);
7006            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7007            rn = "VPEScheFBack";
7008            break;
7009        case 7:
7010            CP0_CHECK(ctx->insn_flags & ASE_MT);
7011            gen_helper_mtc0_vpeopt(cpu_env, arg);
7012            rn = "VPEOpt";
7013            break;
7014        default:
7015            goto cp0_unimplemented;
7016        }
7017        break;
7018    case 2:
7019        switch (sel) {
7020        case 0:
7021            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7022            rn = "EntryLo0";
7023            break;
7024        case 1:
7025            CP0_CHECK(ctx->insn_flags & ASE_MT);
7026            gen_helper_mtc0_tcstatus(cpu_env, arg);
7027            rn = "TCStatus";
7028            break;
7029        case 2:
7030            CP0_CHECK(ctx->insn_flags & ASE_MT);
7031            gen_helper_mtc0_tcbind(cpu_env, arg);
7032            rn = "TCBind";
7033            break;
7034        case 3:
7035            CP0_CHECK(ctx->insn_flags & ASE_MT);
7036            gen_helper_mtc0_tcrestart(cpu_env, arg);
7037            rn = "TCRestart";
7038            break;
7039        case 4:
7040            CP0_CHECK(ctx->insn_flags & ASE_MT);
7041            gen_helper_mtc0_tchalt(cpu_env, arg);
7042            rn = "TCHalt";
7043            break;
7044        case 5:
7045            CP0_CHECK(ctx->insn_flags & ASE_MT);
7046            gen_helper_mtc0_tccontext(cpu_env, arg);
7047            rn = "TCContext";
7048            break;
7049        case 6:
7050            CP0_CHECK(ctx->insn_flags & ASE_MT);
7051            gen_helper_mtc0_tcschedule(cpu_env, arg);
7052            rn = "TCSchedule";
7053            break;
7054        case 7:
7055            CP0_CHECK(ctx->insn_flags & ASE_MT);
7056            gen_helper_mtc0_tcschefback(cpu_env, arg);
7057            rn = "TCScheFBack";
7058            break;
7059        default:
7060            goto cp0_unimplemented;
7061        }
7062        break;
7063    case 3:
7064        switch (sel) {
7065        case 0:
7066            gen_helper_dmtc0_entrylo1(cpu_env, arg);
7067            rn = "EntryLo1";
7068            break;
7069        case 1:
7070            CP0_CHECK(ctx->vp);
7071            /* ignored */
7072            rn = "GlobalNumber";
7073            break;
7074        default:
7075            goto cp0_unimplemented;
7076        }
7077        break;
7078    case 4:
7079        switch (sel) {
7080        case 0:
7081            gen_helper_mtc0_context(cpu_env, arg);
7082            rn = "Context";
7083            break;
7084        case 1:
7085//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7086            rn = "ContextConfig";
7087            goto cp0_unimplemented;
7088//           break;
7089        case 2:
7090            CP0_CHECK(ctx->ulri);
7091            tcg_gen_st_tl(arg, cpu_env,
7092                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7093            rn = "UserLocal";
7094            break;
7095        default:
7096            goto cp0_unimplemented;
7097        }
7098        break;
7099    case 5:
7100        switch (sel) {
7101        case 0:
7102            gen_helper_mtc0_pagemask(cpu_env, arg);
7103            rn = "PageMask";
7104            break;
7105        case 1:
7106            check_insn(ctx, ISA_MIPS32R2);
7107            gen_helper_mtc0_pagegrain(cpu_env, arg);
7108            rn = "PageGrain";
7109            break;
7110        default:
7111            goto cp0_unimplemented;
7112        }
7113        break;
7114    case 6:
7115        switch (sel) {
7116        case 0:
7117            gen_helper_mtc0_wired(cpu_env, arg);
7118            rn = "Wired";
7119            break;
7120        case 1:
7121            check_insn(ctx, ISA_MIPS32R2);
7122            gen_helper_mtc0_srsconf0(cpu_env, arg);
7123            rn = "SRSConf0";
7124            break;
7125        case 2:
7126            check_insn(ctx, ISA_MIPS32R2);
7127            gen_helper_mtc0_srsconf1(cpu_env, arg);
7128            rn = "SRSConf1";
7129            break;
7130        case 3:
7131            check_insn(ctx, ISA_MIPS32R2);
7132            gen_helper_mtc0_srsconf2(cpu_env, arg);
7133            rn = "SRSConf2";
7134            break;
7135        case 4:
7136            check_insn(ctx, ISA_MIPS32R2);
7137            gen_helper_mtc0_srsconf3(cpu_env, arg);
7138            rn = "SRSConf3";
7139            break;
7140        case 5:
7141            check_insn(ctx, ISA_MIPS32R2);
7142            gen_helper_mtc0_srsconf4(cpu_env, arg);
7143            rn = "SRSConf4";
7144            break;
7145        default:
7146            goto cp0_unimplemented;
7147        }
7148        break;
7149    case 7:
7150        switch (sel) {
7151        case 0:
7152            check_insn(ctx, ISA_MIPS32R2);
7153            gen_helper_mtc0_hwrena(cpu_env, arg);
7154            ctx->bstate = BS_STOP;
7155            rn = "HWREna";
7156            break;
7157        default:
7158            goto cp0_unimplemented;
7159        }
7160        break;
7161    case 8:
7162        switch (sel) {
7163        case 0:
7164            /* ignored */
7165            rn = "BadVAddr";
7166            break;
7167        case 1:
7168            /* ignored */
7169            rn = "BadInstr";
7170            break;
7171        case 2:
7172            /* ignored */
7173            rn = "BadInstrP";
7174            break;
7175        default:
7176            goto cp0_unimplemented;
7177        }
7178        break;
7179    case 9:
7180        switch (sel) {
7181        case 0:
7182            gen_helper_mtc0_count(cpu_env, arg);
7183            rn = "Count";
7184            break;
7185        /* 6,7 are implementation dependent */
7186        default:
7187            goto cp0_unimplemented;
7188        }
7189        /* Stop translation as we may have switched the execution mode */
7190        ctx->bstate = BS_STOP;
7191        break;
7192    case 10:
7193        switch (sel) {
7194        case 0:
7195            gen_helper_mtc0_entryhi(cpu_env, arg);
7196            rn = "EntryHi";
7197            break;
7198        default:
7199            goto cp0_unimplemented;
7200        }
7201        break;
7202    case 11:
7203        switch (sel) {
7204        case 0:
7205            gen_helper_mtc0_compare(cpu_env, arg);
7206            rn = "Compare";
7207            break;
7208        /* 6,7 are implementation dependent */
7209        default:
7210            goto cp0_unimplemented;
7211        }
7212        /* Stop translation as we may have switched the execution mode */
7213        ctx->bstate = BS_STOP;
7214        break;
7215    case 12:
7216        switch (sel) {
7217        case 0:
7218            save_cpu_state(ctx, 1);
7219            gen_helper_mtc0_status(cpu_env, arg);
7220            /* BS_STOP isn't good enough here, hflags may have changed. */
7221            gen_save_pc(ctx->pc + 4);
7222            ctx->bstate = BS_EXCP;
7223            rn = "Status";
7224            break;
7225        case 1:
7226            check_insn(ctx, ISA_MIPS32R2);
7227            gen_helper_mtc0_intctl(cpu_env, arg);
7228            /* Stop translation as we may have switched the execution mode */
7229            ctx->bstate = BS_STOP;
7230            rn = "IntCtl";
7231            break;
7232        case 2:
7233            check_insn(ctx, ISA_MIPS32R2);
7234            gen_helper_mtc0_srsctl(cpu_env, arg);
7235            /* Stop translation as we may have switched the execution mode */
7236            ctx->bstate = BS_STOP;
7237            rn = "SRSCtl";
7238            break;
7239        case 3:
7240            check_insn(ctx, ISA_MIPS32R2);
7241            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7242            /* Stop translation as we may have switched the execution mode */
7243            ctx->bstate = BS_STOP;
7244            rn = "SRSMap";
7245            break;
7246        default:
7247            goto cp0_unimplemented;
7248        }
7249        break;
7250    case 13:
7251        switch (sel) {
7252        case 0:
7253            save_cpu_state(ctx, 1);
7254            /* Mark as an IO operation because we may trigger a software
7255               interrupt.  */
7256            if (ctx->tb->cflags & CF_USE_ICOUNT) {
7257                gen_io_start();
7258            }
7259            gen_helper_mtc0_cause(cpu_env, arg);
7260            if (ctx->tb->cflags & CF_USE_ICOUNT) {
7261                gen_io_end();
7262            }
7263            /* Stop translation as we may have triggered an intetrupt */
7264            ctx->bstate = BS_STOP;
7265            rn = "Cause";
7266            break;
7267        default:
7268            goto cp0_unimplemented;
7269        }
7270        break;
7271    case 14:
7272        switch (sel) {
7273        case 0:
7274            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7275            rn = "EPC";
7276            break;
7277        default:
7278            goto cp0_unimplemented;
7279        }
7280        break;
7281    case 15:
7282        switch (sel) {
7283        case 0:
7284            /* ignored */
7285            rn = "PRid";
7286            break;
7287        case 1:
7288            check_insn(ctx, ISA_MIPS32R2);
7289            gen_helper_mtc0_ebase(cpu_env, arg);
7290            rn = "EBase";
7291            break;
7292        default:
7293            goto cp0_unimplemented;
7294        }
7295        break;
7296    case 16:
7297        switch (sel) {
7298        case 0:
7299            gen_helper_mtc0_config0(cpu_env, arg);
7300            rn = "Config";
7301            /* Stop translation as we may have switched the execution mode */
7302            ctx->bstate = BS_STOP;
7303            break;
7304        case 1:
7305            /* ignored, read only */
7306            rn = "Config1";
7307            break;
7308        case 2:
7309            gen_helper_mtc0_config2(cpu_env, arg);
7310            rn = "Config2";
7311            /* Stop translation as we may have switched the execution mode */
7312            ctx->bstate = BS_STOP;
7313            break;
7314        case 3:
7315            gen_helper_mtc0_config3(cpu_env, arg);
7316            rn = "Config3";
7317            /* Stop translation as we may have switched the execution mode */
7318            ctx->bstate = BS_STOP;
7319            break;
7320        case 4:
7321            /* currently ignored */
7322            rn = "Config4";
7323            break;
7324        case 5:
7325            gen_helper_mtc0_config5(cpu_env, arg);
7326            rn = "Config5";
7327            /* Stop translation as we may have switched the execution mode */
7328            ctx->bstate = BS_STOP;
7329            break;
7330        /* 6,7 are implementation dependent */
7331        default:
7332            rn = "Invalid config selector";
7333            goto cp0_unimplemented;
7334        }
7335        break;
7336    case 17:
7337        switch (sel) {
7338        case 0:
7339            gen_helper_mtc0_lladdr(cpu_env, arg);
7340            rn = "LLAddr";
7341            break;
7342        case 1:
7343            CP0_CHECK(ctx->mrp);
7344            gen_helper_mtc0_maar(cpu_env, arg);
7345            rn = "MAAR";
7346            break;
7347        case 2:
7348            CP0_CHECK(ctx->mrp);
7349            gen_helper_mtc0_maari(cpu_env, arg);
7350            rn = "MAARI";
7351            break;
7352        default:
7353            goto cp0_unimplemented;
7354        }
7355        break;
7356    case 18:
7357        switch (sel) {
7358        case 0 ... 7:
7359            gen_helper_0e1i(mtc0_watchlo, arg, sel);
7360            rn = "WatchLo";
7361            break;
7362        default:
7363            goto cp0_unimplemented;
7364        }
7365        break;
7366    case 19:
7367        switch (sel) {
7368        case 0 ... 7:
7369            gen_helper_0e1i(mtc0_watchhi, arg, sel);
7370            rn = "WatchHi";
7371            break;
7372        default:
7373            goto cp0_unimplemented;
7374        }
7375        break;
7376    case 20:
7377        switch (sel) {
7378        case 0:
7379            check_insn(ctx, ISA_MIPS3);
7380            gen_helper_mtc0_xcontext(cpu_env, arg);
7381            rn = "XContext";
7382            break;
7383        default:
7384            goto cp0_unimplemented;
7385        }
7386        break;
7387    case 21:
7388       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7389        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7390        switch (sel) {
7391        case 0:
7392            gen_helper_mtc0_framemask(cpu_env, arg);
7393            rn = "Framemask";
7394            break;
7395        default:
7396            goto cp0_unimplemented;
7397        }
7398        break;
7399    case 22:
7400        /* ignored */
7401        rn = "Diagnostic"; /* implementation dependent */
7402        break;
7403    case 23:
7404        switch (sel) {
7405        case 0:
7406            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7407            /* BS_STOP isn't good enough here, hflags may have changed. */
7408            gen_save_pc(ctx->pc + 4);
7409            ctx->bstate = BS_EXCP;
7410            rn = "Debug";
7411            break;
7412        case 1:
7413//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7414            /* Stop translation as we may have switched the execution mode */
7415            ctx->bstate = BS_STOP;
7416            rn = "TraceControl";
7417//            break;
7418        case 2:
7419//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7420            /* Stop translation as we may have switched the execution mode */
7421            ctx->bstate = BS_STOP;
7422            rn = "TraceControl2";
7423//            break;
7424        case 3:
7425//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7426            /* Stop translation as we may have switched the execution mode */
7427            ctx->bstate = BS_STOP;
7428            rn = "UserTraceData";
7429//            break;
7430        case 4:
7431//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7432            /* Stop translation as we may have switched the execution mode */
7433            ctx->bstate = BS_STOP;
7434            rn = "TraceBPC";
7435//            break;
7436        default:
7437            goto cp0_unimplemented;
7438        }
7439        break;
7440    case 24:
7441        switch (sel) {
7442        case 0:
7443            /* EJTAG support */
7444            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7445            rn = "DEPC";
7446            break;
7447        default:
7448            goto cp0_unimplemented;
7449        }
7450        break;
7451    case 25:
7452        switch (sel) {
7453        case 0:
7454            gen_helper_mtc0_performance0(cpu_env, arg);
7455            rn = "Performance0";
7456            break;
7457        case 1:
7458//            gen_helper_mtc0_performance1(cpu_env, arg);
7459            rn = "Performance1";
7460//            break;
7461        case 2:
7462//            gen_helper_mtc0_performance2(cpu_env, arg);
7463            rn = "Performance2";
7464//            break;
7465        case 3:
7466//            gen_helper_mtc0_performance3(cpu_env, arg);
7467            rn = "Performance3";
7468//            break;
7469        case 4:
7470//            gen_helper_mtc0_performance4(cpu_env, arg);
7471            rn = "Performance4";
7472//            break;
7473        case 5:
7474//            gen_helper_mtc0_performance5(cpu_env, arg);
7475            rn = "Performance5";
7476//            break;
7477        case 6:
7478//            gen_helper_mtc0_performance6(cpu_env, arg);
7479            rn = "Performance6";
7480//            break;
7481        case 7:
7482//            gen_helper_mtc0_performance7(cpu_env, arg);
7483            rn = "Performance7";
7484//            break;
7485        default:
7486            goto cp0_unimplemented;
7487        }
7488        break;
7489    case 26:
7490        switch (sel) {
7491        case 0:
7492            gen_helper_mtc0_errctl(cpu_env, arg);
7493            ctx->bstate = BS_STOP;
7494            rn = "ErrCtl";
7495            break;
7496        default:
7497            goto cp0_unimplemented;
7498        }
7499        break;
7500    case 27:
7501        switch (sel) {
7502        case 0 ... 3:
7503            /* ignored */
7504            rn = "CacheErr";
7505            break;
7506        default:
7507            goto cp0_unimplemented;
7508        }
7509        break;
7510    case 28:
7511        switch (sel) {
7512        case 0:
7513        case 2:
7514        case 4:
7515        case 6:
7516            gen_helper_mtc0_taglo(cpu_env, arg);
7517            rn = "TagLo";
7518            break;
7519        case 1:
7520        case 3:
7521        case 5:
7522        case 7:
7523            gen_helper_mtc0_datalo(cpu_env, arg);
7524            rn = "DataLo";
7525            break;
7526        default:
7527            goto cp0_unimplemented;
7528        }
7529        break;
7530    case 29:
7531        switch (sel) {
7532        case 0:
7533        case 2:
7534        case 4:
7535        case 6:
7536            gen_helper_mtc0_taghi(cpu_env, arg);
7537            rn = "TagHi";
7538            break;
7539        case 1:
7540        case 3:
7541        case 5:
7542        case 7:
7543            gen_helper_mtc0_datahi(cpu_env, arg);
7544            rn = "DataHi";
7545            break;
7546        default:
7547            rn = "invalid sel";
7548            goto cp0_unimplemented;
7549        }
7550        break;
7551    case 30:
7552        switch (sel) {
7553        case 0:
7554            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7555            rn = "ErrorEPC";
7556            break;
7557        default:
7558            goto cp0_unimplemented;
7559        }
7560        break;
7561    case 31:
7562        switch (sel) {
7563        case 0:
7564            /* EJTAG support */
7565            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7566            rn = "DESAVE";
7567            break;
7568        case 2 ... 7:
7569            CP0_CHECK(ctx->kscrexist & (1 << sel));
7570            tcg_gen_st_tl(arg, cpu_env,
7571                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7572            rn = "KScratch";
7573            break;
7574        default:
7575            goto cp0_unimplemented;
7576        }
7577        /* Stop translation as we may have switched the execution mode */
7578        ctx->bstate = BS_STOP;
7579        break;
7580    default:
7581        goto cp0_unimplemented;
7582    }
7583    (void)rn; /* avoid a compiler warning */
7584    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7585    /* For simplicity assume that all writes can cause interrupts.  */
7586    if (ctx->tb->cflags & CF_USE_ICOUNT) {
7587        gen_io_end();
7588        ctx->bstate = BS_STOP;
7589    }
7590    return;
7591
7592cp0_unimplemented:
7593    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7594}
7595#endif /* TARGET_MIPS64 */
7596
7597static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7598                     int u, int sel, int h)
7599{
7600    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7601    TCGv t0 = tcg_temp_local_new();
7602
7603    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7604        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7605         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7606        tcg_gen_movi_tl(t0, -1);
7607    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7608             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7609        tcg_gen_movi_tl(t0, -1);
7610    else if (u == 0) {
7611        switch (rt) {
7612        case 1:
7613            switch (sel) {
7614            case 1:
7615                gen_helper_mftc0_vpecontrol(t0, cpu_env);
7616                break;
7617            case 2:
7618                gen_helper_mftc0_vpeconf0(t0, cpu_env);
7619                break;
7620            default:
7621                goto die;
7622                break;
7623            }
7624            break;
7625        case 2:
7626            switch (sel) {
7627            case 1:
7628                gen_helper_mftc0_tcstatus(t0, cpu_env);
7629                break;
7630            case 2:
7631                gen_helper_mftc0_tcbind(t0, cpu_env);
7632                break;
7633            case 3:
7634                gen_helper_mftc0_tcrestart(t0, cpu_env);
7635                break;
7636            case 4:
7637                gen_helper_mftc0_tchalt(t0, cpu_env);
7638                break;
7639            case 5:
7640                gen_helper_mftc0_tccontext(t0, cpu_env);
7641                break;
7642            case 6:
7643                gen_helper_mftc0_tcschedule(t0, cpu_env);
7644                break;
7645            case 7:
7646                gen_helper_mftc0_tcschefback(t0, cpu_env);
7647                break;
7648            default:
7649                gen_mfc0(ctx, t0, rt, sel);
7650                break;
7651            }
7652            break;
7653        case 10:
7654            switch (sel) {
7655            case 0:
7656                gen_helper_mftc0_entryhi(t0, cpu_env);
7657                break;
7658            default:
7659                gen_mfc0(ctx, t0, rt, sel);
7660                break;
7661            }
7662        case 12:
7663            switch (sel) {
7664            case 0:
7665                gen_helper_mftc0_status(t0, cpu_env);
7666                break;
7667            default:
7668                gen_mfc0(ctx, t0, rt, sel);
7669                break;
7670            }
7671        case 13:
7672            switch (sel) {
7673            case 0:
7674                gen_helper_mftc0_cause(t0, cpu_env);
7675                break;
7676            default:
7677                goto die;
7678                break;
7679            }
7680            break;
7681        case 14:
7682            switch (sel) {
7683            case 0:
7684                gen_helper_mftc0_epc(t0, cpu_env);
7685                break;
7686            default:
7687                goto die;
7688                break;
7689            }
7690            break;
7691        case 15:
7692            switch (sel) {
7693            case 1:
7694                gen_helper_mftc0_ebase(t0, cpu_env);
7695                break;
7696            default:
7697                goto die;
7698                break;
7699            }
7700            break;
7701        case 16:
7702            switch (sel) {
7703            case 0 ... 7:
7704                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7705                break;
7706            default:
7707                goto die;
7708                break;
7709            }
7710            break;
7711        case 23:
7712            switch (sel) {
7713            case 0:
7714                gen_helper_mftc0_debug(t0, cpu_env);
7715                break;
7716            default:
7717                gen_mfc0(ctx, t0, rt, sel);
7718                break;
7719            }
7720            break;
7721        default:
7722            gen_mfc0(ctx, t0, rt, sel);
7723        }
7724    } else switch (sel) {
7725    /* GPR registers. */
7726    case 0:
7727        gen_helper_1e0i(mftgpr, t0, rt);
7728        break;
7729    /* Auxiliary CPU registers */
7730    case 1:
7731        switch (rt) {
7732        case 0:
7733            gen_helper_1e0i(mftlo, t0, 0);
7734            break;
7735        case 1:
7736            gen_helper_1e0i(mfthi, t0, 0);
7737            break;
7738        case 2:
7739            gen_helper_1e0i(mftacx, t0, 0);
7740            break;
7741        case 4:
7742            gen_helper_1e0i(mftlo, t0, 1);
7743            break;
7744        case 5:
7745            gen_helper_1e0i(mfthi, t0, 1);
7746            break;
7747        case 6:
7748            gen_helper_1e0i(mftacx, t0, 1);
7749            break;
7750        case 8:
7751            gen_helper_1e0i(mftlo, t0, 2);
7752            break;
7753        case 9:
7754            gen_helper_1e0i(mfthi, t0, 2);
7755            break;
7756        case 10:
7757            gen_helper_1e0i(mftacx, t0, 2);
7758            break;
7759        case 12:
7760            gen_helper_1e0i(mftlo, t0, 3);
7761            break;
7762        case 13:
7763            gen_helper_1e0i(mfthi, t0, 3);
7764            break;
7765        case 14:
7766            gen_helper_1e0i(mftacx, t0, 3);
7767            break;
7768        case 16:
7769            gen_helper_mftdsp(t0, cpu_env);
7770            break;
7771        default:
7772            goto die;
7773        }
7774        break;
7775    /* Floating point (COP1). */
7776    case 2:
7777        /* XXX: For now we support only a single FPU context. */
7778        if (h == 0) {
7779            TCGv_i32 fp0 = tcg_temp_new_i32();
7780
7781            gen_load_fpr32(ctx, fp0, rt);
7782            tcg_gen_ext_i32_tl(t0, fp0);
7783            tcg_temp_free_i32(fp0);
7784        } else {
7785            TCGv_i32 fp0 = tcg_temp_new_i32();
7786
7787            gen_load_fpr32h(ctx, fp0, rt);
7788            tcg_gen_ext_i32_tl(t0, fp0);
7789            tcg_temp_free_i32(fp0);
7790        }
7791        break;
7792    case 3:
7793        /* XXX: For now we support only a single FPU context. */
7794        gen_helper_1e0i(cfc1, t0, rt);
7795        break;
7796    /* COP2: Not implemented. */
7797    case 4:
7798    case 5:
7799        /* fall through */
7800    default:
7801        goto die;
7802    }
7803    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7804    gen_store_gpr(t0, rd);
7805    tcg_temp_free(t0);
7806    return;
7807
7808die:
7809    tcg_temp_free(t0);
7810    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7811    generate_exception_end(ctx, EXCP_RI);
7812}
7813
7814static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7815                     int u, int sel, int h)
7816{
7817    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7818    TCGv t0 = tcg_temp_local_new();
7819
7820    gen_load_gpr(t0, rt);
7821    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7822        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7823         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7824        /* NOP */ ;
7825    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7826             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7827        /* NOP */ ;
7828    else if (u == 0) {
7829        switch (rd) {
7830        case 1:
7831            switch (sel) {
7832            case 1:
7833                gen_helper_mttc0_vpecontrol(cpu_env, t0);
7834                break;
7835            case 2:
7836                gen_helper_mttc0_vpeconf0(cpu_env, t0);
7837                break;
7838            default:
7839                goto die;
7840                break;
7841            }
7842            break;
7843        case 2:
7844            switch (sel) {
7845            case 1:
7846                gen_helper_mttc0_tcstatus(cpu_env, t0);
7847                break;
7848            case 2:
7849                gen_helper_mttc0_tcbind(cpu_env, t0);
7850                break;
7851            case 3:
7852                gen_helper_mttc0_tcrestart(cpu_env, t0);
7853                break;
7854            case 4:
7855                gen_helper_mttc0_tchalt(cpu_env, t0);
7856                break;
7857            case 5:
7858                gen_helper_mttc0_tccontext(cpu_env, t0);
7859                break;
7860            case 6:
7861                gen_helper_mttc0_tcschedule(cpu_env, t0);
7862                break;
7863            case 7:
7864                gen_helper_mttc0_tcschefback(cpu_env, t0);
7865                break;
7866            default:
7867                gen_mtc0(ctx, t0, rd, sel);
7868                break;
7869            }
7870            break;
7871        case 10:
7872            switch (sel) {
7873            case 0:
7874                gen_helper_mttc0_entryhi(cpu_env, t0);
7875                break;
7876            default:
7877                gen_mtc0(ctx, t0, rd, sel);
7878                break;
7879            }
7880        case 12:
7881            switch (sel) {
7882            case 0:
7883                gen_helper_mttc0_status(cpu_env, t0);
7884                break;
7885            default:
7886                gen_mtc0(ctx, t0, rd, sel);
7887                break;
7888            }
7889        case 13:
7890            switch (sel) {
7891            case 0:
7892                gen_helper_mttc0_cause(cpu_env, t0);
7893                break;
7894            default:
7895                goto die;
7896                break;
7897            }
7898            break;
7899        case 15:
7900            switch (sel) {
7901            case 1:
7902                gen_helper_mttc0_ebase(cpu_env, t0);
7903                break;
7904            default:
7905                goto die;
7906                break;
7907            }
7908            break;
7909        case 23:
7910            switch (sel) {
7911            case 0:
7912                gen_helper_mttc0_debug(cpu_env, t0);
7913                break;
7914            default:
7915                gen_mtc0(ctx, t0, rd, sel);
7916                break;
7917            }
7918            break;
7919        default:
7920            gen_mtc0(ctx, t0, rd, sel);
7921        }
7922    } else switch (sel) {
7923    /* GPR registers. */
7924    case 0:
7925        gen_helper_0e1i(mttgpr, t0, rd);
7926        break;
7927    /* Auxiliary CPU registers */
7928    case 1:
7929        switch (rd) {
7930        case 0:
7931            gen_helper_0e1i(mttlo, t0, 0);
7932            break;
7933        case 1:
7934            gen_helper_0e1i(mtthi, t0, 0);
7935            break;
7936        case 2:
7937            gen_helper_0e1i(mttacx, t0, 0);
7938            break;
7939        case 4:
7940            gen_helper_0e1i(mttlo, t0, 1);
7941            break;
7942        case 5:
7943            gen_helper_0e1i(mtthi, t0, 1);
7944            break;
7945        case 6:
7946            gen_helper_0e1i(mttacx, t0, 1);
7947            break;
7948        case 8:
7949            gen_helper_0e1i(mttlo, t0, 2);
7950            break;
7951        case 9:
7952            gen_helper_0e1i(mtthi, t0, 2);
7953            break;
7954        case 10:
7955            gen_helper_0e1i(mttacx, t0, 2);
7956            break;
7957        case 12:
7958            gen_helper_0e1i(mttlo, t0, 3);
7959            break;
7960        case 13:
7961            gen_helper_0e1i(mtthi, t0, 3);
7962            break;
7963        case 14:
7964            gen_helper_0e1i(mttacx, t0, 3);
7965            break;
7966        case 16:
7967            gen_helper_mttdsp(cpu_env, t0);
7968            break;
7969        default:
7970            goto die;
7971        }
7972        break;
7973    /* Floating point (COP1). */
7974    case 2:
7975        /* XXX: For now we support only a single FPU context. */
7976        if (h == 0) {
7977            TCGv_i32 fp0 = tcg_temp_new_i32();
7978
7979            tcg_gen_trunc_tl_i32(fp0, t0);
7980            gen_store_fpr32(ctx, fp0, rd);
7981            tcg_temp_free_i32(fp0);
7982        } else {
7983            TCGv_i32 fp0 = tcg_temp_new_i32();
7984
7985            tcg_gen_trunc_tl_i32(fp0, t0);
7986            gen_store_fpr32h(ctx, fp0, rd);
7987            tcg_temp_free_i32(fp0);
7988        }
7989        break;
7990    case 3:
7991        /* XXX: For now we support only a single FPU context. */
7992        {
7993            TCGv_i32 fs_tmp = tcg_const_i32(rd);
7994
7995            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7996            tcg_temp_free_i32(fs_tmp);
7997        }
7998        /* Stop translation as we may have changed hflags */
7999        ctx->bstate = BS_STOP;
8000        break;
8001    /* COP2: Not implemented. */
8002    case 4:
8003    case 5:
8004        /* fall through */
8005    default:
8006        goto die;
8007    }
8008    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8009    tcg_temp_free(t0);
8010    return;
8011
8012die:
8013    tcg_temp_free(t0);
8014    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8015    generate_exception_end(ctx, EXCP_RI);
8016}
8017
8018static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8019{
8020    const char *opn = "ldst";
8021
8022    check_cp0_enabled(ctx);
8023    switch (opc) {
8024    case OPC_MFC0:
8025        if (rt == 0) {
8026            /* Treat as NOP. */
8027            return;
8028        }
8029        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8030        opn = "mfc0";
8031        break;
8032    case OPC_MTC0:
8033        {
8034            TCGv t0 = tcg_temp_new();
8035
8036            gen_load_gpr(t0, rt);
8037            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8038            tcg_temp_free(t0);
8039        }
8040        opn = "mtc0";
8041        break;
8042#if defined(TARGET_MIPS64)
8043    case OPC_DMFC0:
8044        check_insn(ctx, ISA_MIPS3);
8045        if (rt == 0) {
8046            /* Treat as NOP. */
8047            return;
8048        }
8049        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8050        opn = "dmfc0";
8051        break;
8052    case OPC_DMTC0:
8053        check_insn(ctx, ISA_MIPS3);
8054        {
8055            TCGv t0 = tcg_temp_new();
8056
8057            gen_load_gpr(t0, rt);
8058            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8059            tcg_temp_free(t0);
8060        }
8061        opn = "dmtc0";
8062        break;
8063#endif
8064    case OPC_MFHC0:
8065        check_mvh(ctx);
8066        if (rt == 0) {
8067            /* Treat as NOP. */
8068            return;
8069        }
8070        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8071        opn = "mfhc0";
8072        break;
8073    case OPC_MTHC0:
8074        check_mvh(ctx);
8075        {
8076            TCGv t0 = tcg_temp_new();
8077            gen_load_gpr(t0, rt);
8078            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8079            tcg_temp_free(t0);
8080        }
8081        opn = "mthc0";
8082        break;
8083    case OPC_MFTR:
8084        check_insn(ctx, ASE_MT);
8085        if (rd == 0) {
8086            /* Treat as NOP. */
8087            return;
8088        }
8089        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8090                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8091        opn = "mftr";
8092        break;
8093    case OPC_MTTR:
8094        check_insn(ctx, ASE_MT);
8095        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8096                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8097        opn = "mttr";
8098        break;
8099    case OPC_TLBWI:
8100        opn = "tlbwi";
8101        if (!env->tlb->helper_tlbwi)
8102            goto die;
8103        gen_helper_tlbwi(cpu_env);
8104        break;
8105    case OPC_TLBINV:
8106        opn = "tlbinv";
8107        if (ctx->ie >= 2) {
8108            if (!env->tlb->helper_tlbinv) {
8109                goto die;
8110            }
8111            gen_helper_tlbinv(cpu_env);
8112        } /* treat as nop if TLBINV not supported */
8113        break;
8114    case OPC_TLBINVF:
8115        opn = "tlbinvf";
8116        if (ctx->ie >= 2) {
8117            if (!env->tlb->helper_tlbinvf) {
8118                goto die;
8119            }
8120            gen_helper_tlbinvf(cpu_env);
8121        } /* treat as nop if TLBINV not supported */
8122        break;
8123    case OPC_TLBWR:
8124        opn = "tlbwr";
8125        if (!env->tlb->helper_tlbwr)
8126            goto die;
8127        gen_helper_tlbwr(cpu_env);
8128        break;
8129    case OPC_TLBP:
8130        opn = "tlbp";
8131        if (!env->tlb->helper_tlbp)
8132            goto die;
8133        gen_helper_tlbp(cpu_env);
8134        break;
8135    case OPC_TLBR:
8136        opn = "tlbr";
8137        if (!env->tlb->helper_tlbr)
8138            goto die;
8139        gen_helper_tlbr(cpu_env);
8140        break;
8141    case OPC_ERET: /* OPC_ERETNC */
8142        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8143            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8144            goto die;
8145        } else {
8146            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8147            if (ctx->opcode & (1 << bit_shift)) {
8148                /* OPC_ERETNC */
8149                opn = "eretnc";
8150                check_insn(ctx, ISA_MIPS32R5);
8151                gen_helper_eretnc(cpu_env);
8152            } else {
8153                /* OPC_ERET */
8154                opn = "eret";
8155                check_insn(ctx, ISA_MIPS2);
8156                gen_helper_eret(cpu_env);
8157            }
8158            ctx->bstate = BS_EXCP;
8159        }
8160        break;
8161    case OPC_DERET:
8162        opn = "deret";
8163        check_insn(ctx, ISA_MIPS32);
8164        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8165            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8166            goto die;
8167        }
8168        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8169            MIPS_INVAL(opn);
8170            generate_exception_end(ctx, EXCP_RI);
8171        } else {
8172            gen_helper_deret(cpu_env);
8173            ctx->bstate = BS_EXCP;
8174        }
8175        break;
8176    case OPC_WAIT:
8177        opn = "wait";
8178        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8179        if ((ctx->insn_flags & ISA_MIPS32R6) &&
8180            (ctx->hflags & MIPS_HFLAG_BMASK)) {
8181            goto die;
8182        }
8183        /* If we get an exception, we want to restart at next instruction */
8184        ctx->pc += 4;
8185        save_cpu_state(ctx, 1);
8186        ctx->pc -= 4;
8187        gen_helper_wait(cpu_env);
8188        ctx->bstate = BS_EXCP;
8189        break;
8190    default:
8191 die:
8192        MIPS_INVAL(opn);
8193        generate_exception_end(ctx, EXCP_RI);
8194        return;
8195    }
8196    (void)opn; /* avoid a compiler warning */
8197}
8198#endif /* !CONFIG_USER_ONLY */
8199
8200/* CP1 Branches (before delay slot) */
8201static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8202                                int32_t cc, int32_t offset)
8203{
8204    target_ulong btarget;
8205    TCGv_i32 t0 = tcg_temp_new_i32();
8206
8207    if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8208        generate_exception_end(ctx, EXCP_RI);
8209        goto out;
8210    }
8211
8212    if (cc != 0)
8213        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8214
8215    btarget = ctx->pc + 4 + offset;
8216
8217    switch (op) {
8218    case OPC_BC1F:
8219        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8220        tcg_gen_not_i32(t0, t0);
8221        tcg_gen_andi_i32(t0, t0, 1);
8222        tcg_gen_extu_i32_tl(bcond, t0);
8223        goto not_likely;
8224    case OPC_BC1FL:
8225        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8226        tcg_gen_not_i32(t0, t0);
8227        tcg_gen_andi_i32(t0, t0, 1);
8228        tcg_gen_extu_i32_tl(bcond, t0);
8229        goto likely;
8230    case OPC_BC1T:
8231        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8232        tcg_gen_andi_i32(t0, t0, 1);
8233        tcg_gen_extu_i32_tl(bcond, t0);
8234        goto not_likely;
8235    case OPC_BC1TL:
8236        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8237        tcg_gen_andi_i32(t0, t0, 1);
8238        tcg_gen_extu_i32_tl(bcond, t0);
8239    likely:
8240        ctx->hflags |= MIPS_HFLAG_BL;
8241        break;
8242    case OPC_BC1FANY2:
8243        {
8244            TCGv_i32 t1 = tcg_temp_new_i32();
8245            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8246            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8247            tcg_gen_nand_i32(t0, t0, t1);
8248            tcg_temp_free_i32(t1);
8249            tcg_gen_andi_i32(t0, t0, 1);
8250            tcg_gen_extu_i32_tl(bcond, t0);
8251        }
8252        goto not_likely;
8253    case OPC_BC1TANY2:
8254        {
8255            TCGv_i32 t1 = tcg_temp_new_i32();
8256            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8257            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8258            tcg_gen_or_i32(t0, t0, t1);
8259            tcg_temp_free_i32(t1);
8260            tcg_gen_andi_i32(t0, t0, 1);
8261            tcg_gen_extu_i32_tl(bcond, t0);
8262        }
8263        goto not_likely;
8264    case OPC_BC1FANY4:
8265        {
8266            TCGv_i32 t1 = tcg_temp_new_i32();
8267            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8268            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8269            tcg_gen_and_i32(t0, t0, t1);
8270            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8271            tcg_gen_and_i32(t0, t0, t1);
8272            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8273            tcg_gen_nand_i32(t0, t0, t1);
8274            tcg_temp_free_i32(t1);
8275            tcg_gen_andi_i32(t0, t0, 1);
8276            tcg_gen_extu_i32_tl(bcond, t0);
8277        }
8278        goto not_likely;
8279    case OPC_BC1TANY4:
8280        {
8281            TCGv_i32 t1 = tcg_temp_new_i32();
8282            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8283            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8284            tcg_gen_or_i32(t0, t0, t1);
8285            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8286            tcg_gen_or_i32(t0, t0, t1);
8287            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8288            tcg_gen_or_i32(t0, t0, t1);
8289            tcg_temp_free_i32(t1);
8290            tcg_gen_andi_i32(t0, t0, 1);
8291            tcg_gen_extu_i32_tl(bcond, t0);
8292        }
8293    not_likely:
8294        ctx->hflags |= MIPS_HFLAG_BC;
8295        break;
8296    default:
8297        MIPS_INVAL("cp1 cond branch");
8298        generate_exception_end(ctx, EXCP_RI);
8299        goto out;
8300    }
8301    ctx->btarget = btarget;
8302    ctx->hflags |= MIPS_HFLAG_BDS32;
8303 out:
8304    tcg_temp_free_i32(t0);
8305}
8306
8307/* R6 CP1 Branches */
8308static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8309                                   int32_t ft, int32_t offset,
8310                                   int delayslot_size)
8311{
8312    target_ulong btarget;
8313    TCGv_i64 t0 = tcg_temp_new_i64();
8314
8315    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8316#ifdef MIPS_DEBUG_DISAS
8317        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8318                  "\n", ctx->pc);
8319#endif
8320        generate_exception_end(ctx, EXCP_RI);
8321        goto out;
8322    }
8323
8324    gen_load_fpr64(ctx, t0, ft);
8325    tcg_gen_andi_i64(t0, t0, 1);
8326
8327    btarget = addr_add(ctx, ctx->pc + 4, offset);
8328
8329    switch (op) {
8330    case OPC_BC1EQZ:
8331        tcg_gen_xori_i64(t0, t0, 1);
8332        ctx->hflags |= MIPS_HFLAG_BC;
8333        break;
8334    case OPC_BC1NEZ:
8335        /* t0 already set */
8336        ctx->hflags |= MIPS_HFLAG_BC;
8337        break;
8338    default:
8339        MIPS_INVAL("cp1 cond branch");
8340        generate_exception_end(ctx, EXCP_RI);
8341        goto out;
8342    }
8343
8344    tcg_gen_trunc_i64_tl(bcond, t0);
8345
8346    ctx->btarget = btarget;
8347
8348    switch (delayslot_size) {
8349    case 2:
8350        ctx->hflags |= MIPS_HFLAG_BDS16;
8351        break;
8352    case 4:
8353        ctx->hflags |= MIPS_HFLAG_BDS32;
8354        break;
8355    }
8356
8357out:
8358    tcg_temp_free_i64(t0);
8359}
8360
8361/* Coprocessor 1 (FPU) */
8362
8363#define FOP(func, fmt) (((fmt) << 21) | (func))
8364
8365enum fopcode {
8366    OPC_ADD_S = FOP(0, FMT_S),
8367    OPC_SUB_S = FOP(1, FMT_S),
8368    OPC_MUL_S = FOP(2, FMT_S),
8369    OPC_DIV_S = FOP(3, FMT_S),
8370    OPC_SQRT_S = FOP(4, FMT_S),
8371    OPC_ABS_S = FOP(5, FMT_S),
8372    OPC_MOV_S = FOP(6, FMT_S),
8373    OPC_NEG_S = FOP(7, FMT_S),
8374    OPC_ROUND_L_S = FOP(8, FMT_S),
8375    OPC_TRUNC_L_S = FOP(9, FMT_S),
8376    OPC_CEIL_L_S = FOP(10, FMT_S),
8377    OPC_FLOOR_L_S = FOP(11, FMT_S),
8378    OPC_ROUND_W_S = FOP(12, FMT_S),
8379    OPC_TRUNC_W_S = FOP(13, FMT_S),
8380    OPC_CEIL_W_S = FOP(14, FMT_S),
8381    OPC_FLOOR_W_S = FOP(15, FMT_S),
8382    OPC_SEL_S = FOP(16, FMT_S),
8383    OPC_MOVCF_S = FOP(17, FMT_S),
8384    OPC_MOVZ_S = FOP(18, FMT_S),
8385    OPC_MOVN_S = FOP(19, FMT_S),
8386    OPC_SELEQZ_S = FOP(20, FMT_S),
8387    OPC_RECIP_S = FOP(21, FMT_S),
8388    OPC_RSQRT_S = FOP(22, FMT_S),
8389    OPC_SELNEZ_S = FOP(23, FMT_S),
8390    OPC_MADDF_S = FOP(24, FMT_S),
8391    OPC_MSUBF_S = FOP(25, FMT_S),
8392    OPC_RINT_S = FOP(26, FMT_S),
8393    OPC_CLASS_S = FOP(27, FMT_S),
8394    OPC_MIN_S = FOP(28, FMT_S),
8395    OPC_RECIP2_S = FOP(28, FMT_S),
8396    OPC_MINA_S = FOP(29, FMT_S),
8397    OPC_RECIP1_S = FOP(29, FMT_S),
8398    OPC_MAX_S = FOP(30, FMT_S),
8399    OPC_RSQRT1_S = FOP(30, FMT_S),
8400    OPC_MAXA_S = FOP(31, FMT_S),
8401    OPC_RSQRT2_S = FOP(31, FMT_S),
8402    OPC_CVT_D_S = FOP(33, FMT_S),
8403    OPC_CVT_W_S = FOP(36, FMT_S),
8404    OPC_CVT_L_S = FOP(37, FMT_S),
8405    OPC_CVT_PS_S = FOP(38, FMT_S),
8406    OPC_CMP_F_S = FOP (48, FMT_S),
8407    OPC_CMP_UN_S = FOP (49, FMT_S),
8408    OPC_CMP_EQ_S = FOP (50, FMT_S),
8409    OPC_CMP_UEQ_S = FOP (51, FMT_S),
8410    OPC_CMP_OLT_S = FOP (52, FMT_S),
8411    OPC_CMP_ULT_S = FOP (53, FMT_S),
8412    OPC_CMP_OLE_S = FOP (54, FMT_S),
8413    OPC_CMP_ULE_S = FOP (55, FMT_S),
8414    OPC_CMP_SF_S = FOP (56, FMT_S),
8415    OPC_CMP_NGLE_S = FOP (57, FMT_S),
8416    OPC_CMP_SEQ_S = FOP (58, FMT_S),
8417    OPC_CMP_NGL_S = FOP (59, FMT_S),
8418    OPC_CMP_LT_S = FOP (60, FMT_S),
8419    OPC_CMP_NGE_S = FOP (61, FMT_S),
8420    OPC_CMP_LE_S = FOP (62, FMT_S),
8421    OPC_CMP_NGT_S = FOP (63, FMT_S),
8422
8423    OPC_ADD_D = FOP(0, FMT_D),
8424    OPC_SUB_D = FOP(1, FMT_D),
8425    OPC_MUL_D = FOP(2, FMT_D),
8426    OPC_DIV_D = FOP(3, FMT_D),
8427    OPC_SQRT_D = FOP(4, FMT_D),
8428    OPC_ABS_D = FOP(5, FMT_D),
8429    OPC_MOV_D = FOP(6, FMT_D),
8430    OPC_NEG_D = FOP(7, FMT_D),
8431    OPC_ROUND_L_D = FOP(8, FMT_D),
8432    OPC_TRUNC_L_D = FOP(9, FMT_D),
8433    OPC_CEIL_L_D = FOP(10, FMT_D),
8434    OPC_FLOOR_L_D = FOP(11, FMT_D),
8435    OPC_ROUND_W_D = FOP(12, FMT_D),
8436    OPC_TRUNC_W_D = FOP(13, FMT_D),
8437    OPC_CEIL_W_D = FOP(14, FMT_D),
8438    OPC_FLOOR_W_D = FOP(15, FMT_D),
8439    OPC_SEL_D = FOP(16, FMT_D),
8440    OPC_MOVCF_D = FOP(17, FMT_D),
8441    OPC_MOVZ_D = FOP(18, FMT_D),
8442    OPC_MOVN_D = FOP(19, FMT_D),
8443    OPC_SELEQZ_D = FOP(20, FMT_D),
8444    OPC_RECIP_D = FOP(21, FMT_D),
8445    OPC_RSQRT_D = FOP(22, FMT_D),
8446    OPC_SELNEZ_D = FOP(23, FMT_D),
8447    OPC_MADDF_D = FOP(24, FMT_D),
8448    OPC_MSUBF_D = FOP(25, FMT_D),
8449    OPC_RINT_D = FOP(26, FMT_D),
8450    OPC_CLASS_D = FOP(27, FMT_D),
8451    OPC_MIN_D = FOP(28, FMT_D),
8452    OPC_RECIP2_D = FOP(28, FMT_D),
8453    OPC_MINA_D = FOP(29, FMT_D),
8454    OPC_RECIP1_D = FOP(29, FMT_D),
8455    OPC_MAX_D = FOP(30, FMT_D),
8456    OPC_RSQRT1_D = FOP(30, FMT_D),
8457    OPC_MAXA_D = FOP(31, FMT_D),
8458    OPC_RSQRT2_D = FOP(31, FMT_D),
8459    OPC_CVT_S_D = FOP(32, FMT_D),
8460    OPC_CVT_W_D = FOP(36, FMT_D),
8461    OPC_CVT_L_D = FOP(37, FMT_D),
8462    OPC_CMP_F_D = FOP (48, FMT_D),
8463    OPC_CMP_UN_D = FOP (49, FMT_D),
8464    OPC_CMP_EQ_D = FOP (50, FMT_D),
8465    OPC_CMP_UEQ_D = FOP (51, FMT_D),
8466    OPC_CMP_OLT_D = FOP (52, FMT_D),
8467    OPC_CMP_ULT_D = FOP (53, FMT_D),
8468    OPC_CMP_OLE_D = FOP (54, FMT_D),
8469    OPC_CMP_ULE_D = FOP (55, FMT_D),
8470    OPC_CMP_SF_D = FOP (56, FMT_D),
8471    OPC_CMP_NGLE_D = FOP (57, FMT_D),
8472    OPC_CMP_SEQ_D = FOP (58, FMT_D),
8473    OPC_CMP_NGL_D = FOP (59, FMT_D),
8474    OPC_CMP_LT_D = FOP (60, FMT_D),
8475    OPC_CMP_NGE_D = FOP (61, FMT_D),
8476    OPC_CMP_LE_D = FOP (62, FMT_D),
8477    OPC_CMP_NGT_D = FOP (63, FMT_D),
8478
8479    OPC_CVT_S_W = FOP(32, FMT_W),
8480    OPC_CVT_D_W = FOP(33, FMT_W),
8481    OPC_CVT_S_L = FOP(32, FMT_L),
8482    OPC_CVT_D_L = FOP(33, FMT_L),
8483    OPC_CVT_PS_PW = FOP(38, FMT_W),
8484
8485    OPC_ADD_PS = FOP(0, FMT_PS),
8486    OPC_SUB_PS = FOP(1, FMT_PS),
8487    OPC_MUL_PS = FOP(2, FMT_PS),
8488    OPC_DIV_PS = FOP(3, FMT_PS),
8489    OPC_ABS_PS = FOP(5, FMT_PS),
8490    OPC_MOV_PS = FOP(6, FMT_PS),
8491    OPC_NEG_PS = FOP(7, FMT_PS),
8492    OPC_MOVCF_PS = FOP(17, FMT_PS),
8493    OPC_MOVZ_PS = FOP(18, FMT_PS),
8494    OPC_MOVN_PS = FOP(19, FMT_PS),
8495    OPC_ADDR_PS = FOP(24, FMT_PS),
8496    OPC_MULR_PS = FOP(26, FMT_PS),
8497    OPC_RECIP2_PS = FOP(28, FMT_PS),
8498    OPC_RECIP1_PS = FOP(29, FMT_PS),
8499    OPC_RSQRT1_PS = FOP(30, FMT_PS),
8500    OPC_RSQRT2_PS = FOP(31, FMT_PS),
8501
8502    OPC_CVT_S_PU = FOP(32, FMT_PS),
8503    OPC_CVT_PW_PS = FOP(36, FMT_PS),
8504    OPC_CVT_S_PL = FOP(40, FMT_PS),
8505    OPC_PLL_PS = FOP(44, FMT_PS),
8506    OPC_PLU_PS = FOP(45, FMT_PS),
8507    OPC_PUL_PS = FOP(46, FMT_PS),
8508    OPC_PUU_PS = FOP(47, FMT_PS),
8509    OPC_CMP_F_PS = FOP (48, FMT_PS),
8510    OPC_CMP_UN_PS = FOP (49, FMT_PS),
8511    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8512    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8513    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8514    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8515    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8516    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8517    OPC_CMP_SF_PS = FOP (56, FMT_PS),
8518    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8519    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8520    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8521    OPC_CMP_LT_PS = FOP (60, FMT_PS),
8522    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8523    OPC_CMP_LE_PS = FOP (62, FMT_PS),
8524    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8525};
8526
8527enum r6_f_cmp_op {
8528    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
8529    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
8530    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
8531    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
8532    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
8533    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
8534    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
8535    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
8536    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
8537    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
8538    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
8539    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8540    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
8541    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8542    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
8543    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8544    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
8545    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
8546    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
8547    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
8548    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8549    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
8550
8551    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
8552    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
8553    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
8554    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
8555    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
8556    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
8557    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
8558    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
8559    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
8560    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
8561    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
8562    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8563    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
8564    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8565    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
8566    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8567    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
8568    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
8569    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
8570    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
8571    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8572    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
8573};
8574static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8575{
8576    TCGv t0 = tcg_temp_new();
8577
8578    switch (opc) {
8579    case OPC_MFC1:
8580        {
8581            TCGv_i32 fp0 = tcg_temp_new_i32();
8582
8583            gen_load_fpr32(ctx, fp0, fs);
8584            tcg_gen_ext_i32_tl(t0, fp0);
8585            tcg_temp_free_i32(fp0);
8586        }
8587        gen_store_gpr(t0, rt);
8588        break;
8589    case OPC_MTC1:
8590        gen_load_gpr(t0, rt);
8591        {
8592            TCGv_i32 fp0 = tcg_temp_new_i32();
8593
8594            tcg_gen_trunc_tl_i32(fp0, t0);
8595            gen_store_fpr32(ctx, fp0, fs);
8596            tcg_temp_free_i32(fp0);
8597        }
8598        break;
8599    case OPC_CFC1:
8600        gen_helper_1e0i(cfc1, t0, fs);
8601        gen_store_gpr(t0, rt);
8602        break;
8603    case OPC_CTC1:
8604        gen_load_gpr(t0, rt);
8605        save_cpu_state(ctx, 0);
8606        {
8607            TCGv_i32 fs_tmp = tcg_const_i32(fs);
8608
8609            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8610            tcg_temp_free_i32(fs_tmp);
8611        }
8612        /* Stop translation as we may have changed hflags */
8613        ctx->bstate = BS_STOP;
8614        break;
8615#if defined(TARGET_MIPS64)
8616    case OPC_DMFC1:
8617        gen_load_fpr64(ctx, t0, fs);
8618        gen_store_gpr(t0, rt);
8619        break;
8620    case OPC_DMTC1:
8621        gen_load_gpr(t0, rt);
8622        gen_store_fpr64(ctx, t0, fs);
8623        break;
8624#endif
8625    case OPC_MFHC1:
8626        {
8627            TCGv_i32 fp0 = tcg_temp_new_i32();
8628
8629            gen_load_fpr32h(ctx, fp0, fs);
8630            tcg_gen_ext_i32_tl(t0, fp0);
8631            tcg_temp_free_i32(fp0);
8632        }
8633        gen_store_gpr(t0, rt);
8634        break;
8635    case OPC_MTHC1:
8636        gen_load_gpr(t0, rt);
8637        {
8638            TCGv_i32 fp0 = tcg_temp_new_i32();
8639
8640            tcg_gen_trunc_tl_i32(fp0, t0);
8641            gen_store_fpr32h(ctx, fp0, fs);
8642            tcg_temp_free_i32(fp0);
8643        }
8644        break;
8645    default:
8646        MIPS_INVAL("cp1 move");
8647        generate_exception_end(ctx, EXCP_RI);
8648        goto out;
8649    }
8650
8651 out:
8652    tcg_temp_free(t0);
8653}
8654
8655static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8656{
8657    TCGLabel *l1;
8658    TCGCond cond;
8659    TCGv_i32 t0;
8660
8661    if (rd == 0) {
8662        /* Treat as NOP. */
8663        return;
8664    }
8665
8666    if (tf)
8667        cond = TCG_COND_EQ;
8668    else
8669        cond = TCG_COND_NE;
8670
8671    l1 = gen_new_label();
8672    t0 = tcg_temp_new_i32();
8673    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8674    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8675    tcg_temp_free_i32(t0);
8676    if (rs == 0) {
8677        tcg_gen_movi_tl(cpu_gpr[rd], 0);
8678    } else {
8679        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8680    }
8681    gen_set_label(l1);
8682}
8683
8684static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8685                               int tf)
8686{
8687    int cond;
8688    TCGv_i32 t0 = tcg_temp_new_i32();
8689    TCGLabel *l1 = gen_new_label();
8690
8691    if (tf)
8692        cond = TCG_COND_EQ;
8693    else
8694        cond = TCG_COND_NE;
8695
8696    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8697    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8698    gen_load_fpr32(ctx, t0, fs);
8699    gen_store_fpr32(ctx, t0, fd);
8700    gen_set_label(l1);
8701    tcg_temp_free_i32(t0);
8702}
8703
8704static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8705{
8706    int cond;
8707    TCGv_i32 t0 = tcg_temp_new_i32();
8708    TCGv_i64 fp0;
8709    TCGLabel *l1 = gen_new_label();
8710
8711    if (tf)
8712        cond = TCG_COND_EQ;
8713    else
8714        cond = TCG_COND_NE;
8715
8716    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8717    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8718    tcg_temp_free_i32(t0);
8719    fp0 = tcg_temp_new_i64();
8720    gen_load_fpr64(ctx, fp0, fs);
8721    gen_store_fpr64(ctx, fp0, fd);
8722    tcg_temp_free_i64(fp0);
8723    gen_set_label(l1);
8724}
8725
8726static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8727                                int cc, int tf)
8728{
8729    int cond;
8730    TCGv_i32 t0 = tcg_temp_new_i32();
8731    TCGLabel *l1 = gen_new_label();
8732    TCGLabel *l2 = gen_new_label();
8733
8734    if (tf)
8735        cond = TCG_COND_EQ;
8736    else
8737        cond = TCG_COND_NE;
8738
8739    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8740    tcg_gen_brcondi_i32(cond, t0, 0, l1);
8741    gen_load_fpr32(ctx, t0, fs);
8742    gen_store_fpr32(ctx, t0, fd);
8743    gen_set_label(l1);
8744
8745    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8746    tcg_gen_brcondi_i32(cond, t0, 0, l2);
8747    gen_load_fpr32h(ctx, t0, fs);
8748    gen_store_fpr32h(ctx, t0, fd);
8749    tcg_temp_free_i32(t0);
8750    gen_set_label(l2);
8751}
8752
8753static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8754                      int fs)
8755{
8756    TCGv_i32 t1 = tcg_const_i32(0);
8757    TCGv_i32 fp0 = tcg_temp_new_i32();
8758    TCGv_i32 fp1 = tcg_temp_new_i32();
8759    TCGv_i32 fp2 = tcg_temp_new_i32();
8760    gen_load_fpr32(ctx, fp0, fd);
8761    gen_load_fpr32(ctx, fp1, ft);
8762    gen_load_fpr32(ctx, fp2, fs);
8763
8764    switch (op1) {
8765    case OPC_SEL_S:
8766        tcg_gen_andi_i32(fp0, fp0, 1);
8767        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8768        break;
8769    case OPC_SELEQZ_S:
8770        tcg_gen_andi_i32(fp1, fp1, 1);
8771        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8772        break;
8773    case OPC_SELNEZ_S:
8774        tcg_gen_andi_i32(fp1, fp1, 1);
8775        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8776        break;
8777    default:
8778        MIPS_INVAL("gen_sel_s");
8779        generate_exception_end(ctx, EXCP_RI);
8780        break;
8781    }
8782
8783    gen_store_fpr32(ctx, fp0, fd);
8784    tcg_temp_free_i32(fp2);
8785    tcg_temp_free_i32(fp1);
8786    tcg_temp_free_i32(fp0);
8787    tcg_temp_free_i32(t1);
8788}
8789
8790static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8791                      int fs)
8792{
8793    TCGv_i64 t1 = tcg_const_i64(0);
8794    TCGv_i64 fp0 = tcg_temp_new_i64();
8795    TCGv_i64 fp1 = tcg_temp_new_i64();
8796    TCGv_i64 fp2 = tcg_temp_new_i64();
8797    gen_load_fpr64(ctx, fp0, fd);
8798    gen_load_fpr64(ctx, fp1, ft);
8799    gen_load_fpr64(ctx, fp2, fs);
8800
8801    switch (op1) {
8802    case OPC_SEL_D:
8803        tcg_gen_andi_i64(fp0, fp0, 1);
8804        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8805        break;
8806    case OPC_SELEQZ_D:
8807        tcg_gen_andi_i64(fp1, fp1, 1);
8808        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8809        break;
8810    case OPC_SELNEZ_D:
8811        tcg_gen_andi_i64(fp1, fp1, 1);
8812        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8813        break;
8814    default:
8815        MIPS_INVAL("gen_sel_d");
8816        generate_exception_end(ctx, EXCP_RI);
8817        break;
8818    }
8819
8820    gen_store_fpr64(ctx, fp0, fd);
8821    tcg_temp_free_i64(fp2);
8822    tcg_temp_free_i64(fp1);
8823    tcg_temp_free_i64(fp0);
8824    tcg_temp_free_i64(t1);
8825}
8826
8827static void gen_farith (DisasContext *ctx, enum fopcode op1,
8828                        int ft, int fs, int fd, int cc)
8829{
8830    uint32_t func = ctx->opcode & 0x3f;
8831    switch (op1) {
8832    case OPC_ADD_S:
8833        {
8834            TCGv_i32 fp0 = tcg_temp_new_i32();
8835            TCGv_i32 fp1 = tcg_temp_new_i32();
8836
8837            gen_load_fpr32(ctx, fp0, fs);
8838            gen_load_fpr32(ctx, fp1, ft);
8839            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8840            tcg_temp_free_i32(fp1);
8841            gen_store_fpr32(ctx, fp0, fd);
8842            tcg_temp_free_i32(fp0);
8843        }
8844        break;
8845    case OPC_SUB_S:
8846        {
8847            TCGv_i32 fp0 = tcg_temp_new_i32();
8848            TCGv_i32 fp1 = tcg_temp_new_i32();
8849
8850            gen_load_fpr32(ctx, fp0, fs);
8851            gen_load_fpr32(ctx, fp1, ft);
8852            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8853            tcg_temp_free_i32(fp1);
8854            gen_store_fpr32(ctx, fp0, fd);
8855            tcg_temp_free_i32(fp0);
8856        }
8857        break;
8858    case OPC_MUL_S:
8859        {
8860            TCGv_i32 fp0 = tcg_temp_new_i32();
8861            TCGv_i32 fp1 = tcg_temp_new_i32();
8862
8863            gen_load_fpr32(ctx, fp0, fs);
8864            gen_load_fpr32(ctx, fp1, ft);
8865            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8866            tcg_temp_free_i32(fp1);
8867            gen_store_fpr32(ctx, fp0, fd);
8868            tcg_temp_free_i32(fp0);
8869        }
8870        break;
8871    case OPC_DIV_S:
8872        {
8873            TCGv_i32 fp0 = tcg_temp_new_i32();
8874            TCGv_i32 fp1 = tcg_temp_new_i32();
8875
8876            gen_load_fpr32(ctx, fp0, fs);
8877            gen_load_fpr32(ctx, fp1, ft);
8878            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8879            tcg_temp_free_i32(fp1);
8880            gen_store_fpr32(ctx, fp0, fd);
8881            tcg_temp_free_i32(fp0);
8882        }
8883        break;
8884    case OPC_SQRT_S:
8885        {
8886            TCGv_i32 fp0 = tcg_temp_new_i32();
8887
8888            gen_load_fpr32(ctx, fp0, fs);
8889            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8890            gen_store_fpr32(ctx, fp0, fd);
8891            tcg_temp_free_i32(fp0);
8892        }
8893        break;
8894    case OPC_ABS_S:
8895        {
8896            TCGv_i32 fp0 = tcg_temp_new_i32();
8897
8898            gen_load_fpr32(ctx, fp0, fs);
8899            if (ctx->abs2008) {
8900                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
8901            } else {
8902                gen_helper_float_abs_s(fp0, fp0);
8903            }
8904            gen_store_fpr32(ctx, fp0, fd);
8905            tcg_temp_free_i32(fp0);
8906        }
8907        break;
8908    case OPC_MOV_S:
8909        {
8910            TCGv_i32 fp0 = tcg_temp_new_i32();
8911
8912            gen_load_fpr32(ctx, fp0, fs);
8913            gen_store_fpr32(ctx, fp0, fd);
8914            tcg_temp_free_i32(fp0);
8915        }
8916        break;
8917    case OPC_NEG_S:
8918        {
8919            TCGv_i32 fp0 = tcg_temp_new_i32();
8920
8921            gen_load_fpr32(ctx, fp0, fs);
8922            if (ctx->abs2008) {
8923                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
8924            } else {
8925                gen_helper_float_chs_s(fp0, fp0);
8926            }
8927            gen_store_fpr32(ctx, fp0, fd);
8928            tcg_temp_free_i32(fp0);
8929        }
8930        break;
8931    case OPC_ROUND_L_S:
8932        check_cp1_64bitmode(ctx);
8933        {
8934            TCGv_i32 fp32 = tcg_temp_new_i32();
8935            TCGv_i64 fp64 = tcg_temp_new_i64();
8936
8937            gen_load_fpr32(ctx, fp32, fs);
8938            if (ctx->nan2008) {
8939                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
8940            } else {
8941                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
8942            }
8943            tcg_temp_free_i32(fp32);
8944            gen_store_fpr64(ctx, fp64, fd);
8945            tcg_temp_free_i64(fp64);
8946        }
8947        break;
8948    case OPC_TRUNC_L_S:
8949        check_cp1_64bitmode(ctx);
8950        {
8951            TCGv_i32 fp32 = tcg_temp_new_i32();
8952            TCGv_i64 fp64 = tcg_temp_new_i64();
8953
8954            gen_load_fpr32(ctx, fp32, fs);
8955            if (ctx->nan2008) {
8956                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
8957            } else {
8958                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
8959            }
8960            tcg_temp_free_i32(fp32);
8961            gen_store_fpr64(ctx, fp64, fd);
8962            tcg_temp_free_i64(fp64);
8963        }
8964        break;
8965    case OPC_CEIL_L_S:
8966        check_cp1_64bitmode(ctx);
8967        {
8968            TCGv_i32 fp32 = tcg_temp_new_i32();
8969            TCGv_i64 fp64 = tcg_temp_new_i64();
8970
8971            gen_load_fpr32(ctx, fp32, fs);
8972            if (ctx->nan2008) {
8973                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
8974            } else {
8975                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
8976            }
8977            tcg_temp_free_i32(fp32);
8978            gen_store_fpr64(ctx, fp64, fd);
8979            tcg_temp_free_i64(fp64);
8980        }
8981        break;
8982    case OPC_FLOOR_L_S:
8983        check_cp1_64bitmode(ctx);
8984        {
8985            TCGv_i32 fp32 = tcg_temp_new_i32();
8986            TCGv_i64 fp64 = tcg_temp_new_i64();
8987
8988            gen_load_fpr32(ctx, fp32, fs);
8989            if (ctx->nan2008) {
8990                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
8991            } else {
8992                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
8993            }
8994            tcg_temp_free_i32(fp32);
8995            gen_store_fpr64(ctx, fp64, fd);
8996            tcg_temp_free_i64(fp64);
8997        }
8998        break;
8999    case OPC_ROUND_W_S:
9000        {
9001            TCGv_i32 fp0 = tcg_temp_new_i32();
9002
9003            gen_load_fpr32(ctx, fp0, fs);
9004            if (ctx->nan2008) {
9005                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9006            } else {
9007                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9008            }
9009            gen_store_fpr32(ctx, fp0, fd);
9010            tcg_temp_free_i32(fp0);
9011        }
9012        break;
9013    case OPC_TRUNC_W_S:
9014        {
9015            TCGv_i32 fp0 = tcg_temp_new_i32();
9016
9017            gen_load_fpr32(ctx, fp0, fs);
9018            if (ctx->nan2008) {
9019                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9020            } else {
9021                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9022            }
9023            gen_store_fpr32(ctx, fp0, fd);
9024            tcg_temp_free_i32(fp0);
9025        }
9026        break;
9027    case OPC_CEIL_W_S:
9028        {
9029            TCGv_i32 fp0 = tcg_temp_new_i32();
9030
9031            gen_load_fpr32(ctx, fp0, fs);
9032            if (ctx->nan2008) {
9033                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9034            } else {
9035                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9036            }
9037            gen_store_fpr32(ctx, fp0, fd);
9038            tcg_temp_free_i32(fp0);
9039        }
9040        break;
9041    case OPC_FLOOR_W_S:
9042        {
9043            TCGv_i32 fp0 = tcg_temp_new_i32();
9044
9045            gen_load_fpr32(ctx, fp0, fs);
9046            if (ctx->nan2008) {
9047                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9048            } else {
9049                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9050            }
9051            gen_store_fpr32(ctx, fp0, fd);
9052            tcg_temp_free_i32(fp0);
9053        }
9054        break;
9055    case OPC_SEL_S:
9056        check_insn(ctx, ISA_MIPS32R6);
9057        gen_sel_s(ctx, op1, fd, ft, fs);
9058        break;
9059    case OPC_SELEQZ_S:
9060        check_insn(ctx, ISA_MIPS32R6);
9061        gen_sel_s(ctx, op1, fd, ft, fs);
9062        break;
9063    case OPC_SELNEZ_S:
9064        check_insn(ctx, ISA_MIPS32R6);
9065        gen_sel_s(ctx, op1, fd, ft, fs);
9066        break;
9067    case OPC_MOVCF_S:
9068        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9069        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9070        break;
9071    case OPC_MOVZ_S:
9072        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9073        {
9074            TCGLabel *l1 = gen_new_label();
9075            TCGv_i32 fp0;
9076
9077            if (ft != 0) {
9078                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9079            }
9080            fp0 = tcg_temp_new_i32();
9081            gen_load_fpr32(ctx, fp0, fs);
9082            gen_store_fpr32(ctx, fp0, fd);
9083            tcg_temp_free_i32(fp0);
9084            gen_set_label(l1);
9085        }
9086        break;
9087    case OPC_MOVN_S:
9088        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9089        {
9090            TCGLabel *l1 = gen_new_label();
9091            TCGv_i32 fp0;
9092
9093            if (ft != 0) {
9094                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9095                fp0 = tcg_temp_new_i32();
9096                gen_load_fpr32(ctx, fp0, fs);
9097                gen_store_fpr32(ctx, fp0, fd);
9098                tcg_temp_free_i32(fp0);
9099                gen_set_label(l1);
9100            }
9101        }
9102        break;
9103    case OPC_RECIP_S:
9104        {
9105            TCGv_i32 fp0 = tcg_temp_new_i32();
9106
9107            gen_load_fpr32(ctx, fp0, fs);
9108            gen_helper_float_recip_s(fp0, cpu_env, fp0);
9109            gen_store_fpr32(ctx, fp0, fd);
9110            tcg_temp_free_i32(fp0);
9111        }
9112        break;
9113    case OPC_RSQRT_S:
9114        {
9115            TCGv_i32 fp0 = tcg_temp_new_i32();
9116
9117            gen_load_fpr32(ctx, fp0, fs);
9118            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9119            gen_store_fpr32(ctx, fp0, fd);
9120            tcg_temp_free_i32(fp0);
9121        }
9122        break;
9123    case OPC_MADDF_S:
9124        check_insn(ctx, ISA_MIPS32R6);
9125        {
9126            TCGv_i32 fp0 = tcg_temp_new_i32();
9127            TCGv_i32 fp1 = tcg_temp_new_i32();
9128            TCGv_i32 fp2 = tcg_temp_new_i32();
9129            gen_load_fpr32(ctx, fp0, fs);
9130            gen_load_fpr32(ctx, fp1, ft);
9131            gen_load_fpr32(ctx, fp2, fd);
9132            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9133            gen_store_fpr32(ctx, fp2, fd);
9134            tcg_temp_free_i32(fp2);
9135            tcg_temp_free_i32(fp1);
9136            tcg_temp_free_i32(fp0);
9137        }
9138        break;
9139    case OPC_MSUBF_S:
9140        check_insn(ctx, ISA_MIPS32R6);
9141        {
9142            TCGv_i32 fp0 = tcg_temp_new_i32();
9143            TCGv_i32 fp1 = tcg_temp_new_i32();
9144            TCGv_i32 fp2 = tcg_temp_new_i32();
9145            gen_load_fpr32(ctx, fp0, fs);
9146            gen_load_fpr32(ctx, fp1, ft);
9147            gen_load_fpr32(ctx, fp2, fd);
9148            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9149            gen_store_fpr32(ctx, fp2, fd);
9150            tcg_temp_free_i32(fp2);
9151            tcg_temp_free_i32(fp1);
9152            tcg_temp_free_i32(fp0);
9153        }
9154        break;
9155    case OPC_RINT_S:
9156        check_insn(ctx, ISA_MIPS32R6);
9157        {
9158            TCGv_i32 fp0 = tcg_temp_new_i32();
9159            gen_load_fpr32(ctx, fp0, fs);
9160            gen_helper_float_rint_s(fp0, cpu_env, fp0);
9161            gen_store_fpr32(ctx, fp0, fd);
9162            tcg_temp_free_i32(fp0);
9163        }
9164        break;
9165    case OPC_CLASS_S:
9166        check_insn(ctx, ISA_MIPS32R6);
9167        {
9168            TCGv_i32 fp0 = tcg_temp_new_i32();
9169            gen_load_fpr32(ctx, fp0, fs);
9170            gen_helper_float_class_s(fp0, cpu_env, fp0);
9171            gen_store_fpr32(ctx, fp0, fd);
9172            tcg_temp_free_i32(fp0);
9173        }
9174        break;
9175    case OPC_MIN_S: /* OPC_RECIP2_S */
9176        if (ctx->insn_flags & ISA_MIPS32R6) {
9177            /* OPC_MIN_S */
9178            TCGv_i32 fp0 = tcg_temp_new_i32();
9179            TCGv_i32 fp1 = tcg_temp_new_i32();
9180            TCGv_i32 fp2 = tcg_temp_new_i32();
9181            gen_load_fpr32(ctx, fp0, fs);
9182            gen_load_fpr32(ctx, fp1, ft);
9183            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9184            gen_store_fpr32(ctx, fp2, fd);
9185            tcg_temp_free_i32(fp2);
9186            tcg_temp_free_i32(fp1);
9187            tcg_temp_free_i32(fp0);
9188        } else {
9189            /* OPC_RECIP2_S */
9190            check_cp1_64bitmode(ctx);
9191            {
9192                TCGv_i32 fp0 = tcg_temp_new_i32();
9193                TCGv_i32 fp1 = tcg_temp_new_i32();
9194
9195                gen_load_fpr32(ctx, fp0, fs);
9196                gen_load_fpr32(ctx, fp1, ft);
9197                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9198                tcg_temp_free_i32(fp1);
9199                gen_store_fpr32(ctx, fp0, fd);
9200                tcg_temp_free_i32(fp0);
9201            }
9202        }
9203        break;
9204    case OPC_MINA_S: /* OPC_RECIP1_S */
9205        if (ctx->insn_flags & ISA_MIPS32R6) {
9206            /* OPC_MINA_S */
9207            TCGv_i32 fp0 = tcg_temp_new_i32();
9208            TCGv_i32 fp1 = tcg_temp_new_i32();
9209            TCGv_i32 fp2 = tcg_temp_new_i32();
9210            gen_load_fpr32(ctx, fp0, fs);
9211            gen_load_fpr32(ctx, fp1, ft);
9212            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9213            gen_store_fpr32(ctx, fp2, fd);
9214            tcg_temp_free_i32(fp2);
9215            tcg_temp_free_i32(fp1);
9216            tcg_temp_free_i32(fp0);
9217        } else {
9218            /* OPC_RECIP1_S */
9219            check_cp1_64bitmode(ctx);
9220            {
9221                TCGv_i32 fp0 = tcg_temp_new_i32();
9222
9223                gen_load_fpr32(ctx, fp0, fs);
9224                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9225                gen_store_fpr32(ctx, fp0, fd);
9226                tcg_temp_free_i32(fp0);
9227            }
9228        }
9229        break;
9230    case OPC_MAX_S: /* OPC_RSQRT1_S */
9231        if (ctx->insn_flags & ISA_MIPS32R6) {
9232            /* OPC_MAX_S */
9233            TCGv_i32 fp0 = tcg_temp_new_i32();
9234            TCGv_i32 fp1 = tcg_temp_new_i32();
9235            gen_load_fpr32(ctx, fp0, fs);
9236            gen_load_fpr32(ctx, fp1, ft);
9237            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9238            gen_store_fpr32(ctx, fp1, fd);
9239            tcg_temp_free_i32(fp1);
9240            tcg_temp_free_i32(fp0);
9241        } else {
9242            /* OPC_RSQRT1_S */
9243            check_cp1_64bitmode(ctx);
9244            {
9245                TCGv_i32 fp0 = tcg_temp_new_i32();
9246
9247                gen_load_fpr32(ctx, fp0, fs);
9248                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9249                gen_store_fpr32(ctx, fp0, fd);
9250                tcg_temp_free_i32(fp0);
9251            }
9252        }
9253        break;
9254    case OPC_MAXA_S: /* OPC_RSQRT2_S */
9255        if (ctx->insn_flags & ISA_MIPS32R6) {
9256            /* OPC_MAXA_S */
9257            TCGv_i32 fp0 = tcg_temp_new_i32();
9258            TCGv_i32 fp1 = tcg_temp_new_i32();
9259            gen_load_fpr32(ctx, fp0, fs);
9260            gen_load_fpr32(ctx, fp1, ft);
9261            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9262            gen_store_fpr32(ctx, fp1, fd);
9263            tcg_temp_free_i32(fp1);
9264            tcg_temp_free_i32(fp0);
9265        } else {
9266            /* OPC_RSQRT2_S */
9267            check_cp1_64bitmode(ctx);
9268            {
9269                TCGv_i32 fp0 = tcg_temp_new_i32();
9270                TCGv_i32 fp1 = tcg_temp_new_i32();
9271
9272                gen_load_fpr32(ctx, fp0, fs);
9273                gen_load_fpr32(ctx, fp1, ft);
9274                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9275                tcg_temp_free_i32(fp1);
9276                gen_store_fpr32(ctx, fp0, fd);
9277                tcg_temp_free_i32(fp0);
9278            }
9279        }
9280        break;
9281    case OPC_CVT_D_S:
9282        check_cp1_registers(ctx, fd);
9283        {
9284            TCGv_i32 fp32 = tcg_temp_new_i32();
9285            TCGv_i64 fp64 = tcg_temp_new_i64();
9286
9287            gen_load_fpr32(ctx, fp32, fs);
9288            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9289            tcg_temp_free_i32(fp32);
9290            gen_store_fpr64(ctx, fp64, fd);
9291            tcg_temp_free_i64(fp64);
9292        }
9293        break;
9294    case OPC_CVT_W_S:
9295        {
9296            TCGv_i32 fp0 = tcg_temp_new_i32();
9297
9298            gen_load_fpr32(ctx, fp0, fs);
9299            if (ctx->nan2008) {
9300                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9301            } else {
9302                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9303            }
9304            gen_store_fpr32(ctx, fp0, fd);
9305            tcg_temp_free_i32(fp0);
9306        }
9307        break;
9308    case OPC_CVT_L_S:
9309        check_cp1_64bitmode(ctx);
9310        {
9311            TCGv_i32 fp32 = tcg_temp_new_i32();
9312            TCGv_i64 fp64 = tcg_temp_new_i64();
9313
9314            gen_load_fpr32(ctx, fp32, fs);
9315            if (ctx->nan2008) {
9316                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9317            } else {
9318                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9319            }
9320            tcg_temp_free_i32(fp32);
9321            gen_store_fpr64(ctx, fp64, fd);
9322            tcg_temp_free_i64(fp64);
9323        }
9324        break;
9325    case OPC_CVT_PS_S:
9326        check_ps(ctx);
9327        {
9328            TCGv_i64 fp64 = tcg_temp_new_i64();
9329            TCGv_i32 fp32_0 = tcg_temp_new_i32();
9330            TCGv_i32 fp32_1 = tcg_temp_new_i32();
9331
9332            gen_load_fpr32(ctx, fp32_0, fs);
9333            gen_load_fpr32(ctx, fp32_1, ft);
9334            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9335            tcg_temp_free_i32(fp32_1);
9336            tcg_temp_free_i32(fp32_0);
9337            gen_store_fpr64(ctx, fp64, fd);
9338            tcg_temp_free_i64(fp64);
9339        }
9340        break;
9341    case OPC_CMP_F_S:
9342    case OPC_CMP_UN_S:
9343    case OPC_CMP_EQ_S:
9344    case OPC_CMP_UEQ_S:
9345    case OPC_CMP_OLT_S:
9346    case OPC_CMP_ULT_S:
9347    case OPC_CMP_OLE_S:
9348    case OPC_CMP_ULE_S:
9349    case OPC_CMP_SF_S:
9350    case OPC_CMP_NGLE_S:
9351    case OPC_CMP_SEQ_S:
9352    case OPC_CMP_NGL_S:
9353    case OPC_CMP_LT_S:
9354    case OPC_CMP_NGE_S:
9355    case OPC_CMP_LE_S:
9356    case OPC_CMP_NGT_S:
9357        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9358        if (ctx->opcode & (1 << 6)) {
9359            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9360        } else {
9361            gen_cmp_s(ctx, func-48, ft, fs, cc);
9362        }
9363        break;
9364    case OPC_ADD_D:
9365        check_cp1_registers(ctx, fs | ft | fd);
9366        {
9367            TCGv_i64 fp0 = tcg_temp_new_i64();
9368            TCGv_i64 fp1 = tcg_temp_new_i64();
9369
9370            gen_load_fpr64(ctx, fp0, fs);
9371            gen_load_fpr64(ctx, fp1, ft);
9372            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9373            tcg_temp_free_i64(fp1);
9374            gen_store_fpr64(ctx, fp0, fd);
9375            tcg_temp_free_i64(fp0);
9376        }
9377        break;
9378    case OPC_SUB_D:
9379        check_cp1_registers(ctx, fs | ft | fd);
9380        {
9381            TCGv_i64 fp0 = tcg_temp_new_i64();
9382            TCGv_i64 fp1 = tcg_temp_new_i64();
9383
9384            gen_load_fpr64(ctx, fp0, fs);
9385            gen_load_fpr64(ctx, fp1, ft);
9386            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9387            tcg_temp_free_i64(fp1);
9388            gen_store_fpr64(ctx, fp0, fd);
9389            tcg_temp_free_i64(fp0);
9390        }
9391        break;
9392    case OPC_MUL_D:
9393        check_cp1_registers(ctx, fs | ft | fd);
9394        {
9395            TCGv_i64 fp0 = tcg_temp_new_i64();
9396            TCGv_i64 fp1 = tcg_temp_new_i64();
9397
9398            gen_load_fpr64(ctx, fp0, fs);
9399            gen_load_fpr64(ctx, fp1, ft);
9400            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9401            tcg_temp_free_i64(fp1);
9402            gen_store_fpr64(ctx, fp0, fd);
9403            tcg_temp_free_i64(fp0);
9404        }
9405        break;
9406    case OPC_DIV_D:
9407        check_cp1_registers(ctx, fs | ft | fd);
9408        {
9409            TCGv_i64 fp0 = tcg_temp_new_i64();
9410            TCGv_i64 fp1 = tcg_temp_new_i64();
9411
9412            gen_load_fpr64(ctx, fp0, fs);
9413            gen_load_fpr64(ctx, fp1, ft);
9414            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9415            tcg_temp_free_i64(fp1);
9416            gen_store_fpr64(ctx, fp0, fd);
9417            tcg_temp_free_i64(fp0);
9418        }
9419        break;
9420    case OPC_SQRT_D:
9421        check_cp1_registers(ctx, fs | fd);
9422        {
9423            TCGv_i64 fp0 = tcg_temp_new_i64();
9424
9425            gen_load_fpr64(ctx, fp0, fs);
9426            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9427            gen_store_fpr64(ctx, fp0, fd);
9428            tcg_temp_free_i64(fp0);
9429        }
9430        break;
9431    case OPC_ABS_D:
9432        check_cp1_registers(ctx, fs | fd);
9433        {
9434            TCGv_i64 fp0 = tcg_temp_new_i64();
9435
9436            gen_load_fpr64(ctx, fp0, fs);
9437            if (ctx->abs2008) {
9438                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9439            } else {
9440                gen_helper_float_abs_d(fp0, fp0);
9441            }
9442            gen_store_fpr64(ctx, fp0, fd);
9443            tcg_temp_free_i64(fp0);
9444        }
9445        break;
9446    case OPC_MOV_D:
9447        check_cp1_registers(ctx, fs | fd);
9448        {
9449            TCGv_i64 fp0 = tcg_temp_new_i64();
9450
9451            gen_load_fpr64(ctx, fp0, fs);
9452            gen_store_fpr64(ctx, fp0, fd);
9453            tcg_temp_free_i64(fp0);
9454        }
9455        break;
9456    case OPC_NEG_D:
9457        check_cp1_registers(ctx, fs | fd);
9458        {
9459            TCGv_i64 fp0 = tcg_temp_new_i64();
9460
9461            gen_load_fpr64(ctx, fp0, fs);
9462            if (ctx->abs2008) {
9463                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9464            } else {
9465                gen_helper_float_chs_d(fp0, fp0);
9466            }
9467            gen_store_fpr64(ctx, fp0, fd);
9468            tcg_temp_free_i64(fp0);
9469        }
9470        break;
9471    case OPC_ROUND_L_D:
9472        check_cp1_64bitmode(ctx);
9473        {
9474            TCGv_i64 fp0 = tcg_temp_new_i64();
9475
9476            gen_load_fpr64(ctx, fp0, fs);
9477            if (ctx->nan2008) {
9478                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9479            } else {
9480                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9481            }
9482            gen_store_fpr64(ctx, fp0, fd);
9483            tcg_temp_free_i64(fp0);
9484        }
9485        break;
9486    case OPC_TRUNC_L_D:
9487        check_cp1_64bitmode(ctx);
9488        {
9489            TCGv_i64 fp0 = tcg_temp_new_i64();
9490
9491            gen_load_fpr64(ctx, fp0, fs);
9492            if (ctx->nan2008) {
9493                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9494            } else {
9495                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9496            }
9497            gen_store_fpr64(ctx, fp0, fd);
9498            tcg_temp_free_i64(fp0);
9499        }
9500        break;
9501    case OPC_CEIL_L_D:
9502        check_cp1_64bitmode(ctx);
9503        {
9504            TCGv_i64 fp0 = tcg_temp_new_i64();
9505
9506            gen_load_fpr64(ctx, fp0, fs);
9507            if (ctx->nan2008) {
9508                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9509            } else {
9510                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9511            }
9512            gen_store_fpr64(ctx, fp0, fd);
9513            tcg_temp_free_i64(fp0);
9514        }
9515        break;
9516    case OPC_FLOOR_L_D:
9517        check_cp1_64bitmode(ctx);
9518        {
9519            TCGv_i64 fp0 = tcg_temp_new_i64();
9520
9521            gen_load_fpr64(ctx, fp0, fs);
9522            if (ctx->nan2008) {
9523                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9524            } else {
9525                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9526            }
9527            gen_store_fpr64(ctx, fp0, fd);
9528            tcg_temp_free_i64(fp0);
9529        }
9530        break;
9531    case OPC_ROUND_W_D:
9532        check_cp1_registers(ctx, fs);
9533        {
9534            TCGv_i32 fp32 = tcg_temp_new_i32();
9535            TCGv_i64 fp64 = tcg_temp_new_i64();
9536
9537            gen_load_fpr64(ctx, fp64, fs);
9538            if (ctx->nan2008) {
9539                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9540            } else {
9541                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9542            }
9543            tcg_temp_free_i64(fp64);
9544            gen_store_fpr32(ctx, fp32, fd);
9545            tcg_temp_free_i32(fp32);
9546        }
9547        break;
9548    case OPC_TRUNC_W_D:
9549        check_cp1_registers(ctx, fs);
9550        {
9551            TCGv_i32 fp32 = tcg_temp_new_i32();
9552            TCGv_i64 fp64 = tcg_temp_new_i64();
9553
9554            gen_load_fpr64(ctx, fp64, fs);
9555            if (ctx->nan2008) {
9556                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9557            } else {
9558                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9559            }
9560            tcg_temp_free_i64(fp64);
9561            gen_store_fpr32(ctx, fp32, fd);
9562            tcg_temp_free_i32(fp32);
9563        }
9564        break;
9565    case OPC_CEIL_W_D:
9566        check_cp1_registers(ctx, fs);
9567        {
9568            TCGv_i32 fp32 = tcg_temp_new_i32();
9569            TCGv_i64 fp64 = tcg_temp_new_i64();
9570
9571            gen_load_fpr64(ctx, fp64, fs);
9572            if (ctx->nan2008) {
9573                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9574            } else {
9575                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9576            }
9577            tcg_temp_free_i64(fp64);
9578            gen_store_fpr32(ctx, fp32, fd);
9579            tcg_temp_free_i32(fp32);
9580        }
9581        break;
9582    case OPC_FLOOR_W_D:
9583        check_cp1_registers(ctx, fs);
9584        {
9585            TCGv_i32 fp32 = tcg_temp_new_i32();
9586            TCGv_i64 fp64 = tcg_temp_new_i64();
9587
9588            gen_load_fpr64(ctx, fp64, fs);
9589            if (ctx->nan2008) {
9590                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9591            } else {
9592                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9593            }
9594            tcg_temp_free_i64(fp64);
9595            gen_store_fpr32(ctx, fp32, fd);
9596            tcg_temp_free_i32(fp32);
9597        }
9598        break;
9599    case OPC_SEL_D:
9600        check_insn(ctx, ISA_MIPS32R6);
9601        gen_sel_d(ctx, op1, fd, ft, fs);
9602        break;
9603    case OPC_SELEQZ_D:
9604        check_insn(ctx, ISA_MIPS32R6);
9605        gen_sel_d(ctx, op1, fd, ft, fs);
9606        break;
9607    case OPC_SELNEZ_D:
9608        check_insn(ctx, ISA_MIPS32R6);
9609        gen_sel_d(ctx, op1, fd, ft, fs);
9610        break;
9611    case OPC_MOVCF_D:
9612        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9613        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9614        break;
9615    case OPC_MOVZ_D:
9616        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9617        {
9618            TCGLabel *l1 = gen_new_label();
9619            TCGv_i64 fp0;
9620
9621            if (ft != 0) {
9622                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9623            }
9624            fp0 = tcg_temp_new_i64();
9625            gen_load_fpr64(ctx, fp0, fs);
9626            gen_store_fpr64(ctx, fp0, fd);
9627            tcg_temp_free_i64(fp0);
9628            gen_set_label(l1);
9629        }
9630        break;
9631    case OPC_MOVN_D:
9632        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9633        {
9634            TCGLabel *l1 = gen_new_label();
9635            TCGv_i64 fp0;
9636
9637            if (ft != 0) {
9638                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9639                fp0 = tcg_temp_new_i64();
9640                gen_load_fpr64(ctx, fp0, fs);
9641                gen_store_fpr64(ctx, fp0, fd);
9642                tcg_temp_free_i64(fp0);
9643                gen_set_label(l1);
9644            }
9645        }
9646        break;
9647    case OPC_RECIP_D:
9648        check_cp1_registers(ctx, fs | fd);
9649        {
9650            TCGv_i64 fp0 = tcg_temp_new_i64();
9651
9652            gen_load_fpr64(ctx, fp0, fs);
9653            gen_helper_float_recip_d(fp0, cpu_env, fp0);
9654            gen_store_fpr64(ctx, fp0, fd);
9655            tcg_temp_free_i64(fp0);
9656        }
9657        break;
9658    case OPC_RSQRT_D:
9659        check_cp1_registers(ctx, fs | fd);
9660        {
9661            TCGv_i64 fp0 = tcg_temp_new_i64();
9662
9663            gen_load_fpr64(ctx, fp0, fs);
9664            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9665            gen_store_fpr64(ctx, fp0, fd);
9666            tcg_temp_free_i64(fp0);
9667        }
9668        break;
9669    case OPC_MADDF_D:
9670        check_insn(ctx, ISA_MIPS32R6);
9671        {
9672            TCGv_i64 fp0 = tcg_temp_new_i64();
9673            TCGv_i64 fp1 = tcg_temp_new_i64();
9674            TCGv_i64 fp2 = tcg_temp_new_i64();
9675            gen_load_fpr64(ctx, fp0, fs);
9676            gen_load_fpr64(ctx, fp1, ft);
9677            gen_load_fpr64(ctx, fp2, fd);
9678            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9679            gen_store_fpr64(ctx, fp2, fd);
9680            tcg_temp_free_i64(fp2);
9681            tcg_temp_free_i64(fp1);
9682            tcg_temp_free_i64(fp0);
9683        }
9684        break;
9685    case OPC_MSUBF_D:
9686        check_insn(ctx, ISA_MIPS32R6);
9687        {
9688            TCGv_i64 fp0 = tcg_temp_new_i64();
9689            TCGv_i64 fp1 = tcg_temp_new_i64();
9690            TCGv_i64 fp2 = tcg_temp_new_i64();
9691            gen_load_fpr64(ctx, fp0, fs);
9692            gen_load_fpr64(ctx, fp1, ft);
9693            gen_load_fpr64(ctx, fp2, fd);
9694            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9695            gen_store_fpr64(ctx, fp2, fd);
9696            tcg_temp_free_i64(fp2);
9697            tcg_temp_free_i64(fp1);
9698            tcg_temp_free_i64(fp0);
9699        }
9700        break;
9701    case OPC_RINT_D:
9702        check_insn(ctx, ISA_MIPS32R6);
9703        {
9704            TCGv_i64 fp0 = tcg_temp_new_i64();
9705            gen_load_fpr64(ctx, fp0, fs);
9706            gen_helper_float_rint_d(fp0, cpu_env, fp0);
9707            gen_store_fpr64(ctx, fp0, fd);
9708            tcg_temp_free_i64(fp0);
9709        }
9710        break;
9711    case OPC_CLASS_D:
9712        check_insn(ctx, ISA_MIPS32R6);
9713        {
9714            TCGv_i64 fp0 = tcg_temp_new_i64();
9715            gen_load_fpr64(ctx, fp0, fs);
9716            gen_helper_float_class_d(fp0, cpu_env, fp0);
9717            gen_store_fpr64(ctx, fp0, fd);
9718            tcg_temp_free_i64(fp0);
9719        }
9720        break;
9721    case OPC_MIN_D: /* OPC_RECIP2_D */
9722        if (ctx->insn_flags & ISA_MIPS32R6) {
9723            /* OPC_MIN_D */
9724            TCGv_i64 fp0 = tcg_temp_new_i64();
9725            TCGv_i64 fp1 = tcg_temp_new_i64();
9726            gen_load_fpr64(ctx, fp0, fs);
9727            gen_load_fpr64(ctx, fp1, ft);
9728            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9729            gen_store_fpr64(ctx, fp1, fd);
9730            tcg_temp_free_i64(fp1);
9731            tcg_temp_free_i64(fp0);
9732        } else {
9733            /* OPC_RECIP2_D */
9734            check_cp1_64bitmode(ctx);
9735            {
9736                TCGv_i64 fp0 = tcg_temp_new_i64();
9737                TCGv_i64 fp1 = tcg_temp_new_i64();
9738
9739                gen_load_fpr64(ctx, fp0, fs);
9740                gen_load_fpr64(ctx, fp1, ft);
9741                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9742                tcg_temp_free_i64(fp1);
9743                gen_store_fpr64(ctx, fp0, fd);
9744                tcg_temp_free_i64(fp0);
9745            }
9746        }
9747        break;
9748    case OPC_MINA_D: /* OPC_RECIP1_D */
9749        if (ctx->insn_flags & ISA_MIPS32R6) {
9750            /* OPC_MINA_D */
9751            TCGv_i64 fp0 = tcg_temp_new_i64();
9752            TCGv_i64 fp1 = tcg_temp_new_i64();
9753            gen_load_fpr64(ctx, fp0, fs);
9754            gen_load_fpr64(ctx, fp1, ft);
9755            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9756            gen_store_fpr64(ctx, fp1, fd);
9757            tcg_temp_free_i64(fp1);
9758            tcg_temp_free_i64(fp0);
9759        } else {
9760            /* OPC_RECIP1_D */
9761            check_cp1_64bitmode(ctx);
9762            {
9763                TCGv_i64 fp0 = tcg_temp_new_i64();
9764
9765                gen_load_fpr64(ctx, fp0, fs);
9766                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9767                gen_store_fpr64(ctx, fp0, fd);
9768                tcg_temp_free_i64(fp0);
9769            }
9770        }
9771        break;
9772    case OPC_MAX_D: /*  OPC_RSQRT1_D */
9773        if (ctx->insn_flags & ISA_MIPS32R6) {
9774            /* OPC_MAX_D */
9775            TCGv_i64 fp0 = tcg_temp_new_i64();
9776            TCGv_i64 fp1 = tcg_temp_new_i64();
9777            gen_load_fpr64(ctx, fp0, fs);
9778            gen_load_fpr64(ctx, fp1, ft);
9779            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9780            gen_store_fpr64(ctx, fp1, fd);
9781            tcg_temp_free_i64(fp1);
9782            tcg_temp_free_i64(fp0);
9783        } else {
9784            /* OPC_RSQRT1_D */
9785            check_cp1_64bitmode(ctx);
9786            {
9787                TCGv_i64 fp0 = tcg_temp_new_i64();
9788
9789                gen_load_fpr64(ctx, fp0, fs);
9790                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9791                gen_store_fpr64(ctx, fp0, fd);
9792                tcg_temp_free_i64(fp0);
9793            }
9794        }
9795        break;
9796    case OPC_MAXA_D: /* OPC_RSQRT2_D */
9797        if (ctx->insn_flags & ISA_MIPS32R6) {
9798            /* OPC_MAXA_D */
9799            TCGv_i64 fp0 = tcg_temp_new_i64();
9800            TCGv_i64 fp1 = tcg_temp_new_i64();
9801            gen_load_fpr64(ctx, fp0, fs);
9802            gen_load_fpr64(ctx, fp1, ft);
9803            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9804            gen_store_fpr64(ctx, fp1, fd);
9805            tcg_temp_free_i64(fp1);
9806            tcg_temp_free_i64(fp0);
9807        } else {
9808            /* OPC_RSQRT2_D */
9809            check_cp1_64bitmode(ctx);
9810            {
9811                TCGv_i64 fp0 = tcg_temp_new_i64();
9812                TCGv_i64 fp1 = tcg_temp_new_i64();
9813
9814                gen_load_fpr64(ctx, fp0, fs);
9815                gen_load_fpr64(ctx, fp1, ft);
9816                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9817                tcg_temp_free_i64(fp1);
9818                gen_store_fpr64(ctx, fp0, fd);
9819                tcg_temp_free_i64(fp0);
9820            }
9821        }
9822        break;
9823    case OPC_CMP_F_D:
9824    case OPC_CMP_UN_D:
9825    case OPC_CMP_EQ_D:
9826    case OPC_CMP_UEQ_D:
9827    case OPC_CMP_OLT_D:
9828    case OPC_CMP_ULT_D:
9829    case OPC_CMP_OLE_D:
9830    case OPC_CMP_ULE_D:
9831    case OPC_CMP_SF_D:
9832    case OPC_CMP_NGLE_D:
9833    case OPC_CMP_SEQ_D:
9834    case OPC_CMP_NGL_D:
9835    case OPC_CMP_LT_D:
9836    case OPC_CMP_NGE_D:
9837    case OPC_CMP_LE_D:
9838    case OPC_CMP_NGT_D:
9839        check_insn_opc_removed(ctx, ISA_MIPS32R6);
9840        if (ctx->opcode & (1 << 6)) {
9841            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9842        } else {
9843            gen_cmp_d(ctx, func-48, ft, fs, cc);
9844        }
9845        break;
9846    case OPC_CVT_S_D:
9847        check_cp1_registers(ctx, fs);
9848        {
9849            TCGv_i32 fp32 = tcg_temp_new_i32();
9850            TCGv_i64 fp64 = tcg_temp_new_i64();
9851
9852            gen_load_fpr64(ctx, fp64, fs);
9853            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9854            tcg_temp_free_i64(fp64);
9855            gen_store_fpr32(ctx, fp32, fd);
9856            tcg_temp_free_i32(fp32);
9857        }
9858        break;
9859    case OPC_CVT_W_D:
9860        check_cp1_registers(ctx, fs);
9861        {
9862            TCGv_i32 fp32 = tcg_temp_new_i32();
9863            TCGv_i64 fp64 = tcg_temp_new_i64();
9864
9865            gen_load_fpr64(ctx, fp64, fs);
9866            if (ctx->nan2008) {
9867                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
9868            } else {
9869                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
9870            }
9871            tcg_temp_free_i64(fp64);
9872            gen_store_fpr32(ctx, fp32, fd);
9873            tcg_temp_free_i32(fp32);
9874        }
9875        break;
9876    case OPC_CVT_L_D:
9877        check_cp1_64bitmode(ctx);
9878        {
9879            TCGv_i64 fp0 = tcg_temp_new_i64();
9880
9881            gen_load_fpr64(ctx, fp0, fs);
9882            if (ctx->nan2008) {
9883                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
9884            } else {
9885                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
9886            }
9887            gen_store_fpr64(ctx, fp0, fd);
9888            tcg_temp_free_i64(fp0);
9889        }
9890        break;
9891    case OPC_CVT_S_W:
9892        {
9893            TCGv_i32 fp0 = tcg_temp_new_i32();
9894
9895            gen_load_fpr32(ctx, fp0, fs);
9896            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9897            gen_store_fpr32(ctx, fp0, fd);
9898            tcg_temp_free_i32(fp0);
9899        }
9900        break;
9901    case OPC_CVT_D_W:
9902        check_cp1_registers(ctx, fd);
9903        {
9904            TCGv_i32 fp32 = tcg_temp_new_i32();
9905            TCGv_i64 fp64 = tcg_temp_new_i64();
9906
9907            gen_load_fpr32(ctx, fp32, fs);
9908            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9909            tcg_temp_free_i32(fp32);
9910            gen_store_fpr64(ctx, fp64, fd);
9911            tcg_temp_free_i64(fp64);
9912        }
9913        break;
9914    case OPC_CVT_S_L:
9915        check_cp1_64bitmode(ctx);
9916        {
9917            TCGv_i32 fp32 = tcg_temp_new_i32();
9918            TCGv_i64 fp64 = tcg_temp_new_i64();
9919
9920            gen_load_fpr64(ctx, fp64, fs);
9921            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9922            tcg_temp_free_i64(fp64);
9923            gen_store_fpr32(ctx, fp32, fd);
9924            tcg_temp_free_i32(fp32);
9925        }
9926        break;
9927    case OPC_CVT_D_L:
9928        check_cp1_64bitmode(ctx);
9929        {
9930            TCGv_i64 fp0 = tcg_temp_new_i64();
9931
9932            gen_load_fpr64(ctx, fp0, fs);
9933            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9934            gen_store_fpr64(ctx, fp0, fd);
9935            tcg_temp_free_i64(fp0);
9936        }
9937        break;
9938    case OPC_CVT_PS_PW:
9939        check_ps(ctx);
9940        {
9941            TCGv_i64 fp0 = tcg_temp_new_i64();
9942
9943            gen_load_fpr64(ctx, fp0, fs);
9944            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9945            gen_store_fpr64(ctx, fp0, fd);
9946            tcg_temp_free_i64(fp0);
9947        }
9948        break;
9949    case OPC_ADD_PS:
9950        check_ps(ctx);
9951        {
9952            TCGv_i64 fp0 = tcg_temp_new_i64();
9953            TCGv_i64 fp1 = tcg_temp_new_i64();
9954
9955            gen_load_fpr64(ctx, fp0, fs);
9956            gen_load_fpr64(ctx, fp1, ft);
9957            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9958            tcg_temp_free_i64(fp1);
9959            gen_store_fpr64(ctx, fp0, fd);
9960            tcg_temp_free_i64(fp0);
9961        }
9962        break;
9963    case OPC_SUB_PS:
9964        check_ps(ctx);
9965        {
9966            TCGv_i64 fp0 = tcg_temp_new_i64();
9967            TCGv_i64 fp1 = tcg_temp_new_i64();
9968
9969            gen_load_fpr64(ctx, fp0, fs);
9970            gen_load_fpr64(ctx, fp1, ft);
9971            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9972            tcg_temp_free_i64(fp1);
9973            gen_store_fpr64(ctx, fp0, fd);
9974            tcg_temp_free_i64(fp0);
9975        }
9976        break;
9977    case OPC_MUL_PS:
9978        check_ps(ctx);
9979        {
9980            TCGv_i64 fp0 = tcg_temp_new_i64();
9981            TCGv_i64 fp1 = tcg_temp_new_i64();
9982
9983            gen_load_fpr64(ctx, fp0, fs);
9984            gen_load_fpr64(ctx, fp1, ft);
9985            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9986            tcg_temp_free_i64(fp1);
9987            gen_store_fpr64(ctx, fp0, fd);
9988            tcg_temp_free_i64(fp0);
9989        }
9990        break;
9991    case OPC_ABS_PS:
9992        check_ps(ctx);
9993        {
9994            TCGv_i64 fp0 = tcg_temp_new_i64();
9995
9996            gen_load_fpr64(ctx, fp0, fs);
9997            gen_helper_float_abs_ps(fp0, fp0);
9998            gen_store_fpr64(ctx, fp0, fd);
9999            tcg_temp_free_i64(fp0);
10000        }
10001        break;
10002    case OPC_MOV_PS:
10003        check_ps(ctx);
10004        {
10005            TCGv_i64 fp0 = tcg_temp_new_i64();
10006
10007            gen_load_fpr64(ctx, fp0, fs);
10008            gen_store_fpr64(ctx, fp0, fd);
10009            tcg_temp_free_i64(fp0);
10010        }
10011        break;
10012    case OPC_NEG_PS:
10013        check_ps(ctx);
10014        {
10015            TCGv_i64 fp0 = tcg_temp_new_i64();
10016
10017            gen_load_fpr64(ctx, fp0, fs);
10018            gen_helper_float_chs_ps(fp0, fp0);
10019            gen_store_fpr64(ctx, fp0, fd);
10020            tcg_temp_free_i64(fp0);
10021        }
10022        break;
10023    case OPC_MOVCF_PS:
10024        check_ps(ctx);
10025        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10026        break;
10027    case OPC_MOVZ_PS:
10028        check_ps(ctx);
10029        {
10030            TCGLabel *l1 = gen_new_label();
10031            TCGv_i64 fp0;
10032
10033            if (ft != 0)
10034                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10035            fp0 = tcg_temp_new_i64();
10036            gen_load_fpr64(ctx, fp0, fs);
10037            gen_store_fpr64(ctx, fp0, fd);
10038            tcg_temp_free_i64(fp0);
10039            gen_set_label(l1);
10040        }
10041        break;
10042    case OPC_MOVN_PS:
10043        check_ps(ctx);
10044        {
10045            TCGLabel *l1 = gen_new_label();
10046            TCGv_i64 fp0;
10047
10048            if (ft != 0) {
10049                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10050                fp0 = tcg_temp_new_i64();
10051                gen_load_fpr64(ctx, fp0, fs);
10052                gen_store_fpr64(ctx, fp0, fd);
10053                tcg_temp_free_i64(fp0);
10054                gen_set_label(l1);
10055            }
10056        }
10057        break;
10058    case OPC_ADDR_PS:
10059        check_ps(ctx);
10060        {
10061            TCGv_i64 fp0 = tcg_temp_new_i64();
10062            TCGv_i64 fp1 = tcg_temp_new_i64();
10063
10064            gen_load_fpr64(ctx, fp0, ft);
10065            gen_load_fpr64(ctx, fp1, fs);
10066            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
10067            tcg_temp_free_i64(fp1);
10068            gen_store_fpr64(ctx, fp0, fd);
10069            tcg_temp_free_i64(fp0);
10070        }
10071        break;
10072    case OPC_MULR_PS:
10073        check_ps(ctx);
10074        {
10075            TCGv_i64 fp0 = tcg_temp_new_i64();
10076            TCGv_i64 fp1 = tcg_temp_new_i64();
10077
10078            gen_load_fpr64(ctx, fp0, ft);
10079            gen_load_fpr64(ctx, fp1, fs);
10080            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
10081            tcg_temp_free_i64(fp1);
10082            gen_store_fpr64(ctx, fp0, fd);
10083            tcg_temp_free_i64(fp0);
10084        }
10085        break;
10086    case OPC_RECIP2_PS:
10087        check_ps(ctx);
10088        {
10089            TCGv_i64 fp0 = tcg_temp_new_i64();
10090            TCGv_i64 fp1 = tcg_temp_new_i64();
10091
10092            gen_load_fpr64(ctx, fp0, fs);
10093            gen_load_fpr64(ctx, fp1, ft);
10094            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
10095            tcg_temp_free_i64(fp1);
10096            gen_store_fpr64(ctx, fp0, fd);
10097            tcg_temp_free_i64(fp0);
10098        }
10099        break;
10100    case OPC_RECIP1_PS:
10101        check_ps(ctx);
10102        {
10103            TCGv_i64 fp0 = tcg_temp_new_i64();
10104
10105            gen_load_fpr64(ctx, fp0, fs);
10106            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10107            gen_store_fpr64(ctx, fp0, fd);
10108            tcg_temp_free_i64(fp0);
10109        }
10110        break;
10111    case OPC_RSQRT1_PS:
10112        check_ps(ctx);
10113        {
10114            TCGv_i64 fp0 = tcg_temp_new_i64();
10115
10116            gen_load_fpr64(ctx, fp0, fs);
10117            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10118            gen_store_fpr64(ctx, fp0, fd);
10119            tcg_temp_free_i64(fp0);
10120        }
10121        break;
10122    case OPC_RSQRT2_PS:
10123        check_ps(ctx);
10124        {
10125            TCGv_i64 fp0 = tcg_temp_new_i64();
10126            TCGv_i64 fp1 = tcg_temp_new_i64();
10127
10128            gen_load_fpr64(ctx, fp0, fs);
10129            gen_load_fpr64(ctx, fp1, ft);
10130            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10131            tcg_temp_free_i64(fp1);
10132            gen_store_fpr64(ctx, fp0, fd);
10133            tcg_temp_free_i64(fp0);
10134        }
10135        break;
10136    case OPC_CVT_S_PU:
10137        check_cp1_64bitmode(ctx);
10138        {
10139            TCGv_i32 fp0 = tcg_temp_new_i32();
10140
10141            gen_load_fpr32h(ctx, fp0, fs);
10142            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10143            gen_store_fpr32(ctx, fp0, fd);
10144            tcg_temp_free_i32(fp0);
10145        }
10146        break;
10147    case OPC_CVT_PW_PS:
10148        check_ps(ctx);
10149        {
10150            TCGv_i64 fp0 = tcg_temp_new_i64();
10151
10152            gen_load_fpr64(ctx, fp0, fs);
10153            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10154            gen_store_fpr64(ctx, fp0, fd);
10155            tcg_temp_free_i64(fp0);
10156        }
10157        break;
10158    case OPC_CVT_S_PL:
10159        check_cp1_64bitmode(ctx);
10160        {
10161            TCGv_i32 fp0 = tcg_temp_new_i32();
10162
10163            gen_load_fpr32(ctx, fp0, fs);
10164            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10165            gen_store_fpr32(ctx, fp0, fd);
10166            tcg_temp_free_i32(fp0);
10167        }
10168        break;
10169    case OPC_PLL_PS:
10170        check_ps(ctx);
10171        {
10172            TCGv_i32 fp0 = tcg_temp_new_i32();
10173            TCGv_i32 fp1 = tcg_temp_new_i32();
10174
10175            gen_load_fpr32(ctx, fp0, fs);
10176            gen_load_fpr32(ctx, fp1, ft);
10177            gen_store_fpr32h(ctx, fp0, fd);
10178            gen_store_fpr32(ctx, fp1, fd);
10179            tcg_temp_free_i32(fp0);
10180            tcg_temp_free_i32(fp1);
10181        }
10182        break;
10183    case OPC_PLU_PS:
10184        check_ps(ctx);
10185        {
10186            TCGv_i32 fp0 = tcg_temp_new_i32();
10187            TCGv_i32 fp1 = tcg_temp_new_i32();
10188
10189            gen_load_fpr32(ctx, fp0, fs);
10190            gen_load_fpr32h(ctx, fp1, ft);
10191            gen_store_fpr32(ctx, fp1, fd);
10192            gen_store_fpr32h(ctx, fp0, fd);
10193            tcg_temp_free_i32(fp0);
10194            tcg_temp_free_i32(fp1);
10195        }
10196        break;
10197    case OPC_PUL_PS:
10198        check_ps(ctx);
10199        {
10200            TCGv_i32 fp0 = tcg_temp_new_i32();
10201            TCGv_i32 fp1 = tcg_temp_new_i32();
10202
10203            gen_load_fpr32h(ctx, fp0, fs);
10204            gen_load_fpr32(ctx, fp1, ft);
10205            gen_store_fpr32(ctx, fp1, fd);
10206            gen_store_fpr32h(ctx, fp0, fd);
10207            tcg_temp_free_i32(fp0);
10208            tcg_temp_free_i32(fp1);
10209        }
10210        break;
10211    case OPC_PUU_PS:
10212        check_ps(ctx);
10213        {
10214            TCGv_i32 fp0 = tcg_temp_new_i32();
10215            TCGv_i32 fp1 = tcg_temp_new_i32();
10216
10217            gen_load_fpr32h(ctx, fp0, fs);
10218            gen_load_fpr32h(ctx, fp1, ft);
10219            gen_store_fpr32(ctx, fp1, fd);
10220            gen_store_fpr32h(ctx, fp0, fd);
10221            tcg_temp_free_i32(fp0);
10222            tcg_temp_free_i32(fp1);
10223        }
10224        break;
10225    case OPC_CMP_F_PS:
10226    case OPC_CMP_UN_PS:
10227    case OPC_CMP_EQ_PS:
10228    case OPC_CMP_UEQ_PS:
10229    case OPC_CMP_OLT_PS:
10230    case OPC_CMP_ULT_PS:
10231    case OPC_CMP_OLE_PS:
10232    case OPC_CMP_ULE_PS:
10233    case OPC_CMP_SF_PS:
10234    case OPC_CMP_NGLE_PS:
10235    case OPC_CMP_SEQ_PS:
10236    case OPC_CMP_NGL_PS:
10237    case OPC_CMP_LT_PS:
10238    case OPC_CMP_NGE_PS:
10239    case OPC_CMP_LE_PS:
10240    case OPC_CMP_NGT_PS:
10241        if (ctx->opcode & (1 << 6)) {
10242            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10243        } else {
10244            gen_cmp_ps(ctx, func-48, ft, fs, cc);
10245        }
10246        break;
10247    default:
10248        MIPS_INVAL("farith");
10249        generate_exception_end(ctx, EXCP_RI);
10250        return;
10251    }
10252}
10253
10254/* Coprocessor 3 (FPU) */
10255static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10256                           int fd, int fs, int base, int index)
10257{
10258    TCGv t0 = tcg_temp_new();
10259
10260    if (base == 0) {
10261        gen_load_gpr(t0, index);
10262    } else if (index == 0) {
10263        gen_load_gpr(t0, base);
10264    } else {
10265        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10266    }
10267    /* Don't do NOP if destination is zero: we must perform the actual
10268       memory access. */
10269    switch (opc) {
10270    case OPC_LWXC1:
10271        check_cop1x(ctx);
10272        {
10273            TCGv_i32 fp0 = tcg_temp_new_i32();
10274
10275            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10276            tcg_gen_trunc_tl_i32(fp0, t0);
10277            gen_store_fpr32(ctx, fp0, fd);
10278            tcg_temp_free_i32(fp0);
10279        }
10280        break;
10281    case OPC_LDXC1:
10282        check_cop1x(ctx);
10283        check_cp1_registers(ctx, fd);
10284        {
10285            TCGv_i64 fp0 = tcg_temp_new_i64();
10286            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10287            gen_store_fpr64(ctx, fp0, fd);
10288            tcg_temp_free_i64(fp0);
10289        }
10290        break;
10291    case OPC_LUXC1:
10292        check_cp1_64bitmode(ctx);
10293        tcg_gen_andi_tl(t0, t0, ~0x7);
10294        {
10295            TCGv_i64 fp0 = tcg_temp_new_i64();
10296
10297            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10298            gen_store_fpr64(ctx, fp0, fd);
10299            tcg_temp_free_i64(fp0);
10300        }
10301        break;
10302    case OPC_SWXC1:
10303        check_cop1x(ctx);
10304        {
10305            TCGv_i32 fp0 = tcg_temp_new_i32();
10306            gen_load_fpr32(ctx, fp0, fs);
10307            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10308            tcg_temp_free_i32(fp0);
10309        }
10310        break;
10311    case OPC_SDXC1:
10312        check_cop1x(ctx);
10313        check_cp1_registers(ctx, fs);
10314        {
10315            TCGv_i64 fp0 = tcg_temp_new_i64();
10316            gen_load_fpr64(ctx, fp0, fs);
10317            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10318            tcg_temp_free_i64(fp0);
10319        }
10320        break;
10321    case OPC_SUXC1:
10322        check_cp1_64bitmode(ctx);
10323        tcg_gen_andi_tl(t0, t0, ~0x7);
10324        {
10325            TCGv_i64 fp0 = tcg_temp_new_i64();
10326            gen_load_fpr64(ctx, fp0, fs);
10327            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10328            tcg_temp_free_i64(fp0);
10329        }
10330        break;
10331    }
10332    tcg_temp_free(t0);
10333}
10334
10335static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10336                            int fd, int fr, int fs, int ft)
10337{
10338    switch (opc) {
10339    case OPC_ALNV_PS:
10340        check_ps(ctx);
10341        {
10342            TCGv t0 = tcg_temp_local_new();
10343            TCGv_i32 fp = tcg_temp_new_i32();
10344            TCGv_i32 fph = tcg_temp_new_i32();
10345            TCGLabel *l1 = gen_new_label();
10346            TCGLabel *l2 = gen_new_label();
10347
10348            gen_load_gpr(t0, fr);
10349            tcg_gen_andi_tl(t0, t0, 0x7);
10350
10351            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10352            gen_load_fpr32(ctx, fp, fs);
10353            gen_load_fpr32h(ctx, fph, fs);
10354            gen_store_fpr32(ctx, fp, fd);
10355            gen_store_fpr32h(ctx, fph, fd);
10356            tcg_gen_br(l2);
10357            gen_set_label(l1);
10358            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10359            tcg_temp_free(t0);
10360#ifdef TARGET_WORDS_BIGENDIAN
10361            gen_load_fpr32(ctx, fp, fs);
10362            gen_load_fpr32h(ctx, fph, ft);
10363            gen_store_fpr32h(ctx, fp, fd);
10364            gen_store_fpr32(ctx, fph, fd);
10365#else
10366            gen_load_fpr32h(ctx, fph, fs);
10367            gen_load_fpr32(ctx, fp, ft);
10368            gen_store_fpr32(ctx, fph, fd);
10369            gen_store_fpr32h(ctx, fp, fd);
10370#endif
10371            gen_set_label(l2);
10372            tcg_temp_free_i32(fp);
10373            tcg_temp_free_i32(fph);
10374        }
10375        break;
10376    case OPC_MADD_S:
10377        check_cop1x(ctx);
10378        {
10379            TCGv_i32 fp0 = tcg_temp_new_i32();
10380            TCGv_i32 fp1 = tcg_temp_new_i32();
10381            TCGv_i32 fp2 = tcg_temp_new_i32();
10382
10383            gen_load_fpr32(ctx, fp0, fs);
10384            gen_load_fpr32(ctx, fp1, ft);
10385            gen_load_fpr32(ctx, fp2, fr);
10386            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10387            tcg_temp_free_i32(fp0);
10388            tcg_temp_free_i32(fp1);
10389            gen_store_fpr32(ctx, fp2, fd);
10390            tcg_temp_free_i32(fp2);
10391        }
10392        break;
10393    case OPC_MADD_D:
10394        check_cop1x(ctx);
10395        check_cp1_registers(ctx, fd | fs | ft | fr);
10396        {
10397            TCGv_i64 fp0 = tcg_temp_new_i64();
10398            TCGv_i64 fp1 = tcg_temp_new_i64();
10399            TCGv_i64 fp2 = tcg_temp_new_i64();
10400
10401            gen_load_fpr64(ctx, fp0, fs);
10402            gen_load_fpr64(ctx, fp1, ft);
10403            gen_load_fpr64(ctx, fp2, fr);
10404            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10405            tcg_temp_free_i64(fp0);
10406            tcg_temp_free_i64(fp1);
10407            gen_store_fpr64(ctx, fp2, fd);
10408            tcg_temp_free_i64(fp2);
10409        }
10410        break;
10411    case OPC_MADD_PS:
10412        check_ps(ctx);
10413        {
10414            TCGv_i64 fp0 = tcg_temp_new_i64();
10415            TCGv_i64 fp1 = tcg_temp_new_i64();
10416            TCGv_i64 fp2 = tcg_temp_new_i64();
10417
10418            gen_load_fpr64(ctx, fp0, fs);
10419            gen_load_fpr64(ctx, fp1, ft);
10420            gen_load_fpr64(ctx, fp2, fr);
10421            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10422            tcg_temp_free_i64(fp0);
10423            tcg_temp_free_i64(fp1);
10424            gen_store_fpr64(ctx, fp2, fd);
10425            tcg_temp_free_i64(fp2);
10426        }
10427        break;
10428    case OPC_MSUB_S:
10429        check_cop1x(ctx);
10430        {
10431            TCGv_i32 fp0 = tcg_temp_new_i32();
10432            TCGv_i32 fp1 = tcg_temp_new_i32();
10433            TCGv_i32 fp2 = tcg_temp_new_i32();
10434
10435            gen_load_fpr32(ctx, fp0, fs);
10436            gen_load_fpr32(ctx, fp1, ft);
10437            gen_load_fpr32(ctx, fp2, fr);
10438            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10439            tcg_temp_free_i32(fp0);
10440            tcg_temp_free_i32(fp1);
10441            gen_store_fpr32(ctx, fp2, fd);
10442            tcg_temp_free_i32(fp2);
10443        }
10444        break;
10445    case OPC_MSUB_D:
10446        check_cop1x(ctx);
10447        check_cp1_registers(ctx, fd | fs | ft | fr);
10448        {
10449            TCGv_i64 fp0 = tcg_temp_new_i64();
10450            TCGv_i64 fp1 = tcg_temp_new_i64();
10451            TCGv_i64 fp2 = tcg_temp_new_i64();
10452
10453            gen_load_fpr64(ctx, fp0, fs);
10454            gen_load_fpr64(ctx, fp1, ft);
10455            gen_load_fpr64(ctx, fp2, fr);
10456            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10457            tcg_temp_free_i64(fp0);
10458            tcg_temp_free_i64(fp1);
10459            gen_store_fpr64(ctx, fp2, fd);
10460            tcg_temp_free_i64(fp2);
10461        }
10462        break;
10463    case OPC_MSUB_PS:
10464        check_ps(ctx);
10465        {
10466            TCGv_i64 fp0 = tcg_temp_new_i64();
10467            TCGv_i64 fp1 = tcg_temp_new_i64();
10468            TCGv_i64 fp2 = tcg_temp_new_i64();
10469
10470            gen_load_fpr64(ctx, fp0, fs);
10471            gen_load_fpr64(ctx, fp1, ft);
10472            gen_load_fpr64(ctx, fp2, fr);
10473            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10474            tcg_temp_free_i64(fp0);
10475            tcg_temp_free_i64(fp1);
10476            gen_store_fpr64(ctx, fp2, fd);
10477            tcg_temp_free_i64(fp2);
10478        }
10479        break;
10480    case OPC_NMADD_S:
10481        check_cop1x(ctx);
10482        {
10483            TCGv_i32 fp0 = tcg_temp_new_i32();
10484            TCGv_i32 fp1 = tcg_temp_new_i32();
10485            TCGv_i32 fp2 = tcg_temp_new_i32();
10486
10487            gen_load_fpr32(ctx, fp0, fs);
10488            gen_load_fpr32(ctx, fp1, ft);
10489            gen_load_fpr32(ctx, fp2, fr);
10490            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10491            tcg_temp_free_i32(fp0);
10492            tcg_temp_free_i32(fp1);
10493            gen_store_fpr32(ctx, fp2, fd);
10494            tcg_temp_free_i32(fp2);
10495        }
10496        break;
10497    case OPC_NMADD_D:
10498        check_cop1x(ctx);
10499        check_cp1_registers(ctx, fd | fs | ft | fr);
10500        {
10501            TCGv_i64 fp0 = tcg_temp_new_i64();
10502            TCGv_i64 fp1 = tcg_temp_new_i64();
10503            TCGv_i64 fp2 = tcg_temp_new_i64();
10504
10505            gen_load_fpr64(ctx, fp0, fs);
10506            gen_load_fpr64(ctx, fp1, ft);
10507            gen_load_fpr64(ctx, fp2, fr);
10508            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10509            tcg_temp_free_i64(fp0);
10510            tcg_temp_free_i64(fp1);
10511            gen_store_fpr64(ctx, fp2, fd);
10512            tcg_temp_free_i64(fp2);
10513        }
10514        break;
10515    case OPC_NMADD_PS:
10516        check_ps(ctx);
10517        {
10518            TCGv_i64 fp0 = tcg_temp_new_i64();
10519            TCGv_i64 fp1 = tcg_temp_new_i64();
10520            TCGv_i64 fp2 = tcg_temp_new_i64();
10521
10522            gen_load_fpr64(ctx, fp0, fs);
10523            gen_load_fpr64(ctx, fp1, ft);
10524            gen_load_fpr64(ctx, fp2, fr);
10525            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10526            tcg_temp_free_i64(fp0);
10527            tcg_temp_free_i64(fp1);
10528            gen_store_fpr64(ctx, fp2, fd);
10529            tcg_temp_free_i64(fp2);
10530        }
10531        break;
10532    case OPC_NMSUB_S:
10533        check_cop1x(ctx);
10534        {
10535            TCGv_i32 fp0 = tcg_temp_new_i32();
10536            TCGv_i32 fp1 = tcg_temp_new_i32();
10537            TCGv_i32 fp2 = tcg_temp_new_i32();
10538
10539            gen_load_fpr32(ctx, fp0, fs);
10540            gen_load_fpr32(ctx, fp1, ft);
10541            gen_load_fpr32(ctx, fp2, fr);
10542            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10543            tcg_temp_free_i32(fp0);
10544            tcg_temp_free_i32(fp1);
10545            gen_store_fpr32(ctx, fp2, fd);
10546            tcg_temp_free_i32(fp2);
10547        }
10548        break;
10549    case OPC_NMSUB_D:
10550        check_cop1x(ctx);
10551        check_cp1_registers(ctx, fd | fs | ft | fr);
10552        {
10553            TCGv_i64 fp0 = tcg_temp_new_i64();
10554            TCGv_i64 fp1 = tcg_temp_new_i64();
10555            TCGv_i64 fp2 = tcg_temp_new_i64();
10556
10557            gen_load_fpr64(ctx, fp0, fs);
10558            gen_load_fpr64(ctx, fp1, ft);
10559            gen_load_fpr64(ctx, fp2, fr);
10560            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10561            tcg_temp_free_i64(fp0);
10562            tcg_temp_free_i64(fp1);
10563            gen_store_fpr64(ctx, fp2, fd);
10564            tcg_temp_free_i64(fp2);
10565        }
10566        break;
10567    case OPC_NMSUB_PS:
10568        check_ps(ctx);
10569        {
10570            TCGv_i64 fp0 = tcg_temp_new_i64();
10571            TCGv_i64 fp1 = tcg_temp_new_i64();
10572            TCGv_i64 fp2 = tcg_temp_new_i64();
10573
10574            gen_load_fpr64(ctx, fp0, fs);
10575            gen_load_fpr64(ctx, fp1, ft);
10576            gen_load_fpr64(ctx, fp2, fr);
10577            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10578            tcg_temp_free_i64(fp0);
10579            tcg_temp_free_i64(fp1);
10580            gen_store_fpr64(ctx, fp2, fd);
10581            tcg_temp_free_i64(fp2);
10582        }
10583        break;
10584    default:
10585        MIPS_INVAL("flt3_arith");
10586        generate_exception_end(ctx, EXCP_RI);
10587        return;
10588    }
10589}
10590
10591static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10592{
10593    TCGv t0;
10594
10595#if !defined(CONFIG_USER_ONLY)
10596    /* The Linux kernel will emulate rdhwr if it's not supported natively.
10597       Therefore only check the ISA in system mode.  */
10598    check_insn(ctx, ISA_MIPS32R2);
10599#endif
10600    t0 = tcg_temp_new();
10601
10602    switch (rd) {
10603    case 0:
10604        gen_helper_rdhwr_cpunum(t0, cpu_env);
10605        gen_store_gpr(t0, rt);
10606        break;
10607    case 1:
10608        gen_helper_rdhwr_synci_step(t0, cpu_env);
10609        gen_store_gpr(t0, rt);
10610        break;
10611    case 2:
10612        gen_helper_rdhwr_cc(t0, cpu_env);
10613        gen_store_gpr(t0, rt);
10614        break;
10615    case 3:
10616        gen_helper_rdhwr_ccres(t0, cpu_env);
10617        gen_store_gpr(t0, rt);
10618        break;
10619    case 4:
10620        check_insn(ctx, ISA_MIPS32R6);
10621        if (sel != 0) {
10622            /* Performance counter registers are not implemented other than
10623             * control register 0.
10624             */
10625            generate_exception(ctx, EXCP_RI);
10626        }
10627        gen_helper_rdhwr_performance(t0, cpu_env);
10628        gen_store_gpr(t0, rt);
10629        break;
10630    case 5:
10631        check_insn(ctx, ISA_MIPS32R6);
10632        gen_helper_rdhwr_xnp(t0, cpu_env);
10633        gen_store_gpr(t0, rt);
10634        break;
10635    case 29:
10636#if defined(CONFIG_USER_ONLY)
10637        tcg_gen_ld_tl(t0, cpu_env,
10638                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10639        gen_store_gpr(t0, rt);
10640        break;
10641#else
10642        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10643            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10644            tcg_gen_ld_tl(t0, cpu_env,
10645                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10646            gen_store_gpr(t0, rt);
10647        } else {
10648            generate_exception_end(ctx, EXCP_RI);
10649        }
10650        break;
10651#endif
10652    default:            /* Invalid */
10653        MIPS_INVAL("rdhwr");
10654        generate_exception_end(ctx, EXCP_RI);
10655        break;
10656    }
10657    tcg_temp_free(t0);
10658}
10659
10660static inline void clear_branch_hflags(DisasContext *ctx)
10661{
10662    ctx->hflags &= ~MIPS_HFLAG_BMASK;
10663    if (ctx->bstate == BS_NONE) {
10664        save_cpu_state(ctx, 0);
10665    } else {
10666        /* it is not safe to save ctx->hflags as hflags may be changed
10667           in execution time by the instruction in delay / forbidden slot. */
10668        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10669    }
10670}
10671
10672static void gen_branch(DisasContext *ctx, int insn_bytes)
10673{
10674    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10675        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10676        /* Branches completion */
10677        clear_branch_hflags(ctx);
10678        ctx->bstate = BS_BRANCH;
10679        /* FIXME: Need to clear can_do_io.  */
10680        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10681        case MIPS_HFLAG_FBNSLOT:
10682            gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10683            break;
10684        case MIPS_HFLAG_B:
10685            /* unconditional branch */
10686            if (proc_hflags & MIPS_HFLAG_BX) {
10687                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10688            }
10689            gen_goto_tb(ctx, 0, ctx->btarget);
10690            break;
10691        case MIPS_HFLAG_BL:
10692            /* blikely taken case */
10693            gen_goto_tb(ctx, 0, ctx->btarget);
10694            break;
10695        case MIPS_HFLAG_BC:
10696            /* Conditional branch */
10697            {
10698                TCGLabel *l1 = gen_new_label();
10699
10700                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10701                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10702                gen_set_label(l1);
10703                gen_goto_tb(ctx, 0, ctx->btarget);
10704            }
10705            break;
10706        case MIPS_HFLAG_BR:
10707            /* unconditional branch to register */
10708            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10709                TCGv t0 = tcg_temp_new();
10710                TCGv_i32 t1 = tcg_temp_new_i32();
10711
10712                tcg_gen_andi_tl(t0, btarget, 0x1);
10713                tcg_gen_trunc_tl_i32(t1, t0);
10714                tcg_temp_free(t0);
10715                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10716                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10717                tcg_gen_or_i32(hflags, hflags, t1);
10718                tcg_temp_free_i32(t1);
10719
10720                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10721            } else {
10722                tcg_gen_mov_tl(cpu_PC, btarget);
10723            }
10724            if (ctx->singlestep_enabled) {
10725                save_cpu_state(ctx, 0);
10726                gen_helper_raise_exception_debug(cpu_env);
10727            }
10728            tcg_gen_exit_tb(0);
10729            break;
10730        default:
10731            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10732            abort();
10733        }
10734    }
10735}
10736
10737/* Compact Branches */
10738static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10739                                       int rs, int rt, int32_t offset)
10740{
10741    int bcond_compute = 0;
10742    TCGv t0 = tcg_temp_new();
10743    TCGv t1 = tcg_temp_new();
10744    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10745
10746    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10747#ifdef MIPS_DEBUG_DISAS
10748        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10749                  "\n", ctx->pc);
10750#endif
10751        generate_exception_end(ctx, EXCP_RI);
10752        goto out;
10753    }
10754
10755    /* Load needed operands and calculate btarget */
10756    switch (opc) {
10757    /* compact branch */
10758    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10759    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10760        gen_load_gpr(t0, rs);
10761        gen_load_gpr(t1, rt);
10762        bcond_compute = 1;
10763        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10764        if (rs <= rt && rs == 0) {
10765            /* OPC_BEQZALC, OPC_BNEZALC */
10766            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10767        }
10768        break;
10769    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10770    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10771        gen_load_gpr(t0, rs);
10772        gen_load_gpr(t1, rt);
10773        bcond_compute = 1;
10774        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10775        break;
10776    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10777    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10778        if (rs == 0 || rs == rt) {
10779            /* OPC_BLEZALC, OPC_BGEZALC */
10780            /* OPC_BGTZALC, OPC_BLTZALC */
10781            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10782        }
10783        gen_load_gpr(t0, rs);
10784        gen_load_gpr(t1, rt);
10785        bcond_compute = 1;
10786        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10787        break;
10788    case OPC_BC:
10789    case OPC_BALC:
10790        ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10791        break;
10792    case OPC_BEQZC:
10793    case OPC_BNEZC:
10794        if (rs != 0) {
10795            /* OPC_BEQZC, OPC_BNEZC */
10796            gen_load_gpr(t0, rs);
10797            bcond_compute = 1;
10798            ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10799        } else {
10800            /* OPC_JIC, OPC_JIALC */
10801            TCGv tbase = tcg_temp_new();
10802            TCGv toffset = tcg_temp_new();
10803
10804            gen_load_gpr(tbase, rt);
10805            tcg_gen_movi_tl(toffset, offset);
10806            gen_op_addr_add(ctx, btarget, tbase, toffset);
10807            tcg_temp_free(tbase);
10808            tcg_temp_free(toffset);
10809        }
10810        break;
10811    default:
10812        MIPS_INVAL("Compact branch/jump");
10813        generate_exception_end(ctx, EXCP_RI);
10814        goto out;
10815    }
10816
10817    if (bcond_compute == 0) {
10818        /* Uncoditional compact branch */
10819        switch (opc) {
10820        case OPC_JIALC:
10821            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10822            /* Fallthrough */
10823        case OPC_JIC:
10824            ctx->hflags |= MIPS_HFLAG_BR;
10825            break;
10826        case OPC_BALC:
10827            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10828            /* Fallthrough */
10829        case OPC_BC:
10830            ctx->hflags |= MIPS_HFLAG_B;
10831            break;
10832        default:
10833            MIPS_INVAL("Compact branch/jump");
10834            generate_exception_end(ctx, EXCP_RI);
10835            goto out;
10836        }
10837
10838        /* Generating branch here as compact branches don't have delay slot */
10839        gen_branch(ctx, 4);
10840    } else {
10841        /* Conditional compact branch */
10842        TCGLabel *fs = gen_new_label();
10843        save_cpu_state(ctx, 0);
10844
10845        switch (opc) {
10846        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10847            if (rs == 0 && rt != 0) {
10848                /* OPC_BLEZALC */
10849                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10850            } else if (rs != 0 && rt != 0 && rs == rt) {
10851                /* OPC_BGEZALC */
10852                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10853            } else {
10854                /* OPC_BGEUC */
10855                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10856            }
10857            break;
10858        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10859            if (rs == 0 && rt != 0) {
10860                /* OPC_BGTZALC */
10861                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10862            } else if (rs != 0 && rt != 0 && rs == rt) {
10863                /* OPC_BLTZALC */
10864                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10865            } else {
10866                /* OPC_BLTUC */
10867                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10868            }
10869            break;
10870        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10871            if (rs == 0 && rt != 0) {
10872                /* OPC_BLEZC */
10873                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10874            } else if (rs != 0 && rt != 0 && rs == rt) {
10875                /* OPC_BGEZC */
10876                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10877            } else {
10878                /* OPC_BGEC */
10879                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10880            }
10881            break;
10882        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10883            if (rs == 0 && rt != 0) {
10884                /* OPC_BGTZC */
10885                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10886            } else if (rs != 0 && rt != 0 && rs == rt) {
10887                /* OPC_BLTZC */
10888                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10889            } else {
10890                /* OPC_BLTC */
10891                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10892            }
10893            break;
10894        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10895        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10896            if (rs >= rt) {
10897                /* OPC_BOVC, OPC_BNVC */
10898                TCGv t2 = tcg_temp_new();
10899                TCGv t3 = tcg_temp_new();
10900                TCGv t4 = tcg_temp_new();
10901                TCGv input_overflow = tcg_temp_new();
10902
10903                gen_load_gpr(t0, rs);
10904                gen_load_gpr(t1, rt);
10905                tcg_gen_ext32s_tl(t2, t0);
10906                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10907                tcg_gen_ext32s_tl(t3, t1);
10908                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10909                tcg_gen_or_tl(input_overflow, input_overflow, t4);
10910
10911                tcg_gen_add_tl(t4, t2, t3);
10912                tcg_gen_ext32s_tl(t4, t4);
10913                tcg_gen_xor_tl(t2, t2, t3);
10914                tcg_gen_xor_tl(t3, t4, t3);
10915                tcg_gen_andc_tl(t2, t3, t2);
10916                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10917                tcg_gen_or_tl(t4, t4, input_overflow);
10918                if (opc == OPC_BOVC) {
10919                    /* OPC_BOVC */
10920                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10921                } else {
10922                    /* OPC_BNVC */
10923                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10924                }
10925                tcg_temp_free(input_overflow);
10926                tcg_temp_free(t4);
10927                tcg_temp_free(t3);
10928                tcg_temp_free(t2);
10929            } else if (rs < rt && rs == 0) {
10930                /* OPC_BEQZALC, OPC_BNEZALC */
10931                if (opc == OPC_BEQZALC) {
10932                    /* OPC_BEQZALC */
10933                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10934                } else {
10935                    /* OPC_BNEZALC */
10936                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10937                }
10938            } else {
10939                /* OPC_BEQC, OPC_BNEC */
10940                if (opc == OPC_BEQC) {
10941                    /* OPC_BEQC */
10942                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10943                } else {
10944                    /* OPC_BNEC */
10945                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10946                }
10947            }
10948            break;
10949        case OPC_BEQZC:
10950            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10951            break;
10952        case OPC_BNEZC:
10953            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10954            break;
10955        default:
10956            MIPS_INVAL("Compact conditional branch/jump");
10957            generate_exception_end(ctx, EXCP_RI);
10958            goto out;
10959        }
10960
10961        /* Generating branch here as compact branches don't have delay slot */
10962        gen_goto_tb(ctx, 1, ctx->btarget);
10963        gen_set_label(fs);
10964
10965        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10966    }
10967
10968out:
10969    tcg_temp_free(t0);
10970    tcg_temp_free(t1);
10971}
10972
10973/* ISA extensions (ASEs) */
10974/* MIPS16 extension to MIPS32 */
10975
10976/* MIPS16 major opcodes */
10977enum {
10978  M16_OPC_ADDIUSP = 0x00,
10979  M16_OPC_ADDIUPC = 0x01,
10980  M16_OPC_B = 0x02,
10981  M16_OPC_JAL = 0x03,
10982  M16_OPC_BEQZ = 0x04,
10983  M16_OPC_BNEQZ = 0x05,
10984  M16_OPC_SHIFT = 0x06,
10985  M16_OPC_LD = 0x07,
10986  M16_OPC_RRIA = 0x08,
10987  M16_OPC_ADDIU8 = 0x09,
10988  M16_OPC_SLTI = 0x0a,
10989  M16_OPC_SLTIU = 0x0b,
10990  M16_OPC_I8 = 0x0c,
10991  M16_OPC_LI = 0x0d,
10992  M16_OPC_CMPI = 0x0e,
10993  M16_OPC_SD = 0x0f,
10994  M16_OPC_LB = 0x10,
10995  M16_OPC_LH = 0x11,
10996  M16_OPC_LWSP = 0x12,
10997  M16_OPC_LW = 0x13,
10998  M16_OPC_LBU = 0x14,
10999  M16_OPC_LHU = 0x15,
11000  M16_OPC_LWPC = 0x16,
11001  M16_OPC_LWU = 0x17,
11002  M16_OPC_SB = 0x18,
11003  M16_OPC_SH = 0x19,
11004  M16_OPC_SWSP = 0x1a,
11005  M16_OPC_SW = 0x1b,
11006  M16_OPC_RRR = 0x1c,
11007  M16_OPC_RR = 0x1d,
11008  M16_OPC_EXTEND = 0x1e,
11009  M16_OPC_I64 = 0x1f
11010};
11011
11012/* I8 funct field */
11013enum {
11014  I8_BTEQZ = 0x0,
11015  I8_BTNEZ = 0x1,
11016  I8_SWRASP = 0x2,
11017  I8_ADJSP = 0x3,
11018  I8_SVRS = 0x4,
11019  I8_MOV32R = 0x5,
11020  I8_MOVR32 = 0x7
11021};
11022
11023/* RRR f field */
11024enum {
11025  RRR_DADDU = 0x0,
11026  RRR_ADDU = 0x1,
11027  RRR_DSUBU = 0x2,
11028  RRR_SUBU = 0x3
11029};
11030
11031/* RR funct field */
11032enum {
11033  RR_JR = 0x00,
11034  RR_SDBBP = 0x01,
11035  RR_SLT = 0x02,
11036  RR_SLTU = 0x03,
11037  RR_SLLV = 0x04,
11038  RR_BREAK = 0x05,
11039  RR_SRLV = 0x06,
11040  RR_SRAV = 0x07,
11041  RR_DSRL = 0x08,
11042  RR_CMP = 0x0a,
11043  RR_NEG = 0x0b,
11044  RR_AND = 0x0c,
11045  RR_OR = 0x0d,
11046  RR_XOR = 0x0e,
11047  RR_NOT = 0x0f,
11048  RR_MFHI = 0x10,
11049  RR_CNVT = 0x11,
11050  RR_MFLO = 0x12,
11051  RR_DSRA = 0x13,
11052  RR_DSLLV = 0x14,
11053  RR_DSRLV = 0x16,
11054  RR_DSRAV = 0x17,
11055  RR_MULT = 0x18,
11056  RR_MULTU = 0x19,
11057  RR_DIV = 0x1a,
11058  RR_DIVU = 0x1b,
11059  RR_DMULT = 0x1c,
11060  RR_DMULTU = 0x1d,
11061  RR_DDIV = 0x1e,
11062  RR_DDIVU = 0x1f
11063};
11064
11065/* I64 funct field */
11066enum {
11067  I64_LDSP = 0x0,
11068  I64_SDSP = 0x1,
11069  I64_SDRASP = 0x2,
11070  I64_DADJSP = 0x3,
11071  I64_LDPC = 0x4,
11072  I64_DADDIU5 = 0x5,
11073  I64_DADDIUPC = 0x6,
11074  I64_DADDIUSP = 0x7
11075};
11076
11077/* RR ry field for CNVT */
11078enum {
11079  RR_RY_CNVT_ZEB = 0x0,
11080  RR_RY_CNVT_ZEH = 0x1,
11081  RR_RY_CNVT_ZEW = 0x2,
11082  RR_RY_CNVT_SEB = 0x4,
11083  RR_RY_CNVT_SEH = 0x5,
11084  RR_RY_CNVT_SEW = 0x6,
11085};
11086
11087static int xlat (int r)
11088{
11089  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11090
11091  return map[r];
11092}
11093
11094static void gen_mips16_save (DisasContext *ctx,
11095                             int xsregs, int aregs,
11096                             int do_ra, int do_s0, int do_s1,
11097                             int framesize)
11098{
11099    TCGv t0 = tcg_temp_new();
11100    TCGv t1 = tcg_temp_new();
11101    TCGv t2 = tcg_temp_new();
11102    int args, astatic;
11103
11104    switch (aregs) {
11105    case 0:
11106    case 1:
11107    case 2:
11108    case 3:
11109    case 11:
11110        args = 0;
11111        break;
11112    case 4:
11113    case 5:
11114    case 6:
11115    case 7:
11116        args = 1;
11117        break;
11118    case 8:
11119    case 9:
11120    case 10:
11121        args = 2;
11122        break;
11123    case 12:
11124    case 13:
11125        args = 3;
11126        break;
11127    case 14:
11128        args = 4;
11129        break;
11130    default:
11131        generate_exception_end(ctx, EXCP_RI);
11132        return;
11133    }
11134
11135    switch (args) {
11136    case 4:
11137        gen_base_offset_addr(ctx, t0, 29, 12);
11138        gen_load_gpr(t1, 7);
11139        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11140        /* Fall through */
11141    case 3:
11142        gen_base_offset_addr(ctx, t0, 29, 8);
11143        gen_load_gpr(t1, 6);
11144        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11145        /* Fall through */
11146    case 2:
11147        gen_base_offset_addr(ctx, t0, 29, 4);
11148        gen_load_gpr(t1, 5);
11149        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11150        /* Fall through */
11151    case 1:
11152        gen_base_offset_addr(ctx, t0, 29, 0);
11153        gen_load_gpr(t1, 4);
11154        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11155    }
11156
11157    gen_load_gpr(t0, 29);
11158
11159#define DECR_AND_STORE(reg) do {                                 \
11160        tcg_gen_movi_tl(t2, -4);                                 \
11161        gen_op_addr_add(ctx, t0, t0, t2);                        \
11162        gen_load_gpr(t1, reg);                                   \
11163        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11164    } while (0)
11165
11166    if (do_ra) {
11167        DECR_AND_STORE(31);
11168    }
11169
11170    switch (xsregs) {
11171    case 7:
11172        DECR_AND_STORE(30);
11173        /* Fall through */
11174    case 6:
11175        DECR_AND_STORE(23);
11176        /* Fall through */
11177    case 5:
11178        DECR_AND_STORE(22);
11179        /* Fall through */
11180    case 4:
11181        DECR_AND_STORE(21);
11182        /* Fall through */
11183    case 3:
11184        DECR_AND_STORE(20);
11185        /* Fall through */
11186    case 2:
11187        DECR_AND_STORE(19);
11188        /* Fall through */
11189    case 1:
11190        DECR_AND_STORE(18);
11191    }
11192
11193    if (do_s1) {
11194        DECR_AND_STORE(17);
11195    }
11196    if (do_s0) {
11197        DECR_AND_STORE(16);
11198    }
11199
11200    switch (aregs) {
11201    case 0:
11202    case 4:
11203    case 8:
11204    case 12:
11205    case 14:
11206        astatic = 0;
11207        break;
11208    case 1:
11209    case 5:
11210    case 9:
11211    case 13:
11212        astatic = 1;
11213        break;
11214    case 2:
11215    case 6:
11216    case 10:
11217        astatic = 2;
11218        break;
11219    case 3:
11220    case 7:
11221        astatic = 3;
11222        break;
11223    case 11:
11224        astatic = 4;
11225        break;
11226    default:
11227        generate_exception_end(ctx, EXCP_RI);
11228        return;
11229    }
11230
11231    if (astatic > 0) {
11232        DECR_AND_STORE(7);
11233        if (astatic > 1) {
11234            DECR_AND_STORE(6);
11235            if (astatic > 2) {
11236                DECR_AND_STORE(5);
11237                if (astatic > 3) {
11238                    DECR_AND_STORE(4);
11239                }
11240            }
11241        }
11242    }
11243#undef DECR_AND_STORE
11244
11245    tcg_gen_movi_tl(t2, -framesize);
11246    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11247    tcg_temp_free(t0);
11248    tcg_temp_free(t1);
11249    tcg_temp_free(t2);
11250}
11251
11252static void gen_mips16_restore (DisasContext *ctx,
11253                                int xsregs, int aregs,
11254                                int do_ra, int do_s0, int do_s1,
11255                                int framesize)
11256{
11257    int astatic;
11258    TCGv t0 = tcg_temp_new();
11259    TCGv t1 = tcg_temp_new();
11260    TCGv t2 = tcg_temp_new();
11261
11262    tcg_gen_movi_tl(t2, framesize);
11263    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11264
11265#define DECR_AND_LOAD(reg) do {                            \
11266        tcg_gen_movi_tl(t2, -4);                           \
11267        gen_op_addr_add(ctx, t0, t0, t2);                  \
11268        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11269        gen_store_gpr(t1, reg);                            \
11270    } while (0)
11271
11272    if (do_ra) {
11273        DECR_AND_LOAD(31);
11274    }
11275
11276    switch (xsregs) {
11277    case 7:
11278        DECR_AND_LOAD(30);
11279        /* Fall through */
11280    case 6:
11281        DECR_AND_LOAD(23);
11282        /* Fall through */
11283    case 5:
11284        DECR_AND_LOAD(22);
11285        /* Fall through */
11286    case 4:
11287        DECR_AND_LOAD(21);
11288        /* Fall through */
11289    case 3:
11290        DECR_AND_LOAD(20);
11291        /* Fall through */
11292    case 2:
11293        DECR_AND_LOAD(19);
11294        /* Fall through */
11295    case 1:
11296        DECR_AND_LOAD(18);
11297    }
11298
11299    if (do_s1) {
11300        DECR_AND_LOAD(17);
11301    }
11302    if (do_s0) {
11303        DECR_AND_LOAD(16);
11304    }
11305
11306    switch (aregs) {
11307    case 0:
11308    case 4:
11309    case 8:
11310    case 12:
11311    case 14:
11312        astatic = 0;
11313        break;
11314    case 1:
11315    case 5:
11316    case 9:
11317    case 13:
11318        astatic = 1;
11319        break;
11320    case 2:
11321    case 6:
11322    case 10:
11323        astatic = 2;
11324        break;
11325    case 3:
11326    case 7:
11327        astatic = 3;
11328        break;
11329    case 11:
11330        astatic = 4;
11331        break;
11332    default:
11333        generate_exception_end(ctx, EXCP_RI);
11334        return;
11335    }
11336
11337    if (astatic > 0) {
11338        DECR_AND_LOAD(7);
11339        if (astatic > 1) {
11340            DECR_AND_LOAD(6);
11341            if (astatic > 2) {
11342                DECR_AND_LOAD(5);
11343                if (astatic > 3) {
11344                    DECR_AND_LOAD(4);
11345                }
11346            }
11347        }
11348    }
11349#undef DECR_AND_LOAD
11350
11351    tcg_gen_movi_tl(t2, framesize);
11352    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11353    tcg_temp_free(t0);
11354    tcg_temp_free(t1);
11355    tcg_temp_free(t2);
11356}
11357
11358static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11359                         int is_64_bit, int extended)
11360{
11361    TCGv t0;
11362
11363    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11364        generate_exception_end(ctx, EXCP_RI);
11365        return;
11366    }
11367
11368    t0 = tcg_temp_new();
11369
11370    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11371    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11372    if (!is_64_bit) {
11373        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11374    }
11375
11376    tcg_temp_free(t0);
11377}
11378
11379static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11380                                int16_t offset)
11381{
11382    TCGv_i32 t0 = tcg_const_i32(op);
11383    TCGv t1 = tcg_temp_new();
11384    gen_base_offset_addr(ctx, t1, base, offset);
11385    gen_helper_cache(cpu_env, t1, t0);
11386}
11387
11388#if defined(TARGET_MIPS64)
11389static void decode_i64_mips16 (DisasContext *ctx,
11390                               int ry, int funct, int16_t offset,
11391                               int extended)
11392{
11393    switch (funct) {
11394    case I64_LDSP:
11395        check_insn(ctx, ISA_MIPS3);
11396        check_mips_64(ctx);
11397        offset = extended ? offset : offset << 3;
11398        gen_ld(ctx, OPC_LD, ry, 29, offset);
11399        break;
11400    case I64_SDSP:
11401        check_insn(ctx, ISA_MIPS3);
11402        check_mips_64(ctx);
11403        offset = extended ? offset : offset << 3;
11404        gen_st(ctx, OPC_SD, ry, 29, offset);
11405        break;
11406    case I64_SDRASP:
11407        check_insn(ctx, ISA_MIPS3);
11408        check_mips_64(ctx);
11409        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11410        gen_st(ctx, OPC_SD, 31, 29, offset);
11411        break;
11412    case I64_DADJSP:
11413        check_insn(ctx, ISA_MIPS3);
11414        check_mips_64(ctx);
11415        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11416        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11417        break;
11418    case I64_LDPC:
11419        check_insn(ctx, ISA_MIPS3);
11420        check_mips_64(ctx);
11421        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11422            generate_exception_end(ctx, EXCP_RI);
11423        } else {
11424            offset = extended ? offset : offset << 3;
11425            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11426        }
11427        break;
11428    case I64_DADDIU5:
11429        check_insn(ctx, ISA_MIPS3);
11430        check_mips_64(ctx);
11431        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11432        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11433        break;
11434    case I64_DADDIUPC:
11435        check_insn(ctx, ISA_MIPS3);
11436        check_mips_64(ctx);
11437        offset = extended ? offset : offset << 2;
11438        gen_addiupc(ctx, ry, offset, 1, extended);
11439        break;
11440    case I64_DADDIUSP:
11441        check_insn(ctx, ISA_MIPS3);
11442        check_mips_64(ctx);
11443        offset = extended ? offset : offset << 2;
11444        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11445        break;
11446    }
11447}
11448#endif
11449
11450static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11451{
11452    int extend = cpu_lduw_code(env, ctx->pc + 2);
11453    int op, rx, ry, funct, sa;
11454    int16_t imm, offset;
11455
11456    ctx->opcode = (ctx->opcode << 16) | extend;
11457    op = (ctx->opcode >> 11) & 0x1f;
11458    sa = (ctx->opcode >> 22) & 0x1f;
11459    funct = (ctx->opcode >> 8) & 0x7;
11460    rx = xlat((ctx->opcode >> 8) & 0x7);
11461    ry = xlat((ctx->opcode >> 5) & 0x7);
11462    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11463                              | ((ctx->opcode >> 21) & 0x3f) << 5
11464                              | (ctx->opcode & 0x1f));
11465
11466    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11467       counterparts.  */
11468    switch (op) {
11469    case M16_OPC_ADDIUSP:
11470        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11471        break;
11472    case M16_OPC_ADDIUPC:
11473        gen_addiupc(ctx, rx, imm, 0, 1);
11474        break;
11475    case M16_OPC_B:
11476        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11477        /* No delay slot, so just process as a normal instruction */
11478        break;
11479    case M16_OPC_BEQZ:
11480        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11481        /* No delay slot, so just process as a normal instruction */
11482        break;
11483    case M16_OPC_BNEQZ:
11484        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11485        /* No delay slot, so just process as a normal instruction */
11486        break;
11487    case M16_OPC_SHIFT:
11488        switch (ctx->opcode & 0x3) {
11489        case 0x0:
11490            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11491            break;
11492        case 0x1:
11493#if defined(TARGET_MIPS64)
11494            check_mips_64(ctx);
11495            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11496#else
11497            generate_exception_end(ctx, EXCP_RI);
11498#endif
11499            break;
11500        case 0x2:
11501            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11502            break;
11503        case 0x3:
11504            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11505            break;
11506        }
11507        break;
11508#if defined(TARGET_MIPS64)
11509    case M16_OPC_LD:
11510        check_insn(ctx, ISA_MIPS3);
11511        check_mips_64(ctx);
11512        gen_ld(ctx, OPC_LD, ry, rx, offset);
11513        break;
11514#endif
11515    case M16_OPC_RRIA:
11516        imm = ctx->opcode & 0xf;
11517        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11518        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11519        imm = (int16_t) (imm << 1) >> 1;
11520        if ((ctx->opcode >> 4) & 0x1) {
11521#if defined(TARGET_MIPS64)
11522            check_mips_64(ctx);
11523            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11524#else
11525            generate_exception_end(ctx, EXCP_RI);
11526#endif
11527        } else {
11528            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11529        }
11530        break;
11531    case M16_OPC_ADDIU8:
11532        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11533        break;
11534    case M16_OPC_SLTI:
11535        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11536        break;
11537    case M16_OPC_SLTIU:
11538        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11539        break;
11540    case M16_OPC_I8:
11541        switch (funct) {
11542        case I8_BTEQZ:
11543            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11544            break;
11545        case I8_BTNEZ:
11546            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11547            break;
11548        case I8_SWRASP:
11549            gen_st(ctx, OPC_SW, 31, 29, imm);
11550            break;
11551        case I8_ADJSP:
11552            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11553            break;
11554        case I8_SVRS:
11555            check_insn(ctx, ISA_MIPS32);
11556            {
11557                int xsregs = (ctx->opcode >> 24) & 0x7;
11558                int aregs = (ctx->opcode >> 16) & 0xf;
11559                int do_ra = (ctx->opcode >> 6) & 0x1;
11560                int do_s0 = (ctx->opcode >> 5) & 0x1;
11561                int do_s1 = (ctx->opcode >> 4) & 0x1;
11562                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11563                                 | (ctx->opcode & 0xf)) << 3;
11564
11565                if (ctx->opcode & (1 << 7)) {
11566                    gen_mips16_save(ctx, xsregs, aregs,
11567                                    do_ra, do_s0, do_s1,
11568                                    framesize);
11569                } else {
11570                    gen_mips16_restore(ctx, xsregs, aregs,
11571                                       do_ra, do_s0, do_s1,
11572                                       framesize);
11573                }
11574            }
11575            break;
11576        default:
11577            generate_exception_end(ctx, EXCP_RI);
11578            break;
11579        }
11580        break;
11581    case M16_OPC_LI:
11582        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11583        break;
11584    case M16_OPC_CMPI:
11585        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11586        break;
11587#if defined(TARGET_MIPS64)
11588    case M16_OPC_SD:
11589        check_insn(ctx, ISA_MIPS3);
11590        check_mips_64(ctx);
11591        gen_st(ctx, OPC_SD, ry, rx, offset);
11592        break;
11593#endif
11594    case M16_OPC_LB:
11595        gen_ld(ctx, OPC_LB, ry, rx, offset);
11596        break;
11597    case M16_OPC_LH:
11598        gen_ld(ctx, OPC_LH, ry, rx, offset);
11599        break;
11600    case M16_OPC_LWSP:
11601        gen_ld(ctx, OPC_LW, rx, 29, offset);
11602        break;
11603    case M16_OPC_LW:
11604        gen_ld(ctx, OPC_LW, ry, rx, offset);
11605        break;
11606    case M16_OPC_LBU:
11607        gen_ld(ctx, OPC_LBU, ry, rx, offset);
11608        break;
11609    case M16_OPC_LHU:
11610        gen_ld(ctx, OPC_LHU, ry, rx, offset);
11611        break;
11612    case M16_OPC_LWPC:
11613        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11614        break;
11615#if defined(TARGET_MIPS64)
11616    case M16_OPC_LWU:
11617        check_insn(ctx, ISA_MIPS3);
11618        check_mips_64(ctx);
11619        gen_ld(ctx, OPC_LWU, ry, rx, offset);
11620        break;
11621#endif
11622    case M16_OPC_SB:
11623        gen_st(ctx, OPC_SB, ry, rx, offset);
11624        break;
11625    case M16_OPC_SH:
11626        gen_st(ctx, OPC_SH, ry, rx, offset);
11627        break;
11628    case M16_OPC_SWSP:
11629        gen_st(ctx, OPC_SW, rx, 29, offset);
11630        break;
11631    case M16_OPC_SW:
11632        gen_st(ctx, OPC_SW, ry, rx, offset);
11633        break;
11634#if defined(TARGET_MIPS64)
11635    case M16_OPC_I64:
11636        decode_i64_mips16(ctx, ry, funct, offset, 1);
11637        break;
11638#endif
11639    default:
11640        generate_exception_end(ctx, EXCP_RI);
11641        break;
11642    }
11643
11644    return 4;
11645}
11646
11647static inline bool is_uhi(int sdbbp_code)
11648{
11649#ifdef CONFIG_USER_ONLY
11650    return false;
11651#else
11652    return semihosting_enabled() && sdbbp_code == 1;
11653#endif
11654}
11655
11656static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11657{
11658    int rx, ry;
11659    int sa;
11660    int op, cnvt_op, op1, offset;
11661    int funct;
11662    int n_bytes;
11663
11664    op = (ctx->opcode >> 11) & 0x1f;
11665    sa = (ctx->opcode >> 2) & 0x7;
11666    sa = sa == 0 ? 8 : sa;
11667    rx = xlat((ctx->opcode >> 8) & 0x7);
11668    cnvt_op = (ctx->opcode >> 5) & 0x7;
11669    ry = xlat((ctx->opcode >> 5) & 0x7);
11670    op1 = offset = ctx->opcode & 0x1f;
11671
11672    n_bytes = 2;
11673
11674    switch (op) {
11675    case M16_OPC_ADDIUSP:
11676        {
11677            int16_t imm = ((uint8_t) ctx->opcode) << 2;
11678
11679            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11680        }
11681        break;
11682    case M16_OPC_ADDIUPC:
11683        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11684        break;
11685    case M16_OPC_B:
11686        offset = (ctx->opcode & 0x7ff) << 1;
11687        offset = (int16_t)(offset << 4) >> 4;
11688        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11689        /* No delay slot, so just process as a normal instruction */
11690        break;
11691    case M16_OPC_JAL:
11692        offset = cpu_lduw_code(env, ctx->pc + 2);
11693        offset = (((ctx->opcode & 0x1f) << 21)
11694                  | ((ctx->opcode >> 5) & 0x1f) << 16
11695                  | offset) << 2;
11696        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11697        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11698        n_bytes = 4;
11699        break;
11700    case M16_OPC_BEQZ:
11701        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11702                           ((int8_t)ctx->opcode) << 1, 0);
11703        /* No delay slot, so just process as a normal instruction */
11704        break;
11705    case M16_OPC_BNEQZ:
11706        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11707                           ((int8_t)ctx->opcode) << 1, 0);
11708        /* No delay slot, so just process as a normal instruction */
11709        break;
11710    case M16_OPC_SHIFT:
11711        switch (ctx->opcode & 0x3) {
11712        case 0x0:
11713            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11714            break;
11715        case 0x1:
11716#if defined(TARGET_MIPS64)
11717            check_insn(ctx, ISA_MIPS3);
11718            check_mips_64(ctx);
11719            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11720#else
11721            generate_exception_end(ctx, EXCP_RI);
11722#endif
11723            break;
11724        case 0x2:
11725            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11726            break;
11727        case 0x3:
11728            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11729            break;
11730        }
11731        break;
11732#if defined(TARGET_MIPS64)
11733    case M16_OPC_LD:
11734        check_insn(ctx, ISA_MIPS3);
11735        check_mips_64(ctx);
11736        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11737        break;
11738#endif
11739    case M16_OPC_RRIA:
11740        {
11741            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11742
11743            if ((ctx->opcode >> 4) & 1) {
11744#if defined(TARGET_MIPS64)
11745                check_insn(ctx, ISA_MIPS3);
11746                check_mips_64(ctx);
11747                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11748#else
11749                generate_exception_end(ctx, EXCP_RI);
11750#endif
11751            } else {
11752                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11753            }
11754        }
11755        break;
11756    case M16_OPC_ADDIU8:
11757        {
11758            int16_t imm = (int8_t) ctx->opcode;
11759
11760            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11761        }
11762        break;
11763    case M16_OPC_SLTI:
11764        {
11765            int16_t imm = (uint8_t) ctx->opcode;
11766            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11767        }
11768        break;
11769    case M16_OPC_SLTIU:
11770        {
11771            int16_t imm = (uint8_t) ctx->opcode;
11772            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11773        }
11774        break;
11775    case M16_OPC_I8:
11776        {
11777            int reg32;
11778
11779            funct = (ctx->opcode >> 8) & 0x7;
11780            switch (funct) {
11781            case I8_BTEQZ:
11782                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11783                                   ((int8_t)ctx->opcode) << 1, 0);
11784                break;
11785            case I8_BTNEZ:
11786                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11787                                   ((int8_t)ctx->opcode) << 1, 0);
11788                break;
11789            case I8_SWRASP:
11790                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11791                break;
11792            case I8_ADJSP:
11793                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11794                              ((int8_t)ctx->opcode) << 3);
11795                break;
11796            case I8_SVRS:
11797                check_insn(ctx, ISA_MIPS32);
11798                {
11799                    int do_ra = ctx->opcode & (1 << 6);
11800                    int do_s0 = ctx->opcode & (1 << 5);
11801                    int do_s1 = ctx->opcode & (1 << 4);
11802                    int framesize = ctx->opcode & 0xf;
11803
11804                    if (framesize == 0) {
11805                        framesize = 128;
11806                    } else {
11807                        framesize = framesize << 3;
11808                    }
11809
11810                    if (ctx->opcode & (1 << 7)) {
11811                        gen_mips16_save(ctx, 0, 0,
11812                                        do_ra, do_s0, do_s1, framesize);
11813                    } else {
11814                        gen_mips16_restore(ctx, 0, 0,
11815                                           do_ra, do_s0, do_s1, framesize);
11816                    }
11817                }
11818                break;
11819            case I8_MOV32R:
11820                {
11821                    int rz = xlat(ctx->opcode & 0x7);
11822
11823                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11824                        ((ctx->opcode >> 5) & 0x7);
11825                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11826                }
11827                break;
11828            case I8_MOVR32:
11829                reg32 = ctx->opcode & 0x1f;
11830                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11831                break;
11832            default:
11833                generate_exception_end(ctx, EXCP_RI);
11834                break;
11835            }
11836        }
11837        break;
11838    case M16_OPC_LI:
11839        {
11840            int16_t imm = (uint8_t) ctx->opcode;
11841
11842            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11843        }
11844        break;
11845    case M16_OPC_CMPI:
11846        {
11847            int16_t imm = (uint8_t) ctx->opcode;
11848            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11849        }
11850        break;
11851#if defined(TARGET_MIPS64)
11852    case M16_OPC_SD:
11853        check_insn(ctx, ISA_MIPS3);
11854        check_mips_64(ctx);
11855        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11856        break;
11857#endif
11858    case M16_OPC_LB:
11859        gen_ld(ctx, OPC_LB, ry, rx, offset);
11860        break;
11861    case M16_OPC_LH:
11862        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11863        break;
11864    case M16_OPC_LWSP:
11865        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11866        break;
11867    case M16_OPC_LW:
11868        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11869        break;
11870    case M16_OPC_LBU:
11871        gen_ld(ctx, OPC_LBU, ry, rx, offset);
11872        break;
11873    case M16_OPC_LHU:
11874        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11875        break;
11876    case M16_OPC_LWPC:
11877        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11878        break;
11879#if defined (TARGET_MIPS64)
11880    case M16_OPC_LWU:
11881        check_insn(ctx, ISA_MIPS3);
11882        check_mips_64(ctx);
11883        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11884        break;
11885#endif
11886    case M16_OPC_SB:
11887        gen_st(ctx, OPC_SB, ry, rx, offset);
11888        break;
11889    case M16_OPC_SH:
11890        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11891        break;
11892    case M16_OPC_SWSP:
11893        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11894        break;
11895    case M16_OPC_SW:
11896        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11897        break;
11898    case M16_OPC_RRR:
11899        {
11900            int rz = xlat((ctx->opcode >> 2) & 0x7);
11901            int mips32_op;
11902
11903            switch (ctx->opcode & 0x3) {
11904            case RRR_ADDU:
11905                mips32_op = OPC_ADDU;
11906                break;
11907            case RRR_SUBU:
11908                mips32_op = OPC_SUBU;
11909                break;
11910#if defined(TARGET_MIPS64)
11911            case RRR_DADDU:
11912                mips32_op = OPC_DADDU;
11913                check_insn(ctx, ISA_MIPS3);
11914                check_mips_64(ctx);
11915                break;
11916            case RRR_DSUBU:
11917                mips32_op = OPC_DSUBU;
11918                check_insn(ctx, ISA_MIPS3);
11919                check_mips_64(ctx);
11920                break;
11921#endif
11922            default:
11923                generate_exception_end(ctx, EXCP_RI);
11924                goto done;
11925            }
11926
11927            gen_arith(ctx, mips32_op, rz, rx, ry);
11928        done:
11929            ;
11930        }
11931        break;
11932    case M16_OPC_RR:
11933        switch (op1) {
11934        case RR_JR:
11935            {
11936                int nd = (ctx->opcode >> 7) & 0x1;
11937                int link = (ctx->opcode >> 6) & 0x1;
11938                int ra = (ctx->opcode >> 5) & 0x1;
11939
11940                if (nd) {
11941                    check_insn(ctx, ISA_MIPS32);
11942                }
11943
11944                if (link) {
11945                    op = OPC_JALR;
11946                } else {
11947                    op = OPC_JR;
11948                }
11949
11950                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11951                                   (nd ? 0 : 2));
11952            }
11953            break;
11954        case RR_SDBBP:
11955            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11956                gen_helper_do_semihosting(cpu_env);
11957            } else {
11958                /* XXX: not clear which exception should be raised
11959                 *      when in debug mode...
11960                 */
11961                check_insn(ctx, ISA_MIPS32);
11962                generate_exception_end(ctx, EXCP_DBp);
11963            }
11964            break;
11965        case RR_SLT:
11966            gen_slt(ctx, OPC_SLT, 24, rx, ry);
11967            break;
11968        case RR_SLTU:
11969            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11970            break;
11971        case RR_BREAK:
11972            generate_exception_end(ctx, EXCP_BREAK);
11973            break;
11974        case RR_SLLV:
11975            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11976            break;
11977        case RR_SRLV:
11978            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11979            break;
11980        case RR_SRAV:
11981            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11982            break;
11983#if defined (TARGET_MIPS64)
11984        case RR_DSRL:
11985            check_insn(ctx, ISA_MIPS3);
11986            check_mips_64(ctx);
11987            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11988            break;
11989#endif
11990        case RR_CMP:
11991            gen_logic(ctx, OPC_XOR, 24, rx, ry);
11992            break;
11993        case RR_NEG:
11994            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11995            break;
11996        case RR_AND:
11997            gen_logic(ctx, OPC_AND, rx, rx, ry);
11998            break;
11999        case RR_OR:
12000            gen_logic(ctx, OPC_OR, rx, rx, ry);
12001            break;
12002        case RR_XOR:
12003            gen_logic(ctx, OPC_XOR, rx, rx, ry);
12004            break;
12005        case RR_NOT:
12006            gen_logic(ctx, OPC_NOR, rx, ry, 0);
12007            break;
12008        case RR_MFHI:
12009            gen_HILO(ctx, OPC_MFHI, 0, rx);
12010            break;
12011        case RR_CNVT:
12012            check_insn(ctx, ISA_MIPS32);
12013            switch (cnvt_op) {
12014            case RR_RY_CNVT_ZEB:
12015                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12016                break;
12017            case RR_RY_CNVT_ZEH:
12018                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12019                break;
12020            case RR_RY_CNVT_SEB:
12021                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12022                break;
12023            case RR_RY_CNVT_SEH:
12024                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12025                break;
12026#if defined (TARGET_MIPS64)
12027            case RR_RY_CNVT_ZEW:
12028                check_insn(ctx, ISA_MIPS64);
12029                check_mips_64(ctx);
12030                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12031                break;
12032            case RR_RY_CNVT_SEW:
12033                check_insn(ctx, ISA_MIPS64);
12034                check_mips_64(ctx);
12035                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12036                break;
12037#endif
12038            default:
12039                generate_exception_end(ctx, EXCP_RI);
12040                break;
12041            }
12042            break;
12043        case RR_MFLO:
12044            gen_HILO(ctx, OPC_MFLO, 0, rx);
12045            break;
12046#if defined (TARGET_MIPS64)
12047        case RR_DSRA:
12048            check_insn(ctx, ISA_MIPS3);
12049            check_mips_64(ctx);
12050            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
12051            break;
12052        case RR_DSLLV:
12053            check_insn(ctx, ISA_MIPS3);
12054            check_mips_64(ctx);
12055            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
12056            break;
12057        case RR_DSRLV:
12058            check_insn(ctx, ISA_MIPS3);
12059            check_mips_64(ctx);
12060            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
12061            break;
12062        case RR_DSRAV:
12063            check_insn(ctx, ISA_MIPS3);
12064            check_mips_64(ctx);
12065            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
12066            break;
12067#endif
12068        case RR_MULT:
12069            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
12070            break;
12071        case RR_MULTU:
12072            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
12073            break;
12074        case RR_DIV:
12075            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
12076            break;
12077        case RR_DIVU:
12078            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
12079            break;
12080#if defined (TARGET_MIPS64)
12081        case RR_DMULT:
12082            check_insn(ctx, ISA_MIPS3);
12083            check_mips_64(ctx);
12084            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
12085            break;
12086        case RR_DMULTU:
12087            check_insn(ctx, ISA_MIPS3);
12088            check_mips_64(ctx);
12089            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
12090            break;
12091        case RR_DDIV:
12092            check_insn(ctx, ISA_MIPS3);
12093            check_mips_64(ctx);
12094            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
12095            break;
12096        case RR_DDIVU:
12097            check_insn(ctx, ISA_MIPS3);
12098            check_mips_64(ctx);
12099            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
12100            break;
12101#endif
12102        default:
12103            generate_exception_end(ctx, EXCP_RI);
12104            break;
12105        }
12106        break;
12107    case M16_OPC_EXTEND:
12108        decode_extended_mips16_opc(env, ctx);
12109        n_bytes = 4;
12110        break;
12111#if defined(TARGET_MIPS64)
12112    case M16_OPC_I64:
12113        funct = (ctx->opcode >> 8) & 0x7;
12114        decode_i64_mips16(ctx, ry, funct, offset, 0);
12115        break;
12116#endif
12117    default:
12118        generate_exception_end(ctx, EXCP_RI);
12119        break;
12120    }
12121
12122    return n_bytes;
12123}
12124
12125/* microMIPS extension to MIPS32/MIPS64 */
12126
12127/*
12128 * microMIPS32/microMIPS64 major opcodes
12129 *
12130 * 1. MIPS Architecture for Programmers Volume II-B:
12131 *      The microMIPS32 Instruction Set (Revision 3.05)
12132 *
12133 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
12134 *
12135 * 2. MIPS Architecture For Programmers Volume II-A:
12136 *      The MIPS64 Instruction Set (Revision 3.51)
12137 */
12138
12139enum {
12140    POOL32A = 0x00,
12141    POOL16A = 0x01,
12142    LBU16 = 0x02,
12143    MOVE16 = 0x03,
12144    ADDI32 = 0x04,
12145    R6_LUI = 0x04,
12146    AUI = 0x04,
12147    LBU32 = 0x05,
12148    SB32 = 0x06,
12149    LB32 = 0x07,
12150
12151    POOL32B = 0x08,
12152    POOL16B = 0x09,
12153    LHU16 = 0x0a,
12154    ANDI16 = 0x0b,
12155    ADDIU32 = 0x0c,
12156    LHU32 = 0x0d,
12157    SH32 = 0x0e,
12158    LH32 = 0x0f,
12159
12160    POOL32I = 0x10,
12161    POOL16C = 0x11,
12162    LWSP16 = 0x12,
12163    POOL16D = 0x13,
12164    ORI32 = 0x14,
12165    POOL32F = 0x15,
12166    POOL32S = 0x16,  /* MIPS64 */
12167    DADDIU32 = 0x17, /* MIPS64 */
12168
12169    POOL32C = 0x18,
12170    LWGP16 = 0x19,
12171    LW16 = 0x1a,
12172    POOL16E = 0x1b,
12173    XORI32 = 0x1c,
12174    JALS32 = 0x1d,
12175    BOVC = 0x1d,
12176    BEQC = 0x1d,
12177    BEQZALC = 0x1d,
12178    ADDIUPC = 0x1e,
12179    PCREL = 0x1e,
12180    BNVC = 0x1f,
12181    BNEC = 0x1f,
12182    BNEZALC = 0x1f,
12183
12184    R6_BEQZC = 0x20,
12185    JIC = 0x20,
12186    POOL16F = 0x21,
12187    SB16 = 0x22,
12188    BEQZ16 = 0x23,
12189    BEQZC16 = 0x23,
12190    SLTI32 = 0x24,
12191    BEQ32 = 0x25,
12192    BC = 0x25,
12193    SWC132 = 0x26,
12194    LWC132 = 0x27,
12195
12196    /* 0x29 is reserved */
12197    RES_29 = 0x29,
12198    R6_BNEZC = 0x28,
12199    JIALC = 0x28,
12200    SH16 = 0x2a,
12201    BNEZ16 = 0x2b,
12202    BNEZC16 = 0x2b,
12203    SLTIU32 = 0x2c,
12204    BNE32 = 0x2d,
12205    BALC = 0x2d,
12206    SDC132 = 0x2e,
12207    LDC132 = 0x2f,
12208
12209    /* 0x31 is reserved */
12210    RES_31 = 0x31,
12211    BLEZALC = 0x30,
12212    BGEZALC = 0x30,
12213    BGEUC = 0x30,
12214    SWSP16 = 0x32,
12215    B16 = 0x33,
12216    BC16 = 0x33,
12217    ANDI32 = 0x34,
12218    J32 = 0x35,
12219    BGTZC = 0x35,
12220    BLTZC = 0x35,
12221    BLTC = 0x35,
12222    SD32 = 0x36, /* MIPS64 */
12223    LD32 = 0x37, /* MIPS64 */
12224
12225    /* 0x39 is reserved */
12226    RES_39 = 0x39,
12227    BGTZALC = 0x38,
12228    BLTZALC = 0x38,
12229    BLTUC = 0x38,
12230    SW16 = 0x3a,
12231    LI16 = 0x3b,
12232    JALX32 = 0x3c,
12233    JAL32 = 0x3d,
12234    BLEZC = 0x3d,
12235    BGEZC = 0x3d,
12236    BGEC = 0x3d,
12237    SW32 = 0x3e,
12238    LW32 = 0x3f
12239};
12240
12241/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12242enum {
12243    ADDIUPC_00 = 0x00,
12244    ADDIUPC_07 = 0x07,
12245    AUIPC = 0x1e,
12246    ALUIPC = 0x1f,
12247    LWPC_08 = 0x08,
12248    LWPC_0F = 0x0F,
12249};
12250
12251/* POOL32A encoding of minor opcode field */
12252
12253enum {
12254    /* These opcodes are distinguished only by bits 9..6; those bits are
12255     * what are recorded below. */
12256    SLL32 = 0x0,
12257    SRL32 = 0x1,
12258    SRA = 0x2,
12259    ROTR = 0x3,
12260    SELEQZ = 0x5,
12261    SELNEZ = 0x6,
12262    R6_RDHWR = 0x7,
12263
12264    SLLV = 0x0,
12265    SRLV = 0x1,
12266    SRAV = 0x2,
12267    ROTRV = 0x3,
12268    ADD = 0x4,
12269    ADDU32 = 0x5,
12270    SUB = 0x6,
12271    SUBU32 = 0x7,
12272    MUL = 0x8,
12273    AND = 0x9,
12274    OR32 = 0xa,
12275    NOR = 0xb,
12276    XOR32 = 0xc,
12277    SLT = 0xd,
12278    SLTU = 0xe,
12279
12280    MOVN = 0x0,
12281    R6_MUL  = 0x0,
12282    MOVZ = 0x1,
12283    MUH  = 0x1,
12284    MULU = 0x2,
12285    MUHU = 0x3,
12286    LWXS = 0x4,
12287    R6_DIV  = 0x4,
12288    MOD  = 0x5,
12289    R6_DIVU = 0x6,
12290    MODU = 0x7,
12291
12292    /* The following can be distinguished by their lower 6 bits. */
12293    BREAK32 = 0x07,
12294    INS = 0x0c,
12295    LSA = 0x0f,
12296    ALIGN = 0x1f,
12297    EXT = 0x2c,
12298    POOL32AXF = 0x3c,
12299    SIGRIE = 0x3f
12300};
12301
12302/* POOL32AXF encoding of minor opcode field extension */
12303
12304/*
12305 * 1. MIPS Architecture for Programmers Volume II-B:
12306 *      The microMIPS32 Instruction Set (Revision 3.05)
12307 *
12308 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12309 *
12310 * 2. MIPS Architecture for Programmers VolumeIV-e:
12311 *      The MIPS DSP Application-Specific Extension
12312 *        to the microMIPS32 Architecture (Revision 2.34)
12313 *
12314 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12315 */
12316
12317enum {
12318    /* bits 11..6 */
12319    TEQ = 0x00,
12320    TGE = 0x08,
12321    TGEU = 0x10,
12322    TLT = 0x20,
12323    TLTU = 0x28,
12324    TNE = 0x30,
12325
12326    MFC0 = 0x03,
12327    MTC0 = 0x0b,
12328
12329    /* begin of microMIPS32 DSP */
12330
12331    /* bits 13..12 for 0x01 */
12332    MFHI_ACC = 0x0,
12333    MFLO_ACC = 0x1,
12334    MTHI_ACC = 0x2,
12335    MTLO_ACC = 0x3,
12336
12337    /* bits 13..12 for 0x2a */
12338    MADD_ACC = 0x0,
12339    MADDU_ACC = 0x1,
12340    MSUB_ACC = 0x2,
12341    MSUBU_ACC = 0x3,
12342
12343    /* bits 13..12 for 0x32 */
12344    MULT_ACC = 0x0,
12345    MULTU_ACC = 0x1,
12346
12347    /* end of microMIPS32 DSP */
12348
12349    /* bits 15..12 for 0x2c */
12350    BITSWAP = 0x0,
12351    SEB = 0x2,
12352    SEH = 0x3,
12353    CLO = 0x4,
12354    CLZ = 0x5,
12355    RDHWR = 0x6,
12356    WSBH = 0x7,
12357    MULT = 0x8,
12358    MULTU = 0x9,
12359    DIV = 0xa,
12360    DIVU = 0xb,
12361    MADD = 0xc,
12362    MADDU = 0xd,
12363    MSUB = 0xe,
12364    MSUBU = 0xf,
12365
12366    /* bits 15..12 for 0x34 */
12367    MFC2 = 0x4,
12368    MTC2 = 0x5,
12369    MFHC2 = 0x8,
12370    MTHC2 = 0x9,
12371    CFC2 = 0xc,
12372    CTC2 = 0xd,
12373
12374    /* bits 15..12 for 0x3c */
12375    JALR = 0x0,
12376    JR = 0x0,                   /* alias */
12377    JALRC = 0x0,
12378    JRC = 0x0,
12379    JALR_HB = 0x1,
12380    JALRC_HB = 0x1,
12381    JALRS = 0x4,
12382    JALRS_HB = 0x5,
12383
12384    /* bits 15..12 for 0x05 */
12385    RDPGPR = 0xe,
12386    WRPGPR = 0xf,
12387
12388    /* bits 15..12 for 0x0d */
12389    TLBP = 0x0,
12390    TLBR = 0x1,
12391    TLBWI = 0x2,
12392    TLBWR = 0x3,
12393    TLBINV = 0x4,
12394    TLBINVF = 0x5,
12395    WAIT = 0x9,
12396    IRET = 0xd,
12397    DERET = 0xe,
12398    ERET = 0xf,
12399
12400    /* bits 15..12 for 0x15 */
12401    DMT = 0x0,
12402    DVPE = 0x1,
12403    EMT = 0x2,
12404    EVPE = 0x3,
12405
12406    /* bits 15..12 for 0x1d */
12407    DI = 0x4,
12408    EI = 0x5,
12409
12410    /* bits 15..12 for 0x2d */
12411    SYNC = 0x6,
12412    SYSCALL = 0x8,
12413    SDBBP = 0xd,
12414
12415    /* bits 15..12 for 0x35 */
12416    MFHI32 = 0x0,
12417    MFLO32 = 0x1,
12418    MTHI32 = 0x2,
12419    MTLO32 = 0x3,
12420};
12421
12422/* POOL32B encoding of minor opcode field (bits 15..12) */
12423
12424enum {
12425    LWC2 = 0x0,
12426    LWP = 0x1,
12427    LDP = 0x4,
12428    LWM32 = 0x5,
12429    CACHE = 0x6,
12430    LDM = 0x7,
12431    SWC2 = 0x8,
12432    SWP = 0x9,
12433    SDP = 0xc,
12434    SWM32 = 0xd,
12435    SDM = 0xf
12436};
12437
12438/* POOL32C encoding of minor opcode field (bits 15..12) */
12439
12440enum {
12441    LWL = 0x0,
12442    SWL = 0x8,
12443    LWR = 0x1,
12444    SWR = 0x9,
12445    PREF = 0x2,
12446    /* 0xa is reserved */
12447    LL = 0x3,
12448    SC = 0xb,
12449    LDL = 0x4,
12450    SDL = 0xc,
12451    LDR = 0x5,
12452    SDR = 0xd,
12453    /* 0x6 is reserved */
12454    LWU = 0xe,
12455    LLD = 0x7,
12456    SCD = 0xf
12457};
12458
12459/* POOL32F encoding of minor opcode field (bits 5..0) */
12460
12461enum {
12462    /* These are the bit 7..6 values */
12463    ADD_FMT = 0x0,
12464
12465    SUB_FMT = 0x1,
12466
12467    MUL_FMT = 0x2,
12468
12469    DIV_FMT = 0x3,
12470
12471    /* These are the bit 8..6 values */
12472    MOVN_FMT = 0x0,
12473    RSQRT2_FMT = 0x0,
12474    MOVF_FMT = 0x0,
12475    RINT_FMT = 0x0,
12476    SELNEZ_FMT = 0x0,
12477
12478    MOVZ_FMT = 0x1,
12479    LWXC1 = 0x1,
12480    MOVT_FMT = 0x1,
12481    CLASS_FMT = 0x1,
12482    SELEQZ_FMT = 0x1,
12483
12484    PLL_PS = 0x2,
12485    SWXC1 = 0x2,
12486    SEL_FMT = 0x2,
12487
12488    PLU_PS = 0x3,
12489    LDXC1 = 0x3,
12490
12491    MOVN_FMT_04 = 0x4,
12492    PUL_PS = 0x4,
12493    SDXC1 = 0x4,
12494    RECIP2_FMT = 0x4,
12495
12496    MOVZ_FMT_05 = 0x05,
12497    PUU_PS = 0x5,
12498    LUXC1 = 0x5,
12499
12500    CVT_PS_S = 0x6,
12501    SUXC1 = 0x6,
12502    ADDR_PS = 0x6,
12503    PREFX = 0x6,
12504    MADDF_FMT = 0x6,
12505
12506    MULR_PS = 0x7,
12507    MSUBF_FMT = 0x7,
12508
12509    MADD_S = 0x01,
12510    MADD_D = 0x09,
12511    MADD_PS = 0x11,
12512    ALNV_PS = 0x19,
12513    MSUB_S = 0x21,
12514    MSUB_D = 0x29,
12515    MSUB_PS = 0x31,
12516
12517    NMADD_S = 0x02,
12518    NMADD_D = 0x0a,
12519    NMADD_PS = 0x12,
12520    NMSUB_S = 0x22,
12521    NMSUB_D = 0x2a,
12522    NMSUB_PS = 0x32,
12523
12524    MIN_FMT = 0x3,
12525    MAX_FMT = 0xb,
12526    MINA_FMT = 0x23,
12527    MAXA_FMT = 0x2b,
12528    POOL32FXF = 0x3b,
12529
12530    CABS_COND_FMT = 0x1c,              /* MIPS3D */
12531    C_COND_FMT = 0x3c,
12532
12533    CMP_CONDN_S = 0x5,
12534    CMP_CONDN_D = 0x15
12535};
12536
12537/* POOL32Fxf encoding of minor opcode extension field */
12538
12539enum {
12540    CVT_L = 0x04,
12541    RSQRT_FMT = 0x08,
12542    FLOOR_L = 0x0c,
12543    CVT_PW_PS = 0x1c,
12544    CVT_W = 0x24,
12545    SQRT_FMT = 0x28,
12546    FLOOR_W = 0x2c,
12547    CVT_PS_PW = 0x3c,
12548    CFC1 = 0x40,
12549    RECIP_FMT = 0x48,
12550    CEIL_L = 0x4c,
12551    CTC1 = 0x60,
12552    CEIL_W = 0x6c,
12553    MFC1 = 0x80,
12554    CVT_S_PL = 0x84,
12555    TRUNC_L = 0x8c,
12556    MTC1 = 0xa0,
12557    CVT_S_PU = 0xa4,
12558    TRUNC_W = 0xac,
12559    MFHC1 = 0xc0,
12560    ROUND_L = 0xcc,
12561    MTHC1 = 0xe0,
12562    ROUND_W = 0xec,
12563
12564    MOV_FMT = 0x01,
12565    MOVF = 0x05,
12566    ABS_FMT = 0x0d,
12567    RSQRT1_FMT = 0x1d,
12568    MOVT = 0x25,
12569    NEG_FMT = 0x2d,
12570    CVT_D = 0x4d,
12571    RECIP1_FMT = 0x5d,
12572    CVT_S = 0x6d
12573};
12574
12575/* POOL32I encoding of minor opcode field (bits 25..21) */
12576
12577enum {
12578    BLTZ = 0x00,
12579    BLTZAL = 0x01,
12580    BGEZ = 0x02,
12581    BGEZAL = 0x03,
12582    BLEZ = 0x04,
12583    BNEZC = 0x05,
12584    BGTZ = 0x06,
12585    BEQZC = 0x07,
12586    TLTI = 0x08,
12587    BC1EQZC = 0x08,
12588    TGEI = 0x09,
12589    BC1NEZC = 0x09,
12590    TLTIU = 0x0a,
12591    BC2EQZC = 0x0a,
12592    TGEIU = 0x0b,
12593    BC2NEZC = 0x0a,
12594    TNEI = 0x0c,
12595    R6_SYNCI = 0x0c,
12596    LUI = 0x0d,
12597    TEQI = 0x0e,
12598    SYNCI = 0x10,
12599    BLTZALS = 0x11,
12600    BGEZALS = 0x13,
12601    BC2F = 0x14,
12602    BC2T = 0x15,
12603    BPOSGE64 = 0x1a,
12604    BPOSGE32 = 0x1b,
12605    /* These overlap and are distinguished by bit16 of the instruction */
12606    BC1F = 0x1c,
12607    BC1T = 0x1d,
12608    BC1ANY2F = 0x1c,
12609    BC1ANY2T = 0x1d,
12610    BC1ANY4F = 0x1e,
12611    BC1ANY4T = 0x1f
12612};
12613
12614/* POOL16A encoding of minor opcode field */
12615
12616enum {
12617    ADDU16 = 0x0,
12618    SUBU16 = 0x1
12619};
12620
12621/* POOL16B encoding of minor opcode field */
12622
12623enum {
12624    SLL16 = 0x0,
12625    SRL16 = 0x1
12626};
12627
12628/* POOL16C encoding of minor opcode field */
12629
12630enum {
12631    NOT16 = 0x00,
12632    XOR16 = 0x04,
12633    AND16 = 0x08,
12634    OR16 = 0x0c,
12635    LWM16 = 0x10,
12636    SWM16 = 0x14,
12637    JR16 = 0x18,
12638    JRC16 = 0x1a,
12639    JALR16 = 0x1c,
12640    JALR16S = 0x1e,
12641    MFHI16 = 0x20,
12642    MFLO16 = 0x24,
12643    BREAK16 = 0x28,
12644    SDBBP16 = 0x2c,
12645    JRADDIUSP = 0x30
12646};
12647
12648/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12649
12650enum {
12651    R6_NOT16    = 0x00,
12652    R6_AND16    = 0x01,
12653    R6_LWM16    = 0x02,
12654    R6_JRC16    = 0x03,
12655    MOVEP       = 0x04,
12656    MOVEP_07    = 0x07,
12657    R6_XOR16    = 0x08,
12658    R6_OR16     = 0x09,
12659    R6_SWM16    = 0x0a,
12660    JALRC16     = 0x0b,
12661    MOVEP_0C    = 0x0c,
12662    MOVEP_0F    = 0x0f,
12663    JRCADDIUSP  = 0x13,
12664    R6_BREAK16  = 0x1b,
12665    R6_SDBBP16  = 0x3b
12666};
12667
12668/* POOL16D encoding of minor opcode field */
12669
12670enum {
12671    ADDIUS5 = 0x0,
12672    ADDIUSP = 0x1
12673};
12674
12675/* POOL16E encoding of minor opcode field */
12676
12677enum {
12678    ADDIUR2 = 0x0,
12679    ADDIUR1SP = 0x1
12680};
12681
12682static int mmreg (int r)
12683{
12684    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12685
12686    return map[r];
12687}
12688
12689/* Used for 16-bit store instructions.  */
12690static int mmreg2 (int r)
12691{
12692    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12693
12694    return map[r];
12695}
12696
12697#define uMIPS_RD(op) ((op >> 7) & 0x7)
12698#define uMIPS_RS(op) ((op >> 4) & 0x7)
12699#define uMIPS_RS2(op) uMIPS_RS(op)
12700#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12701#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12702#define uMIPS_RS5(op) (op & 0x1f)
12703
12704/* Signed immediate */
12705#define SIMM(op, start, width)                                          \
12706    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
12707               << (32-width))                                           \
12708     >> (32-width))
12709/* Zero-extended immediate */
12710#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12711
12712static void gen_addiur1sp(DisasContext *ctx)
12713{
12714    int rd = mmreg(uMIPS_RD(ctx->opcode));
12715
12716    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12717}
12718
12719static void gen_addiur2(DisasContext *ctx)
12720{
12721    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12722    int rd = mmreg(uMIPS_RD(ctx->opcode));
12723    int rs = mmreg(uMIPS_RS(ctx->opcode));
12724
12725    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12726}
12727
12728static void gen_addiusp(DisasContext *ctx)
12729{
12730    int encoded = ZIMM(ctx->opcode, 1, 9);
12731    int decoded;
12732
12733    if (encoded <= 1) {
12734        decoded = 256 + encoded;
12735    } else if (encoded <= 255) {
12736        decoded = encoded;
12737    } else if (encoded <= 509) {
12738        decoded = encoded - 512;
12739    } else {
12740        decoded = encoded - 768;
12741    }
12742
12743    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12744}
12745
12746static void gen_addius5(DisasContext *ctx)
12747{
12748    int imm = SIMM(ctx->opcode, 1, 4);
12749    int rd = (ctx->opcode >> 5) & 0x1f;
12750
12751    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12752}
12753
12754static void gen_andi16(DisasContext *ctx)
12755{
12756    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12757                                 31, 32, 63, 64, 255, 32768, 65535 };
12758    int rd = mmreg(uMIPS_RD(ctx->opcode));
12759    int rs = mmreg(uMIPS_RS(ctx->opcode));
12760    int encoded = ZIMM(ctx->opcode, 0, 4);
12761
12762    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12763}
12764
12765static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12766                               int base, int16_t offset)
12767{
12768    TCGv t0, t1;
12769    TCGv_i32 t2;
12770
12771    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12772        generate_exception_end(ctx, EXCP_RI);
12773        return;
12774    }
12775
12776    t0 = tcg_temp_new();
12777
12778    gen_base_offset_addr(ctx, t0, base, offset);
12779
12780    t1 = tcg_const_tl(reglist);
12781    t2 = tcg_const_i32(ctx->mem_idx);
12782
12783    save_cpu_state(ctx, 1);
12784    switch (opc) {
12785    case LWM32:
12786        gen_helper_lwm(cpu_env, t0, t1, t2);
12787        break;
12788    case SWM32:
12789        gen_helper_swm(cpu_env, t0, t1, t2);
12790        break;
12791#ifdef TARGET_MIPS64
12792    case LDM:
12793        gen_helper_ldm(cpu_env, t0, t1, t2);
12794        break;
12795    case SDM:
12796        gen_helper_sdm(cpu_env, t0, t1, t2);
12797        break;
12798#endif
12799    }
12800    tcg_temp_free(t0);
12801    tcg_temp_free(t1);
12802    tcg_temp_free_i32(t2);
12803}
12804
12805
12806static void gen_pool16c_insn(DisasContext *ctx)
12807{
12808    int rd = mmreg((ctx->opcode >> 3) & 0x7);
12809    int rs = mmreg(ctx->opcode & 0x7);
12810
12811    switch (((ctx->opcode) >> 4) & 0x3f) {
12812    case NOT16 + 0:
12813    case NOT16 + 1:
12814    case NOT16 + 2:
12815    case NOT16 + 3:
12816        gen_logic(ctx, OPC_NOR, rd, rs, 0);
12817        break;
12818    case XOR16 + 0:
12819    case XOR16 + 1:
12820    case XOR16 + 2:
12821    case XOR16 + 3:
12822        gen_logic(ctx, OPC_XOR, rd, rd, rs);
12823        break;
12824    case AND16 + 0:
12825    case AND16 + 1:
12826    case AND16 + 2:
12827    case AND16 + 3:
12828        gen_logic(ctx, OPC_AND, rd, rd, rs);
12829        break;
12830    case OR16 + 0:
12831    case OR16 + 1:
12832    case OR16 + 2:
12833    case OR16 + 3:
12834        gen_logic(ctx, OPC_OR, rd, rd, rs);
12835        break;
12836    case LWM16 + 0:
12837    case LWM16 + 1:
12838    case LWM16 + 2:
12839    case LWM16 + 3:
12840        {
12841            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12842            int offset = ZIMM(ctx->opcode, 0, 4);
12843
12844            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12845                              29, offset << 2);
12846        }
12847        break;
12848    case SWM16 + 0:
12849    case SWM16 + 1:
12850    case SWM16 + 2:
12851    case SWM16 + 3:
12852        {
12853            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12854            int offset = ZIMM(ctx->opcode, 0, 4);
12855
12856            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12857                              29, offset << 2);
12858        }
12859        break;
12860    case JR16 + 0:
12861    case JR16 + 1:
12862        {
12863            int reg = ctx->opcode & 0x1f;
12864
12865            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12866        }
12867        break;
12868    case JRC16 + 0:
12869    case JRC16 + 1:
12870        {
12871            int reg = ctx->opcode & 0x1f;
12872            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12873            /* Let normal delay slot handling in our caller take us
12874               to the branch target.  */
12875        }
12876        break;
12877    case JALR16 + 0:
12878    case JALR16 + 1:
12879        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12880        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12881        break;
12882    case JALR16S + 0:
12883    case JALR16S + 1:
12884        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12885        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12886        break;
12887    case MFHI16 + 0:
12888    case MFHI16 + 1:
12889        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12890        break;
12891    case MFLO16 + 0:
12892    case MFLO16 + 1:
12893        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12894        break;
12895    case BREAK16:
12896        generate_exception_end(ctx, EXCP_BREAK);
12897        break;
12898    case SDBBP16:
12899        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12900            gen_helper_do_semihosting(cpu_env);
12901        } else {
12902            /* XXX: not clear which exception should be raised
12903             *      when in debug mode...
12904             */
12905            check_insn(ctx, ISA_MIPS32);
12906            generate_exception_end(ctx, EXCP_DBp);
12907        }
12908        break;
12909    case JRADDIUSP + 0:
12910    case JRADDIUSP + 1:
12911        {
12912            int imm = ZIMM(ctx->opcode, 0, 5);
12913            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12914            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12915            /* Let normal delay slot handling in our caller take us
12916               to the branch target.  */
12917        }
12918        break;
12919    default:
12920        generate_exception_end(ctx, EXCP_RI);
12921        break;
12922    }
12923}
12924
12925static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12926                             int enc_rs)
12927{
12928    int rd, rs, re, rt;
12929    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12930    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12931    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12932    rd = rd_enc[enc_dest];
12933    re = re_enc[enc_dest];
12934    rs = rs_rt_enc[enc_rs];
12935    rt = rs_rt_enc[enc_rt];
12936    if (rs) {
12937        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12938    } else {
12939        tcg_gen_movi_tl(cpu_gpr[rd], 0);
12940    }
12941    if (rt) {
12942        tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12943    } else {
12944        tcg_gen_movi_tl(cpu_gpr[re], 0);
12945    }
12946}
12947
12948static void gen_pool16c_r6_insn(DisasContext *ctx)
12949{
12950    int rt = mmreg((ctx->opcode >> 7) & 0x7);
12951    int rs = mmreg((ctx->opcode >> 4) & 0x7);
12952
12953    switch (ctx->opcode & 0xf) {
12954    case R6_NOT16:
12955        gen_logic(ctx, OPC_NOR, rt, rs, 0);
12956        break;
12957    case R6_AND16:
12958        gen_logic(ctx, OPC_AND, rt, rt, rs);
12959        break;
12960    case R6_LWM16:
12961        {
12962            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12963            int offset = extract32(ctx->opcode, 4, 4);
12964            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12965        }
12966        break;
12967    case R6_JRC16: /* JRCADDIUSP */
12968        if ((ctx->opcode >> 4) & 1) {
12969            /* JRCADDIUSP */
12970            int imm = extract32(ctx->opcode, 5, 5);
12971            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12972            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12973        } else {
12974            /* JRC16 */
12975            int rs = extract32(ctx->opcode, 5, 5);
12976            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12977        }
12978        break;
12979    case MOVEP ... MOVEP_07:
12980    case MOVEP_0C ... MOVEP_0F:
12981        {
12982            int enc_dest = uMIPS_RD(ctx->opcode);
12983            int enc_rt = uMIPS_RS2(ctx->opcode);
12984            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12985            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12986        }
12987        break;
12988    case R6_XOR16:
12989        gen_logic(ctx, OPC_XOR, rt, rt, rs);
12990        break;
12991    case R6_OR16:
12992        gen_logic(ctx, OPC_OR, rt, rt, rs);
12993        break;
12994    case R6_SWM16:
12995        {
12996            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12997            int offset = extract32(ctx->opcode, 4, 4);
12998            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12999        }
13000        break;
13001    case JALRC16: /* BREAK16, SDBBP16 */
13002        switch (ctx->opcode & 0x3f) {
13003        case JALRC16:
13004        case JALRC16 + 0x20:
13005            /* JALRC16 */
13006            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13007                               31, 0, 0);
13008            break;
13009        case R6_BREAK16:
13010            /* BREAK16 */
13011            generate_exception(ctx, EXCP_BREAK);
13012            break;
13013        case R6_SDBBP16:
13014            /* SDBBP16 */
13015            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13016                gen_helper_do_semihosting(cpu_env);
13017            } else {
13018                if (ctx->hflags & MIPS_HFLAG_SBRI) {
13019                    generate_exception(ctx, EXCP_RI);
13020                } else {
13021                    generate_exception(ctx, EXCP_DBp);
13022                }
13023            }
13024            break;
13025        }
13026        break;
13027    default:
13028        generate_exception(ctx, EXCP_RI);
13029        break;
13030    }
13031}
13032
13033static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13034{
13035    TCGv t0 = tcg_temp_new();
13036    TCGv t1 = tcg_temp_new();
13037
13038    gen_load_gpr(t0, base);
13039
13040    if (index != 0) {
13041        gen_load_gpr(t1, index);
13042        tcg_gen_shli_tl(t1, t1, 2);
13043        gen_op_addr_add(ctx, t0, t1, t0);
13044    }
13045
13046    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13047    gen_store_gpr(t1, rd);
13048
13049    tcg_temp_free(t0);
13050    tcg_temp_free(t1);
13051}
13052
13053static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13054                           int base, int16_t offset)
13055{
13056    TCGv t0, t1;
13057
13058    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
13059        generate_exception_end(ctx, EXCP_RI);
13060        return;
13061    }
13062
13063    t0 = tcg_temp_new();
13064    t1 = tcg_temp_new();
13065
13066    gen_base_offset_addr(ctx, t0, base, offset);
13067
13068    switch (opc) {
13069    case LWP:
13070        if (rd == base) {
13071            generate_exception_end(ctx, EXCP_RI);
13072            return;
13073        }
13074        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13075        gen_store_gpr(t1, rd);
13076        tcg_gen_movi_tl(t1, 4);
13077        gen_op_addr_add(ctx, t0, t0, t1);
13078        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13079        gen_store_gpr(t1, rd+1);
13080        break;
13081    case SWP:
13082        gen_load_gpr(t1, rd);
13083        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13084        tcg_gen_movi_tl(t1, 4);
13085        gen_op_addr_add(ctx, t0, t0, t1);
13086        gen_load_gpr(t1, rd+1);
13087        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13088        break;
13089#ifdef TARGET_MIPS64
13090    case LDP:
13091        if (rd == base) {
13092            generate_exception_end(ctx, EXCP_RI);
13093            return;
13094        }
13095        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13096        gen_store_gpr(t1, rd);
13097        tcg_gen_movi_tl(t1, 8);
13098        gen_op_addr_add(ctx, t0, t0, t1);
13099        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13100        gen_store_gpr(t1, rd+1);
13101        break;
13102    case SDP:
13103        gen_load_gpr(t1, rd);
13104        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13105        tcg_gen_movi_tl(t1, 8);
13106        gen_op_addr_add(ctx, t0, t0, t1);
13107        gen_load_gpr(t1, rd+1);
13108        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13109        break;
13110#endif
13111    }
13112    tcg_temp_free(t0);
13113    tcg_temp_free(t1);
13114}
13115
13116static void gen_sync(int stype)
13117{
13118    TCGBar tcg_mo = TCG_BAR_SC;
13119
13120    switch (stype) {
13121    case 0x4: /* SYNC_WMB */
13122        tcg_mo |= TCG_MO_ST_ST;
13123        break;
13124    case 0x10: /* SYNC_MB */
13125        tcg_mo |= TCG_MO_ALL;
13126        break;
13127    case 0x11: /* SYNC_ACQUIRE */
13128        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13129        break;
13130    case 0x12: /* SYNC_RELEASE */
13131        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13132        break;
13133    case 0x13: /* SYNC_RMB */
13134        tcg_mo |= TCG_MO_LD_LD;
13135        break;
13136    default:
13137        tcg_mo |= TCG_MO_ALL;
13138        break;
13139    }
13140
13141    tcg_gen_mb(tcg_mo);
13142}
13143
13144static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13145{
13146    int extension = (ctx->opcode >> 6) & 0x3f;
13147    int minor = (ctx->opcode >> 12) & 0xf;
13148    uint32_t mips32_op;
13149
13150    switch (extension) {
13151    case TEQ:
13152        mips32_op = OPC_TEQ;
13153        goto do_trap;
13154    case TGE:
13155        mips32_op = OPC_TGE;
13156        goto do_trap;
13157    case TGEU:
13158        mips32_op = OPC_TGEU;
13159        goto do_trap;
13160    case TLT:
13161        mips32_op = OPC_TLT;
13162        goto do_trap;
13163    case TLTU:
13164        mips32_op = OPC_TLTU;
13165        goto do_trap;
13166    case TNE:
13167        mips32_op = OPC_TNE;
13168    do_trap:
13169        gen_trap(ctx, mips32_op, rs, rt, -1);
13170        break;
13171#ifndef CONFIG_USER_ONLY
13172    case MFC0:
13173    case MFC0 + 32:
13174        check_cp0_enabled(ctx);
13175        if (rt == 0) {
13176            /* Treat as NOP. */
13177            break;
13178        }
13179        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13180        break;
13181    case MTC0:
13182    case MTC0 + 32:
13183        check_cp0_enabled(ctx);
13184        {
13185            TCGv t0 = tcg_temp_new();
13186
13187            gen_load_gpr(t0, rt);
13188            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13189            tcg_temp_free(t0);
13190        }
13191        break;
13192#endif
13193    case 0x2a:
13194        switch (minor & 3) {
13195        case MADD_ACC:
13196            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13197            break;
13198        case MADDU_ACC:
13199            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13200            break;
13201        case MSUB_ACC:
13202            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13203            break;
13204        case MSUBU_ACC:
13205            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13206            break;
13207        default:
13208            goto pool32axf_invalid;
13209        }
13210        break;
13211    case 0x32:
13212        switch (minor & 3) {
13213        case MULT_ACC:
13214            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13215            break;
13216        case MULTU_ACC:
13217            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13218            break;
13219        default:
13220            goto pool32axf_invalid;
13221        }
13222        break;
13223    case 0x2c:
13224        switch (minor) {
13225        case BITSWAP:
13226            check_insn(ctx, ISA_MIPS32R6);
13227            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13228            break;
13229        case SEB:
13230            gen_bshfl(ctx, OPC_SEB, rs, rt);
13231            break;
13232        case SEH:
13233            gen_bshfl(ctx, OPC_SEH, rs, rt);
13234            break;
13235        case CLO:
13236            mips32_op = OPC_CLO;
13237            goto do_cl;
13238        case CLZ:
13239            mips32_op = OPC_CLZ;
13240        do_cl:
13241            check_insn(ctx, ISA_MIPS32);
13242            gen_cl(ctx, mips32_op, rt, rs);
13243            break;
13244        case RDHWR:
13245            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13246            gen_rdhwr(ctx, rt, rs, 0);
13247            break;
13248        case WSBH:
13249            gen_bshfl(ctx, OPC_WSBH, rs, rt);
13250            break;
13251        case MULT:
13252            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13253            mips32_op = OPC_MULT;
13254            goto do_mul;
13255        case MULTU:
13256            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13257            mips32_op = OPC_MULTU;
13258            goto do_mul;
13259        case DIV:
13260            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13261            mips32_op = OPC_DIV;
13262            goto do_div;
13263        case DIVU:
13264            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13265            mips32_op = OPC_DIVU;
13266            goto do_div;
13267        do_div:
13268            check_insn(ctx, ISA_MIPS32);
13269            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13270            break;
13271        case MADD:
13272            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13273            mips32_op = OPC_MADD;
13274            goto do_mul;
13275        case MADDU:
13276            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13277            mips32_op = OPC_MADDU;
13278            goto do_mul;
13279        case MSUB:
13280            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13281            mips32_op = OPC_MSUB;
13282            goto do_mul;
13283        case MSUBU:
13284            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13285            mips32_op = OPC_MSUBU;
13286        do_mul:
13287            check_insn(ctx, ISA_MIPS32);
13288            gen_muldiv(ctx, mips32_op, 0, rs, rt);
13289            break;
13290        default:
13291            goto pool32axf_invalid;
13292        }
13293        break;
13294    case 0x34:
13295        switch (minor) {
13296        case MFC2:
13297        case MTC2:
13298        case MFHC2:
13299        case MTHC2:
13300        case CFC2:
13301        case CTC2:
13302            generate_exception_err(ctx, EXCP_CpU, 2);
13303            break;
13304        default:
13305            goto pool32axf_invalid;
13306        }
13307        break;
13308    case 0x3c:
13309        switch (minor) {
13310        case JALR:    /* JALRC */
13311        case JALR_HB: /* JALRC_HB */
13312            if (ctx->insn_flags & ISA_MIPS32R6) {
13313                /* JALRC, JALRC_HB */
13314                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13315            } else {
13316                /* JALR, JALR_HB */
13317                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13318                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13319            }
13320            break;
13321        case JALRS:
13322        case JALRS_HB:
13323            check_insn_opc_removed(ctx, ISA_MIPS32R6);
13324            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13325            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13326            break;
13327        default:
13328            goto pool32axf_invalid;
13329        }
13330        break;
13331    case 0x05:
13332        switch (minor) {
13333        case RDPGPR:
13334            check_cp0_enabled(ctx);
13335            check_insn(ctx, ISA_MIPS32R2);
13336            gen_load_srsgpr(rs, rt);
13337            break;
13338        case WRPGPR:
13339            check_cp0_enabled(ctx);
13340            check_insn(ctx, ISA_MIPS32R2);
13341            gen_store_srsgpr(rs, rt);
13342            break;
13343        default:
13344            goto pool32axf_invalid;
13345        }
13346        break;
13347#ifndef CONFIG_USER_ONLY
13348    case 0x0d:
13349        switch (minor) {
13350        case TLBP:
13351            mips32_op = OPC_TLBP;
13352            goto do_cp0;
13353        case TLBR:
13354            mips32_op = OPC_TLBR;
13355            goto do_cp0;
13356        case TLBWI:
13357            mips32_op = OPC_TLBWI;
13358            goto do_cp0;
13359        case TLBWR:
13360            mips32_op = OPC_TLBWR;
13361            goto do_cp0;
13362        case TLBINV:
13363            mips32_op = OPC_TLBINV;
13364            goto do_cp0;
13365        case TLBINVF:
13366            mips32_op = OPC_TLBINVF;
13367            goto do_cp0;
13368        case WAIT:
13369            mips32_op = OPC_WAIT;
13370            goto do_cp0;
13371        case DERET:
13372            mips32_op = OPC_DERET;
13373            goto do_cp0;
13374        case ERET:
13375            mips32_op = OPC_ERET;
13376        do_cp0:
13377            gen_cp0(env, ctx, mips32_op, rt, rs);
13378            break;
13379        default:
13380            goto pool32axf_invalid;
13381        }
13382        break;
13383    case 0x1d:
13384        switch (minor) {
13385        case DI:
13386            check_cp0_enabled(ctx);
13387            {
13388                TCGv t0 = tcg_temp_new();
13389
13390                save_cpu_state(ctx, 1);
13391                gen_helper_di(t0, cpu_env);
13392                gen_store_gpr(t0, rs);
13393                /* Stop translation as we may have switched the execution mode */
13394                ctx->bstate = BS_STOP;
13395                tcg_temp_free(t0);
13396            }
13397            break;
13398        case EI:
13399            check_cp0_enabled(ctx);
13400            {
13401                TCGv t0 = tcg_temp_new();
13402
13403                save_cpu_state(ctx, 1);
13404                gen_helper_ei(t0, cpu_env);
13405                gen_store_gpr(t0, rs);
13406                /* Stop translation as we may have switched the execution mode */
13407                ctx->bstate = BS_STOP;
13408                tcg_temp_free(t0);
13409            }
13410            break;
13411        default:
13412            goto pool32axf_invalid;
13413        }
13414        break;
13415#endif
13416    case 0x2d:
13417        switch (minor) {
13418        case SYNC:
13419            gen_sync(extract32(ctx->opcode, 16, 5));
13420            break;
13421        case SYSCALL:
13422            generate_exception_end(ctx, EXCP_SYSCALL);
13423            break;
13424        case SDBBP:
13425            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13426                gen_helper_do_semihosting(cpu_env);
13427            } else {
13428                check_insn(ctx, ISA_MIPS32);
13429                if (ctx->hflags & MIPS_HFLAG_SBRI) {
13430                    generate_exception_end(ctx, EXCP_RI);
13431                } else {
13432                    generate_exception_end(ctx, EXCP_DBp);
13433                }
13434            }
13435            break;
13436        default:
13437            goto pool32axf_invalid;
13438        }
13439        break;
13440    case 0x01:
13441        switch (minor & 3) {
13442        case MFHI_ACC:
13443            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13444            break;
13445        case MFLO_ACC:
13446            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13447            break;
13448        case MTHI_ACC:
13449            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13450            break;
13451        case MTLO_ACC:
13452            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13453            break;
13454        default:
13455            goto pool32axf_invalid;
13456        }
13457        break;
13458    case 0x35:
13459        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13460        switch (minor) {
13461        case MFHI32:
13462            gen_HILO(ctx, OPC_MFHI, 0, rs);
13463            break;
13464        case MFLO32:
13465            gen_HILO(ctx, OPC_MFLO, 0, rs);
13466            break;
13467        case MTHI32:
13468            gen_HILO(ctx, OPC_MTHI, 0, rs);
13469            break;
13470        case MTLO32:
13471            gen_HILO(ctx, OPC_MTLO, 0, rs);
13472            break;
13473        default:
13474            goto pool32axf_invalid;
13475        }
13476        break;
13477    default:
13478    pool32axf_invalid:
13479        MIPS_INVAL("pool32axf");
13480        generate_exception_end(ctx, EXCP_RI);
13481        break;
13482    }
13483}
13484
13485/* Values for microMIPS fmt field.  Variable-width, depending on which
13486   formats the instruction supports.  */
13487
13488enum {
13489    FMT_SD_S = 0,
13490    FMT_SD_D = 1,
13491
13492    FMT_SDPS_S = 0,
13493    FMT_SDPS_D = 1,
13494    FMT_SDPS_PS = 2,
13495
13496    FMT_SWL_S = 0,
13497    FMT_SWL_W = 1,
13498    FMT_SWL_L = 2,
13499
13500    FMT_DWL_D = 0,
13501    FMT_DWL_W = 1,
13502    FMT_DWL_L = 2
13503};
13504
13505static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13506{
13507    int extension = (ctx->opcode >> 6) & 0x3ff;
13508    uint32_t mips32_op;
13509
13510#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13511#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13512#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13513
13514    switch (extension) {
13515    case FLOAT_1BIT_FMT(CFC1, 0):
13516        mips32_op = OPC_CFC1;
13517        goto do_cp1;
13518    case FLOAT_1BIT_FMT(CTC1, 0):
13519        mips32_op = OPC_CTC1;
13520        goto do_cp1;
13521    case FLOAT_1BIT_FMT(MFC1, 0):
13522        mips32_op = OPC_MFC1;
13523        goto do_cp1;
13524    case FLOAT_1BIT_FMT(MTC1, 0):
13525        mips32_op = OPC_MTC1;
13526        goto do_cp1;
13527    case FLOAT_1BIT_FMT(MFHC1, 0):
13528        mips32_op = OPC_MFHC1;
13529        goto do_cp1;
13530    case FLOAT_1BIT_FMT(MTHC1, 0):
13531        mips32_op = OPC_MTHC1;
13532    do_cp1:
13533        gen_cp1(ctx, mips32_op, rt, rs);
13534        break;
13535
13536        /* Reciprocal square root */
13537    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13538        mips32_op = OPC_RSQRT_S;
13539        goto do_unaryfp;
13540    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13541        mips32_op = OPC_RSQRT_D;
13542        goto do_unaryfp;
13543
13544        /* Square root */
13545    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13546        mips32_op = OPC_SQRT_S;
13547        goto do_unaryfp;
13548    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13549        mips32_op = OPC_SQRT_D;
13550        goto do_unaryfp;
13551
13552        /* Reciprocal */
13553    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13554        mips32_op = OPC_RECIP_S;
13555        goto do_unaryfp;
13556    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13557        mips32_op = OPC_RECIP_D;
13558        goto do_unaryfp;
13559
13560        /* Floor */
13561    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13562        mips32_op = OPC_FLOOR_L_S;
13563        goto do_unaryfp;
13564    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13565        mips32_op = OPC_FLOOR_L_D;
13566        goto do_unaryfp;
13567    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13568        mips32_op = OPC_FLOOR_W_S;
13569        goto do_unaryfp;
13570    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13571        mips32_op = OPC_FLOOR_W_D;
13572        goto do_unaryfp;
13573
13574        /* Ceiling */
13575    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13576        mips32_op = OPC_CEIL_L_S;
13577        goto do_unaryfp;
13578    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13579        mips32_op = OPC_CEIL_L_D;
13580        goto do_unaryfp;
13581    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13582        mips32_op = OPC_CEIL_W_S;
13583        goto do_unaryfp;
13584    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13585        mips32_op = OPC_CEIL_W_D;
13586        goto do_unaryfp;
13587
13588        /* Truncation */
13589    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13590        mips32_op = OPC_TRUNC_L_S;
13591        goto do_unaryfp;
13592    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13593        mips32_op = OPC_TRUNC_L_D;
13594        goto do_unaryfp;
13595    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13596        mips32_op = OPC_TRUNC_W_S;
13597        goto do_unaryfp;
13598    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13599        mips32_op = OPC_TRUNC_W_D;
13600        goto do_unaryfp;
13601
13602        /* Round */
13603    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13604        mips32_op = OPC_ROUND_L_S;
13605        goto do_unaryfp;
13606    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13607        mips32_op = OPC_ROUND_L_D;
13608        goto do_unaryfp;
13609    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13610        mips32_op = OPC_ROUND_W_S;
13611        goto do_unaryfp;
13612    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13613        mips32_op = OPC_ROUND_W_D;
13614        goto do_unaryfp;
13615
13616        /* Integer to floating-point conversion */
13617    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13618        mips32_op = OPC_CVT_L_S;
13619        goto do_unaryfp;
13620    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13621        mips32_op = OPC_CVT_L_D;
13622        goto do_unaryfp;
13623    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13624        mips32_op = OPC_CVT_W_S;
13625        goto do_unaryfp;
13626    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13627        mips32_op = OPC_CVT_W_D;
13628        goto do_unaryfp;
13629
13630        /* Paired-foo conversions */
13631    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13632        mips32_op = OPC_CVT_S_PL;
13633        goto do_unaryfp;
13634    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13635        mips32_op = OPC_CVT_S_PU;
13636        goto do_unaryfp;
13637    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13638        mips32_op = OPC_CVT_PW_PS;
13639        goto do_unaryfp;
13640    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13641        mips32_op = OPC_CVT_PS_PW;
13642        goto do_unaryfp;
13643
13644        /* Floating-point moves */
13645    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13646        mips32_op = OPC_MOV_S;
13647        goto do_unaryfp;
13648    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13649        mips32_op = OPC_MOV_D;
13650        goto do_unaryfp;
13651    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13652        mips32_op = OPC_MOV_PS;
13653        goto do_unaryfp;
13654
13655        /* Absolute value */
13656    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13657        mips32_op = OPC_ABS_S;
13658        goto do_unaryfp;
13659    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13660        mips32_op = OPC_ABS_D;
13661        goto do_unaryfp;
13662    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13663        mips32_op = OPC_ABS_PS;
13664        goto do_unaryfp;
13665
13666        /* Negation */
13667    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13668        mips32_op = OPC_NEG_S;
13669        goto do_unaryfp;
13670    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13671        mips32_op = OPC_NEG_D;
13672        goto do_unaryfp;
13673    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13674        mips32_op = OPC_NEG_PS;
13675        goto do_unaryfp;
13676
13677        /* Reciprocal square root step */
13678    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13679        mips32_op = OPC_RSQRT1_S;
13680        goto do_unaryfp;
13681    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13682        mips32_op = OPC_RSQRT1_D;
13683        goto do_unaryfp;
13684    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13685        mips32_op = OPC_RSQRT1_PS;
13686        goto do_unaryfp;
13687
13688        /* Reciprocal step */
13689    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13690        mips32_op = OPC_RECIP1_S;
13691        goto do_unaryfp;
13692    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13693        mips32_op = OPC_RECIP1_S;
13694        goto do_unaryfp;
13695    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13696        mips32_op = OPC_RECIP1_PS;
13697        goto do_unaryfp;
13698
13699        /* Conversions from double */
13700    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13701        mips32_op = OPC_CVT_D_S;
13702        goto do_unaryfp;
13703    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13704        mips32_op = OPC_CVT_D_W;
13705        goto do_unaryfp;
13706    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13707        mips32_op = OPC_CVT_D_L;
13708        goto do_unaryfp;
13709
13710        /* Conversions from single */
13711    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13712        mips32_op = OPC_CVT_S_D;
13713        goto do_unaryfp;
13714    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13715        mips32_op = OPC_CVT_S_W;
13716        goto do_unaryfp;
13717    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13718        mips32_op = OPC_CVT_S_L;
13719    do_unaryfp:
13720        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13721        break;
13722
13723        /* Conditional moves on floating-point codes */
13724    case COND_FLOAT_MOV(MOVT, 0):
13725    case COND_FLOAT_MOV(MOVT, 1):
13726    case COND_FLOAT_MOV(MOVT, 2):
13727    case COND_FLOAT_MOV(MOVT, 3):
13728    case COND_FLOAT_MOV(MOVT, 4):
13729    case COND_FLOAT_MOV(MOVT, 5):
13730    case COND_FLOAT_MOV(MOVT, 6):
13731    case COND_FLOAT_MOV(MOVT, 7):
13732        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13733        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13734        break;
13735    case COND_FLOAT_MOV(MOVF, 0):
13736    case COND_FLOAT_MOV(MOVF, 1):
13737    case COND_FLOAT_MOV(MOVF, 2):
13738    case COND_FLOAT_MOV(MOVF, 3):
13739    case COND_FLOAT_MOV(MOVF, 4):
13740    case COND_FLOAT_MOV(MOVF, 5):
13741    case COND_FLOAT_MOV(MOVF, 6):
13742    case COND_FLOAT_MOV(MOVF, 7):
13743        check_insn_opc_removed(ctx, ISA_MIPS32R6);
13744        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13745        break;
13746    default:
13747        MIPS_INVAL("pool32fxf");
13748        generate_exception_end(ctx, EXCP_RI);
13749        break;
13750    }
13751}
13752
13753static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13754{
13755    int32_t offset;
13756    uint16_t insn;
13757    int rt, rs, rd, rr;
13758    int16_t imm;
13759    uint32_t op, minor, mips32_op;
13760    uint32_t cond, fmt, cc;
13761
13762    insn = cpu_lduw_code(env, ctx->pc + 2);
13763    ctx->opcode = (ctx->opcode << 16) | insn;
13764
13765    rt = (ctx->opcode >> 21) & 0x1f;
13766    rs = (ctx->opcode >> 16) & 0x1f;
13767    rd = (ctx->opcode >> 11) & 0x1f;
13768    rr = (ctx->opcode >> 6) & 0x1f;
13769    imm = (int16_t) ctx->opcode;
13770
13771    op = (ctx->opcode >> 26) & 0x3f;
13772    switch (op) {
13773    case POOL32A:
13774        minor = ctx->opcode & 0x3f;
13775        switch (minor) {
13776        case 0x00:
13777            minor = (ctx->opcode >> 6) & 0xf;
13778            switch (minor) {
13779            case SLL32:
13780                mips32_op = OPC_SLL;
13781                goto do_shifti;
13782            case SRA:
13783                mips32_op = OPC_SRA;
13784                goto do_shifti;
13785            case SRL32:
13786                mips32_op = OPC_SRL;
13787                goto do_shifti;
13788            case ROTR:
13789                mips32_op = OPC_ROTR;
13790            do_shifti:
13791                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13792                break;
13793            case SELEQZ:
13794                check_insn(ctx, ISA_MIPS32R6);
13795                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13796                break;
13797            case SELNEZ:
13798                check_insn(ctx, ISA_MIPS32R6);
13799                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13800                break;
13801            case R6_RDHWR:
13802                check_insn(ctx, ISA_MIPS32R6);
13803                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13804                break;
13805            default:
13806                goto pool32a_invalid;
13807            }
13808            break;
13809        case 0x10:
13810            minor = (ctx->opcode >> 6) & 0xf;
13811            switch (minor) {
13812                /* Arithmetic */
13813            case ADD:
13814                mips32_op = OPC_ADD;
13815                goto do_arith;
13816            case ADDU32:
13817                mips32_op = OPC_ADDU;
13818                goto do_arith;
13819            case SUB:
13820                mips32_op = OPC_SUB;
13821                goto do_arith;
13822            case SUBU32:
13823                mips32_op = OPC_SUBU;
13824                goto do_arith;
13825            case MUL:
13826                check_insn_opc_removed(ctx, ISA_MIPS32R6);
13827                mips32_op = OPC_MUL;
13828            do_arith:
13829                gen_arith(ctx, mips32_op, rd, rs, rt);
13830                break;
13831                /* Shifts */
13832            case SLLV:
13833                mips32_op = OPC_SLLV;
13834                goto do_shift;
13835            case SRLV:
13836                mips32_op = OPC_SRLV;
13837                goto do_shift;
13838            case SRAV:
13839                mips32_op = OPC_SRAV;
13840                goto do_shift;
13841            case ROTRV:
13842                mips32_op = OPC_ROTRV;
13843            do_shift:
13844                gen_shift(ctx, mips32_op, rd, rs, rt);
13845                break;
13846                /* Logical operations */
13847            case AND:
13848                mips32_op = OPC_AND;
13849                goto do_logic;
13850            case OR32:
13851                mips32_op = OPC_OR;
13852                goto do_logic;
13853            case NOR:
13854                mips32_op = OPC_NOR;
13855                goto do_logic;
13856            case XOR32:
13857                mips32_op = OPC_XOR;
13858            do_logic:
13859                gen_logic(ctx, mips32_op, rd, rs, rt);
13860                break;
13861                /* Set less than */
13862            case SLT:
13863                mips32_op = OPC_SLT;
13864                goto do_slt;
13865            case SLTU:
13866                mips32_op = OPC_SLTU;
13867            do_slt:
13868                gen_slt(ctx, mips32_op, rd, rs, rt);
13869                break;
13870            default:
13871                goto pool32a_invalid;
13872            }
13873            break;
13874        case 0x18:
13875            minor = (ctx->opcode >> 6) & 0xf;
13876            switch (minor) {
13877                /* Conditional moves */
13878            case MOVN: /* MUL */
13879                if (ctx->insn_flags & ISA_MIPS32R6) {
13880                    /* MUL */
13881                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13882                } else {
13883                    /* MOVN */
13884                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13885                }
13886                break;
13887            case MOVZ: /* MUH */
13888                if (ctx->insn_flags & ISA_MIPS32R6) {
13889                    /* MUH */
13890                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13891                } else {
13892                    /* MOVZ */
13893                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13894                }
13895                break;
13896            case MULU:
13897                check_insn(ctx, ISA_MIPS32R6);
13898                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13899                break;
13900            case MUHU:
13901                check_insn(ctx, ISA_MIPS32R6);
13902                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13903                break;
13904            case LWXS: /* DIV */
13905                if (ctx->insn_flags & ISA_MIPS32R6) {
13906                    /* DIV */
13907                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13908                } else {
13909                    /* LWXS */
13910                    gen_ldxs(ctx, rs, rt, rd);
13911                }
13912                break;
13913            case MOD:
13914                check_insn(ctx, ISA_MIPS32R6);
13915                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13916                break;
13917            case R6_DIVU:
13918                check_insn(ctx, ISA_MIPS32R6);
13919                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13920                break;
13921            case MODU:
13922                check_insn(ctx, ISA_MIPS32R6);
13923                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13924                break;
13925            default:
13926                goto pool32a_invalid;
13927            }
13928            break;
13929        case INS:
13930            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13931            return;
13932        case LSA:
13933            check_insn(ctx, ISA_MIPS32R6);
13934            gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13935                    extract32(ctx->opcode, 9, 2));
13936            break;
13937        case ALIGN:
13938            check_insn(ctx, ISA_MIPS32R6);
13939            gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13940                      extract32(ctx->opcode, 9, 2));
13941            break;
13942        case EXT:
13943            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13944            return;
13945        case POOL32AXF:
13946            gen_pool32axf(env, ctx, rt, rs);
13947            break;
13948        case BREAK32:
13949            generate_exception_end(ctx, EXCP_BREAK);
13950            break;
13951        case SIGRIE:
13952            check_insn(ctx, ISA_MIPS32R6);
13953            generate_exception_end(ctx, EXCP_RI);
13954            break;
13955        default:
13956        pool32a_invalid:
13957                MIPS_INVAL("pool32a");
13958                generate_exception_end(ctx, EXCP_RI);
13959                break;
13960        }
13961        break;
13962    case POOL32B:
13963        minor = (ctx->opcode >> 12) & 0xf;
13964        switch (minor) {
13965        case CACHE:
13966            check_cp0_enabled(ctx);
13967            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13968                gen_cache_operation(ctx, rt, rs, imm);
13969            }
13970            break;
13971        case LWC2:
13972        case SWC2:
13973            /* COP2: Not implemented. */
13974            generate_exception_err(ctx, EXCP_CpU, 2);
13975            break;
13976#ifdef TARGET_MIPS64
13977        case LDP:
13978        case SDP:
13979            check_insn(ctx, ISA_MIPS3);
13980            check_mips_64(ctx);
13981            /* Fallthrough */
13982#endif
13983        case LWP:
13984        case SWP:
13985            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13986            break;
13987#ifdef TARGET_MIPS64
13988        case LDM:
13989        case SDM:
13990            check_insn(ctx, ISA_MIPS3);
13991            check_mips_64(ctx);
13992            /* Fallthrough */
13993#endif
13994        case LWM32:
13995        case SWM32:
13996            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13997            break;
13998        default:
13999            MIPS_INVAL("pool32b");
14000            generate_exception_end(ctx, EXCP_RI);
14001            break;
14002        }
14003        break;
14004    case POOL32F:
14005        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14006            minor = ctx->opcode & 0x3f;
14007            check_cp1_enabled(ctx);
14008            switch (minor) {
14009            case ALNV_PS:
14010                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14011                mips32_op = OPC_ALNV_PS;
14012                goto do_madd;
14013            case MADD_S:
14014                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14015                mips32_op = OPC_MADD_S;
14016                goto do_madd;
14017            case MADD_D:
14018                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14019                mips32_op = OPC_MADD_D;
14020                goto do_madd;
14021            case MADD_PS:
14022                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14023                mips32_op = OPC_MADD_PS;
14024                goto do_madd;
14025            case MSUB_S:
14026                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14027                mips32_op = OPC_MSUB_S;
14028                goto do_madd;
14029            case MSUB_D:
14030                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14031                mips32_op = OPC_MSUB_D;
14032                goto do_madd;
14033            case MSUB_PS:
14034                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14035                mips32_op = OPC_MSUB_PS;
14036                goto do_madd;
14037            case NMADD_S:
14038                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14039                mips32_op = OPC_NMADD_S;
14040                goto do_madd;
14041            case NMADD_D:
14042                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14043                mips32_op = OPC_NMADD_D;
14044                goto do_madd;
14045            case NMADD_PS:
14046                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14047                mips32_op = OPC_NMADD_PS;
14048                goto do_madd;
14049            case NMSUB_S:
14050                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14051                mips32_op = OPC_NMSUB_S;
14052                goto do_madd;
14053            case NMSUB_D:
14054                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14055                mips32_op = OPC_NMSUB_D;
14056                goto do_madd;
14057            case NMSUB_PS:
14058                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14059                mips32_op = OPC_NMSUB_PS;
14060            do_madd:
14061                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14062                break;
14063            case CABS_COND_FMT:
14064                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14065                cond = (ctx->opcode >> 6) & 0xf;
14066                cc = (ctx->opcode >> 13) & 0x7;
14067                fmt = (ctx->opcode >> 10) & 0x3;
14068                switch (fmt) {
14069                case 0x0:
14070                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
14071                    break;
14072                case 0x1:
14073                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
14074                    break;
14075                case 0x2:
14076                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14077                    break;
14078                default:
14079                    goto pool32f_invalid;
14080                }
14081                break;
14082            case C_COND_FMT:
14083                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14084                cond = (ctx->opcode >> 6) & 0xf;
14085                cc = (ctx->opcode >> 13) & 0x7;
14086                fmt = (ctx->opcode >> 10) & 0x3;
14087                switch (fmt) {
14088                case 0x0:
14089                    gen_cmp_s(ctx, cond, rt, rs, cc);
14090                    break;
14091                case 0x1:
14092                    gen_cmp_d(ctx, cond, rt, rs, cc);
14093                    break;
14094                case 0x2:
14095                    gen_cmp_ps(ctx, cond, rt, rs, cc);
14096                    break;
14097                default:
14098                    goto pool32f_invalid;
14099                }
14100                break;
14101            case CMP_CONDN_S:
14102                check_insn(ctx, ISA_MIPS32R6);
14103                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14104                break;
14105            case CMP_CONDN_D:
14106                check_insn(ctx, ISA_MIPS32R6);
14107                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14108                break;
14109            case POOL32FXF:
14110                gen_pool32fxf(ctx, rt, rs);
14111                break;
14112            case 0x00:
14113                /* PLL foo */
14114                switch ((ctx->opcode >> 6) & 0x7) {
14115                case PLL_PS:
14116                    mips32_op = OPC_PLL_PS;
14117                    goto do_ps;
14118                case PLU_PS:
14119                    mips32_op = OPC_PLU_PS;
14120                    goto do_ps;
14121                case PUL_PS:
14122                    mips32_op = OPC_PUL_PS;
14123                    goto do_ps;
14124                case PUU_PS:
14125                    mips32_op = OPC_PUU_PS;
14126                    goto do_ps;
14127                case CVT_PS_S:
14128                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14129                    mips32_op = OPC_CVT_PS_S;
14130                do_ps:
14131                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14132                    break;
14133                default:
14134                    goto pool32f_invalid;
14135                }
14136                break;
14137            case MIN_FMT:
14138                check_insn(ctx, ISA_MIPS32R6);
14139                switch ((ctx->opcode >> 9) & 0x3) {
14140                case FMT_SDPS_S:
14141                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14142                    break;
14143                case FMT_SDPS_D:
14144                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14145                    break;
14146                default:
14147                    goto pool32f_invalid;
14148                }
14149                break;
14150            case 0x08:
14151                /* [LS][WDU]XC1 */
14152                switch ((ctx->opcode >> 6) & 0x7) {
14153                case LWXC1:
14154                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14155                    mips32_op = OPC_LWXC1;
14156                    goto do_ldst_cp1;
14157                case SWXC1:
14158                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14159                    mips32_op = OPC_SWXC1;
14160                    goto do_ldst_cp1;
14161                case LDXC1:
14162                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14163                    mips32_op = OPC_LDXC1;
14164                    goto do_ldst_cp1;
14165                case SDXC1:
14166                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14167                    mips32_op = OPC_SDXC1;
14168                    goto do_ldst_cp1;
14169                case LUXC1:
14170                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14171                    mips32_op = OPC_LUXC1;
14172                    goto do_ldst_cp1;
14173                case SUXC1:
14174                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14175                    mips32_op = OPC_SUXC1;
14176                do_ldst_cp1:
14177                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14178                    break;
14179                default:
14180                    goto pool32f_invalid;
14181                }
14182                break;
14183            case MAX_FMT:
14184                check_insn(ctx, ISA_MIPS32R6);
14185                switch ((ctx->opcode >> 9) & 0x3) {
14186                case FMT_SDPS_S:
14187                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14188                    break;
14189                case FMT_SDPS_D:
14190                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14191                    break;
14192                default:
14193                    goto pool32f_invalid;
14194                }
14195                break;
14196            case 0x18:
14197                /* 3D insns */
14198                check_insn_opc_removed(ctx, ISA_MIPS32R6);
14199                fmt = (ctx->opcode >> 9) & 0x3;
14200                switch ((ctx->opcode >> 6) & 0x7) {
14201                case RSQRT2_FMT:
14202                    switch (fmt) {
14203                    case FMT_SDPS_S:
14204                        mips32_op = OPC_RSQRT2_S;
14205                        goto do_3d;
14206                    case FMT_SDPS_D:
14207                        mips32_op = OPC_RSQRT2_D;
14208                        goto do_3d;
14209                    case FMT_SDPS_PS:
14210                        mips32_op = OPC_RSQRT2_PS;
14211                        goto do_3d;
14212                    default:
14213                        goto pool32f_invalid;
14214                    }
14215                    break;
14216                case RECIP2_FMT:
14217                    switch (fmt) {
14218                    case FMT_SDPS_S:
14219                        mips32_op = OPC_RECIP2_S;
14220                        goto do_3d;
14221                    case FMT_SDPS_D:
14222                        mips32_op = OPC_RECIP2_D;
14223                        goto do_3d;
14224                    case FMT_SDPS_PS:
14225                        mips32_op = OPC_RECIP2_PS;
14226                        goto do_3d;
14227                    default:
14228                        goto pool32f_invalid;
14229                    }
14230                    break;
14231                case ADDR_PS:
14232                    mips32_op = OPC_ADDR_PS;
14233                    goto do_3d;
14234                case MULR_PS:
14235                    mips32_op = OPC_MULR_PS;
14236                do_3d:
14237                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14238                    break;
14239                default:
14240                    goto pool32f_invalid;
14241                }
14242                break;
14243            case 0x20:
14244                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14245                cc = (ctx->opcode >> 13) & 0x7;
14246                fmt = (ctx->opcode >> 9) & 0x3;
14247                switch ((ctx->opcode >> 6) & 0x7) {
14248                case MOVF_FMT: /* RINT_FMT */
14249                    if (ctx->insn_flags & ISA_MIPS32R6) {
14250                        /* RINT_FMT */
14251                        switch (fmt) {
14252                        case FMT_SDPS_S:
14253                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14254                            break;
14255                        case FMT_SDPS_D:
14256                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14257                            break;
14258                        default:
14259                            goto pool32f_invalid;
14260                        }
14261                    } else {
14262                        /* MOVF_FMT */
14263                        switch (fmt) {
14264                        case FMT_SDPS_S:
14265                            gen_movcf_s(ctx, rs, rt, cc, 0);
14266                            break;
14267                        case FMT_SDPS_D:
14268                            gen_movcf_d(ctx, rs, rt, cc, 0);
14269                            break;
14270                        case FMT_SDPS_PS:
14271                            check_ps(ctx);
14272                            gen_movcf_ps(ctx, rs, rt, cc, 0);
14273                            break;
14274                        default:
14275                            goto pool32f_invalid;
14276                        }
14277                    }
14278                    break;
14279                case MOVT_FMT: /* CLASS_FMT */
14280                    if (ctx->insn_flags & ISA_MIPS32R6) {
14281                        /* CLASS_FMT */
14282                        switch (fmt) {
14283                        case FMT_SDPS_S:
14284                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14285                            break;
14286                        case FMT_SDPS_D:
14287                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14288                            break;
14289                        default:
14290                            goto pool32f_invalid;
14291                        }
14292                    } else {
14293                        /* MOVT_FMT */
14294                        switch (fmt) {
14295                        case FMT_SDPS_S:
14296                            gen_movcf_s(ctx, rs, rt, cc, 1);
14297                            break;
14298                        case FMT_SDPS_D:
14299                            gen_movcf_d(ctx, rs, rt, cc, 1);
14300                            break;
14301                        case FMT_SDPS_PS:
14302                            check_ps(ctx);
14303                            gen_movcf_ps(ctx, rs, rt, cc, 1);
14304                            break;
14305                        default:
14306                            goto pool32f_invalid;
14307                        }
14308                    }
14309                    break;
14310                case PREFX:
14311                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14312                    break;
14313                default:
14314                    goto pool32f_invalid;
14315                }
14316                break;
14317#define FINSN_3ARG_SDPS(prfx)                           \
14318                switch ((ctx->opcode >> 8) & 0x3) {     \
14319                case FMT_SDPS_S:                        \
14320                    mips32_op = OPC_##prfx##_S;         \
14321                    goto do_fpop;                       \
14322                case FMT_SDPS_D:                        \
14323                    mips32_op = OPC_##prfx##_D;         \
14324                    goto do_fpop;                       \
14325                case FMT_SDPS_PS:                       \
14326                    check_ps(ctx);                      \
14327                    mips32_op = OPC_##prfx##_PS;        \
14328                    goto do_fpop;                       \
14329                default:                                \
14330                    goto pool32f_invalid;               \
14331                }
14332            case MINA_FMT:
14333                check_insn(ctx, ISA_MIPS32R6);
14334                switch ((ctx->opcode >> 9) & 0x3) {
14335                case FMT_SDPS_S:
14336                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14337                    break;
14338                case FMT_SDPS_D:
14339                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14340                    break;
14341                default:
14342                    goto pool32f_invalid;
14343                }
14344                break;
14345            case MAXA_FMT:
14346                check_insn(ctx, ISA_MIPS32R6);
14347                switch ((ctx->opcode >> 9) & 0x3) {
14348                case FMT_SDPS_S:
14349                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14350                    break;
14351                case FMT_SDPS_D:
14352                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14353                    break;
14354                default:
14355                    goto pool32f_invalid;
14356                }
14357                break;
14358            case 0x30:
14359                /* regular FP ops */
14360                switch ((ctx->opcode >> 6) & 0x3) {
14361                case ADD_FMT:
14362                    FINSN_3ARG_SDPS(ADD);
14363                    break;
14364                case SUB_FMT:
14365                    FINSN_3ARG_SDPS(SUB);
14366                    break;
14367                case MUL_FMT:
14368                    FINSN_3ARG_SDPS(MUL);
14369                    break;
14370                case DIV_FMT:
14371                    fmt = (ctx->opcode >> 8) & 0x3;
14372                    if (fmt == 1) {
14373                        mips32_op = OPC_DIV_D;
14374                    } else if (fmt == 0) {
14375                        mips32_op = OPC_DIV_S;
14376                    } else {
14377                        goto pool32f_invalid;
14378                    }
14379                    goto do_fpop;
14380                default:
14381                    goto pool32f_invalid;
14382                }
14383                break;
14384            case 0x38:
14385                /* cmovs */
14386                switch ((ctx->opcode >> 6) & 0x7) {
14387                case MOVN_FMT: /* SELNEZ_FMT */
14388                    if (ctx->insn_flags & ISA_MIPS32R6) {
14389                        /* SELNEZ_FMT */
14390                        switch ((ctx->opcode >> 9) & 0x3) {
14391                        case FMT_SDPS_S:
14392                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14393                            break;
14394                        case FMT_SDPS_D:
14395                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14396                            break;
14397                        default:
14398                            goto pool32f_invalid;
14399                        }
14400                    } else {
14401                        /* MOVN_FMT */
14402                        FINSN_3ARG_SDPS(MOVN);
14403                    }
14404                    break;
14405                case MOVN_FMT_04:
14406                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14407                    FINSN_3ARG_SDPS(MOVN);
14408                    break;
14409                case MOVZ_FMT: /* SELEQZ_FMT */
14410                    if (ctx->insn_flags & ISA_MIPS32R6) {
14411                        /* SELEQZ_FMT */
14412                        switch ((ctx->opcode >> 9) & 0x3) {
14413                        case FMT_SDPS_S:
14414                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14415                            break;
14416                        case FMT_SDPS_D:
14417                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14418                            break;
14419                        default:
14420                            goto pool32f_invalid;
14421                        }
14422                    } else {
14423                        /* MOVZ_FMT */
14424                        FINSN_3ARG_SDPS(MOVZ);
14425                    }
14426                    break;
14427                case MOVZ_FMT_05:
14428                    check_insn_opc_removed(ctx, ISA_MIPS32R6);
14429                    FINSN_3ARG_SDPS(MOVZ);
14430                    break;
14431                case SEL_FMT:
14432                    check_insn(ctx, ISA_MIPS32R6);
14433                    switch ((ctx->opcode >> 9) & 0x3) {
14434                    case FMT_SDPS_S:
14435                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14436                        break;
14437                    case FMT_SDPS_D:
14438                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14439                        break;
14440                    default:
14441                        goto pool32f_invalid;
14442                    }
14443                    break;
14444                case MADDF_FMT:
14445                    check_insn(ctx, ISA_MIPS32R6);
14446                    switch ((ctx->opcode >> 9) & 0x3) {
14447                    case FMT_SDPS_S:
14448                        mips32_op = OPC_MADDF_S;
14449                        goto do_fpop;
14450                    case FMT_SDPS_D:
14451                        mips32_op = OPC_MADDF_D;
14452                        goto do_fpop;
14453                    default:
14454                        goto pool32f_invalid;
14455                    }
14456                    break;
14457                case MSUBF_FMT:
14458                    check_insn(ctx, ISA_MIPS32R6);
14459                    switch ((ctx->opcode >> 9) & 0x3) {
14460                    case FMT_SDPS_S:
14461                        mips32_op = OPC_MSUBF_S;
14462                        goto do_fpop;
14463                    case FMT_SDPS_D:
14464                        mips32_op = OPC_MSUBF_D;
14465                        goto do_fpop;
14466                    default:
14467                        goto pool32f_invalid;
14468                    }
14469                    break;
14470                default:
14471                    goto pool32f_invalid;
14472                }
14473                break;
14474            do_fpop:
14475                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14476                break;
14477            default:
14478            pool32f_invalid:
14479                MIPS_INVAL("pool32f");
14480                generate_exception_end(ctx, EXCP_RI);
14481                break;
14482            }
14483        } else {
14484            generate_exception_err(ctx, EXCP_CpU, 1);
14485        }
14486        break;
14487    case POOL32I:
14488        minor = (ctx->opcode >> 21) & 0x1f;
14489        switch (minor) {
14490        case BLTZ:
14491            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14492            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14493            break;
14494        case BLTZAL:
14495            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14496            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14497            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14498            break;
14499        case BLTZALS:
14500            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14501            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14502            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14503            break;
14504        case BGEZ:
14505            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14506            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14507            break;
14508        case BGEZAL:
14509            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14510            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14511            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14512            break;
14513        case BGEZALS:
14514            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14515            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14516            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14517            break;
14518        case BLEZ:
14519            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14520            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14521            break;
14522        case BGTZ:
14523            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14524            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14525            break;
14526
14527            /* Traps */
14528        case TLTI: /* BC1EQZC */
14529            if (ctx->insn_flags & ISA_MIPS32R6) {
14530                /* BC1EQZC */
14531                check_cp1_enabled(ctx);
14532                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14533            } else {
14534                /* TLTI */
14535                mips32_op = OPC_TLTI;
14536                goto do_trapi;
14537            }
14538            break;
14539        case TGEI: /* BC1NEZC */
14540            if (ctx->insn_flags & ISA_MIPS32R6) {
14541                /* BC1NEZC */
14542                check_cp1_enabled(ctx);
14543                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14544            } else {
14545                /* TGEI */
14546                mips32_op = OPC_TGEI;
14547                goto do_trapi;
14548            }
14549            break;
14550        case TLTIU:
14551            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14552            mips32_op = OPC_TLTIU;
14553            goto do_trapi;
14554        case TGEIU:
14555            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14556            mips32_op = OPC_TGEIU;
14557            goto do_trapi;
14558        case TNEI: /* SYNCI */
14559            if (ctx->insn_flags & ISA_MIPS32R6) {
14560                /* SYNCI */
14561                /* Break the TB to be able to sync copied instructions
14562                   immediately */
14563                ctx->bstate = BS_STOP;
14564            } else {
14565                /* TNEI */
14566                mips32_op = OPC_TNEI;
14567                goto do_trapi;
14568            }
14569            break;
14570        case TEQI:
14571            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14572            mips32_op = OPC_TEQI;
14573        do_trapi:
14574            gen_trap(ctx, mips32_op, rs, -1, imm);
14575            break;
14576
14577        case BNEZC:
14578        case BEQZC:
14579            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14580            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14581                               4, rs, 0, imm << 1, 0);
14582            /* Compact branches don't have a delay slot, so just let
14583               the normal delay slot handling take us to the branch
14584               target. */
14585            break;
14586        case LUI:
14587            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14588            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14589            break;
14590        case SYNCI:
14591            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14592            /* Break the TB to be able to sync copied instructions
14593               immediately */
14594            ctx->bstate = BS_STOP;
14595            break;
14596        case BC2F:
14597        case BC2T:
14598            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14599            /* COP2: Not implemented. */
14600            generate_exception_err(ctx, EXCP_CpU, 2);
14601            break;
14602        case BC1F:
14603            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14604            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14605            goto do_cp1branch;
14606        case BC1T:
14607            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14608            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14609            goto do_cp1branch;
14610        case BC1ANY4F:
14611            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14612            mips32_op = OPC_BC1FANY4;
14613            goto do_cp1mips3d;
14614        case BC1ANY4T:
14615            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14616            mips32_op = OPC_BC1TANY4;
14617        do_cp1mips3d:
14618            check_cop1x(ctx);
14619            check_insn(ctx, ASE_MIPS3D);
14620            /* Fall through */
14621        do_cp1branch:
14622            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14623                check_cp1_enabled(ctx);
14624                gen_compute_branch1(ctx, mips32_op,
14625                                    (ctx->opcode >> 18) & 0x7, imm << 1);
14626            } else {
14627                generate_exception_err(ctx, EXCP_CpU, 1);
14628            }
14629            break;
14630        case BPOSGE64:
14631        case BPOSGE32:
14632            /* MIPS DSP: not implemented */
14633            /* Fall through */
14634        default:
14635            MIPS_INVAL("pool32i");
14636            generate_exception_end(ctx, EXCP_RI);
14637            break;
14638        }
14639        break;
14640    case POOL32C:
14641        minor = (ctx->opcode >> 12) & 0xf;
14642        offset = sextract32(ctx->opcode, 0,
14643                            (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14644        switch (minor) {
14645        case LWL:
14646            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14647            mips32_op = OPC_LWL;
14648            goto do_ld_lr;
14649        case SWL:
14650            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14651            mips32_op = OPC_SWL;
14652            goto do_st_lr;
14653        case LWR:
14654            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14655            mips32_op = OPC_LWR;
14656            goto do_ld_lr;
14657        case SWR:
14658            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14659            mips32_op = OPC_SWR;
14660            goto do_st_lr;
14661#if defined(TARGET_MIPS64)
14662        case LDL:
14663            check_insn(ctx, ISA_MIPS3);
14664            check_mips_64(ctx);
14665            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14666            mips32_op = OPC_LDL;
14667            goto do_ld_lr;
14668        case SDL:
14669            check_insn(ctx, ISA_MIPS3);
14670            check_mips_64(ctx);
14671            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14672            mips32_op = OPC_SDL;
14673            goto do_st_lr;
14674        case LDR:
14675            check_insn(ctx, ISA_MIPS3);
14676            check_mips_64(ctx);
14677            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14678            mips32_op = OPC_LDR;
14679            goto do_ld_lr;
14680        case SDR:
14681            check_insn(ctx, ISA_MIPS3);
14682            check_mips_64(ctx);
14683            check_insn_opc_removed(ctx, ISA_MIPS32R6);
14684            mips32_op = OPC_SDR;
14685            goto do_st_lr;
14686        case LWU:
14687            check_insn(ctx, ISA_MIPS3);
14688            check_mips_64(ctx);
14689            mips32_op = OPC_LWU;
14690            goto do_ld_lr;
14691        case LLD:
14692            check_insn(ctx, ISA_MIPS3);
14693            check_mips_64(ctx);
14694            mips32_op = OPC_LLD;
14695            goto do_ld_lr;
14696#endif
14697        case LL:
14698            mips32_op = OPC_LL;
14699            goto do_ld_lr;
14700        do_ld_lr:
14701            gen_ld(ctx, mips32_op, rt, rs, offset);
14702            break;
14703        do_st_lr:
14704            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14705            break;
14706        case SC:
14707            gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14708            break;
14709#if defined(TARGET_MIPS64)
14710        case SCD:
14711            check_insn(ctx, ISA_MIPS3);
14712            check_mips_64(ctx);
14713            gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14714            break;
14715#endif
14716        case PREF:
14717            /* Treat as no-op */
14718            if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14719                /* hint codes 24-31 are reserved and signal RI */
14720                generate_exception(ctx, EXCP_RI);
14721            }
14722            break;
14723        default:
14724            MIPS_INVAL("pool32c");
14725            generate_exception_end(ctx, EXCP_RI);
14726            break;
14727        }
14728        break;
14729    case ADDI32: /* AUI, LUI */
14730        if (ctx->insn_flags & ISA_MIPS32R6) {
14731            /* AUI, LUI */
14732            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14733        } else {
14734            /* ADDI32 */
14735            mips32_op = OPC_ADDI;
14736            goto do_addi;
14737        }
14738        break;
14739    case ADDIU32:
14740        mips32_op = OPC_ADDIU;
14741    do_addi:
14742        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14743        break;
14744
14745        /* Logical operations */
14746    case ORI32:
14747        mips32_op = OPC_ORI;
14748        goto do_logici;
14749    case XORI32:
14750        mips32_op = OPC_XORI;
14751        goto do_logici;
14752    case ANDI32:
14753        mips32_op = OPC_ANDI;
14754    do_logici:
14755        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14756        break;
14757
14758        /* Set less than immediate */
14759    case SLTI32:
14760        mips32_op = OPC_SLTI;
14761        goto do_slti;
14762    case SLTIU32:
14763        mips32_op = OPC_SLTIU;
14764    do_slti:
14765        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14766        break;
14767    case JALX32:
14768        check_insn_opc_removed(ctx, ISA_MIPS32R6);
14769        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14770        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14771        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14772        break;
14773    case JALS32: /* BOVC, BEQC, BEQZALC */
14774        if (ctx->insn_flags & ISA_MIPS32R6) {
14775            if (rs >= rt) {
14776                /* BOVC */
14777                mips32_op = OPC_BOVC;
14778            } else if (rs < rt && rs == 0) {
14779                /* BEQZALC */
14780                mips32_op = OPC_BEQZALC;
14781            } else {
14782                /* BEQC */
14783                mips32_op = OPC_BEQC;
14784            }
14785            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14786        } else {
14787            /* JALS32 */
14788            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14789            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14790            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14791        }
14792        break;
14793    case BEQ32: /* BC */
14794        if (ctx->insn_flags & ISA_MIPS32R6) {
14795            /* BC */
14796            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14797                                       sextract32(ctx->opcode << 1, 0, 27));
14798        } else {
14799            /* BEQ32 */
14800            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14801        }
14802        break;
14803    case BNE32: /* BALC */
14804        if (ctx->insn_flags & ISA_MIPS32R6) {
14805            /* BALC */
14806            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14807                                       sextract32(ctx->opcode << 1, 0, 27));
14808        } else {
14809            /* BNE32 */
14810            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14811        }
14812        break;
14813    case J32: /* BGTZC, BLTZC, BLTC */
14814        if (ctx->insn_flags & ISA_MIPS32R6) {
14815            if (rs == 0 && rt != 0) {
14816                /* BGTZC */
14817                mips32_op = OPC_BGTZC;
14818            } else if (rs != 0 && rt != 0 && rs == rt) {
14819                /* BLTZC */
14820                mips32_op = OPC_BLTZC;
14821            } else {
14822                /* BLTC */
14823                mips32_op = OPC_BLTC;
14824            }
14825            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14826        } else {
14827            /* J32 */
14828            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14829                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14830        }
14831        break;
14832    case JAL32: /* BLEZC, BGEZC, BGEC */
14833        if (ctx->insn_flags & ISA_MIPS32R6) {
14834            if (rs == 0 && rt != 0) {
14835                /* BLEZC */
14836                mips32_op = OPC_BLEZC;
14837            } else if (rs != 0 && rt != 0 && rs == rt) {
14838                /* BGEZC */
14839                mips32_op = OPC_BGEZC;
14840            } else {
14841                /* BGEC */
14842                mips32_op = OPC_BGEC;
14843            }
14844            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14845        } else {
14846            /* JAL32 */
14847            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14848                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14849            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14850        }
14851        break;
14852        /* Floating point (COP1) */
14853    case LWC132:
14854        mips32_op = OPC_LWC1;
14855        goto do_cop1;
14856    case LDC132:
14857        mips32_op = OPC_LDC1;
14858        goto do_cop1;
14859    case SWC132:
14860        mips32_op = OPC_SWC1;
14861        goto do_cop1;
14862    case SDC132:
14863        mips32_op = OPC_SDC1;
14864    do_cop1:
14865        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14866        break;
14867    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14868        if (ctx->insn_flags & ISA_MIPS32R6) {
14869            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14870            switch ((ctx->opcode >> 16) & 0x1f) {
14871            case ADDIUPC_00 ... ADDIUPC_07:
14872                gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14873                break;
14874            case AUIPC:
14875                gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14876                break;
14877            case ALUIPC:
14878                gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14879                break;
14880            case LWPC_08 ... LWPC_0F:
14881                gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14882                break;
14883            default:
14884                generate_exception(ctx, EXCP_RI);
14885                break;
14886            }
14887        } else {
14888            /* ADDIUPC */
14889            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14890            int offset = SIMM(ctx->opcode, 0, 23) << 2;
14891
14892            gen_addiupc(ctx, reg, offset, 0, 0);
14893        }
14894        break;
14895    case BNVC: /* BNEC, BNEZALC */
14896        check_insn(ctx, ISA_MIPS32R6);
14897        if (rs >= rt) {
14898            /* BNVC */
14899            mips32_op = OPC_BNVC;
14900        } else if (rs < rt && rs == 0) {
14901            /* BNEZALC */
14902            mips32_op = OPC_BNEZALC;
14903        } else {
14904            /* BNEC */
14905            mips32_op = OPC_BNEC;
14906        }
14907        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14908        break;
14909    case R6_BNEZC: /* JIALC */
14910        check_insn(ctx, ISA_MIPS32R6);
14911        if (rt != 0) {
14912            /* BNEZC */
14913            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14914                                       sextract32(ctx->opcode << 1, 0, 22));
14915        } else {
14916            /* JIALC */
14917            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14918        }
14919        break;
14920    case R6_BEQZC: /* JIC */
14921        check_insn(ctx, ISA_MIPS32R6);
14922        if (rt != 0) {
14923            /* BEQZC */
14924            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14925                                       sextract32(ctx->opcode << 1, 0, 22));
14926        } else {
14927            /* JIC */
14928            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14929        }
14930        break;
14931    case BLEZALC: /* BGEZALC, BGEUC */
14932        check_insn(ctx, ISA_MIPS32R6);
14933        if (rs == 0 && rt != 0) {
14934            /* BLEZALC */
14935            mips32_op = OPC_BLEZALC;
14936        } else if (rs != 0 && rt != 0 && rs == rt) {
14937            /* BGEZALC */
14938            mips32_op = OPC_BGEZALC;
14939        } else {
14940            /* BGEUC */
14941            mips32_op = OPC_BGEUC;
14942        }
14943        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14944        break;
14945    case BGTZALC: /* BLTZALC, BLTUC */
14946        check_insn(ctx, ISA_MIPS32R6);
14947        if (rs == 0 && rt != 0) {
14948            /* BGTZALC */
14949            mips32_op = OPC_BGTZALC;
14950        } else if (rs != 0 && rt != 0 && rs == rt) {
14951            /* BLTZALC */
14952            mips32_op = OPC_BLTZALC;
14953        } else {
14954            /* BLTUC */
14955            mips32_op = OPC_BLTUC;
14956        }
14957        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14958        break;
14959        /* Loads and stores */
14960    case LB32:
14961        mips32_op = OPC_LB;
14962        goto do_ld;
14963    case LBU32:
14964        mips32_op = OPC_LBU;
14965        goto do_ld;
14966    case LH32:
14967        mips32_op = OPC_LH;
14968        goto do_ld;
14969    case LHU32:
14970        mips32_op = OPC_LHU;
14971        goto do_ld;
14972    case LW32:
14973        mips32_op = OPC_LW;
14974        goto do_ld;
14975#ifdef TARGET_MIPS64
14976    case LD32:
14977        check_insn(ctx, ISA_MIPS3);
14978        check_mips_64(ctx);
14979        mips32_op = OPC_LD;
14980        goto do_ld;
14981    case SD32:
14982        check_insn(ctx, ISA_MIPS3);
14983        check_mips_64(ctx);
14984        mips32_op = OPC_SD;
14985        goto do_st;
14986#endif
14987    case SB32:
14988        mips32_op = OPC_SB;
14989        goto do_st;
14990    case SH32:
14991        mips32_op = OPC_SH;
14992        goto do_st;
14993    case SW32:
14994        mips32_op = OPC_SW;
14995        goto do_st;
14996    do_ld:
14997        gen_ld(ctx, mips32_op, rt, rs, imm);
14998        break;
14999    do_st:
15000        gen_st(ctx, mips32_op, rt, rs, imm);
15001        break;
15002    default:
15003        generate_exception_end(ctx, EXCP_RI);
15004        break;
15005    }
15006}
15007
15008static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
15009{
15010    uint32_t op;
15011
15012    /* make sure instructions are on a halfword boundary */
15013    if (ctx->pc & 0x1) {
15014        env->CP0_BadVAddr = ctx->pc;
15015        generate_exception_end(ctx, EXCP_AdEL);
15016        return 2;
15017    }
15018
15019    op = (ctx->opcode >> 10) & 0x3f;
15020    /* Enforce properly-sized instructions in a delay slot */
15021    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15022        switch (op & 0x7) { /* MSB-3..MSB-5 */
15023        case 0:
15024        /* POOL32A, POOL32B, POOL32I, POOL32C */
15025        case 4:
15026        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15027        case 5:
15028        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15029        case 6:
15030        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15031        case 7:
15032        /* LB32, LH32, LWC132, LDC132, LW32 */
15033            if (ctx->hflags & MIPS_HFLAG_BDS16) {
15034                generate_exception_end(ctx, EXCP_RI);
15035                return 2;
15036            }
15037            break;
15038        case 1:
15039        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15040        case 2:
15041        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15042        case 3:
15043        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15044            if (ctx->hflags & MIPS_HFLAG_BDS32) {
15045                generate_exception_end(ctx, EXCP_RI);
15046                return 2;
15047            }
15048            break;
15049        }
15050    }
15051
15052    switch (op) {
15053    case POOL16A:
15054        {
15055            int rd = mmreg(uMIPS_RD(ctx->opcode));
15056            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15057            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15058            uint32_t opc = 0;
15059
15060            switch (ctx->opcode & 0x1) {
15061            case ADDU16:
15062                opc = OPC_ADDU;
15063                break;
15064            case SUBU16:
15065                opc = OPC_SUBU;
15066                break;
15067            }
15068            if (ctx->insn_flags & ISA_MIPS32R6) {
15069                /* In the Release 6 the register number location in
15070                 * the instruction encoding has changed.
15071                 */
15072                gen_arith(ctx, opc, rs1, rd, rs2);
15073            } else {
15074                gen_arith(ctx, opc, rd, rs1, rs2);
15075            }
15076        }
15077        break;
15078    case POOL16B:
15079        {
15080            int rd = mmreg(uMIPS_RD(ctx->opcode));
15081            int rs = mmreg(uMIPS_RS(ctx->opcode));
15082            int amount = (ctx->opcode >> 1) & 0x7;
15083            uint32_t opc = 0;
15084            amount = amount == 0 ? 8 : amount;
15085
15086            switch (ctx->opcode & 0x1) {
15087            case SLL16:
15088                opc = OPC_SLL;
15089                break;
15090            case SRL16:
15091                opc = OPC_SRL;
15092                break;
15093            }
15094
15095            gen_shift_imm(ctx, opc, rd, rs, amount);
15096        }
15097        break;
15098    case POOL16C:
15099        if (ctx->insn_flags & ISA_MIPS32R6) {
15100            gen_pool16c_r6_insn(ctx);
15101        } else {
15102            gen_pool16c_insn(ctx);
15103        }
15104        break;
15105    case LWGP16:
15106        {
15107            int rd = mmreg(uMIPS_RD(ctx->opcode));
15108            int rb = 28;            /* GP */
15109            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15110
15111            gen_ld(ctx, OPC_LW, rd, rb, offset);
15112        }
15113        break;
15114    case POOL16F:
15115        check_insn_opc_removed(ctx, ISA_MIPS32R6);
15116        if (ctx->opcode & 1) {
15117            generate_exception_end(ctx, EXCP_RI);
15118        } else {
15119            /* MOVEP */
15120            int enc_dest = uMIPS_RD(ctx->opcode);
15121            int enc_rt = uMIPS_RS2(ctx->opcode);
15122            int enc_rs = uMIPS_RS1(ctx->opcode);
15123            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15124        }
15125        break;
15126    case LBU16:
15127        {
15128            int rd = mmreg(uMIPS_RD(ctx->opcode));
15129            int rb = mmreg(uMIPS_RS(ctx->opcode));
15130            int16_t offset = ZIMM(ctx->opcode, 0, 4);
15131            offset = (offset == 0xf ? -1 : offset);
15132
15133            gen_ld(ctx, OPC_LBU, rd, rb, offset);
15134        }
15135        break;
15136    case LHU16:
15137        {
15138            int rd = mmreg(uMIPS_RD(ctx->opcode));
15139            int rb = mmreg(uMIPS_RS(ctx->opcode));
15140            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15141
15142            gen_ld(ctx, OPC_LHU, rd, rb, offset);
15143        }
15144        break;
15145    case LWSP16:
15146        {
15147            int rd = (ctx->opcode >> 5) & 0x1f;
15148            int rb = 29;            /* SP */
15149            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15150
15151            gen_ld(ctx, OPC_LW, rd, rb, offset);
15152        }
15153        break;
15154    case LW16:
15155        {
15156            int rd = mmreg(uMIPS_RD(ctx->opcode));
15157            int rb = mmreg(uMIPS_RS(ctx->opcode));
15158            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15159
15160            gen_ld(ctx, OPC_LW, rd, rb, offset);
15161        }
15162        break;
15163    case SB16:
15164        {
15165            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15166            int rb = mmreg(uMIPS_RS(ctx->opcode));
15167            int16_t offset = ZIMM(ctx->opcode, 0, 4);
15168
15169            gen_st(ctx, OPC_SB, rd, rb, offset);
15170        }
15171        break;
15172    case SH16:
15173        {
15174            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15175            int rb = mmreg(uMIPS_RS(ctx->opcode));
15176            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15177
15178            gen_st(ctx, OPC_SH, rd, rb, offset);
15179        }
15180        break;
15181    case SWSP16:
15182        {
15183            int rd = (ctx->opcode >> 5) & 0x1f;
15184            int rb = 29;            /* SP */
15185            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15186
15187            gen_st(ctx, OPC_SW, rd, rb, offset);
15188        }
15189        break;
15190    case SW16:
15191        {
15192            int rd = mmreg2(uMIPS_RD(ctx->opcode));
15193            int rb = mmreg(uMIPS_RS(ctx->opcode));
15194            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15195
15196            gen_st(ctx, OPC_SW, rd, rb, offset);
15197        }
15198        break;
15199    case MOVE16:
15200        {
15201            int rd = uMIPS_RD5(ctx->opcode);
15202            int rs = uMIPS_RS5(ctx->opcode);
15203
15204            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15205        }
15206        break;
15207    case ANDI16:
15208        gen_andi16(ctx);
15209        break;
15210    case POOL16D:
15211        switch (ctx->opcode & 0x1) {
15212        case ADDIUS5:
15213            gen_addius5(ctx);
15214            break;
15215        case ADDIUSP:
15216            gen_addiusp(ctx);
15217            break;
15218        }
15219        break;
15220    case POOL16E:
15221        switch (ctx->opcode & 0x1) {
15222        case ADDIUR2:
15223            gen_addiur2(ctx);
15224            break;
15225        case ADDIUR1SP:
15226            gen_addiur1sp(ctx);
15227            break;
15228        }
15229        break;
15230    case B16: /* BC16 */
15231        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15232                           sextract32(ctx->opcode, 0, 10) << 1,
15233                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15234        break;
15235    case BNEZ16: /* BNEZC16 */
15236    case BEQZ16: /* BEQZC16 */
15237        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15238                           mmreg(uMIPS_RD(ctx->opcode)),
15239                           0, sextract32(ctx->opcode, 0, 7) << 1,
15240                           (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15241
15242        break;
15243    case LI16:
15244        {
15245            int reg = mmreg(uMIPS_RD(ctx->opcode));
15246            int imm = ZIMM(ctx->opcode, 0, 7);
15247
15248            imm = (imm == 0x7f ? -1 : imm);
15249            tcg_gen_movi_tl(cpu_gpr[reg], imm);
15250        }
15251        break;
15252    case RES_29:
15253    case RES_31:
15254    case RES_39:
15255        generate_exception_end(ctx, EXCP_RI);
15256        break;
15257    default:
15258        decode_micromips32_opc(env, ctx);
15259        return 4;
15260    }
15261
15262    return 2;
15263}
15264
15265/* SmartMIPS extension to MIPS32 */
15266
15267#if defined(TARGET_MIPS64)
15268
15269/* MDMX extension to MIPS64 */
15270
15271#endif
15272
15273/* MIPSDSP functions. */
15274static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15275                           int rd, int base, int offset)
15276{
15277    TCGv t0;
15278
15279    check_dsp(ctx);
15280    t0 = tcg_temp_new();
15281
15282    if (base == 0) {
15283        gen_load_gpr(t0, offset);
15284    } else if (offset == 0) {
15285        gen_load_gpr(t0, base);
15286    } else {
15287        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15288    }
15289
15290    switch (opc) {
15291    case OPC_LBUX:
15292        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15293        gen_store_gpr(t0, rd);
15294        break;
15295    case OPC_LHX:
15296        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15297        gen_store_gpr(t0, rd);
15298        break;
15299    case OPC_LWX:
15300        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15301        gen_store_gpr(t0, rd);
15302        break;
15303#if defined(TARGET_MIPS64)
15304    case OPC_LDX:
15305        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15306        gen_store_gpr(t0, rd);
15307        break;
15308#endif
15309    }
15310    tcg_temp_free(t0);
15311}
15312
15313static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15314                              int ret, int v1, int v2)
15315{
15316    TCGv v1_t;
15317    TCGv v2_t;
15318
15319    if (ret == 0) {
15320        /* Treat as NOP. */
15321        return;
15322    }
15323
15324    v1_t = tcg_temp_new();
15325    v2_t = tcg_temp_new();
15326
15327    gen_load_gpr(v1_t, v1);
15328    gen_load_gpr(v2_t, v2);
15329
15330    switch (op1) {
15331    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15332    case OPC_MULT_G_2E:
15333        check_dspr2(ctx);
15334        switch (op2) {
15335        case OPC_ADDUH_QB:
15336            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15337            break;
15338        case OPC_ADDUH_R_QB:
15339            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15340            break;
15341        case OPC_ADDQH_PH:
15342            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15343            break;
15344        case OPC_ADDQH_R_PH:
15345            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15346            break;
15347        case OPC_ADDQH_W:
15348            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15349            break;
15350        case OPC_ADDQH_R_W:
15351            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15352            break;
15353        case OPC_SUBUH_QB:
15354            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15355            break;
15356        case OPC_SUBUH_R_QB:
15357            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15358            break;
15359        case OPC_SUBQH_PH:
15360            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15361            break;
15362        case OPC_SUBQH_R_PH:
15363            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15364            break;
15365        case OPC_SUBQH_W:
15366            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15367            break;
15368        case OPC_SUBQH_R_W:
15369            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15370            break;
15371        }
15372        break;
15373    case OPC_ABSQ_S_PH_DSP:
15374        switch (op2) {
15375        case OPC_ABSQ_S_QB:
15376            check_dspr2(ctx);
15377            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15378            break;
15379        case OPC_ABSQ_S_PH:
15380            check_dsp(ctx);
15381            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15382            break;
15383        case OPC_ABSQ_S_W:
15384            check_dsp(ctx);
15385            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15386            break;
15387        case OPC_PRECEQ_W_PHL:
15388            check_dsp(ctx);
15389            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15390            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15391            break;
15392        case OPC_PRECEQ_W_PHR:
15393            check_dsp(ctx);
15394            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15395            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15396            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15397            break;
15398        case OPC_PRECEQU_PH_QBL:
15399            check_dsp(ctx);
15400            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15401            break;
15402        case OPC_PRECEQU_PH_QBR:
15403            check_dsp(ctx);
15404            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15405            break;
15406        case OPC_PRECEQU_PH_QBLA:
15407            check_dsp(ctx);
15408            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15409            break;
15410        case OPC_PRECEQU_PH_QBRA:
15411            check_dsp(ctx);
15412            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15413            break;
15414        case OPC_PRECEU_PH_QBL:
15415            check_dsp(ctx);
15416            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15417            break;
15418        case OPC_PRECEU_PH_QBR:
15419            check_dsp(ctx);
15420            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15421            break;
15422        case OPC_PRECEU_PH_QBLA:
15423            check_dsp(ctx);
15424            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15425            break;
15426        case OPC_PRECEU_PH_QBRA:
15427            check_dsp(ctx);
15428            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15429            break;
15430        }
15431        break;
15432    case OPC_ADDU_QB_DSP:
15433        switch (op2) {
15434        case OPC_ADDQ_PH:
15435            check_dsp(ctx);
15436            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15437            break;
15438        case OPC_ADDQ_S_PH:
15439            check_dsp(ctx);
15440            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15441            break;
15442        case OPC_ADDQ_S_W:
15443            check_dsp(ctx);
15444            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15445            break;
15446        case OPC_ADDU_QB:
15447            check_dsp(ctx);
15448            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15449            break;
15450        case OPC_ADDU_S_QB:
15451            check_dsp(ctx);
15452            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15453            break;
15454        case OPC_ADDU_PH:
15455            check_dspr2(ctx);
15456            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15457            break;
15458        case OPC_ADDU_S_PH:
15459            check_dspr2(ctx);
15460            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15461            break;
15462        case OPC_SUBQ_PH:
15463            check_dsp(ctx);
15464            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15465            break;
15466        case OPC_SUBQ_S_PH:
15467            check_dsp(ctx);
15468            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15469            break;
15470        case OPC_SUBQ_S_W:
15471            check_dsp(ctx);
15472            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15473            break;
15474        case OPC_SUBU_QB:
15475            check_dsp(ctx);
15476            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15477            break;
15478        case OPC_SUBU_S_QB:
15479            check_dsp(ctx);
15480            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15481            break;
15482        case OPC_SUBU_PH:
15483            check_dspr2(ctx);
15484            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15485            break;
15486        case OPC_SUBU_S_PH:
15487            check_dspr2(ctx);
15488            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15489            break;
15490        case OPC_ADDSC:
15491            check_dsp(ctx);
15492            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15493            break;
15494        case OPC_ADDWC:
15495            check_dsp(ctx);
15496            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15497            break;
15498        case OPC_MODSUB:
15499            check_dsp(ctx);
15500            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15501            break;
15502        case OPC_RADDU_W_QB:
15503            check_dsp(ctx);
15504            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15505            break;
15506        }
15507        break;
15508    case OPC_CMPU_EQ_QB_DSP:
15509        switch (op2) {
15510        case OPC_PRECR_QB_PH:
15511            check_dspr2(ctx);
15512            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15513            break;
15514        case OPC_PRECRQ_QB_PH:
15515            check_dsp(ctx);
15516            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15517            break;
15518        case OPC_PRECR_SRA_PH_W:
15519            check_dspr2(ctx);
15520            {
15521                TCGv_i32 sa_t = tcg_const_i32(v2);
15522                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15523                                          cpu_gpr[ret]);
15524                tcg_temp_free_i32(sa_t);
15525                break;
15526            }
15527        case OPC_PRECR_SRA_R_PH_W:
15528            check_dspr2(ctx);
15529            {
15530                TCGv_i32 sa_t = tcg_const_i32(v2);
15531                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15532                                            cpu_gpr[ret]);
15533                tcg_temp_free_i32(sa_t);
15534                break;
15535            }
15536        case OPC_PRECRQ_PH_W:
15537            check_dsp(ctx);
15538            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15539            break;
15540        case OPC_PRECRQ_RS_PH_W:
15541            check_dsp(ctx);
15542            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15543            break;
15544        case OPC_PRECRQU_S_QB_PH:
15545            check_dsp(ctx);
15546            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15547            break;
15548        }
15549        break;
15550#ifdef TARGET_MIPS64
15551    case OPC_ABSQ_S_QH_DSP:
15552        switch (op2) {
15553        case OPC_PRECEQ_L_PWL:
15554            check_dsp(ctx);
15555            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15556            break;
15557        case OPC_PRECEQ_L_PWR:
15558            check_dsp(ctx);
15559            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15560            break;
15561        case OPC_PRECEQ_PW_QHL:
15562            check_dsp(ctx);
15563            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15564            break;
15565        case OPC_PRECEQ_PW_QHR:
15566            check_dsp(ctx);
15567            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15568            break;
15569        case OPC_PRECEQ_PW_QHLA:
15570            check_dsp(ctx);
15571            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15572            break;
15573        case OPC_PRECEQ_PW_QHRA:
15574            check_dsp(ctx);
15575            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15576            break;
15577        case OPC_PRECEQU_QH_OBL:
15578            check_dsp(ctx);
15579            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15580            break;
15581        case OPC_PRECEQU_QH_OBR:
15582            check_dsp(ctx);
15583            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15584            break;
15585        case OPC_PRECEQU_QH_OBLA:
15586            check_dsp(ctx);
15587            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15588            break;
15589        case OPC_PRECEQU_QH_OBRA:
15590            check_dsp(ctx);
15591            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15592            break;
15593        case OPC_PRECEU_QH_OBL:
15594            check_dsp(ctx);
15595            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15596            break;
15597        case OPC_PRECEU_QH_OBR:
15598            check_dsp(ctx);
15599            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15600            break;
15601        case OPC_PRECEU_QH_OBLA:
15602            check_dsp(ctx);
15603            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15604            break;
15605        case OPC_PRECEU_QH_OBRA:
15606            check_dsp(ctx);
15607            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15608            break;
15609        case OPC_ABSQ_S_OB:
15610            check_dspr2(ctx);
15611            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15612            break;
15613        case OPC_ABSQ_S_PW:
15614            check_dsp(ctx);
15615            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15616            break;
15617        case OPC_ABSQ_S_QH:
15618            check_dsp(ctx);
15619            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15620            break;
15621        }
15622        break;
15623    case OPC_ADDU_OB_DSP:
15624        switch (op2) {
15625        case OPC_RADDU_L_OB:
15626            check_dsp(ctx);
15627            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15628            break;
15629        case OPC_SUBQ_PW:
15630            check_dsp(ctx);
15631            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15632            break;
15633        case OPC_SUBQ_S_PW:
15634            check_dsp(ctx);
15635            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15636            break;
15637        case OPC_SUBQ_QH:
15638            check_dsp(ctx);
15639            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15640            break;
15641        case OPC_SUBQ_S_QH:
15642            check_dsp(ctx);
15643            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15644            break;
15645        case OPC_SUBU_OB:
15646            check_dsp(ctx);
15647            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15648            break;
15649        case OPC_SUBU_S_OB:
15650            check_dsp(ctx);
15651            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15652            break;
15653        case OPC_SUBU_QH:
15654            check_dspr2(ctx);
15655            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15656            break;
15657        case OPC_SUBU_S_QH:
15658            check_dspr2(ctx);
15659            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15660            break;
15661        case OPC_SUBUH_OB:
15662            check_dspr2(ctx);
15663            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15664            break;
15665        case OPC_SUBUH_R_OB:
15666            check_dspr2(ctx);
15667            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15668            break;
15669        case OPC_ADDQ_PW:
15670            check_dsp(ctx);
15671            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15672            break;
15673        case OPC_ADDQ_S_PW:
15674            check_dsp(ctx);
15675            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15676            break;
15677        case OPC_ADDQ_QH:
15678            check_dsp(ctx);
15679            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15680            break;
15681        case OPC_ADDQ_S_QH:
15682            check_dsp(ctx);
15683            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15684            break;
15685        case OPC_ADDU_OB:
15686            check_dsp(ctx);
15687            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15688            break;
15689        case OPC_ADDU_S_OB:
15690            check_dsp(ctx);
15691            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15692            break;
15693        case OPC_ADDU_QH:
15694            check_dspr2(ctx);
15695            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15696            break;
15697        case OPC_ADDU_S_QH:
15698            check_dspr2(ctx);
15699            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15700            break;
15701        case OPC_ADDUH_OB:
15702            check_dspr2(ctx);
15703            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15704            break;
15705        case OPC_ADDUH_R_OB:
15706            check_dspr2(ctx);
15707            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15708            break;
15709        }
15710        break;
15711    case OPC_CMPU_EQ_OB_DSP:
15712        switch (op2) {
15713        case OPC_PRECR_OB_QH:
15714            check_dspr2(ctx);
15715            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15716            break;
15717        case OPC_PRECR_SRA_QH_PW:
15718            check_dspr2(ctx);
15719            {
15720                TCGv_i32 ret_t = tcg_const_i32(ret);
15721                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15722                tcg_temp_free_i32(ret_t);
15723                break;
15724            }
15725        case OPC_PRECR_SRA_R_QH_PW:
15726            check_dspr2(ctx);
15727            {
15728                TCGv_i32 sa_v = tcg_const_i32(ret);
15729                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15730                tcg_temp_free_i32(sa_v);
15731                break;
15732            }
15733        case OPC_PRECRQ_OB_QH:
15734            check_dsp(ctx);
15735            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15736            break;
15737        case OPC_PRECRQ_PW_L:
15738            check_dsp(ctx);
15739            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15740            break;
15741        case OPC_PRECRQ_QH_PW:
15742            check_dsp(ctx);
15743            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15744            break;
15745        case OPC_PRECRQ_RS_QH_PW:
15746            check_dsp(ctx);
15747            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15748            break;
15749        case OPC_PRECRQU_S_OB_QH:
15750            check_dsp(ctx);
15751            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15752            break;
15753        }
15754        break;
15755#endif
15756    }
15757
15758    tcg_temp_free(v1_t);
15759    tcg_temp_free(v2_t);
15760}
15761
15762static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15763                              int ret, int v1, int v2)
15764{
15765    uint32_t op2;
15766    TCGv t0;
15767    TCGv v1_t;
15768    TCGv v2_t;
15769
15770    if (ret == 0) {
15771        /* Treat as NOP. */
15772        return;
15773    }
15774
15775    t0 = tcg_temp_new();
15776    v1_t = tcg_temp_new();
15777    v2_t = tcg_temp_new();
15778
15779    tcg_gen_movi_tl(t0, v1);
15780    gen_load_gpr(v1_t, v1);
15781    gen_load_gpr(v2_t, v2);
15782
15783    switch (opc) {
15784    case OPC_SHLL_QB_DSP:
15785        {
15786            op2 = MASK_SHLL_QB(ctx->opcode);
15787            switch (op2) {
15788            case OPC_SHLL_QB:
15789                check_dsp(ctx);
15790                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15791                break;
15792            case OPC_SHLLV_QB:
15793                check_dsp(ctx);
15794                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15795                break;
15796            case OPC_SHLL_PH:
15797                check_dsp(ctx);
15798                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15799                break;
15800            case OPC_SHLLV_PH:
15801                check_dsp(ctx);
15802                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15803                break;
15804            case OPC_SHLL_S_PH:
15805                check_dsp(ctx);
15806                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15807                break;
15808            case OPC_SHLLV_S_PH:
15809                check_dsp(ctx);
15810                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15811                break;
15812            case OPC_SHLL_S_W:
15813                check_dsp(ctx);
15814                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15815                break;
15816            case OPC_SHLLV_S_W:
15817                check_dsp(ctx);
15818                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15819                break;
15820            case OPC_SHRL_QB:
15821                check_dsp(ctx);
15822                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15823                break;
15824            case OPC_SHRLV_QB:
15825                check_dsp(ctx);
15826                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15827                break;
15828            case OPC_SHRL_PH:
15829                check_dspr2(ctx);
15830                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15831                break;
15832            case OPC_SHRLV_PH:
15833                check_dspr2(ctx);
15834                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15835                break;
15836            case OPC_SHRA_QB:
15837                check_dspr2(ctx);
15838                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15839                break;
15840            case OPC_SHRA_R_QB:
15841                check_dspr2(ctx);
15842                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15843                break;
15844            case OPC_SHRAV_QB:
15845                check_dspr2(ctx);
15846                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15847                break;
15848            case OPC_SHRAV_R_QB:
15849                check_dspr2(ctx);
15850                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15851                break;
15852            case OPC_SHRA_PH:
15853                check_dsp(ctx);
15854                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15855                break;
15856            case OPC_SHRA_R_PH:
15857                check_dsp(ctx);
15858                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15859                break;
15860            case OPC_SHRAV_PH:
15861                check_dsp(ctx);
15862                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15863                break;
15864            case OPC_SHRAV_R_PH:
15865                check_dsp(ctx);
15866                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15867                break;
15868            case OPC_SHRA_R_W:
15869                check_dsp(ctx);
15870                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15871                break;
15872            case OPC_SHRAV_R_W:
15873                check_dsp(ctx);
15874                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15875                break;
15876            default:            /* Invalid */
15877                MIPS_INVAL("MASK SHLL.QB");
15878                generate_exception_end(ctx, EXCP_RI);
15879                break;
15880            }
15881            break;
15882        }
15883#ifdef TARGET_MIPS64
15884    case OPC_SHLL_OB_DSP:
15885        op2 = MASK_SHLL_OB(ctx->opcode);
15886        switch (op2) {
15887        case OPC_SHLL_PW:
15888            check_dsp(ctx);
15889            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15890            break;
15891        case OPC_SHLLV_PW:
15892            check_dsp(ctx);
15893            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15894            break;
15895        case OPC_SHLL_S_PW:
15896            check_dsp(ctx);
15897            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15898            break;
15899        case OPC_SHLLV_S_PW:
15900            check_dsp(ctx);
15901            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15902            break;
15903        case OPC_SHLL_OB:
15904            check_dsp(ctx);
15905            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15906            break;
15907        case OPC_SHLLV_OB:
15908            check_dsp(ctx);
15909            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15910            break;
15911        case OPC_SHLL_QH:
15912            check_dsp(ctx);
15913            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15914            break;
15915        case OPC_SHLLV_QH:
15916            check_dsp(ctx);
15917            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15918            break;
15919        case OPC_SHLL_S_QH:
15920            check_dsp(ctx);
15921            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15922            break;
15923        case OPC_SHLLV_S_QH:
15924            check_dsp(ctx);
15925            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15926            break;
15927        case OPC_SHRA_OB:
15928            check_dspr2(ctx);
15929            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15930            break;
15931        case OPC_SHRAV_OB:
15932            check_dspr2(ctx);
15933            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15934            break;
15935        case OPC_SHRA_R_OB:
15936            check_dspr2(ctx);
15937            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15938            break;
15939        case OPC_SHRAV_R_OB:
15940            check_dspr2(ctx);
15941            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15942            break;
15943        case OPC_SHRA_PW:
15944            check_dsp(ctx);
15945            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15946            break;
15947        case OPC_SHRAV_PW:
15948            check_dsp(ctx);
15949            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15950            break;
15951        case OPC_SHRA_R_PW:
15952            check_dsp(ctx);
15953            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15954            break;
15955        case OPC_SHRAV_R_PW:
15956            check_dsp(ctx);
15957            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15958            break;
15959        case OPC_SHRA_QH:
15960            check_dsp(ctx);
15961            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15962            break;
15963        case OPC_SHRAV_QH:
15964            check_dsp(ctx);
15965            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15966            break;
15967        case OPC_SHRA_R_QH:
15968            check_dsp(ctx);
15969            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15970            break;
15971        case OPC_SHRAV_R_QH:
15972            check_dsp(ctx);
15973            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15974            break;
15975        case OPC_SHRL_OB:
15976            check_dsp(ctx);
15977            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15978            break;
15979        case OPC_SHRLV_OB:
15980            check_dsp(ctx);
15981            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15982            break;
15983        case OPC_SHRL_QH:
15984            check_dspr2(ctx);
15985            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15986            break;
15987        case OPC_SHRLV_QH:
15988            check_dspr2(ctx);
15989            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15990            break;
15991        default:            /* Invalid */
15992            MIPS_INVAL("MASK SHLL.OB");
15993            generate_exception_end(ctx, EXCP_RI);
15994            break;
15995        }
15996        break;
15997#endif
15998    }
15999
16000    tcg_temp_free(t0);
16001    tcg_temp_free(v1_t);
16002    tcg_temp_free(v2_t);
16003}
16004
16005static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16006                                 int ret, int v1, int v2, int check_ret)
16007{
16008    TCGv_i32 t0;
16009    TCGv v1_t;
16010    TCGv v2_t;
16011
16012    if ((ret == 0) && (check_ret == 1)) {
16013        /* Treat as NOP. */
16014        return;
16015    }
16016
16017    t0 = tcg_temp_new_i32();
16018    v1_t = tcg_temp_new();
16019    v2_t = tcg_temp_new();
16020
16021    tcg_gen_movi_i32(t0, ret);
16022    gen_load_gpr(v1_t, v1);
16023    gen_load_gpr(v2_t, v2);
16024
16025    switch (op1) {
16026    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16027     * the same mask and op1. */
16028    case OPC_MULT_G_2E:
16029        check_dspr2(ctx);
16030        switch (op2) {
16031        case  OPC_MUL_PH:
16032            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16033            break;
16034        case  OPC_MUL_S_PH:
16035            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16036            break;
16037        case OPC_MULQ_S_W:
16038            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16039            break;
16040        case OPC_MULQ_RS_W:
16041            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16042            break;
16043        }
16044        break;
16045    case OPC_DPA_W_PH_DSP:
16046        switch (op2) {
16047        case OPC_DPAU_H_QBL:
16048            check_dsp(ctx);
16049            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16050            break;
16051        case OPC_DPAU_H_QBR:
16052            check_dsp(ctx);
16053            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16054            break;
16055        case OPC_DPSU_H_QBL:
16056            check_dsp(ctx);
16057            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16058            break;
16059        case OPC_DPSU_H_QBR:
16060            check_dsp(ctx);
16061            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16062            break;
16063        case OPC_DPA_W_PH:
16064            check_dspr2(ctx);
16065            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16066            break;
16067        case OPC_DPAX_W_PH:
16068            check_dspr2(ctx);
16069            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16070            break;
16071        case OPC_DPAQ_S_W_PH:
16072            check_dsp(ctx);
16073            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16074            break;
16075        case OPC_DPAQX_S_W_PH:
16076            check_dspr2(ctx);
16077            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16078            break;
16079        case OPC_DPAQX_SA_W_PH:
16080            check_dspr2(ctx);
16081            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16082            break;
16083        case OPC_DPS_W_PH:
16084            check_dspr2(ctx);
16085            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16086            break;
16087        case OPC_DPSX_W_PH:
16088            check_dspr2(ctx);
16089            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16090            break;
16091        case OPC_DPSQ_S_W_PH:
16092            check_dsp(ctx);
16093            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16094            break;
16095        case OPC_DPSQX_S_W_PH:
16096            check_dspr2(ctx);
16097            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16098            break;
16099        case OPC_DPSQX_SA_W_PH:
16100            check_dspr2(ctx);
16101            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16102            break;
16103        case OPC_MULSAQ_S_W_PH:
16104            check_dsp(ctx);
16105            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16106            break;
16107        case OPC_DPAQ_SA_L_W:
16108            check_dsp(ctx);
16109            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16110            break;
16111        case OPC_DPSQ_SA_L_W:
16112            check_dsp(ctx);
16113            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16114            break;
16115        case OPC_MAQ_S_W_PHL:
16116            check_dsp(ctx);
16117            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16118            break;
16119        case OPC_MAQ_S_W_PHR:
16120            check_dsp(ctx);
16121            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16122            break;
16123        case OPC_MAQ_SA_W_PHL:
16124            check_dsp(ctx);
16125            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16126            break;
16127        case OPC_MAQ_SA_W_PHR:
16128            check_dsp(ctx);
16129            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16130            break;
16131        case OPC_MULSA_W_PH:
16132            check_dspr2(ctx);
16133            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16134            break;
16135        }
16136        break;
16137#ifdef TARGET_MIPS64
16138    case OPC_DPAQ_W_QH_DSP:
16139        {
16140            int ac = ret & 0x03;
16141            tcg_gen_movi_i32(t0, ac);
16142
16143            switch (op2) {
16144            case OPC_DMADD:
16145                check_dsp(ctx);
16146                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16147                break;
16148            case OPC_DMADDU:
16149                check_dsp(ctx);
16150                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16151                break;
16152            case OPC_DMSUB:
16153                check_dsp(ctx);
16154                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16155                break;
16156            case OPC_DMSUBU:
16157                check_dsp(ctx);
16158                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16159                break;
16160            case OPC_DPA_W_QH:
16161                check_dspr2(ctx);
16162                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16163                break;
16164            case OPC_DPAQ_S_W_QH:
16165                check_dsp(ctx);
16166                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16167                break;
16168            case OPC_DPAQ_SA_L_PW:
16169                check_dsp(ctx);
16170                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16171                break;
16172            case OPC_DPAU_H_OBL:
16173                check_dsp(ctx);
16174                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16175                break;
16176            case OPC_DPAU_H_OBR:
16177                check_dsp(ctx);
16178                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16179                break;
16180            case OPC_DPS_W_QH:
16181                check_dspr2(ctx);
16182                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16183                break;
16184            case OPC_DPSQ_S_W_QH:
16185                check_dsp(ctx);
16186                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16187                break;
16188            case OPC_DPSQ_SA_L_PW:
16189                check_dsp(ctx);
16190                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16191                break;
16192            case OPC_DPSU_H_OBL:
16193                check_dsp(ctx);
16194                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16195                break;
16196            case OPC_DPSU_H_OBR:
16197                check_dsp(ctx);
16198                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16199                break;
16200            case OPC_MAQ_S_L_PWL:
16201                check_dsp(ctx);
16202                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16203                break;
16204            case OPC_MAQ_S_L_PWR:
16205                check_dsp(ctx);
16206                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16207                break;
16208            case OPC_MAQ_S_W_QHLL:
16209                check_dsp(ctx);
16210                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16211                break;
16212            case OPC_MAQ_SA_W_QHLL:
16213                check_dsp(ctx);
16214                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16215                break;
16216            case OPC_MAQ_S_W_QHLR:
16217                check_dsp(ctx);
16218                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16219                break;
16220            case OPC_MAQ_SA_W_QHLR:
16221                check_dsp(ctx);
16222                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16223                break;
16224            case OPC_MAQ_S_W_QHRL:
16225                check_dsp(ctx);
16226                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16227                break;
16228            case OPC_MAQ_SA_W_QHRL:
16229                check_dsp(ctx);
16230                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16231                break;
16232            case OPC_MAQ_S_W_QHRR:
16233                check_dsp(ctx);
16234                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16235                break;
16236            case OPC_MAQ_SA_W_QHRR:
16237                check_dsp(ctx);
16238                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16239                break;
16240            case OPC_MULSAQ_S_L_PW:
16241                check_dsp(ctx);
16242                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16243                break;
16244            case OPC_MULSAQ_S_W_QH:
16245                check_dsp(ctx);
16246                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16247                break;
16248            }
16249        }
16250        break;
16251#endif
16252    case OPC_ADDU_QB_DSP:
16253        switch (op2) {
16254        case OPC_MULEU_S_PH_QBL:
16255            check_dsp(ctx);
16256            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16257            break;
16258        case OPC_MULEU_S_PH_QBR:
16259            check_dsp(ctx);
16260            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16261            break;
16262        case OPC_MULQ_RS_PH:
16263            check_dsp(ctx);
16264            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16265            break;
16266        case OPC_MULEQ_S_W_PHL:
16267            check_dsp(ctx);
16268            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16269            break;
16270        case OPC_MULEQ_S_W_PHR:
16271            check_dsp(ctx);
16272            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16273            break;
16274        case OPC_MULQ_S_PH:
16275            check_dspr2(ctx);
16276            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16277            break;
16278        }
16279        break;
16280#ifdef TARGET_MIPS64
16281    case OPC_ADDU_OB_DSP:
16282        switch (op2) {
16283        case OPC_MULEQ_S_PW_QHL:
16284            check_dsp(ctx);
16285            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16286            break;
16287        case OPC_MULEQ_S_PW_QHR:
16288            check_dsp(ctx);
16289            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16290            break;
16291        case OPC_MULEU_S_QH_OBL:
16292            check_dsp(ctx);
16293            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16294            break;
16295        case OPC_MULEU_S_QH_OBR:
16296            check_dsp(ctx);
16297            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16298            break;
16299        case OPC_MULQ_RS_QH:
16300            check_dsp(ctx);
16301            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16302            break;
16303        }
16304        break;
16305#endif
16306    }
16307
16308    tcg_temp_free_i32(t0);
16309    tcg_temp_free(v1_t);
16310    tcg_temp_free(v2_t);
16311}
16312
16313static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16314                                int ret, int val)
16315{
16316    int16_t imm;
16317    TCGv t0;
16318    TCGv val_t;
16319
16320    if (ret == 0) {
16321        /* Treat as NOP. */
16322        return;
16323    }
16324
16325    t0 = tcg_temp_new();
16326    val_t = tcg_temp_new();
16327    gen_load_gpr(val_t, val);
16328
16329    switch (op1) {
16330    case OPC_ABSQ_S_PH_DSP:
16331        switch (op2) {
16332        case OPC_BITREV:
16333            check_dsp(ctx);
16334            gen_helper_bitrev(cpu_gpr[ret], val_t);
16335            break;
16336        case OPC_REPL_QB:
16337            check_dsp(ctx);
16338            {
16339                target_long result;
16340                imm = (ctx->opcode >> 16) & 0xFF;
16341                result = (uint32_t)imm << 24 |
16342                         (uint32_t)imm << 16 |
16343                         (uint32_t)imm << 8  |
16344                         (uint32_t)imm;
16345                result = (int32_t)result;
16346                tcg_gen_movi_tl(cpu_gpr[ret], result);
16347            }
16348            break;
16349        case OPC_REPLV_QB:
16350            check_dsp(ctx);
16351            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16352            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16353            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16354            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16355            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16356            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16357            break;
16358        case OPC_REPL_PH:
16359            check_dsp(ctx);
16360            {
16361                imm = (ctx->opcode >> 16) & 0x03FF;
16362                imm = (int16_t)(imm << 6) >> 6;
16363                tcg_gen_movi_tl(cpu_gpr[ret], \
16364                                (target_long)((int32_t)imm << 16 | \
16365                                (uint16_t)imm));
16366            }
16367            break;
16368        case OPC_REPLV_PH:
16369            check_dsp(ctx);
16370            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16371            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16372            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16373            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16374            break;
16375        }
16376        break;
16377#ifdef TARGET_MIPS64
16378    case OPC_ABSQ_S_QH_DSP:
16379        switch (op2) {
16380        case OPC_REPL_OB:
16381            check_dsp(ctx);
16382            {
16383                target_long temp;
16384
16385                imm = (ctx->opcode >> 16) & 0xFF;
16386                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16387                temp = (temp << 16) | temp;
16388                temp = (temp << 32) | temp;
16389                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16390                break;
16391            }
16392        case OPC_REPL_PW:
16393            check_dsp(ctx);
16394            {
16395                target_long temp;
16396
16397                imm = (ctx->opcode >> 16) & 0x03FF;
16398                imm = (int16_t)(imm << 6) >> 6;
16399                temp = ((target_long)imm << 32) \
16400                       | ((target_long)imm & 0xFFFFFFFF);
16401                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16402                break;
16403            }
16404        case OPC_REPL_QH:
16405            check_dsp(ctx);
16406            {
16407                target_long temp;
16408
16409                imm = (ctx->opcode >> 16) & 0x03FF;
16410                imm = (int16_t)(imm << 6) >> 6;
16411
16412                temp = ((uint64_t)(uint16_t)imm << 48) |
16413                       ((uint64_t)(uint16_t)imm << 32) |
16414                       ((uint64_t)(uint16_t)imm << 16) |
16415                       (uint64_t)(uint16_t)imm;
16416                tcg_gen_movi_tl(cpu_gpr[ret], temp);
16417                break;
16418            }
16419        case OPC_REPLV_OB:
16420            check_dsp(ctx);
16421            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16422            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16423            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16424            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16425            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16426            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16427            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16428            break;
16429        case OPC_REPLV_PW:
16430            check_dsp(ctx);
16431            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16432            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16433            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16434            break;
16435        case OPC_REPLV_QH:
16436            check_dsp(ctx);
16437            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16438            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16439            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16440            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16441            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16442            break;
16443        }
16444        break;
16445#endif
16446    }
16447    tcg_temp_free(t0);
16448    tcg_temp_free(val_t);
16449}
16450
16451static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16452                                     uint32_t op1, uint32_t op2,
16453                                     int ret, int v1, int v2, int check_ret)
16454{
16455    TCGv t1;
16456    TCGv v1_t;
16457    TCGv v2_t;
16458
16459    if ((ret == 0) && (check_ret == 1)) {
16460        /* Treat as NOP. */
16461        return;
16462    }
16463
16464    t1 = tcg_temp_new();
16465    v1_t = tcg_temp_new();
16466    v2_t = tcg_temp_new();
16467
16468    gen_load_gpr(v1_t, v1);
16469    gen_load_gpr(v2_t, v2);
16470
16471    switch (op1) {
16472    case OPC_CMPU_EQ_QB_DSP:
16473        switch (op2) {
16474        case OPC_CMPU_EQ_QB:
16475            check_dsp(ctx);
16476            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16477            break;
16478        case OPC_CMPU_LT_QB:
16479            check_dsp(ctx);
16480            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16481            break;
16482        case OPC_CMPU_LE_QB:
16483            check_dsp(ctx);
16484            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16485            break;
16486        case OPC_CMPGU_EQ_QB:
16487            check_dsp(ctx);
16488            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16489            break;
16490        case OPC_CMPGU_LT_QB:
16491            check_dsp(ctx);
16492            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16493            break;
16494        case OPC_CMPGU_LE_QB:
16495            check_dsp(ctx);
16496            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16497            break;
16498        case OPC_CMPGDU_EQ_QB:
16499            check_dspr2(ctx);
16500            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16501            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16502            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16503            tcg_gen_shli_tl(t1, t1, 24);
16504            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16505            break;
16506        case OPC_CMPGDU_LT_QB:
16507            check_dspr2(ctx);
16508            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16509            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16510            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16511            tcg_gen_shli_tl(t1, t1, 24);
16512            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16513            break;
16514        case OPC_CMPGDU_LE_QB:
16515            check_dspr2(ctx);
16516            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16517            tcg_gen_mov_tl(cpu_gpr[ret], t1);
16518            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16519            tcg_gen_shli_tl(t1, t1, 24);
16520            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16521            break;
16522        case OPC_CMP_EQ_PH:
16523            check_dsp(ctx);
16524            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16525            break;
16526        case OPC_CMP_LT_PH:
16527            check_dsp(ctx);
16528            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16529            break;
16530        case OPC_CMP_LE_PH:
16531            check_dsp(ctx);
16532            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16533            break;
16534        case OPC_PICK_QB:
16535            check_dsp(ctx);
16536            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16537            break;
16538        case OPC_PICK_PH:
16539            check_dsp(ctx);
16540            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16541            break;
16542        case OPC_PACKRL_PH:
16543            check_dsp(ctx);
16544            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16545            break;
16546        }
16547        break;
16548#ifdef TARGET_MIPS64
16549    case OPC_CMPU_EQ_OB_DSP:
16550        switch (op2) {
16551        case OPC_CMP_EQ_PW:
16552            check_dsp(ctx);
16553            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16554            break;
16555        case OPC_CMP_LT_PW:
16556            check_dsp(ctx);
16557            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16558            break;
16559        case OPC_CMP_LE_PW:
16560            check_dsp(ctx);
16561            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16562            break;
16563        case OPC_CMP_EQ_QH:
16564            check_dsp(ctx);
16565            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16566            break;
16567        case OPC_CMP_LT_QH:
16568            check_dsp(ctx);
16569            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16570            break;
16571        case OPC_CMP_LE_QH:
16572            check_dsp(ctx);
16573            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16574            break;
16575        case OPC_CMPGDU_EQ_OB:
16576            check_dspr2(ctx);
16577            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16578            break;
16579        case OPC_CMPGDU_LT_OB:
16580            check_dspr2(ctx);
16581            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16582            break;
16583        case OPC_CMPGDU_LE_OB:
16584            check_dspr2(ctx);
16585            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16586            break;
16587        case OPC_CMPGU_EQ_OB:
16588            check_dsp(ctx);
16589            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16590            break;
16591        case OPC_CMPGU_LT_OB:
16592            check_dsp(ctx);
16593            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16594            break;
16595        case OPC_CMPGU_LE_OB:
16596            check_dsp(ctx);
16597            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16598            break;
16599        case OPC_CMPU_EQ_OB:
16600            check_dsp(ctx);
16601            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16602            break;
16603        case OPC_CMPU_LT_OB:
16604            check_dsp(ctx);
16605            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16606            break;
16607        case OPC_CMPU_LE_OB:
16608            check_dsp(ctx);
16609            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16610            break;
16611        case OPC_PACKRL_PW:
16612            check_dsp(ctx);
16613            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16614            break;
16615        case OPC_PICK_OB:
16616            check_dsp(ctx);
16617            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16618            break;
16619        case OPC_PICK_PW:
16620            check_dsp(ctx);
16621            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16622            break;
16623        case OPC_PICK_QH:
16624            check_dsp(ctx);
16625            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16626            break;
16627        }
16628        break;
16629#endif
16630    }
16631
16632    tcg_temp_free(t1);
16633    tcg_temp_free(v1_t);
16634    tcg_temp_free(v2_t);
16635}
16636
16637static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16638                               uint32_t op1, int rt, int rs, int sa)
16639{
16640    TCGv t0;
16641
16642    check_dspr2(ctx);
16643
16644    if (rt == 0) {
16645        /* Treat as NOP. */
16646        return;
16647    }
16648
16649    t0 = tcg_temp_new();
16650    gen_load_gpr(t0, rs);
16651
16652    switch (op1) {
16653    case OPC_APPEND_DSP:
16654        switch (MASK_APPEND(ctx->opcode)) {
16655        case OPC_APPEND:
16656            if (sa != 0) {
16657                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16658            }
16659            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16660            break;
16661        case OPC_PREPEND:
16662            if (sa != 0) {
16663                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16664                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16665                tcg_gen_shli_tl(t0, t0, 32 - sa);
16666                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16667            }
16668            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16669            break;
16670        case OPC_BALIGN:
16671            sa &= 3;
16672            if (sa != 0 && sa != 2) {
16673                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16674                tcg_gen_ext32u_tl(t0, t0);
16675                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16676                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16677            }
16678            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16679            break;
16680        default:            /* Invalid */
16681            MIPS_INVAL("MASK APPEND");
16682            generate_exception_end(ctx, EXCP_RI);
16683            break;
16684        }
16685        break;
16686#ifdef TARGET_MIPS64
16687    case OPC_DAPPEND_DSP:
16688        switch (MASK_DAPPEND(ctx->opcode)) {
16689        case OPC_DAPPEND:
16690            if (sa != 0) {
16691                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16692            }
16693            break;
16694        case OPC_PREPENDD:
16695            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16696            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16697            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16698            break;
16699        case OPC_PREPENDW:
16700            if (sa != 0) {
16701                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16702                tcg_gen_shli_tl(t0, t0, 64 - sa);
16703                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16704            }
16705            break;
16706        case OPC_DBALIGN:
16707            sa &= 7;
16708            if (sa != 0 && sa != 2 && sa != 4) {
16709                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16710                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16711                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16712            }
16713            break;
16714        default:            /* Invalid */
16715            MIPS_INVAL("MASK DAPPEND");
16716            generate_exception_end(ctx, EXCP_RI);
16717            break;
16718        }
16719        break;
16720#endif
16721    }
16722    tcg_temp_free(t0);
16723}
16724
16725static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16726                                int ret, int v1, int v2, int check_ret)
16727
16728{
16729    TCGv t0;
16730    TCGv t1;
16731    TCGv v1_t;
16732    TCGv v2_t;
16733    int16_t imm;
16734
16735    if ((ret == 0) && (check_ret == 1)) {
16736        /* Treat as NOP. */
16737        return;
16738    }
16739
16740    t0 = tcg_temp_new();
16741    t1 = tcg_temp_new();
16742    v1_t = tcg_temp_new();
16743    v2_t = tcg_temp_new();
16744
16745    gen_load_gpr(v1_t, v1);
16746    gen_load_gpr(v2_t, v2);
16747
16748    switch (op1) {
16749    case OPC_EXTR_W_DSP:
16750        check_dsp(ctx);
16751        switch (op2) {
16752        case OPC_EXTR_W:
16753            tcg_gen_movi_tl(t0, v2);
16754            tcg_gen_movi_tl(t1, v1);
16755            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16756            break;
16757        case OPC_EXTR_R_W:
16758            tcg_gen_movi_tl(t0, v2);
16759            tcg_gen_movi_tl(t1, v1);
16760            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16761            break;
16762        case OPC_EXTR_RS_W:
16763            tcg_gen_movi_tl(t0, v2);
16764            tcg_gen_movi_tl(t1, v1);
16765            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16766            break;
16767        case OPC_EXTR_S_H:
16768            tcg_gen_movi_tl(t0, v2);
16769            tcg_gen_movi_tl(t1, v1);
16770            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16771            break;
16772        case OPC_EXTRV_S_H:
16773            tcg_gen_movi_tl(t0, v2);
16774            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16775            break;
16776        case OPC_EXTRV_W:
16777            tcg_gen_movi_tl(t0, v2);
16778            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16779            break;
16780        case OPC_EXTRV_R_W:
16781            tcg_gen_movi_tl(t0, v2);
16782            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16783            break;
16784        case OPC_EXTRV_RS_W:
16785            tcg_gen_movi_tl(t0, v2);
16786            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16787            break;
16788        case OPC_EXTP:
16789            tcg_gen_movi_tl(t0, v2);
16790            tcg_gen_movi_tl(t1, v1);
16791            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16792            break;
16793        case OPC_EXTPV:
16794            tcg_gen_movi_tl(t0, v2);
16795            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16796            break;
16797        case OPC_EXTPDP:
16798            tcg_gen_movi_tl(t0, v2);
16799            tcg_gen_movi_tl(t1, v1);
16800            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16801            break;
16802        case OPC_EXTPDPV:
16803            tcg_gen_movi_tl(t0, v2);
16804            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16805            break;
16806        case OPC_SHILO:
16807            imm = (ctx->opcode >> 20) & 0x3F;
16808            tcg_gen_movi_tl(t0, ret);
16809            tcg_gen_movi_tl(t1, imm);
16810            gen_helper_shilo(t0, t1, cpu_env);
16811            break;
16812        case OPC_SHILOV:
16813            tcg_gen_movi_tl(t0, ret);
16814            gen_helper_shilo(t0, v1_t, cpu_env);
16815            break;
16816        case OPC_MTHLIP:
16817            tcg_gen_movi_tl(t0, ret);
16818            gen_helper_mthlip(t0, v1_t, cpu_env);
16819            break;
16820        case OPC_WRDSP:
16821            imm = (ctx->opcode >> 11) & 0x3FF;
16822            tcg_gen_movi_tl(t0, imm);
16823            gen_helper_wrdsp(v1_t, t0, cpu_env);
16824            break;
16825        case OPC_RDDSP:
16826            imm = (ctx->opcode >> 16) & 0x03FF;
16827            tcg_gen_movi_tl(t0, imm);
16828            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16829            break;
16830        }
16831        break;
16832#ifdef TARGET_MIPS64
16833    case OPC_DEXTR_W_DSP:
16834        check_dsp(ctx);
16835        switch (op2) {
16836        case OPC_DMTHLIP:
16837            tcg_gen_movi_tl(t0, ret);
16838            gen_helper_dmthlip(v1_t, t0, cpu_env);
16839            break;
16840        case OPC_DSHILO:
16841            {
16842                int shift = (ctx->opcode >> 19) & 0x7F;
16843                int ac = (ctx->opcode >> 11) & 0x03;
16844                tcg_gen_movi_tl(t0, shift);
16845                tcg_gen_movi_tl(t1, ac);
16846                gen_helper_dshilo(t0, t1, cpu_env);
16847                break;
16848            }
16849        case OPC_DSHILOV:
16850            {
16851                int ac = (ctx->opcode >> 11) & 0x03;
16852                tcg_gen_movi_tl(t0, ac);
16853                gen_helper_dshilo(v1_t, t0, cpu_env);
16854                break;
16855            }
16856        case OPC_DEXTP:
16857            tcg_gen_movi_tl(t0, v2);
16858            tcg_gen_movi_tl(t1, v1);
16859
16860            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16861            break;
16862        case OPC_DEXTPV:
16863            tcg_gen_movi_tl(t0, v2);
16864            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16865            break;
16866        case OPC_DEXTPDP:
16867            tcg_gen_movi_tl(t0, v2);
16868            tcg_gen_movi_tl(t1, v1);
16869            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16870            break;
16871        case OPC_DEXTPDPV:
16872            tcg_gen_movi_tl(t0, v2);
16873            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16874            break;
16875        case OPC_DEXTR_L:
16876            tcg_gen_movi_tl(t0, v2);
16877            tcg_gen_movi_tl(t1, v1);
16878            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16879            break;
16880        case OPC_DEXTR_R_L:
16881            tcg_gen_movi_tl(t0, v2);
16882            tcg_gen_movi_tl(t1, v1);
16883            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16884            break;
16885        case OPC_DEXTR_RS_L:
16886            tcg_gen_movi_tl(t0, v2);
16887            tcg_gen_movi_tl(t1, v1);
16888            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16889            break;
16890        case OPC_DEXTR_W:
16891            tcg_gen_movi_tl(t0, v2);
16892            tcg_gen_movi_tl(t1, v1);
16893            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16894            break;
16895        case OPC_DEXTR_R_W:
16896            tcg_gen_movi_tl(t0, v2);
16897            tcg_gen_movi_tl(t1, v1);
16898            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16899            break;
16900        case OPC_DEXTR_RS_W:
16901            tcg_gen_movi_tl(t0, v2);
16902            tcg_gen_movi_tl(t1, v1);
16903            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16904            break;
16905        case OPC_DEXTR_S_H:
16906            tcg_gen_movi_tl(t0, v2);
16907            tcg_gen_movi_tl(t1, v1);
16908            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16909            break;
16910        case OPC_DEXTRV_S_H:
16911            tcg_gen_movi_tl(t0, v2);
16912            tcg_gen_movi_tl(t1, v1);
16913            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16914            break;
16915        case OPC_DEXTRV_L:
16916            tcg_gen_movi_tl(t0, v2);
16917            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16918            break;
16919        case OPC_DEXTRV_R_L:
16920            tcg_gen_movi_tl(t0, v2);
16921            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16922            break;
16923        case OPC_DEXTRV_RS_L:
16924            tcg_gen_movi_tl(t0, v2);
16925            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16926            break;
16927        case OPC_DEXTRV_W:
16928            tcg_gen_movi_tl(t0, v2);
16929            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16930            break;
16931        case OPC_DEXTRV_R_W:
16932            tcg_gen_movi_tl(t0, v2);
16933            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16934            break;
16935        case OPC_DEXTRV_RS_W:
16936            tcg_gen_movi_tl(t0, v2);
16937            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16938            break;
16939        }
16940        break;
16941#endif
16942    }
16943
16944    tcg_temp_free(t0);
16945    tcg_temp_free(t1);
16946    tcg_temp_free(v1_t);
16947    tcg_temp_free(v2_t);
16948}
16949
16950/* End MIPSDSP functions. */
16951
16952static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16953{
16954    int rs, rt, rd, sa;
16955    uint32_t op1, op2;
16956
16957    rs = (ctx->opcode >> 21) & 0x1f;
16958    rt = (ctx->opcode >> 16) & 0x1f;
16959    rd = (ctx->opcode >> 11) & 0x1f;
16960    sa = (ctx->opcode >> 6) & 0x1f;
16961
16962    op1 = MASK_SPECIAL(ctx->opcode);
16963    switch (op1) {
16964    case OPC_LSA:
16965        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16966        break;
16967    case OPC_MULT ... OPC_DIVU:
16968        op2 = MASK_R6_MULDIV(ctx->opcode);
16969        switch (op2) {
16970        case R6_OPC_MUL:
16971        case R6_OPC_MUH:
16972        case R6_OPC_MULU:
16973        case R6_OPC_MUHU:
16974        case R6_OPC_DIV:
16975        case R6_OPC_MOD:
16976        case R6_OPC_DIVU:
16977        case R6_OPC_MODU:
16978            gen_r6_muldiv(ctx, op2, rd, rs, rt);
16979            break;
16980        default:
16981            MIPS_INVAL("special_r6 muldiv");
16982            generate_exception_end(ctx, EXCP_RI);
16983            break;
16984        }
16985        break;
16986    case OPC_SELEQZ:
16987    case OPC_SELNEZ:
16988        gen_cond_move(ctx, op1, rd, rs, rt);
16989        break;
16990    case R6_OPC_CLO:
16991    case R6_OPC_CLZ:
16992        if (rt == 0 && sa == 1) {
16993            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16994               We need additionally to check other fields */
16995            gen_cl(ctx, op1, rd, rs);
16996        } else {
16997            generate_exception_end(ctx, EXCP_RI);
16998        }
16999        break;
17000    case R6_OPC_SDBBP:
17001        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17002            gen_helper_do_semihosting(cpu_env);
17003        } else {
17004            if (ctx->hflags & MIPS_HFLAG_SBRI) {
17005                generate_exception_end(ctx, EXCP_RI);
17006            } else {
17007                generate_exception_end(ctx, EXCP_DBp);
17008            }
17009        }
17010        break;
17011#if defined(TARGET_MIPS64)
17012    case OPC_DLSA:
17013        check_mips_64(ctx);
17014        gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
17015        break;
17016    case R6_OPC_DCLO:
17017    case R6_OPC_DCLZ:
17018        if (rt == 0 && sa == 1) {
17019            /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17020               We need additionally to check other fields */
17021            check_mips_64(ctx);
17022            gen_cl(ctx, op1, rd, rs);
17023        } else {
17024            generate_exception_end(ctx, EXCP_RI);
17025        }
17026        break;
17027    case OPC_DMULT ... OPC_DDIVU:
17028        op2 = MASK_R6_MULDIV(ctx->opcode);
17029        switch (op2) {
17030        case R6_OPC_DMUL:
17031        case R6_OPC_DMUH:
17032        case R6_OPC_DMULU:
17033        case R6_OPC_DMUHU:
17034        case R6_OPC_DDIV:
17035        case R6_OPC_DMOD:
17036        case R6_OPC_DDIVU:
17037        case R6_OPC_DMODU:
17038            check_mips_64(ctx);
17039            gen_r6_muldiv(ctx, op2, rd, rs, rt);
17040            break;
17041        default:
17042            MIPS_INVAL("special_r6 muldiv");
17043            generate_exception_end(ctx, EXCP_RI);
17044            break;
17045        }
17046        break;
17047#endif
17048    default:            /* Invalid */
17049        MIPS_INVAL("special_r6");
17050        generate_exception_end(ctx, EXCP_RI);
17051        break;
17052    }
17053}
17054
17055static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17056{
17057    int rs, rt, rd, sa;
17058    uint32_t op1;
17059
17060    rs = (ctx->opcode >> 21) & 0x1f;
17061    rt = (ctx->opcode >> 16) & 0x1f;
17062    rd = (ctx->opcode >> 11) & 0x1f;
17063    sa = (ctx->opcode >> 6) & 0x1f;
17064
17065    op1 = MASK_SPECIAL(ctx->opcode);
17066    switch (op1) {
17067    case OPC_MOVN:         /* Conditional move */
17068    case OPC_MOVZ:
17069        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17070                   INSN_LOONGSON2E | INSN_LOONGSON2F);
17071        gen_cond_move(ctx, op1, rd, rs, rt);
17072        break;
17073    case OPC_MFHI:          /* Move from HI/LO */
17074    case OPC_MFLO:
17075        gen_HILO(ctx, op1, rs & 3, rd);
17076        break;
17077    case OPC_MTHI:
17078    case OPC_MTLO:          /* Move to HI/LO */
17079        gen_HILO(ctx, op1, rd & 3, rs);
17080        break;
17081    case OPC_MOVCI:
17082        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17083        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17084            check_cp1_enabled(ctx);
17085            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17086                      (ctx->opcode >> 16) & 1);
17087        } else {
17088            generate_exception_err(ctx, EXCP_CpU, 1);
17089        }
17090        break;
17091    case OPC_MULT:
17092    case OPC_MULTU:
17093        if (sa) {
17094            check_insn(ctx, INSN_VR54XX);
17095            op1 = MASK_MUL_VR54XX(ctx->opcode);
17096            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17097        } else {
17098            gen_muldiv(ctx, op1, rd & 3, rs, rt);
17099        }
17100        break;
17101    case OPC_DIV:
17102    case OPC_DIVU:
17103        gen_muldiv(ctx, op1, 0, rs, rt);
17104        break;
17105#if defined(TARGET_MIPS64)
17106    case OPC_DMULT ... OPC_DDIVU:
17107        check_insn(ctx, ISA_MIPS3);
17108        check_mips_64(ctx);
17109        gen_muldiv(ctx, op1, 0, rs, rt);
17110        break;
17111#endif
17112    case OPC_JR:
17113        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17114        break;
17115    case OPC_SPIM:
17116#ifdef MIPS_STRICT_STANDARD
17117        MIPS_INVAL("SPIM");
17118        generate_exception_end(ctx, EXCP_RI);
17119#else
17120        /* Implemented as RI exception for now. */
17121        MIPS_INVAL("spim (unofficial)");
17122        generate_exception_end(ctx, EXCP_RI);
17123#endif
17124        break;
17125    default:            /* Invalid */
17126        MIPS_INVAL("special_legacy");
17127        generate_exception_end(ctx, EXCP_RI);
17128        break;
17129    }
17130}
17131
17132static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
17133{
17134    int rs, rt, rd, sa;
17135    uint32_t op1;
17136
17137    rs = (ctx->opcode >> 21) & 0x1f;
17138    rt = (ctx->opcode >> 16) & 0x1f;
17139    rd = (ctx->opcode >> 11) & 0x1f;
17140    sa = (ctx->opcode >> 6) & 0x1f;
17141
17142    op1 = MASK_SPECIAL(ctx->opcode);
17143    switch (op1) {
17144    case OPC_SLL:          /* Shift with immediate */
17145        if (sa == 5 && rd == 0 &&
17146            rs == 0 && rt == 0) { /* PAUSE */
17147            if ((ctx->insn_flags & ISA_MIPS32R6) &&
17148                (ctx->hflags & MIPS_HFLAG_BMASK)) {
17149                generate_exception_end(ctx, EXCP_RI);
17150                break;
17151            }
17152        }
17153        /* Fallthrough */
17154    case OPC_SRA:
17155        gen_shift_imm(ctx, op1, rd, rt, sa);
17156        break;
17157    case OPC_SRL:
17158        switch ((ctx->opcode >> 21) & 0x1f) {
17159        case 1:
17160            /* rotr is decoded as srl on non-R2 CPUs */
17161            if (ctx->insn_flags & ISA_MIPS32R2) {
17162                op1 = OPC_ROTR;
17163            }
17164            /* Fallthrough */
17165        case 0:
17166            gen_shift_imm(ctx, op1, rd, rt, sa);
17167            break;
17168        default:
17169            generate_exception_end(ctx, EXCP_RI);
17170            break;
17171        }
17172        break;
17173    case OPC_ADD ... OPC_SUBU:
17174        gen_arith(ctx, op1, rd, rs, rt);
17175        break;
17176    case OPC_SLLV:         /* Shifts */
17177    case OPC_SRAV:
17178        gen_shift(ctx, op1, rd, rs, rt);
17179        break;
17180    case OPC_SRLV:
17181        switch ((ctx->opcode >> 6) & 0x1f) {
17182        case 1:
17183            /* rotrv is decoded as srlv on non-R2 CPUs */
17184            if (ctx->insn_flags & ISA_MIPS32R2) {
17185                op1 = OPC_ROTRV;
17186            }
17187            /* Fallthrough */
17188        case 0:
17189            gen_shift(ctx, op1, rd, rs, rt);
17190            break;
17191        default:
17192            generate_exception_end(ctx, EXCP_RI);
17193            break;
17194        }
17195        break;
17196    case OPC_SLT:          /* Set on less than */
17197    case OPC_SLTU:
17198        gen_slt(ctx, op1, rd, rs, rt);
17199        break;
17200    case OPC_AND:          /* Logic*/
17201    case OPC_OR:
17202    case OPC_NOR:
17203    case OPC_XOR:
17204        gen_logic(ctx, op1, rd, rs, rt);
17205        break;
17206    case OPC_JALR:
17207        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17208        break;
17209    case OPC_TGE ... OPC_TEQ: /* Traps */
17210    case OPC_TNE:
17211        check_insn(ctx, ISA_MIPS2);
17212        gen_trap(ctx, op1, rs, rt, -1);
17213        break;
17214    case OPC_LSA: /* OPC_PMON */
17215        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17216            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17217            decode_opc_special_r6(env, ctx);
17218        } else {
17219            /* Pmon entry point, also R4010 selsl */
17220#ifdef MIPS_STRICT_STANDARD
17221            MIPS_INVAL("PMON / selsl");
17222            generate_exception_end(ctx, EXCP_RI);
17223#else
17224            gen_helper_0e0i(pmon, sa);
17225#endif
17226        }
17227        break;
17228    case OPC_SYSCALL:
17229        generate_exception_end(ctx, EXCP_SYSCALL);
17230        break;
17231    case OPC_BREAK:
17232        generate_exception_end(ctx, EXCP_BREAK);
17233        break;
17234    case OPC_SYNC:
17235        check_insn(ctx, ISA_MIPS2);
17236        gen_sync(extract32(ctx->opcode, 6, 5));
17237        break;
17238
17239#if defined(TARGET_MIPS64)
17240        /* MIPS64 specific opcodes */
17241    case OPC_DSLL:
17242    case OPC_DSRA:
17243    case OPC_DSLL32:
17244    case OPC_DSRA32:
17245        check_insn(ctx, ISA_MIPS3);
17246        check_mips_64(ctx);
17247        gen_shift_imm(ctx, op1, rd, rt, sa);
17248        break;
17249    case OPC_DSRL:
17250        switch ((ctx->opcode >> 21) & 0x1f) {
17251        case 1:
17252            /* drotr is decoded as dsrl on non-R2 CPUs */
17253            if (ctx->insn_flags & ISA_MIPS32R2) {
17254                op1 = OPC_DROTR;
17255            }
17256            /* Fallthrough */
17257        case 0:
17258            check_insn(ctx, ISA_MIPS3);
17259            check_mips_64(ctx);
17260            gen_shift_imm(ctx, op1, rd, rt, sa);
17261            break;
17262        default:
17263            generate_exception_end(ctx, EXCP_RI);
17264            break;
17265        }
17266        break;
17267    case OPC_DSRL32:
17268        switch ((ctx->opcode >> 21) & 0x1f) {
17269        case 1:
17270            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17271            if (ctx->insn_flags & ISA_MIPS32R2) {
17272                op1 = OPC_DROTR32;
17273            }
17274            /* Fallthrough */
17275        case 0:
17276            check_insn(ctx, ISA_MIPS3);
17277            check_mips_64(ctx);
17278            gen_shift_imm(ctx, op1, rd, rt, sa);
17279            break;
17280        default:
17281            generate_exception_end(ctx, EXCP_RI);
17282            break;
17283        }
17284        break;
17285    case OPC_DADD ... OPC_DSUBU:
17286        check_insn(ctx, ISA_MIPS3);
17287        check_mips_64(ctx);
17288        gen_arith(ctx, op1, rd, rs, rt);
17289        break;
17290    case OPC_DSLLV:
17291    case OPC_DSRAV:
17292        check_insn(ctx, ISA_MIPS3);
17293        check_mips_64(ctx);
17294        gen_shift(ctx, op1, rd, rs, rt);
17295        break;
17296    case OPC_DSRLV:
17297        switch ((ctx->opcode >> 6) & 0x1f) {
17298        case 1:
17299            /* drotrv is decoded as dsrlv on non-R2 CPUs */
17300            if (ctx->insn_flags & ISA_MIPS32R2) {
17301                op1 = OPC_DROTRV;
17302            }
17303            /* Fallthrough */
17304        case 0:
17305            check_insn(ctx, ISA_MIPS3);
17306            check_mips_64(ctx);
17307            gen_shift(ctx, op1, rd, rs, rt);
17308            break;
17309        default:
17310            generate_exception_end(ctx, EXCP_RI);
17311            break;
17312        }
17313        break;
17314    case OPC_DLSA:
17315        if ((ctx->insn_flags & ISA_MIPS32R6) ||
17316            (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17317            decode_opc_special_r6(env, ctx);
17318        }
17319        break;
17320#endif
17321    default:
17322        if (ctx->insn_flags & ISA_MIPS32R6) {
17323            decode_opc_special_r6(env, ctx);
17324        } else {
17325            decode_opc_special_legacy(env, ctx);
17326        }
17327    }
17328}
17329
17330static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17331{
17332    int rs, rt, rd;
17333    uint32_t op1;
17334
17335    check_insn_opc_removed(ctx, ISA_MIPS32R6);
17336
17337    rs = (ctx->opcode >> 21) & 0x1f;
17338    rt = (ctx->opcode >> 16) & 0x1f;
17339    rd = (ctx->opcode >> 11) & 0x1f;
17340
17341    op1 = MASK_SPECIAL2(ctx->opcode);
17342    switch (op1) {
17343    case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17344    case OPC_MSUB ... OPC_MSUBU:
17345        check_insn(ctx, ISA_MIPS32);
17346        gen_muldiv(ctx, op1, rd & 3, rs, rt);
17347        break;
17348    case OPC_MUL:
17349        gen_arith(ctx, op1, rd, rs, rt);
17350        break;
17351    case OPC_DIV_G_2F:
17352    case OPC_DIVU_G_2F:
17353    case OPC_MULT_G_2F:
17354    case OPC_MULTU_G_2F:
17355    case OPC_MOD_G_2F:
17356    case OPC_MODU_G_2F:
17357        check_insn(ctx, INSN_LOONGSON2F);
17358        gen_loongson_integer(ctx, op1, rd, rs, rt);
17359        break;
17360    case OPC_CLO:
17361    case OPC_CLZ:
17362        check_insn(ctx, ISA_MIPS32);
17363        gen_cl(ctx, op1, rd, rs);
17364        break;
17365    case OPC_SDBBP:
17366        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17367            gen_helper_do_semihosting(cpu_env);
17368        } else {
17369            /* XXX: not clear which exception should be raised
17370             *      when in debug mode...
17371             */
17372            check_insn(ctx, ISA_MIPS32);
17373            generate_exception_end(ctx, EXCP_DBp);
17374        }
17375        break;
17376#if defined(TARGET_MIPS64)
17377    case OPC_DCLO:
17378    case OPC_DCLZ:
17379        check_insn(ctx, ISA_MIPS64);
17380        check_mips_64(ctx);
17381        gen_cl(ctx, op1, rd, rs);
17382        break;
17383    case OPC_DMULT_G_2F:
17384    case OPC_DMULTU_G_2F:
17385    case OPC_DDIV_G_2F:
17386    case OPC_DDIVU_G_2F:
17387    case OPC_DMOD_G_2F:
17388    case OPC_DMODU_G_2F:
17389        check_insn(ctx, INSN_LOONGSON2F);
17390        gen_loongson_integer(ctx, op1, rd, rs, rt);
17391        break;
17392#endif
17393    default:            /* Invalid */
17394        MIPS_INVAL("special2_legacy");
17395        generate_exception_end(ctx, EXCP_RI);
17396        break;
17397    }
17398}
17399
17400static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17401{
17402    int rs, rt, rd, sa;
17403    uint32_t op1, op2;
17404    int16_t imm;
17405
17406    rs = (ctx->opcode >> 21) & 0x1f;
17407    rt = (ctx->opcode >> 16) & 0x1f;
17408    rd = (ctx->opcode >> 11) & 0x1f;
17409    sa = (ctx->opcode >> 6) & 0x1f;
17410    imm = (int16_t)ctx->opcode >> 7;
17411
17412    op1 = MASK_SPECIAL3(ctx->opcode);
17413    switch (op1) {
17414    case R6_OPC_PREF:
17415        if (rt >= 24) {
17416            /* hint codes 24-31 are reserved and signal RI */
17417            generate_exception_end(ctx, EXCP_RI);
17418        }
17419        /* Treat as NOP. */
17420        break;
17421    case R6_OPC_CACHE:
17422        check_cp0_enabled(ctx);
17423        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17424            gen_cache_operation(ctx, rt, rs, imm);
17425        }
17426        break;
17427    case R6_OPC_SC:
17428        gen_st_cond(ctx, op1, rt, rs, imm);
17429        break;
17430    case R6_OPC_LL:
17431        gen_ld(ctx, op1, rt, rs, imm);
17432        break;
17433    case OPC_BSHFL:
17434        {
17435            if (rd == 0) {
17436                /* Treat as NOP. */
17437                break;
17438            }
17439            op2 = MASK_BSHFL(ctx->opcode);
17440            switch (op2) {
17441            case OPC_ALIGN ... OPC_ALIGN_END:
17442                gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17443                break;
17444            case OPC_BITSWAP:
17445                gen_bitswap(ctx, op2, rd, rt);
17446                break;
17447            }
17448        }
17449        break;
17450#if defined(TARGET_MIPS64)
17451    case R6_OPC_SCD:
17452        gen_st_cond(ctx, op1, rt, rs, imm);
17453        break;
17454    case R6_OPC_LLD:
17455        gen_ld(ctx, op1, rt, rs, imm);
17456        break;
17457    case OPC_DBSHFL:
17458        check_mips_64(ctx);
17459        {
17460            if (rd == 0) {
17461                /* Treat as NOP. */
17462                break;
17463            }
17464            op2 = MASK_DBSHFL(ctx->opcode);
17465            switch (op2) {
17466            case OPC_DALIGN ... OPC_DALIGN_END:
17467                gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17468                break;
17469            case OPC_DBITSWAP:
17470                gen_bitswap(ctx, op2, rd, rt);
17471                break;
17472            }
17473
17474        }
17475        break;
17476#endif
17477    default:            /* Invalid */
17478        MIPS_INVAL("special3_r6");
17479        generate_exception_end(ctx, EXCP_RI);
17480        break;
17481    }
17482}
17483
17484static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17485{
17486    int rs, rt, rd;
17487    uint32_t op1, op2;
17488
17489    rs = (ctx->opcode >> 21) & 0x1f;
17490    rt = (ctx->opcode >> 16) & 0x1f;
17491    rd = (ctx->opcode >> 11) & 0x1f;
17492
17493    op1 = MASK_SPECIAL3(ctx->opcode);
17494    switch (op1) {
17495    case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17496    case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17497    case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17498        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17499         * the same mask and op1. */
17500        if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17501            op2 = MASK_ADDUH_QB(ctx->opcode);
17502            switch (op2) {
17503            case OPC_ADDUH_QB:
17504            case OPC_ADDUH_R_QB:
17505            case OPC_ADDQH_PH:
17506            case OPC_ADDQH_R_PH:
17507            case OPC_ADDQH_W:
17508            case OPC_ADDQH_R_W:
17509            case OPC_SUBUH_QB:
17510            case OPC_SUBUH_R_QB:
17511            case OPC_SUBQH_PH:
17512            case OPC_SUBQH_R_PH:
17513            case OPC_SUBQH_W:
17514            case OPC_SUBQH_R_W:
17515                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17516                break;
17517            case OPC_MUL_PH:
17518            case OPC_MUL_S_PH:
17519            case OPC_MULQ_S_W:
17520            case OPC_MULQ_RS_W:
17521                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17522                break;
17523            default:
17524                MIPS_INVAL("MASK ADDUH.QB");
17525                generate_exception_end(ctx, EXCP_RI);
17526                break;
17527            }
17528        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17529            gen_loongson_integer(ctx, op1, rd, rs, rt);
17530        } else {
17531            generate_exception_end(ctx, EXCP_RI);
17532        }
17533        break;
17534    case OPC_LX_DSP:
17535        op2 = MASK_LX(ctx->opcode);
17536        switch (op2) {
17537#if defined(TARGET_MIPS64)
17538        case OPC_LDX:
17539#endif
17540        case OPC_LBUX:
17541        case OPC_LHX:
17542        case OPC_LWX:
17543            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17544            break;
17545        default:            /* Invalid */
17546            MIPS_INVAL("MASK LX");
17547            generate_exception_end(ctx, EXCP_RI);
17548            break;
17549        }
17550        break;
17551    case OPC_ABSQ_S_PH_DSP:
17552        op2 = MASK_ABSQ_S_PH(ctx->opcode);
17553        switch (op2) {
17554        case OPC_ABSQ_S_QB:
17555        case OPC_ABSQ_S_PH:
17556        case OPC_ABSQ_S_W:
17557        case OPC_PRECEQ_W_PHL:
17558        case OPC_PRECEQ_W_PHR:
17559        case OPC_PRECEQU_PH_QBL:
17560        case OPC_PRECEQU_PH_QBR:
17561        case OPC_PRECEQU_PH_QBLA:
17562        case OPC_PRECEQU_PH_QBRA:
17563        case OPC_PRECEU_PH_QBL:
17564        case OPC_PRECEU_PH_QBR:
17565        case OPC_PRECEU_PH_QBLA:
17566        case OPC_PRECEU_PH_QBRA:
17567            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17568            break;
17569        case OPC_BITREV:
17570        case OPC_REPL_QB:
17571        case OPC_REPLV_QB:
17572        case OPC_REPL_PH:
17573        case OPC_REPLV_PH:
17574            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17575            break;
17576        default:
17577            MIPS_INVAL("MASK ABSQ_S.PH");
17578            generate_exception_end(ctx, EXCP_RI);
17579            break;
17580        }
17581        break;
17582    case OPC_ADDU_QB_DSP:
17583        op2 = MASK_ADDU_QB(ctx->opcode);
17584        switch (op2) {
17585        case OPC_ADDQ_PH:
17586        case OPC_ADDQ_S_PH:
17587        case OPC_ADDQ_S_W:
17588        case OPC_ADDU_QB:
17589        case OPC_ADDU_S_QB:
17590        case OPC_ADDU_PH:
17591        case OPC_ADDU_S_PH:
17592        case OPC_SUBQ_PH:
17593        case OPC_SUBQ_S_PH:
17594        case OPC_SUBQ_S_W:
17595        case OPC_SUBU_QB:
17596        case OPC_SUBU_S_QB:
17597        case OPC_SUBU_PH:
17598        case OPC_SUBU_S_PH:
17599        case OPC_ADDSC:
17600        case OPC_ADDWC:
17601        case OPC_MODSUB:
17602        case OPC_RADDU_W_QB:
17603            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17604            break;
17605        case OPC_MULEU_S_PH_QBL:
17606        case OPC_MULEU_S_PH_QBR:
17607        case OPC_MULQ_RS_PH:
17608        case OPC_MULEQ_S_W_PHL:
17609        case OPC_MULEQ_S_W_PHR:
17610        case OPC_MULQ_S_PH:
17611            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17612            break;
17613        default:            /* Invalid */
17614            MIPS_INVAL("MASK ADDU.QB");
17615            generate_exception_end(ctx, EXCP_RI);
17616            break;
17617
17618        }
17619        break;
17620    case OPC_CMPU_EQ_QB_DSP:
17621        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17622        switch (op2) {
17623        case OPC_PRECR_SRA_PH_W:
17624        case OPC_PRECR_SRA_R_PH_W:
17625            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17626            break;
17627        case OPC_PRECR_QB_PH:
17628        case OPC_PRECRQ_QB_PH:
17629        case OPC_PRECRQ_PH_W:
17630        case OPC_PRECRQ_RS_PH_W:
17631        case OPC_PRECRQU_S_QB_PH:
17632            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17633            break;
17634        case OPC_CMPU_EQ_QB:
17635        case OPC_CMPU_LT_QB:
17636        case OPC_CMPU_LE_QB:
17637        case OPC_CMP_EQ_PH:
17638        case OPC_CMP_LT_PH:
17639        case OPC_CMP_LE_PH:
17640            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17641            break;
17642        case OPC_CMPGU_EQ_QB:
17643        case OPC_CMPGU_LT_QB:
17644        case OPC_CMPGU_LE_QB:
17645        case OPC_CMPGDU_EQ_QB:
17646        case OPC_CMPGDU_LT_QB:
17647        case OPC_CMPGDU_LE_QB:
17648        case OPC_PICK_QB:
17649        case OPC_PICK_PH:
17650        case OPC_PACKRL_PH:
17651            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17652            break;
17653        default:            /* Invalid */
17654            MIPS_INVAL("MASK CMPU.EQ.QB");
17655            generate_exception_end(ctx, EXCP_RI);
17656            break;
17657        }
17658        break;
17659    case OPC_SHLL_QB_DSP:
17660        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17661        break;
17662    case OPC_DPA_W_PH_DSP:
17663        op2 = MASK_DPA_W_PH(ctx->opcode);
17664        switch (op2) {
17665        case OPC_DPAU_H_QBL:
17666        case OPC_DPAU_H_QBR:
17667        case OPC_DPSU_H_QBL:
17668        case OPC_DPSU_H_QBR:
17669        case OPC_DPA_W_PH:
17670        case OPC_DPAX_W_PH:
17671        case OPC_DPAQ_S_W_PH:
17672        case OPC_DPAQX_S_W_PH:
17673        case OPC_DPAQX_SA_W_PH:
17674        case OPC_DPS_W_PH:
17675        case OPC_DPSX_W_PH:
17676        case OPC_DPSQ_S_W_PH:
17677        case OPC_DPSQX_S_W_PH:
17678        case OPC_DPSQX_SA_W_PH:
17679        case OPC_MULSAQ_S_W_PH:
17680        case OPC_DPAQ_SA_L_W:
17681        case OPC_DPSQ_SA_L_W:
17682        case OPC_MAQ_S_W_PHL:
17683        case OPC_MAQ_S_W_PHR:
17684        case OPC_MAQ_SA_W_PHL:
17685        case OPC_MAQ_SA_W_PHR:
17686        case OPC_MULSA_W_PH:
17687            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17688            break;
17689        default:            /* Invalid */
17690            MIPS_INVAL("MASK DPAW.PH");
17691            generate_exception_end(ctx, EXCP_RI);
17692            break;
17693        }
17694        break;
17695    case OPC_INSV_DSP:
17696        op2 = MASK_INSV(ctx->opcode);
17697        switch (op2) {
17698        case OPC_INSV:
17699            check_dsp(ctx);
17700            {
17701                TCGv t0, t1;
17702
17703                if (rt == 0) {
17704                    break;
17705                }
17706
17707                t0 = tcg_temp_new();
17708                t1 = tcg_temp_new();
17709
17710                gen_load_gpr(t0, rt);
17711                gen_load_gpr(t1, rs);
17712
17713                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17714
17715                tcg_temp_free(t0);
17716                tcg_temp_free(t1);
17717                break;
17718            }
17719        default:            /* Invalid */
17720            MIPS_INVAL("MASK INSV");
17721            generate_exception_end(ctx, EXCP_RI);
17722            break;
17723        }
17724        break;
17725    case OPC_APPEND_DSP:
17726        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17727        break;
17728    case OPC_EXTR_W_DSP:
17729        op2 = MASK_EXTR_W(ctx->opcode);
17730        switch (op2) {
17731        case OPC_EXTR_W:
17732        case OPC_EXTR_R_W:
17733        case OPC_EXTR_RS_W:
17734        case OPC_EXTR_S_H:
17735        case OPC_EXTRV_S_H:
17736        case OPC_EXTRV_W:
17737        case OPC_EXTRV_R_W:
17738        case OPC_EXTRV_RS_W:
17739        case OPC_EXTP:
17740        case OPC_EXTPV:
17741        case OPC_EXTPDP:
17742        case OPC_EXTPDPV:
17743            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17744            break;
17745        case OPC_RDDSP:
17746            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17747            break;
17748        case OPC_SHILO:
17749        case OPC_SHILOV:
17750        case OPC_MTHLIP:
17751        case OPC_WRDSP:
17752            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17753            break;
17754        default:            /* Invalid */
17755            MIPS_INVAL("MASK EXTR.W");
17756            generate_exception_end(ctx, EXCP_RI);
17757            break;
17758        }
17759        break;
17760#if defined(TARGET_MIPS64)
17761    case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17762    case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17763    case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17764        check_insn(ctx, INSN_LOONGSON2E);
17765        gen_loongson_integer(ctx, op1, rd, rs, rt);
17766        break;
17767    case OPC_ABSQ_S_QH_DSP:
17768        op2 = MASK_ABSQ_S_QH(ctx->opcode);
17769        switch (op2) {
17770        case OPC_PRECEQ_L_PWL:
17771        case OPC_PRECEQ_L_PWR:
17772        case OPC_PRECEQ_PW_QHL:
17773        case OPC_PRECEQ_PW_QHR:
17774        case OPC_PRECEQ_PW_QHLA:
17775        case OPC_PRECEQ_PW_QHRA:
17776        case OPC_PRECEQU_QH_OBL:
17777        case OPC_PRECEQU_QH_OBR:
17778        case OPC_PRECEQU_QH_OBLA:
17779        case OPC_PRECEQU_QH_OBRA:
17780        case OPC_PRECEU_QH_OBL:
17781        case OPC_PRECEU_QH_OBR:
17782        case OPC_PRECEU_QH_OBLA:
17783        case OPC_PRECEU_QH_OBRA:
17784        case OPC_ABSQ_S_OB:
17785        case OPC_ABSQ_S_PW:
17786        case OPC_ABSQ_S_QH:
17787            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17788            break;
17789        case OPC_REPL_OB:
17790        case OPC_REPL_PW:
17791        case OPC_REPL_QH:
17792        case OPC_REPLV_OB:
17793        case OPC_REPLV_PW:
17794        case OPC_REPLV_QH:
17795            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17796            break;
17797        default:            /* Invalid */
17798            MIPS_INVAL("MASK ABSQ_S.QH");
17799            generate_exception_end(ctx, EXCP_RI);
17800            break;
17801        }
17802        break;
17803    case OPC_ADDU_OB_DSP:
17804        op2 = MASK_ADDU_OB(ctx->opcode);
17805        switch (op2) {
17806        case OPC_RADDU_L_OB:
17807        case OPC_SUBQ_PW:
17808        case OPC_SUBQ_S_PW:
17809        case OPC_SUBQ_QH:
17810        case OPC_SUBQ_S_QH:
17811        case OPC_SUBU_OB:
17812        case OPC_SUBU_S_OB:
17813        case OPC_SUBU_QH:
17814        case OPC_SUBU_S_QH:
17815        case OPC_SUBUH_OB:
17816        case OPC_SUBUH_R_OB:
17817        case OPC_ADDQ_PW:
17818        case OPC_ADDQ_S_PW:
17819        case OPC_ADDQ_QH:
17820        case OPC_ADDQ_S_QH:
17821        case OPC_ADDU_OB:
17822        case OPC_ADDU_S_OB:
17823        case OPC_ADDU_QH:
17824        case OPC_ADDU_S_QH:
17825        case OPC_ADDUH_OB:
17826        case OPC_ADDUH_R_OB:
17827            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17828            break;
17829        case OPC_MULEQ_S_PW_QHL:
17830        case OPC_MULEQ_S_PW_QHR:
17831        case OPC_MULEU_S_QH_OBL:
17832        case OPC_MULEU_S_QH_OBR:
17833        case OPC_MULQ_RS_QH:
17834            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17835            break;
17836        default:            /* Invalid */
17837            MIPS_INVAL("MASK ADDU.OB");
17838            generate_exception_end(ctx, EXCP_RI);
17839            break;
17840        }
17841        break;
17842    case OPC_CMPU_EQ_OB_DSP:
17843        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17844        switch (op2) {
17845        case OPC_PRECR_SRA_QH_PW:
17846        case OPC_PRECR_SRA_R_QH_PW:
17847            /* Return value is rt. */
17848            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17849            break;
17850        case OPC_PRECR_OB_QH:
17851        case OPC_PRECRQ_OB_QH:
17852        case OPC_PRECRQ_PW_L:
17853        case OPC_PRECRQ_QH_PW:
17854        case OPC_PRECRQ_RS_QH_PW:
17855        case OPC_PRECRQU_S_OB_QH:
17856            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17857            break;
17858        case OPC_CMPU_EQ_OB:
17859        case OPC_CMPU_LT_OB:
17860        case OPC_CMPU_LE_OB:
17861        case OPC_CMP_EQ_QH:
17862        case OPC_CMP_LT_QH:
17863        case OPC_CMP_LE_QH:
17864        case OPC_CMP_EQ_PW:
17865        case OPC_CMP_LT_PW:
17866        case OPC_CMP_LE_PW:
17867            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17868            break;
17869        case OPC_CMPGDU_EQ_OB:
17870        case OPC_CMPGDU_LT_OB:
17871        case OPC_CMPGDU_LE_OB:
17872        case OPC_CMPGU_EQ_OB:
17873        case OPC_CMPGU_LT_OB:
17874        case OPC_CMPGU_LE_OB:
17875        case OPC_PACKRL_PW:
17876        case OPC_PICK_OB:
17877        case OPC_PICK_PW:
17878        case OPC_PICK_QH:
17879            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17880            break;
17881        default:            /* Invalid */
17882            MIPS_INVAL("MASK CMPU_EQ.OB");
17883            generate_exception_end(ctx, EXCP_RI);
17884            break;
17885        }
17886        break;
17887    case OPC_DAPPEND_DSP:
17888        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17889        break;
17890    case OPC_DEXTR_W_DSP:
17891        op2 = MASK_DEXTR_W(ctx->opcode);
17892        switch (op2) {
17893        case OPC_DEXTP:
17894        case OPC_DEXTPDP:
17895        case OPC_DEXTPDPV:
17896        case OPC_DEXTPV:
17897        case OPC_DEXTR_L:
17898        case OPC_DEXTR_R_L:
17899        case OPC_DEXTR_RS_L:
17900        case OPC_DEXTR_W:
17901        case OPC_DEXTR_R_W:
17902        case OPC_DEXTR_RS_W:
17903        case OPC_DEXTR_S_H:
17904        case OPC_DEXTRV_L:
17905        case OPC_DEXTRV_R_L:
17906        case OPC_DEXTRV_RS_L:
17907        case OPC_DEXTRV_S_H:
17908        case OPC_DEXTRV_W:
17909        case OPC_DEXTRV_R_W:
17910        case OPC_DEXTRV_RS_W:
17911            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17912            break;
17913        case OPC_DMTHLIP:
17914        case OPC_DSHILO:
17915        case OPC_DSHILOV:
17916            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17917            break;
17918        default:            /* Invalid */
17919            MIPS_INVAL("MASK EXTR.W");
17920            generate_exception_end(ctx, EXCP_RI);
17921            break;
17922        }
17923        break;
17924    case OPC_DPAQ_W_QH_DSP:
17925        op2 = MASK_DPAQ_W_QH(ctx->opcode);
17926        switch (op2) {
17927        case OPC_DPAU_H_OBL:
17928        case OPC_DPAU_H_OBR:
17929        case OPC_DPSU_H_OBL:
17930        case OPC_DPSU_H_OBR:
17931        case OPC_DPA_W_QH:
17932        case OPC_DPAQ_S_W_QH:
17933        case OPC_DPS_W_QH:
17934        case OPC_DPSQ_S_W_QH:
17935        case OPC_MULSAQ_S_W_QH:
17936        case OPC_DPAQ_SA_L_PW:
17937        case OPC_DPSQ_SA_L_PW:
17938        case OPC_MULSAQ_S_L_PW:
17939            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17940            break;
17941        case OPC_MAQ_S_W_QHLL:
17942        case OPC_MAQ_S_W_QHLR:
17943        case OPC_MAQ_S_W_QHRL:
17944        case OPC_MAQ_S_W_QHRR:
17945        case OPC_MAQ_SA_W_QHLL:
17946        case OPC_MAQ_SA_W_QHLR:
17947        case OPC_MAQ_SA_W_QHRL:
17948        case OPC_MAQ_SA_W_QHRR:
17949        case OPC_MAQ_S_L_PWL:
17950        case OPC_MAQ_S_L_PWR:
17951        case OPC_DMADD:
17952        case OPC_DMADDU:
17953        case OPC_DMSUB:
17954        case OPC_DMSUBU:
17955            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17956            break;
17957        default:            /* Invalid */
17958            MIPS_INVAL("MASK DPAQ.W.QH");
17959            generate_exception_end(ctx, EXCP_RI);
17960            break;
17961        }
17962        break;
17963    case OPC_DINSV_DSP:
17964        op2 = MASK_INSV(ctx->opcode);
17965        switch (op2) {
17966        case OPC_DINSV:
17967        {
17968            TCGv t0, t1;
17969
17970            if (rt == 0) {
17971                break;
17972            }
17973            check_dsp(ctx);
17974
17975            t0 = tcg_temp_new();
17976            t1 = tcg_temp_new();
17977
17978            gen_load_gpr(t0, rt);
17979            gen_load_gpr(t1, rs);
17980
17981            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17982
17983            tcg_temp_free(t0);
17984            tcg_temp_free(t1);
17985            break;
17986        }
17987        default:            /* Invalid */
17988            MIPS_INVAL("MASK DINSV");
17989            generate_exception_end(ctx, EXCP_RI);
17990            break;
17991        }
17992        break;
17993    case OPC_SHLL_OB_DSP:
17994        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17995        break;
17996#endif
17997    default:            /* Invalid */
17998        MIPS_INVAL("special3_legacy");
17999        generate_exception_end(ctx, EXCP_RI);
18000        break;
18001    }
18002}
18003
18004static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18005{
18006    int rs, rt, rd, sa;
18007    uint32_t op1, op2;
18008
18009    rs = (ctx->opcode >> 21) & 0x1f;
18010    rt = (ctx->opcode >> 16) & 0x1f;
18011    rd = (ctx->opcode >> 11) & 0x1f;
18012    sa = (ctx->opcode >> 6) & 0x1f;
18013
18014    op1 = MASK_SPECIAL3(ctx->opcode);
18015    switch (op1) {
18016    case OPC_EXT:
18017    case OPC_INS:
18018        check_insn(ctx, ISA_MIPS32R2);
18019        gen_bitops(ctx, op1, rt, rs, sa, rd);
18020        break;
18021    case OPC_BSHFL:
18022        op2 = MASK_BSHFL(ctx->opcode);
18023        switch (op2) {
18024        case OPC_ALIGN ... OPC_ALIGN_END:
18025        case OPC_BITSWAP:
18026            check_insn(ctx, ISA_MIPS32R6);
18027            decode_opc_special3_r6(env, ctx);
18028            break;
18029        default:
18030            check_insn(ctx, ISA_MIPS32R2);
18031            gen_bshfl(ctx, op2, rt, rd);
18032            break;
18033        }
18034        break;
18035#if defined(TARGET_MIPS64)
18036    case OPC_DEXTM ... OPC_DEXT:
18037    case OPC_DINSM ... OPC_DINS:
18038        check_insn(ctx, ISA_MIPS64R2);
18039        check_mips_64(ctx);
18040        gen_bitops(ctx, op1, rt, rs, sa, rd);
18041        break;
18042    case OPC_DBSHFL:
18043        op2 = MASK_DBSHFL(ctx->opcode);
18044        switch (op2) {
18045        case OPC_DALIGN ... OPC_DALIGN_END:
18046        case OPC_DBITSWAP:
18047            check_insn(ctx, ISA_MIPS32R6);
18048            decode_opc_special3_r6(env, ctx);
18049            break;
18050        default:
18051            check_insn(ctx, ISA_MIPS64R2);
18052            check_mips_64(ctx);
18053            op2 = MASK_DBSHFL(ctx->opcode);
18054            gen_bshfl(ctx, op2, rt, rd);
18055            break;
18056        }
18057        break;
18058#endif
18059    case OPC_RDHWR:
18060        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
18061        break;
18062    case OPC_FORK:
18063        check_insn(ctx, ASE_MT);
18064        {
18065            TCGv t0 = tcg_temp_new();
18066            TCGv t1 = tcg_temp_new();
18067
18068            gen_load_gpr(t0, rt);
18069            gen_load_gpr(t1, rs);
18070            gen_helper_fork(t0, t1);
18071            tcg_temp_free(t0);
18072            tcg_temp_free(t1);
18073        }
18074        break;
18075    case OPC_YIELD:
18076        check_insn(ctx, ASE_MT);
18077        {
18078            TCGv t0 = tcg_temp_new();
18079
18080            gen_load_gpr(t0, rs);
18081            gen_helper_yield(t0, cpu_env, t0);
18082            gen_store_gpr(t0, rd);
18083            tcg_temp_free(t0);
18084        }
18085        break;
18086    default:
18087        if (ctx->insn_flags & ISA_MIPS32R6) {
18088            decode_opc_special3_r6(env, ctx);
18089        } else {
18090            decode_opc_special3_legacy(env, ctx);
18091        }
18092    }
18093}
18094
18095/* MIPS SIMD Architecture (MSA)  */
18096static inline int check_msa_access(DisasContext *ctx)
18097{
18098    if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18099                 !(ctx->hflags & MIPS_HFLAG_F64))) {
18100        generate_exception_end(ctx, EXCP_RI);
18101        return 0;
18102    }
18103
18104    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18105        if (ctx->insn_flags & ASE_MSA) {
18106            generate_exception_end(ctx, EXCP_MSADIS);
18107            return 0;
18108        } else {
18109            generate_exception_end(ctx, EXCP_RI);
18110            return 0;
18111        }
18112    }
18113    return 1;
18114}
18115
18116static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18117{
18118    /* generates tcg ops to check if any element is 0 */
18119    /* Note this function only works with MSA_WRLEN = 128 */
18120    uint64_t eval_zero_or_big = 0;
18121    uint64_t eval_big = 0;
18122    TCGv_i64 t0 = tcg_temp_new_i64();
18123    TCGv_i64 t1 = tcg_temp_new_i64();
18124    switch (df) {
18125    case DF_BYTE:
18126        eval_zero_or_big = 0x0101010101010101ULL;
18127        eval_big = 0x8080808080808080ULL;
18128        break;
18129    case DF_HALF:
18130        eval_zero_or_big = 0x0001000100010001ULL;
18131        eval_big = 0x8000800080008000ULL;
18132        break;
18133    case DF_WORD:
18134        eval_zero_or_big = 0x0000000100000001ULL;
18135        eval_big = 0x8000000080000000ULL;
18136        break;
18137    case DF_DOUBLE:
18138        eval_zero_or_big = 0x0000000000000001ULL;
18139        eval_big = 0x8000000000000000ULL;
18140        break;
18141    }
18142    tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18143    tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18144    tcg_gen_andi_i64(t0, t0, eval_big);
18145    tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18146    tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18147    tcg_gen_andi_i64(t1, t1, eval_big);
18148    tcg_gen_or_i64(t0, t0, t1);
18149    /* if all bits are zero then all elements are not zero */
18150    /* if some bit is non-zero then some element is zero */
18151    tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18152    tcg_gen_trunc_i64_tl(tresult, t0);
18153    tcg_temp_free_i64(t0);
18154    tcg_temp_free_i64(t1);
18155}
18156
18157static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18158{
18159    uint8_t df = (ctx->opcode >> 21) & 0x3;
18160    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18161    int64_t s16 = (int16_t)ctx->opcode;
18162
18163    check_msa_access(ctx);
18164
18165    if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
18166        generate_exception_end(ctx, EXCP_RI);
18167        return;
18168    }
18169    switch (op1) {
18170    case OPC_BZ_V:
18171    case OPC_BNZ_V:
18172        {
18173            TCGv_i64 t0 = tcg_temp_new_i64();
18174            tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18175            tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18176                    TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18177            tcg_gen_trunc_i64_tl(bcond, t0);
18178            tcg_temp_free_i64(t0);
18179        }
18180        break;
18181    case OPC_BZ_B:
18182    case OPC_BZ_H:
18183    case OPC_BZ_W:
18184    case OPC_BZ_D:
18185        gen_check_zero_element(bcond, df, wt);
18186        break;
18187    case OPC_BNZ_B:
18188    case OPC_BNZ_H:
18189    case OPC_BNZ_W:
18190    case OPC_BNZ_D:
18191        gen_check_zero_element(bcond, df, wt);
18192        tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18193        break;
18194    }
18195
18196    ctx->btarget = ctx->pc + (s16 << 2) + 4;
18197
18198    ctx->hflags |= MIPS_HFLAG_BC;
18199    ctx->hflags |= MIPS_HFLAG_BDS32;
18200}
18201
18202static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18203{
18204#define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18205    uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18206    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18207    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18208
18209    TCGv_i32 twd = tcg_const_i32(wd);
18210    TCGv_i32 tws = tcg_const_i32(ws);
18211    TCGv_i32 ti8 = tcg_const_i32(i8);
18212
18213    switch (MASK_MSA_I8(ctx->opcode)) {
18214    case OPC_ANDI_B:
18215        gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18216        break;
18217    case OPC_ORI_B:
18218        gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18219        break;
18220    case OPC_NORI_B:
18221        gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18222        break;
18223    case OPC_XORI_B:
18224        gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18225        break;
18226    case OPC_BMNZI_B:
18227        gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18228        break;
18229    case OPC_BMZI_B:
18230        gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18231        break;
18232    case OPC_BSELI_B:
18233        gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18234        break;
18235    case OPC_SHF_B:
18236    case OPC_SHF_H:
18237    case OPC_SHF_W:
18238        {
18239            uint8_t df = (ctx->opcode >> 24) & 0x3;
18240            if (df == DF_DOUBLE) {
18241                generate_exception_end(ctx, EXCP_RI);
18242            } else {
18243                TCGv_i32 tdf = tcg_const_i32(df);
18244                gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18245                tcg_temp_free_i32(tdf);
18246            }
18247        }
18248        break;
18249    default:
18250        MIPS_INVAL("MSA instruction");
18251        generate_exception_end(ctx, EXCP_RI);
18252        break;
18253    }
18254
18255    tcg_temp_free_i32(twd);
18256    tcg_temp_free_i32(tws);
18257    tcg_temp_free_i32(ti8);
18258}
18259
18260static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18261{
18262#define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18263    uint8_t df = (ctx->opcode >> 21) & 0x3;
18264    int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18265    uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18266    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18267    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18268
18269    TCGv_i32 tdf = tcg_const_i32(df);
18270    TCGv_i32 twd = tcg_const_i32(wd);
18271    TCGv_i32 tws = tcg_const_i32(ws);
18272    TCGv_i32 timm = tcg_temp_new_i32();
18273    tcg_gen_movi_i32(timm, u5);
18274
18275    switch (MASK_MSA_I5(ctx->opcode)) {
18276    case OPC_ADDVI_df:
18277        gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18278        break;
18279    case OPC_SUBVI_df:
18280        gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18281        break;
18282    case OPC_MAXI_S_df:
18283        tcg_gen_movi_i32(timm, s5);
18284        gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18285        break;
18286    case OPC_MAXI_U_df:
18287        gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18288        break;
18289    case OPC_MINI_S_df:
18290        tcg_gen_movi_i32(timm, s5);
18291        gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18292        break;
18293    case OPC_MINI_U_df:
18294        gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18295        break;
18296    case OPC_CEQI_df:
18297        tcg_gen_movi_i32(timm, s5);
18298        gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18299        break;
18300    case OPC_CLTI_S_df:
18301        tcg_gen_movi_i32(timm, s5);
18302        gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18303        break;
18304    case OPC_CLTI_U_df:
18305        gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18306        break;
18307    case OPC_CLEI_S_df:
18308        tcg_gen_movi_i32(timm, s5);
18309        gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18310        break;
18311    case OPC_CLEI_U_df:
18312        gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18313        break;
18314    case OPC_LDI_df:
18315        {
18316            int32_t s10 = sextract32(ctx->opcode, 11, 10);
18317            tcg_gen_movi_i32(timm, s10);
18318            gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18319        }
18320        break;
18321    default:
18322        MIPS_INVAL("MSA instruction");
18323        generate_exception_end(ctx, EXCP_RI);
18324        break;
18325    }
18326
18327    tcg_temp_free_i32(tdf);
18328    tcg_temp_free_i32(twd);
18329    tcg_temp_free_i32(tws);
18330    tcg_temp_free_i32(timm);
18331}
18332
18333static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18334{
18335#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18336    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18337    uint32_t df = 0, m = 0;
18338    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18339    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18340
18341    TCGv_i32 tdf;
18342    TCGv_i32 tm;
18343    TCGv_i32 twd;
18344    TCGv_i32 tws;
18345
18346    if ((dfm & 0x40) == 0x00) {
18347        m = dfm & 0x3f;
18348        df = DF_DOUBLE;
18349    } else if ((dfm & 0x60) == 0x40) {
18350        m = dfm & 0x1f;
18351        df = DF_WORD;
18352    } else if ((dfm & 0x70) == 0x60) {
18353        m = dfm & 0x0f;
18354        df = DF_HALF;
18355    } else if ((dfm & 0x78) == 0x70) {
18356        m = dfm & 0x7;
18357        df = DF_BYTE;
18358    } else {
18359        generate_exception_end(ctx, EXCP_RI);
18360        return;
18361    }
18362
18363    tdf = tcg_const_i32(df);
18364    tm  = tcg_const_i32(m);
18365    twd = tcg_const_i32(wd);
18366    tws = tcg_const_i32(ws);
18367
18368    switch (MASK_MSA_BIT(ctx->opcode)) {
18369    case OPC_SLLI_df:
18370        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18371        break;
18372    case OPC_SRAI_df:
18373        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18374        break;
18375    case OPC_SRLI_df:
18376        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18377        break;
18378    case OPC_BCLRI_df:
18379        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18380        break;
18381    case OPC_BSETI_df:
18382        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18383        break;
18384    case OPC_BNEGI_df:
18385        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18386        break;
18387    case OPC_BINSLI_df:
18388        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18389        break;
18390    case OPC_BINSRI_df:
18391        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18392        break;
18393    case OPC_SAT_S_df:
18394        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18395        break;
18396    case OPC_SAT_U_df:
18397        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18398        break;
18399    case OPC_SRARI_df:
18400        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18401        break;
18402    case OPC_SRLRI_df:
18403        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18404        break;
18405    default:
18406        MIPS_INVAL("MSA instruction");
18407        generate_exception_end(ctx, EXCP_RI);
18408        break;
18409    }
18410
18411    tcg_temp_free_i32(tdf);
18412    tcg_temp_free_i32(tm);
18413    tcg_temp_free_i32(twd);
18414    tcg_temp_free_i32(tws);
18415}
18416
18417static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18418{
18419#define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18420    uint8_t df = (ctx->opcode >> 21) & 0x3;
18421    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18422    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18423    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18424
18425    TCGv_i32 tdf = tcg_const_i32(df);
18426    TCGv_i32 twd = tcg_const_i32(wd);
18427    TCGv_i32 tws = tcg_const_i32(ws);
18428    TCGv_i32 twt = tcg_const_i32(wt);
18429
18430    switch (MASK_MSA_3R(ctx->opcode)) {
18431    case OPC_SLL_df:
18432        gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18433        break;
18434    case OPC_ADDV_df:
18435        gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18436        break;
18437    case OPC_CEQ_df:
18438        gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18439        break;
18440    case OPC_ADD_A_df:
18441        gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18442        break;
18443    case OPC_SUBS_S_df:
18444        gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18445        break;
18446    case OPC_MULV_df:
18447        gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18448        break;
18449    case OPC_SLD_df:
18450        gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18451        break;
18452    case OPC_VSHF_df:
18453        gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18454        break;
18455    case OPC_SRA_df:
18456        gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18457        break;
18458    case OPC_SUBV_df:
18459        gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18460        break;
18461    case OPC_ADDS_A_df:
18462        gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18463        break;
18464    case OPC_SUBS_U_df:
18465        gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18466        break;
18467    case OPC_MADDV_df:
18468        gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18469        break;
18470    case OPC_SPLAT_df:
18471        gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18472        break;
18473    case OPC_SRAR_df:
18474        gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18475        break;
18476    case OPC_SRL_df:
18477        gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18478        break;
18479    case OPC_MAX_S_df:
18480        gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18481        break;
18482    case OPC_CLT_S_df:
18483        gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18484        break;
18485    case OPC_ADDS_S_df:
18486        gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18487        break;
18488    case OPC_SUBSUS_U_df:
18489        gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18490        break;
18491    case OPC_MSUBV_df:
18492        gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18493        break;
18494    case OPC_PCKEV_df:
18495        gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18496        break;
18497    case OPC_SRLR_df:
18498        gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18499        break;
18500    case OPC_BCLR_df:
18501        gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18502        break;
18503    case OPC_MAX_U_df:
18504        gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18505        break;
18506    case OPC_CLT_U_df:
18507        gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18508        break;
18509    case OPC_ADDS_U_df:
18510        gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18511        break;
18512    case OPC_SUBSUU_S_df:
18513        gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18514        break;
18515    case OPC_PCKOD_df:
18516        gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18517        break;
18518    case OPC_BSET_df:
18519        gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18520        break;
18521    case OPC_MIN_S_df:
18522        gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18523        break;
18524    case OPC_CLE_S_df:
18525        gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18526        break;
18527    case OPC_AVE_S_df:
18528        gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18529        break;
18530    case OPC_ASUB_S_df:
18531        gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18532        break;
18533    case OPC_DIV_S_df:
18534        gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18535        break;
18536    case OPC_ILVL_df:
18537        gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18538        break;
18539    case OPC_BNEG_df:
18540        gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18541        break;
18542    case OPC_MIN_U_df:
18543        gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18544        break;
18545    case OPC_CLE_U_df:
18546        gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18547        break;
18548    case OPC_AVE_U_df:
18549        gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18550        break;
18551    case OPC_ASUB_U_df:
18552        gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18553        break;
18554    case OPC_DIV_U_df:
18555        gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18556        break;
18557    case OPC_ILVR_df:
18558        gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18559        break;
18560    case OPC_BINSL_df:
18561        gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18562        break;
18563    case OPC_MAX_A_df:
18564        gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18565        break;
18566    case OPC_AVER_S_df:
18567        gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18568        break;
18569    case OPC_MOD_S_df:
18570        gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18571        break;
18572    case OPC_ILVEV_df:
18573        gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18574        break;
18575    case OPC_BINSR_df:
18576        gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18577        break;
18578    case OPC_MIN_A_df:
18579        gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18580        break;
18581    case OPC_AVER_U_df:
18582        gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18583        break;
18584    case OPC_MOD_U_df:
18585        gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18586        break;
18587    case OPC_ILVOD_df:
18588        gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18589        break;
18590
18591    case OPC_DOTP_S_df:
18592    case OPC_DOTP_U_df:
18593    case OPC_DPADD_S_df:
18594    case OPC_DPADD_U_df:
18595    case OPC_DPSUB_S_df:
18596    case OPC_HADD_S_df:
18597    case OPC_DPSUB_U_df:
18598    case OPC_HADD_U_df:
18599    case OPC_HSUB_S_df:
18600    case OPC_HSUB_U_df:
18601        if (df == DF_BYTE) {
18602            generate_exception_end(ctx, EXCP_RI);
18603            break;
18604        }
18605        switch (MASK_MSA_3R(ctx->opcode)) {
18606        case OPC_DOTP_S_df:
18607            gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18608            break;
18609        case OPC_DOTP_U_df:
18610            gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18611            break;
18612        case OPC_DPADD_S_df:
18613            gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18614            break;
18615        case OPC_DPADD_U_df:
18616            gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18617            break;
18618        case OPC_DPSUB_S_df:
18619            gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18620            break;
18621        case OPC_HADD_S_df:
18622            gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18623            break;
18624        case OPC_DPSUB_U_df:
18625            gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18626            break;
18627        case OPC_HADD_U_df:
18628            gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18629            break;
18630        case OPC_HSUB_S_df:
18631            gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18632            break;
18633        case OPC_HSUB_U_df:
18634            gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18635            break;
18636        }
18637        break;
18638    default:
18639        MIPS_INVAL("MSA instruction");
18640        generate_exception_end(ctx, EXCP_RI);
18641        break;
18642    }
18643    tcg_temp_free_i32(twd);
18644    tcg_temp_free_i32(tws);
18645    tcg_temp_free_i32(twt);
18646    tcg_temp_free_i32(tdf);
18647}
18648
18649static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18650{
18651#define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18652    uint8_t source = (ctx->opcode >> 11) & 0x1f;
18653    uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18654    TCGv telm = tcg_temp_new();
18655    TCGv_i32 tsr = tcg_const_i32(source);
18656    TCGv_i32 tdt = tcg_const_i32(dest);
18657
18658    switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18659    case OPC_CTCMSA:
18660        gen_load_gpr(telm, source);
18661        gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18662        break;
18663    case OPC_CFCMSA:
18664        gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18665        gen_store_gpr(telm, dest);
18666        break;
18667    case OPC_MOVE_V:
18668        gen_helper_msa_move_v(cpu_env, tdt, tsr);
18669        break;
18670    default:
18671        MIPS_INVAL("MSA instruction");
18672        generate_exception_end(ctx, EXCP_RI);
18673        break;
18674    }
18675
18676    tcg_temp_free(telm);
18677    tcg_temp_free_i32(tdt);
18678    tcg_temp_free_i32(tsr);
18679}
18680
18681static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18682        uint32_t n)
18683{
18684#define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18685    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18686    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18687
18688    TCGv_i32 tws = tcg_const_i32(ws);
18689    TCGv_i32 twd = tcg_const_i32(wd);
18690    TCGv_i32 tn  = tcg_const_i32(n);
18691    TCGv_i32 tdf = tcg_const_i32(df);
18692
18693    switch (MASK_MSA_ELM(ctx->opcode)) {
18694    case OPC_SLDI_df:
18695        gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18696        break;
18697    case OPC_SPLATI_df:
18698        gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18699        break;
18700    case OPC_INSVE_df:
18701        gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18702        break;
18703    case OPC_COPY_S_df:
18704    case OPC_COPY_U_df:
18705    case OPC_INSERT_df:
18706#if !defined(TARGET_MIPS64)
18707        /* Double format valid only for MIPS64 */
18708        if (df == DF_DOUBLE) {
18709            generate_exception_end(ctx, EXCP_RI);
18710            break;
18711        }
18712#endif
18713        switch (MASK_MSA_ELM(ctx->opcode)) {
18714        case OPC_COPY_S_df:
18715            gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18716            break;
18717        case OPC_COPY_U_df:
18718            gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18719            break;
18720        case OPC_INSERT_df:
18721            gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18722            break;
18723        }
18724        break;
18725    default:
18726        MIPS_INVAL("MSA instruction");
18727        generate_exception_end(ctx, EXCP_RI);
18728    }
18729    tcg_temp_free_i32(twd);
18730    tcg_temp_free_i32(tws);
18731    tcg_temp_free_i32(tn);
18732    tcg_temp_free_i32(tdf);
18733}
18734
18735static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18736{
18737    uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18738    uint32_t df = 0, n = 0;
18739
18740    if ((dfn & 0x30) == 0x00) {
18741        n = dfn & 0x0f;
18742        df = DF_BYTE;
18743    } else if ((dfn & 0x38) == 0x20) {
18744        n = dfn & 0x07;
18745        df = DF_HALF;
18746    } else if ((dfn & 0x3c) == 0x30) {
18747        n = dfn & 0x03;
18748        df = DF_WORD;
18749    } else if ((dfn & 0x3e) == 0x38) {
18750        n = dfn & 0x01;
18751        df = DF_DOUBLE;
18752    } else if (dfn == 0x3E) {
18753        /* CTCMSA, CFCMSA, MOVE.V */
18754        gen_msa_elm_3e(env, ctx);
18755        return;
18756    } else {
18757        generate_exception_end(ctx, EXCP_RI);
18758        return;
18759    }
18760
18761    gen_msa_elm_df(env, ctx, df, n);
18762}
18763
18764static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18765{
18766#define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18767    uint8_t df = (ctx->opcode >> 21) & 0x1;
18768    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18769    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18770    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18771
18772    TCGv_i32 twd = tcg_const_i32(wd);
18773    TCGv_i32 tws = tcg_const_i32(ws);
18774    TCGv_i32 twt = tcg_const_i32(wt);
18775    TCGv_i32 tdf = tcg_temp_new_i32();
18776
18777    /* adjust df value for floating-point instruction */
18778    tcg_gen_movi_i32(tdf, df + 2);
18779
18780    switch (MASK_MSA_3RF(ctx->opcode)) {
18781    case OPC_FCAF_df:
18782        gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18783        break;
18784    case OPC_FADD_df:
18785        gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18786        break;
18787    case OPC_FCUN_df:
18788        gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18789        break;
18790    case OPC_FSUB_df:
18791        gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18792        break;
18793    case OPC_FCOR_df:
18794        gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18795        break;
18796    case OPC_FCEQ_df:
18797        gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18798        break;
18799    case OPC_FMUL_df:
18800        gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18801        break;
18802    case OPC_FCUNE_df:
18803        gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18804        break;
18805    case OPC_FCUEQ_df:
18806        gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18807        break;
18808    case OPC_FDIV_df:
18809        gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18810        break;
18811    case OPC_FCNE_df:
18812        gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18813        break;
18814    case OPC_FCLT_df:
18815        gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18816        break;
18817    case OPC_FMADD_df:
18818        gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18819        break;
18820    case OPC_MUL_Q_df:
18821        tcg_gen_movi_i32(tdf, df + 1);
18822        gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18823        break;
18824    case OPC_FCULT_df:
18825        gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18826        break;
18827    case OPC_FMSUB_df:
18828        gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18829        break;
18830    case OPC_MADD_Q_df:
18831        tcg_gen_movi_i32(tdf, df + 1);
18832        gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18833        break;
18834    case OPC_FCLE_df:
18835        gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18836        break;
18837    case OPC_MSUB_Q_df:
18838        tcg_gen_movi_i32(tdf, df + 1);
18839        gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18840        break;
18841    case OPC_FCULE_df:
18842        gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18843        break;
18844    case OPC_FEXP2_df:
18845        gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18846        break;
18847    case OPC_FSAF_df:
18848        gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18849        break;
18850    case OPC_FEXDO_df:
18851        gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18852        break;
18853    case OPC_FSUN_df:
18854        gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18855        break;
18856    case OPC_FSOR_df:
18857        gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18858        break;
18859    case OPC_FSEQ_df:
18860        gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18861        break;
18862    case OPC_FTQ_df:
18863        gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18864        break;
18865    case OPC_FSUNE_df:
18866        gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18867        break;
18868    case OPC_FSUEQ_df:
18869        gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18870        break;
18871    case OPC_FSNE_df:
18872        gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18873        break;
18874    case OPC_FSLT_df:
18875        gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18876        break;
18877    case OPC_FMIN_df:
18878        gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18879        break;
18880    case OPC_MULR_Q_df:
18881        tcg_gen_movi_i32(tdf, df + 1);
18882        gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18883        break;
18884    case OPC_FSULT_df:
18885        gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18886        break;
18887    case OPC_FMIN_A_df:
18888        gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18889        break;
18890    case OPC_MADDR_Q_df:
18891        tcg_gen_movi_i32(tdf, df + 1);
18892        gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18893        break;
18894    case OPC_FSLE_df:
18895        gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18896        break;
18897    case OPC_FMAX_df:
18898        gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18899        break;
18900    case OPC_MSUBR_Q_df:
18901        tcg_gen_movi_i32(tdf, df + 1);
18902        gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18903        break;
18904    case OPC_FSULE_df:
18905        gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18906        break;
18907    case OPC_FMAX_A_df:
18908        gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18909        break;
18910    default:
18911        MIPS_INVAL("MSA instruction");
18912        generate_exception_end(ctx, EXCP_RI);
18913        break;
18914    }
18915
18916    tcg_temp_free_i32(twd);
18917    tcg_temp_free_i32(tws);
18918    tcg_temp_free_i32(twt);
18919    tcg_temp_free_i32(tdf);
18920}
18921
18922static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18923{
18924#define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18925                            (op & (0x7 << 18)))
18926    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18927    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18928    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18929    uint8_t df = (ctx->opcode >> 16) & 0x3;
18930    TCGv_i32 twd = tcg_const_i32(wd);
18931    TCGv_i32 tws = tcg_const_i32(ws);
18932    TCGv_i32 twt = tcg_const_i32(wt);
18933    TCGv_i32 tdf = tcg_const_i32(df);
18934
18935    switch (MASK_MSA_2R(ctx->opcode)) {
18936    case OPC_FILL_df:
18937#if !defined(TARGET_MIPS64)
18938        /* Double format valid only for MIPS64 */
18939        if (df == DF_DOUBLE) {
18940            generate_exception_end(ctx, EXCP_RI);
18941            break;
18942        }
18943#endif
18944        gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18945        break;
18946    case OPC_PCNT_df:
18947        gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18948        break;
18949    case OPC_NLOC_df:
18950        gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18951        break;
18952    case OPC_NLZC_df:
18953        gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18954        break;
18955    default:
18956        MIPS_INVAL("MSA instruction");
18957        generate_exception_end(ctx, EXCP_RI);
18958        break;
18959    }
18960
18961    tcg_temp_free_i32(twd);
18962    tcg_temp_free_i32(tws);
18963    tcg_temp_free_i32(twt);
18964    tcg_temp_free_i32(tdf);
18965}
18966
18967static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18968{
18969#define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18970                            (op & (0xf << 17)))
18971    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18972    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18973    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18974    uint8_t df = (ctx->opcode >> 16) & 0x1;
18975    TCGv_i32 twd = tcg_const_i32(wd);
18976    TCGv_i32 tws = tcg_const_i32(ws);
18977    TCGv_i32 twt = tcg_const_i32(wt);
18978    /* adjust df value for floating-point instruction */
18979    TCGv_i32 tdf = tcg_const_i32(df + 2);
18980
18981    switch (MASK_MSA_2RF(ctx->opcode)) {
18982    case OPC_FCLASS_df:
18983        gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18984        break;
18985    case OPC_FTRUNC_S_df:
18986        gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18987        break;
18988    case OPC_FTRUNC_U_df:
18989        gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18990        break;
18991    case OPC_FSQRT_df:
18992        gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18993        break;
18994    case OPC_FRSQRT_df:
18995        gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18996        break;
18997    case OPC_FRCP_df:
18998        gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18999        break;
19000    case OPC_FRINT_df:
19001        gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19002        break;
19003    case OPC_FLOG2_df:
19004        gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19005        break;
19006    case OPC_FEXUPL_df:
19007        gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19008        break;
19009    case OPC_FEXUPR_df:
19010        gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19011        break;
19012    case OPC_FFQL_df:
19013        gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19014        break;
19015    case OPC_FFQR_df:
19016        gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19017        break;
19018    case OPC_FTINT_S_df:
19019        gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19020        break;
19021    case OPC_FTINT_U_df:
19022        gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19023        break;
19024    case OPC_FFINT_S_df:
19025        gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19026        break;
19027    case OPC_FFINT_U_df:
19028        gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19029        break;
19030    }
19031
19032    tcg_temp_free_i32(twd);
19033    tcg_temp_free_i32(tws);
19034    tcg_temp_free_i32(twt);
19035    tcg_temp_free_i32(tdf);
19036}
19037
19038static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19039{
19040#define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19041    uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19042    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19043    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19044    TCGv_i32 twd = tcg_const_i32(wd);
19045    TCGv_i32 tws = tcg_const_i32(ws);
19046    TCGv_i32 twt = tcg_const_i32(wt);
19047
19048    switch (MASK_MSA_VEC(ctx->opcode)) {
19049    case OPC_AND_V:
19050        gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19051        break;
19052    case OPC_OR_V:
19053        gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19054        break;
19055    case OPC_NOR_V:
19056        gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19057        break;
19058    case OPC_XOR_V:
19059        gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19060        break;
19061    case OPC_BMNZ_V:
19062        gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19063        break;
19064    case OPC_BMZ_V:
19065        gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19066        break;
19067    case OPC_BSEL_V:
19068        gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19069        break;
19070    default:
19071        MIPS_INVAL("MSA instruction");
19072        generate_exception_end(ctx, EXCP_RI);
19073        break;
19074    }
19075
19076    tcg_temp_free_i32(twd);
19077    tcg_temp_free_i32(tws);
19078    tcg_temp_free_i32(twt);
19079}
19080
19081static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19082{
19083    switch (MASK_MSA_VEC(ctx->opcode)) {
19084    case OPC_AND_V:
19085    case OPC_OR_V:
19086    case OPC_NOR_V:
19087    case OPC_XOR_V:
19088    case OPC_BMNZ_V:
19089    case OPC_BMZ_V:
19090    case OPC_BSEL_V:
19091        gen_msa_vec_v(env, ctx);
19092        break;
19093    case OPC_MSA_2R:
19094        gen_msa_2r(env, ctx);
19095        break;
19096    case OPC_MSA_2RF:
19097        gen_msa_2rf(env, ctx);
19098        break;
19099    default:
19100        MIPS_INVAL("MSA instruction");
19101        generate_exception_end(ctx, EXCP_RI);
19102        break;
19103    }
19104}
19105
19106static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19107{
19108    uint32_t opcode = ctx->opcode;
19109    check_insn(ctx, ASE_MSA);
19110    check_msa_access(ctx);
19111
19112    switch (MASK_MSA_MINOR(opcode)) {
19113    case OPC_MSA_I8_00:
19114    case OPC_MSA_I8_01:
19115    case OPC_MSA_I8_02:
19116        gen_msa_i8(env, ctx);
19117        break;
19118    case OPC_MSA_I5_06:
19119    case OPC_MSA_I5_07:
19120        gen_msa_i5(env, ctx);
19121        break;
19122    case OPC_MSA_BIT_09:
19123    case OPC_MSA_BIT_0A:
19124        gen_msa_bit(env, ctx);
19125        break;
19126    case OPC_MSA_3R_0D:
19127    case OPC_MSA_3R_0E:
19128    case OPC_MSA_3R_0F:
19129    case OPC_MSA_3R_10:
19130    case OPC_MSA_3R_11:
19131    case OPC_MSA_3R_12:
19132    case OPC_MSA_3R_13:
19133    case OPC_MSA_3R_14:
19134    case OPC_MSA_3R_15:
19135        gen_msa_3r(env, ctx);
19136        break;
19137    case OPC_MSA_ELM:
19138        gen_msa_elm(env, ctx);
19139        break;
19140    case OPC_MSA_3RF_1A:
19141    case OPC_MSA_3RF_1B:
19142    case OPC_MSA_3RF_1C:
19143        gen_msa_3rf(env, ctx);
19144        break;
19145    case OPC_MSA_VEC:
19146        gen_msa_vec(env, ctx);
19147        break;
19148    case OPC_LD_B:
19149    case OPC_LD_H:
19150    case OPC_LD_W:
19151    case OPC_LD_D:
19152    case OPC_ST_B:
19153    case OPC_ST_H:
19154    case OPC_ST_W:
19155    case OPC_ST_D:
19156        {
19157            int32_t s10 = sextract32(ctx->opcode, 16, 10);
19158            uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19159            uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19160            uint8_t df = (ctx->opcode >> 0) & 0x3;
19161
19162            TCGv_i32 twd = tcg_const_i32(wd);
19163            TCGv taddr = tcg_temp_new();
19164            gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19165
19166            switch (MASK_MSA_MINOR(opcode)) {
19167            case OPC_LD_B:
19168                gen_helper_msa_ld_b(cpu_env, twd, taddr);
19169                break;
19170            case OPC_LD_H:
19171                gen_helper_msa_ld_h(cpu_env, twd, taddr);
19172                break;
19173            case OPC_LD_W:
19174                gen_helper_msa_ld_w(cpu_env, twd, taddr);
19175                break;
19176            case OPC_LD_D:
19177                gen_helper_msa_ld_d(cpu_env, twd, taddr);
19178                break;
19179            case OPC_ST_B:
19180                gen_helper_msa_st_b(cpu_env, twd, taddr);
19181                break;
19182            case OPC_ST_H:
19183                gen_helper_msa_st_h(cpu_env, twd, taddr);
19184                break;
19185            case OPC_ST_W:
19186                gen_helper_msa_st_w(cpu_env, twd, taddr);
19187                break;
19188            case OPC_ST_D:
19189                gen_helper_msa_st_d(cpu_env, twd, taddr);
19190                break;
19191            }
19192
19193            tcg_temp_free_i32(twd);
19194            tcg_temp_free(taddr);
19195        }
19196        break;
19197    default:
19198        MIPS_INVAL("MSA instruction");
19199        generate_exception_end(ctx, EXCP_RI);
19200        break;
19201    }
19202
19203}
19204
19205static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19206{
19207    int32_t offset;
19208    int rs, rt, rd, sa;
19209    uint32_t op, op1;
19210    int16_t imm;
19211
19212    /* make sure instructions are on a word boundary */
19213    if (ctx->pc & 0x3) {
19214        env->CP0_BadVAddr = ctx->pc;
19215        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19216        return;
19217    }
19218
19219    /* Handle blikely not taken case */
19220    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19221        TCGLabel *l1 = gen_new_label();
19222
19223        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19224        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19225        gen_goto_tb(ctx, 1, ctx->pc + 4);
19226        gen_set_label(l1);
19227    }
19228
19229    op = MASK_OP_MAJOR(ctx->opcode);
19230    rs = (ctx->opcode >> 21) & 0x1f;
19231    rt = (ctx->opcode >> 16) & 0x1f;
19232    rd = (ctx->opcode >> 11) & 0x1f;
19233    sa = (ctx->opcode >> 6) & 0x1f;
19234    imm = (int16_t)ctx->opcode;
19235    switch (op) {
19236    case OPC_SPECIAL:
19237        decode_opc_special(env, ctx);
19238        break;
19239    case OPC_SPECIAL2:
19240        decode_opc_special2_legacy(env, ctx);
19241        break;
19242    case OPC_SPECIAL3:
19243        decode_opc_special3(env, ctx);
19244        break;
19245    case OPC_REGIMM:
19246        op1 = MASK_REGIMM(ctx->opcode);
19247        switch (op1) {
19248        case OPC_BLTZL: /* REGIMM branches */
19249        case OPC_BGEZL:
19250        case OPC_BLTZALL:
19251        case OPC_BGEZALL:
19252            check_insn(ctx, ISA_MIPS2);
19253            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19254            /* Fallthrough */
19255        case OPC_BLTZ:
19256        case OPC_BGEZ:
19257            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19258            break;
19259        case OPC_BLTZAL:
19260        case OPC_BGEZAL:
19261            if (ctx->insn_flags & ISA_MIPS32R6) {
19262                if (rs == 0) {
19263                    /* OPC_NAL, OPC_BAL */
19264                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19265                } else {
19266                    generate_exception_end(ctx, EXCP_RI);
19267                }
19268            } else {
19269                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19270            }
19271            break;
19272        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19273        case OPC_TNEI:
19274            check_insn(ctx, ISA_MIPS2);
19275            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19276            gen_trap(ctx, op1, rs, -1, imm);
19277            break;
19278        case OPC_SIGRIE:
19279            check_insn(ctx, ISA_MIPS32R6);
19280            generate_exception_end(ctx, EXCP_RI);
19281            break;
19282        case OPC_SYNCI:
19283            check_insn(ctx, ISA_MIPS32R2);
19284            /* Break the TB to be able to sync copied instructions
19285               immediately */
19286            ctx->bstate = BS_STOP;
19287            break;
19288        case OPC_BPOSGE32:    /* MIPS DSP branch */
19289#if defined(TARGET_MIPS64)
19290        case OPC_BPOSGE64:
19291#endif
19292            check_dsp(ctx);
19293            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19294            break;
19295#if defined(TARGET_MIPS64)
19296        case OPC_DAHI:
19297            check_insn(ctx, ISA_MIPS32R6);
19298            check_mips_64(ctx);
19299            if (rs != 0) {
19300                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19301            }
19302            break;
19303        case OPC_DATI:
19304            check_insn(ctx, ISA_MIPS32R6);
19305            check_mips_64(ctx);
19306            if (rs != 0) {
19307                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19308            }
19309            break;
19310#endif
19311        default:            /* Invalid */
19312            MIPS_INVAL("regimm");
19313            generate_exception_end(ctx, EXCP_RI);
19314            break;
19315        }
19316        break;
19317    case OPC_CP0:
19318        check_cp0_enabled(ctx);
19319        op1 = MASK_CP0(ctx->opcode);
19320        switch (op1) {
19321        case OPC_MFC0:
19322        case OPC_MTC0:
19323        case OPC_MFTR:
19324        case OPC_MTTR:
19325        case OPC_MFHC0:
19326        case OPC_MTHC0:
19327#if defined(TARGET_MIPS64)
19328        case OPC_DMFC0:
19329        case OPC_DMTC0:
19330#endif
19331#ifndef CONFIG_USER_ONLY
19332            gen_cp0(env, ctx, op1, rt, rd);
19333#endif /* !CONFIG_USER_ONLY */
19334            break;
19335        case OPC_C0_FIRST ... OPC_C0_LAST:
19336#ifndef CONFIG_USER_ONLY
19337            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19338#endif /* !CONFIG_USER_ONLY */
19339            break;
19340        case OPC_MFMC0:
19341#ifndef CONFIG_USER_ONLY
19342            {
19343                uint32_t op2;
19344                TCGv t0 = tcg_temp_new();
19345
19346                op2 = MASK_MFMC0(ctx->opcode);
19347                switch (op2) {
19348                case OPC_DMT:
19349                    check_insn(ctx, ASE_MT);
19350                    gen_helper_dmt(t0);
19351                    gen_store_gpr(t0, rt);
19352                    break;
19353                case OPC_EMT:
19354                    check_insn(ctx, ASE_MT);
19355                    gen_helper_emt(t0);
19356                    gen_store_gpr(t0, rt);
19357                    break;
19358                case OPC_DVPE:
19359                    check_insn(ctx, ASE_MT);
19360                    gen_helper_dvpe(t0, cpu_env);
19361                    gen_store_gpr(t0, rt);
19362                    break;
19363                case OPC_EVPE:
19364                    check_insn(ctx, ASE_MT);
19365                    gen_helper_evpe(t0, cpu_env);
19366                    gen_store_gpr(t0, rt);
19367                    break;
19368                case OPC_DVP:
19369                    check_insn(ctx, ISA_MIPS32R6);
19370                    if (ctx->vp) {
19371                        gen_helper_dvp(t0, cpu_env);
19372                        gen_store_gpr(t0, rt);
19373                    }
19374                    break;
19375                case OPC_EVP:
19376                    check_insn(ctx, ISA_MIPS32R6);
19377                    if (ctx->vp) {
19378                        gen_helper_evp(t0, cpu_env);
19379                        gen_store_gpr(t0, rt);
19380                    }
19381                    break;
19382                case OPC_DI:
19383                    check_insn(ctx, ISA_MIPS32R2);
19384                    save_cpu_state(ctx, 1);
19385                    gen_helper_di(t0, cpu_env);
19386                    gen_store_gpr(t0, rt);
19387                    /* Stop translation as we may have switched
19388                       the execution mode.  */
19389                    ctx->bstate = BS_STOP;
19390                    break;
19391                case OPC_EI:
19392                    check_insn(ctx, ISA_MIPS32R2);
19393                    save_cpu_state(ctx, 1);
19394                    gen_helper_ei(t0, cpu_env);
19395                    gen_store_gpr(t0, rt);
19396                    /* Stop translation as we may have switched
19397                       the execution mode.  */
19398                    ctx->bstate = BS_STOP;
19399                    break;
19400                default:            /* Invalid */
19401                    MIPS_INVAL("mfmc0");
19402                    generate_exception_end(ctx, EXCP_RI);
19403                    break;
19404                }
19405                tcg_temp_free(t0);
19406            }
19407#endif /* !CONFIG_USER_ONLY */
19408            break;
19409        case OPC_RDPGPR:
19410            check_insn(ctx, ISA_MIPS32R2);
19411            gen_load_srsgpr(rt, rd);
19412            break;
19413        case OPC_WRPGPR:
19414            check_insn(ctx, ISA_MIPS32R2);
19415            gen_store_srsgpr(rt, rd);
19416            break;
19417        default:
19418            MIPS_INVAL("cp0");
19419            generate_exception_end(ctx, EXCP_RI);
19420            break;
19421        }
19422        break;
19423    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19424        if (ctx->insn_flags & ISA_MIPS32R6) {
19425            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19426            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19427        } else {
19428            /* OPC_ADDI */
19429            /* Arithmetic with immediate opcode */
19430            gen_arith_imm(ctx, op, rt, rs, imm);
19431        }
19432        break;
19433    case OPC_ADDIU:
19434         gen_arith_imm(ctx, op, rt, rs, imm);
19435         break;
19436    case OPC_SLTI: /* Set on less than with immediate opcode */
19437    case OPC_SLTIU:
19438         gen_slt_imm(ctx, op, rt, rs, imm);
19439         break;
19440    case OPC_ANDI: /* Arithmetic with immediate opcode */
19441    case OPC_LUI: /* OPC_AUI */
19442    case OPC_ORI:
19443    case OPC_XORI:
19444         gen_logic_imm(ctx, op, rt, rs, imm);
19445         break;
19446    case OPC_J ... OPC_JAL: /* Jump */
19447         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19448         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19449         break;
19450    /* Branch */
19451    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19452        if (ctx->insn_flags & ISA_MIPS32R6) {
19453            if (rt == 0) {
19454                generate_exception_end(ctx, EXCP_RI);
19455                break;
19456            }
19457            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19458            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19459        } else {
19460            /* OPC_BLEZL */
19461            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19462        }
19463        break;
19464    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19465        if (ctx->insn_flags & ISA_MIPS32R6) {
19466            if (rt == 0) {
19467                generate_exception_end(ctx, EXCP_RI);
19468                break;
19469            }
19470            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19471            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19472        } else {
19473            /* OPC_BGTZL */
19474            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19475        }
19476        break;
19477    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19478        if (rt == 0) {
19479            /* OPC_BLEZ */
19480            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19481        } else {
19482            check_insn(ctx, ISA_MIPS32R6);
19483            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19484            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19485        }
19486        break;
19487    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19488        if (rt == 0) {
19489            /* OPC_BGTZ */
19490            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19491        } else {
19492            check_insn(ctx, ISA_MIPS32R6);
19493            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19494            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19495        }
19496        break;
19497    case OPC_BEQL:
19498    case OPC_BNEL:
19499        check_insn(ctx, ISA_MIPS2);
19500         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19501        /* Fallthrough */
19502    case OPC_BEQ:
19503    case OPC_BNE:
19504         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19505         break;
19506    case OPC_LL: /* Load and stores */
19507        check_insn(ctx, ISA_MIPS2);
19508        /* Fallthrough */
19509    case OPC_LWL:
19510    case OPC_LWR:
19511        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19512         /* Fallthrough */
19513    case OPC_LB ... OPC_LH:
19514    case OPC_LW ... OPC_LHU:
19515         gen_ld(ctx, op, rt, rs, imm);
19516         break;
19517    case OPC_SWL:
19518    case OPC_SWR:
19519        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19520        /* fall through */
19521    case OPC_SB ... OPC_SH:
19522    case OPC_SW:
19523         gen_st(ctx, op, rt, rs, imm);
19524         break;
19525    case OPC_SC:
19526        check_insn(ctx, ISA_MIPS2);
19527         check_insn_opc_removed(ctx, ISA_MIPS32R6);
19528         gen_st_cond(ctx, op, rt, rs, imm);
19529         break;
19530    case OPC_CACHE:
19531        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19532        check_cp0_enabled(ctx);
19533        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19534        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19535            gen_cache_operation(ctx, rt, rs, imm);
19536        }
19537        /* Treat as NOP. */
19538        break;
19539    case OPC_PREF:
19540        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19541        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19542        /* Treat as NOP. */
19543        break;
19544
19545    /* Floating point (COP1). */
19546    case OPC_LWC1:
19547    case OPC_LDC1:
19548    case OPC_SWC1:
19549    case OPC_SDC1:
19550        gen_cop1_ldst(ctx, op, rt, rs, imm);
19551        break;
19552
19553    case OPC_CP1:
19554        op1 = MASK_CP1(ctx->opcode);
19555
19556        switch (op1) {
19557        case OPC_MFHC1:
19558        case OPC_MTHC1:
19559            check_cp1_enabled(ctx);
19560            check_insn(ctx, ISA_MIPS32R2);
19561        case OPC_MFC1:
19562        case OPC_CFC1:
19563        case OPC_MTC1:
19564        case OPC_CTC1:
19565            check_cp1_enabled(ctx);
19566            gen_cp1(ctx, op1, rt, rd);
19567            break;
19568#if defined(TARGET_MIPS64)
19569        case OPC_DMFC1:
19570        case OPC_DMTC1:
19571            check_cp1_enabled(ctx);
19572            check_insn(ctx, ISA_MIPS3);
19573            check_mips_64(ctx);
19574            gen_cp1(ctx, op1, rt, rd);
19575            break;
19576#endif
19577        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19578            check_cp1_enabled(ctx);
19579            if (ctx->insn_flags & ISA_MIPS32R6) {
19580                /* OPC_BC1EQZ */
19581                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19582                                       rt, imm << 2, 4);
19583            } else {
19584                /* OPC_BC1ANY2 */
19585                check_cop1x(ctx);
19586                check_insn(ctx, ASE_MIPS3D);
19587                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19588                                    (rt >> 2) & 0x7, imm << 2);
19589            }
19590            break;
19591        case OPC_BC1NEZ:
19592            check_cp1_enabled(ctx);
19593            check_insn(ctx, ISA_MIPS32R6);
19594            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19595                                   rt, imm << 2, 4);
19596            break;
19597        case OPC_BC1ANY4:
19598            check_cp1_enabled(ctx);
19599            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19600            check_cop1x(ctx);
19601            check_insn(ctx, ASE_MIPS3D);
19602            /* fall through */
19603        case OPC_BC1:
19604            check_cp1_enabled(ctx);
19605            check_insn_opc_removed(ctx, ISA_MIPS32R6);
19606            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19607                                (rt >> 2) & 0x7, imm << 2);
19608            break;
19609        case OPC_PS_FMT:
19610            check_ps(ctx);
19611            /* fall through */
19612        case OPC_S_FMT:
19613        case OPC_D_FMT:
19614            check_cp1_enabled(ctx);
19615            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19616                       (imm >> 8) & 0x7);
19617            break;
19618        case OPC_W_FMT:
19619        case OPC_L_FMT:
19620        {
19621            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19622            check_cp1_enabled(ctx);
19623            if (ctx->insn_flags & ISA_MIPS32R6) {
19624                switch (r6_op) {
19625                case R6_OPC_CMP_AF_S:
19626                case R6_OPC_CMP_UN_S:
19627                case R6_OPC_CMP_EQ_S:
19628                case R6_OPC_CMP_UEQ_S:
19629                case R6_OPC_CMP_LT_S:
19630                case R6_OPC_CMP_ULT_S:
19631                case R6_OPC_CMP_LE_S:
19632                case R6_OPC_CMP_ULE_S:
19633                case R6_OPC_CMP_SAF_S:
19634                case R6_OPC_CMP_SUN_S:
19635                case R6_OPC_CMP_SEQ_S:
19636                case R6_OPC_CMP_SEUQ_S:
19637                case R6_OPC_CMP_SLT_S:
19638                case R6_OPC_CMP_SULT_S:
19639                case R6_OPC_CMP_SLE_S:
19640                case R6_OPC_CMP_SULE_S:
19641                case R6_OPC_CMP_OR_S:
19642                case R6_OPC_CMP_UNE_S:
19643                case R6_OPC_CMP_NE_S:
19644                case R6_OPC_CMP_SOR_S:
19645                case R6_OPC_CMP_SUNE_S:
19646                case R6_OPC_CMP_SNE_S:
19647                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19648                    break;
19649                case R6_OPC_CMP_AF_D:
19650                case R6_OPC_CMP_UN_D:
19651                case R6_OPC_CMP_EQ_D:
19652                case R6_OPC_CMP_UEQ_D:
19653                case R6_OPC_CMP_LT_D:
19654                case R6_OPC_CMP_ULT_D:
19655                case R6_OPC_CMP_LE_D:
19656                case R6_OPC_CMP_ULE_D:
19657                case R6_OPC_CMP_SAF_D:
19658                case R6_OPC_CMP_SUN_D:
19659                case R6_OPC_CMP_SEQ_D:
19660                case R6_OPC_CMP_SEUQ_D:
19661                case R6_OPC_CMP_SLT_D:
19662                case R6_OPC_CMP_SULT_D:
19663                case R6_OPC_CMP_SLE_D:
19664                case R6_OPC_CMP_SULE_D:
19665                case R6_OPC_CMP_OR_D:
19666                case R6_OPC_CMP_UNE_D:
19667                case R6_OPC_CMP_NE_D:
19668                case R6_OPC_CMP_SOR_D:
19669                case R6_OPC_CMP_SUNE_D:
19670                case R6_OPC_CMP_SNE_D:
19671                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19672                    break;
19673                default:
19674                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19675                               rt, rd, sa, (imm >> 8) & 0x7);
19676
19677                    break;
19678                }
19679            } else {
19680                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19681                           (imm >> 8) & 0x7);
19682            }
19683            break;
19684        }
19685        case OPC_BZ_V:
19686        case OPC_BNZ_V:
19687        case OPC_BZ_B:
19688        case OPC_BZ_H:
19689        case OPC_BZ_W:
19690        case OPC_BZ_D:
19691        case OPC_BNZ_B:
19692        case OPC_BNZ_H:
19693        case OPC_BNZ_W:
19694        case OPC_BNZ_D:
19695            check_insn(ctx, ASE_MSA);
19696            gen_msa_branch(env, ctx, op1);
19697            break;
19698        default:
19699            MIPS_INVAL("cp1");
19700            generate_exception_end(ctx, EXCP_RI);
19701            break;
19702        }
19703        break;
19704
19705    /* Compact branches [R6] and COP2 [non-R6] */
19706    case OPC_BC: /* OPC_LWC2 */
19707    case OPC_BALC: /* OPC_SWC2 */
19708        if (ctx->insn_flags & ISA_MIPS32R6) {
19709            /* OPC_BC, OPC_BALC */
19710            gen_compute_compact_branch(ctx, op, 0, 0,
19711                                       sextract32(ctx->opcode << 2, 0, 28));
19712        } else {
19713            /* OPC_LWC2, OPC_SWC2 */
19714            /* COP2: Not implemented. */
19715            generate_exception_err(ctx, EXCP_CpU, 2);
19716        }
19717        break;
19718    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19719    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19720        if (ctx->insn_flags & ISA_MIPS32R6) {
19721            if (rs != 0) {
19722                /* OPC_BEQZC, OPC_BNEZC */
19723                gen_compute_compact_branch(ctx, op, rs, 0,
19724                                           sextract32(ctx->opcode << 2, 0, 23));
19725            } else {
19726                /* OPC_JIC, OPC_JIALC */
19727                gen_compute_compact_branch(ctx, op, 0, rt, imm);
19728            }
19729        } else {
19730            /* OPC_LWC2, OPC_SWC2 */
19731            /* COP2: Not implemented. */
19732            generate_exception_err(ctx, EXCP_CpU, 2);
19733        }
19734        break;
19735    case OPC_CP2:
19736        check_insn(ctx, INSN_LOONGSON2F);
19737        /* Note that these instructions use different fields.  */
19738        gen_loongson_multimedia(ctx, sa, rd, rt);
19739        break;
19740
19741    case OPC_CP3:
19742        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19743        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19744            check_cp1_enabled(ctx);
19745            op1 = MASK_CP3(ctx->opcode);
19746            switch (op1) {
19747            case OPC_LUXC1:
19748            case OPC_SUXC1:
19749                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19750                /* Fallthrough */
19751            case OPC_LWXC1:
19752            case OPC_LDXC1:
19753            case OPC_SWXC1:
19754            case OPC_SDXC1:
19755                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19756                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19757                break;
19758            case OPC_PREFX:
19759                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19760                /* Treat as NOP. */
19761                break;
19762            case OPC_ALNV_PS:
19763                check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19764                /* Fallthrough */
19765            case OPC_MADD_S:
19766            case OPC_MADD_D:
19767            case OPC_MADD_PS:
19768            case OPC_MSUB_S:
19769            case OPC_MSUB_D:
19770            case OPC_MSUB_PS:
19771            case OPC_NMADD_S:
19772            case OPC_NMADD_D:
19773            case OPC_NMADD_PS:
19774            case OPC_NMSUB_S:
19775            case OPC_NMSUB_D:
19776            case OPC_NMSUB_PS:
19777                check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19778                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19779                break;
19780            default:
19781                MIPS_INVAL("cp3");
19782                generate_exception_end(ctx, EXCP_RI);
19783                break;
19784            }
19785        } else {
19786            generate_exception_err(ctx, EXCP_CpU, 1);
19787        }
19788        break;
19789
19790#if defined(TARGET_MIPS64)
19791    /* MIPS64 opcodes */
19792    case OPC_LDL ... OPC_LDR:
19793    case OPC_LLD:
19794        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19795        /* fall through */
19796    case OPC_LWU:
19797    case OPC_LD:
19798        check_insn(ctx, ISA_MIPS3);
19799        check_mips_64(ctx);
19800        gen_ld(ctx, op, rt, rs, imm);
19801        break;
19802    case OPC_SDL ... OPC_SDR:
19803        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19804        /* fall through */
19805    case OPC_SD:
19806        check_insn(ctx, ISA_MIPS3);
19807        check_mips_64(ctx);
19808        gen_st(ctx, op, rt, rs, imm);
19809        break;
19810    case OPC_SCD:
19811        check_insn_opc_removed(ctx, ISA_MIPS32R6);
19812        check_insn(ctx, ISA_MIPS3);
19813        check_mips_64(ctx);
19814        gen_st_cond(ctx, op, rt, rs, imm);
19815        break;
19816    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19817        if (ctx->insn_flags & ISA_MIPS32R6) {
19818            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19819            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19820        } else {
19821            /* OPC_DADDI */
19822            check_insn(ctx, ISA_MIPS3);
19823            check_mips_64(ctx);
19824            gen_arith_imm(ctx, op, rt, rs, imm);
19825        }
19826        break;
19827    case OPC_DADDIU:
19828        check_insn(ctx, ISA_MIPS3);
19829        check_mips_64(ctx);
19830        gen_arith_imm(ctx, op, rt, rs, imm);
19831        break;
19832#else
19833    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19834        if (ctx->insn_flags & ISA_MIPS32R6) {
19835            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19836        } else {
19837            MIPS_INVAL("major opcode");
19838            generate_exception_end(ctx, EXCP_RI);
19839        }
19840        break;
19841#endif
19842    case OPC_DAUI: /* OPC_JALX */
19843        if (ctx->insn_flags & ISA_MIPS32R6) {
19844#if defined(TARGET_MIPS64)
19845            /* OPC_DAUI */
19846            check_mips_64(ctx);
19847            if (rs == 0) {
19848                generate_exception(ctx, EXCP_RI);
19849            } else if (rt != 0) {
19850                TCGv t0 = tcg_temp_new();
19851                gen_load_gpr(t0, rs);
19852                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19853                tcg_temp_free(t0);
19854            }
19855#else
19856            generate_exception_end(ctx, EXCP_RI);
19857            MIPS_INVAL("major opcode");
19858#endif
19859        } else {
19860            /* OPC_JALX */
19861            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19862            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19863            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19864        }
19865        break;
19866    case OPC_MSA: /* OPC_MDMX */
19867        /* MDMX: Not implemented. */
19868        gen_msa(env, ctx);
19869        break;
19870    case OPC_PCREL:
19871        check_insn(ctx, ISA_MIPS32R6);
19872        gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19873        break;
19874    default:            /* Invalid */
19875        MIPS_INVAL("major opcode");
19876        generate_exception_end(ctx, EXCP_RI);
19877        break;
19878    }
19879}
19880
19881void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19882{
19883    MIPSCPU *cpu = mips_env_get_cpu(env);
19884    CPUState *cs = CPU(cpu);
19885    DisasContext ctx;
19886    target_ulong pc_start;
19887    target_ulong next_page_start;
19888    int num_insns;
19889    int max_insns;
19890    int insn_bytes;
19891    int is_slot;
19892
19893    pc_start = tb->pc;
19894    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19895    ctx.pc = pc_start;
19896    ctx.saved_pc = -1;
19897    ctx.singlestep_enabled = cs->singlestep_enabled;
19898    ctx.insn_flags = env->insn_flags;
19899    ctx.CP0_Config1 = env->CP0_Config1;
19900    ctx.tb = tb;
19901    ctx.bstate = BS_NONE;
19902    ctx.btarget = 0;
19903    ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19904    ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19905    ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19906    ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19907    ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19908    ctx.PAMask = env->PAMask;
19909    ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19910    ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19911    ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
19912    /* Restore delay slot state from the tb context.  */
19913    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19914    ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19915    ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19916             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19917    ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
19918    ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
19919    ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
19920    ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
19921    restore_cpu_state(env, &ctx);
19922#ifdef CONFIG_USER_ONLY
19923        ctx.mem_idx = MIPS_HFLAG_UM;
19924#else
19925        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19926#endif
19927    ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19928                                 MO_UNALN : MO_ALIGN;
19929    num_insns = 0;
19930    max_insns = tb->cflags & CF_COUNT_MASK;
19931    if (max_insns == 0) {
19932        max_insns = CF_COUNT_MASK;
19933    }
19934    if (max_insns > TCG_MAX_INSNS) {
19935        max_insns = TCG_MAX_INSNS;
19936    }
19937
19938    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19939    gen_tb_start(tb);
19940    while (ctx.bstate == BS_NONE) {
19941        tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19942        num_insns++;
19943
19944        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19945            save_cpu_state(&ctx, 1);
19946            ctx.bstate = BS_BRANCH;
19947            gen_helper_raise_exception_debug(cpu_env);
19948            /* The address covered by the breakpoint must be included in
19949               [tb->pc, tb->pc + tb->size) in order to for it to be
19950               properly cleared -- thus we increment the PC here so that
19951               the logic setting tb->size below does the right thing.  */
19952            ctx.pc += 4;
19953            goto done_generating;
19954        }
19955
19956        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19957            gen_io_start();
19958        }
19959
19960        is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19961        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19962            ctx.opcode = cpu_ldl_code(env, ctx.pc);
19963            insn_bytes = 4;
19964            decode_opc(env, &ctx);
19965        } else if (ctx.insn_flags & ASE_MICROMIPS) {
19966            ctx.opcode = cpu_lduw_code(env, ctx.pc);
19967            insn_bytes = decode_micromips_opc(env, &ctx);
19968        } else if (ctx.insn_flags & ASE_MIPS16) {
19969            ctx.opcode = cpu_lduw_code(env, ctx.pc);
19970            insn_bytes = decode_mips16_opc(env, &ctx);
19971        } else {
19972            generate_exception_end(&ctx, EXCP_RI);
19973            break;
19974        }
19975
19976        if (ctx.hflags & MIPS_HFLAG_BMASK) {
19977            if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19978                                MIPS_HFLAG_FBNSLOT))) {
19979                /* force to generate branch as there is neither delay nor
19980                   forbidden slot */
19981                is_slot = 1;
19982            }
19983            if ((ctx.hflags & MIPS_HFLAG_M16) &&
19984                (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19985                /* Force to generate branch as microMIPS R6 doesn't restrict
19986                   branches in the forbidden slot. */
19987                is_slot = 1;
19988            }
19989        }
19990        if (is_slot) {
19991            gen_branch(&ctx, insn_bytes);
19992        }
19993        ctx.pc += insn_bytes;
19994
19995        /* Execute a branch and its delay slot as a single instruction.
19996           This is what GDB expects and is consistent with what the
19997           hardware does (e.g. if a delay slot instruction faults, the
19998           reported PC is the PC of the branch).  */
19999        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
20000            break;
20001        }
20002
20003        if (ctx.pc >= next_page_start) {
20004            break;
20005        }
20006
20007        if (tcg_op_buf_full()) {
20008            break;
20009        }
20010
20011        if (num_insns >= max_insns)
20012            break;
20013
20014        if (singlestep)
20015            break;
20016    }
20017    if (tb->cflags & CF_LAST_IO) {
20018        gen_io_end();
20019    }
20020    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
20021        save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
20022        gen_helper_raise_exception_debug(cpu_env);
20023    } else {
20024        switch (ctx.bstate) {
20025        case BS_STOP:
20026            gen_goto_tb(&ctx, 0, ctx.pc);
20027            break;
20028        case BS_NONE:
20029            save_cpu_state(&ctx, 0);
20030            gen_goto_tb(&ctx, 0, ctx.pc);
20031            break;
20032        case BS_EXCP:
20033            tcg_gen_exit_tb(0);
20034            break;
20035        case BS_BRANCH:
20036        default:
20037            break;
20038        }
20039    }
20040done_generating:
20041    gen_tb_end(tb, num_insns);
20042
20043    tb->size = ctx.pc - pc_start;
20044    tb->icount = num_insns;
20045
20046#ifdef DEBUG_DISAS
20047    LOG_DISAS("\n");
20048    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20049        && qemu_log_in_addr_range(pc_start)) {
20050        qemu_log_lock();
20051        qemu_log("IN: %s\n", lookup_symbol(pc_start));
20052        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
20053        qemu_log("\n");
20054        qemu_log_unlock();
20055    }
20056#endif
20057}
20058
20059static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
20060                           int flags)
20061{
20062    int i;
20063    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
20064
20065#define printfpr(fp)                                                    \
20066    do {                                                                \
20067        if (is_fpu64)                                                   \
20068            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
20069                        " fd:%13g fs:%13g psu: %13g\n",                 \
20070                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
20071                        (double)(fp)->fd,                               \
20072                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
20073                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
20074        else {                                                          \
20075            fpr_t tmp;                                                  \
20076            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
20077            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
20078            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
20079                        " fd:%13g fs:%13g psu:%13g\n",                  \
20080                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
20081                        (double)tmp.fd,                                 \
20082                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
20083                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
20084        }                                                               \
20085    } while(0)
20086
20087
20088    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
20089                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
20090                get_float_exception_flags(&env->active_fpu.fp_status));
20091    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20092        fpu_fprintf(f, "%3s: ", fregnames[i]);
20093        printfpr(&env->active_fpu.fpr[i]);
20094    }
20095
20096#undef printfpr
20097}
20098
20099void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20100                         int flags)
20101{
20102    MIPSCPU *cpu = MIPS_CPU(cs);
20103    CPUMIPSState *env = &cpu->env;
20104    int i;
20105
20106    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20107                " LO=0x" TARGET_FMT_lx " ds %04x "
20108                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
20109                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20110                env->hflags, env->btarget, env->bcond);
20111    for (i = 0; i < 32; i++) {
20112        if ((i & 3) == 0)
20113            cpu_fprintf(f, "GPR%02d:", i);
20114        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
20115        if ((i & 3) == 3)
20116            cpu_fprintf(f, "\n");
20117    }
20118
20119    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
20120                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
20121    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20122                PRIx64 "\n",
20123                env->CP0_Config0, env->CP0_Config1, env->lladdr);
20124    cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
20125                env->CP0_Config2, env->CP0_Config3);
20126    cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
20127                env->CP0_Config4, env->CP0_Config5);
20128    if (env->hflags & MIPS_HFLAG_FPU)
20129        fpu_dump_state(env, f, cpu_fprintf, flags);
20130}
20131
20132void mips_tcg_init(void)
20133{
20134    int i;
20135    static int inited;
20136
20137    /* Initialize various static tables. */
20138    if (inited)
20139        return;
20140
20141    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
20142    tcg_ctx.tcg_env = cpu_env;
20143
20144    TCGV_UNUSED(cpu_gpr[0]);
20145    for (i = 1; i < 32; i++)
20146        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20147                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
20148                                        regnames[i]);
20149
20150    for (i = 0; i < 32; i++) {
20151        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20152        msa_wr_d[i * 2] =
20153                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20154        /* The scalar floating-point unit (FPU) registers are mapped on
20155         * the MSA vector registers. */
20156        fpu_f64[i] = msa_wr_d[i * 2];
20157        off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20158        msa_wr_d[i * 2 + 1] =
20159                tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20160    }
20161
20162    cpu_PC = tcg_global_mem_new(cpu_env,
20163                                offsetof(CPUMIPSState, active_tc.PC), "PC");
20164    for (i = 0; i < MIPS_DSP_ACC; i++) {
20165        cpu_HI[i] = tcg_global_mem_new(cpu_env,
20166                                       offsetof(CPUMIPSState, active_tc.HI[i]),
20167                                       regnames_HI[i]);
20168        cpu_LO[i] = tcg_global_mem_new(cpu_env,
20169                                       offsetof(CPUMIPSState, active_tc.LO[i]),
20170                                       regnames_LO[i]);
20171    }
20172    cpu_dspctrl = tcg_global_mem_new(cpu_env,
20173                                     offsetof(CPUMIPSState, active_tc.DSPControl),
20174                                     "DSPControl");
20175    bcond = tcg_global_mem_new(cpu_env,
20176                               offsetof(CPUMIPSState, bcond), "bcond");
20177    btarget = tcg_global_mem_new(cpu_env,
20178                                 offsetof(CPUMIPSState, btarget), "btarget");
20179    hflags = tcg_global_mem_new_i32(cpu_env,
20180                                    offsetof(CPUMIPSState, hflags), "hflags");
20181
20182    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20183                                      offsetof(CPUMIPSState, active_fpu.fcr0),
20184                                      "fcr0");
20185    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20186                                       offsetof(CPUMIPSState, active_fpu.fcr31),
20187                                       "fcr31");
20188
20189    inited = 1;
20190}
20191
20192#include "translate_init.c"
20193
20194MIPSCPU *cpu_mips_init(const char *cpu_model)
20195{
20196    MIPSCPU *cpu;
20197    CPUMIPSState *env;
20198    const mips_def_t *def;
20199
20200    def = cpu_mips_find_by_name(cpu_model);
20201    if (!def)
20202        return NULL;
20203    cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20204    env = &cpu->env;
20205    env->cpu_model = def;
20206    env->exception_base = (int32_t)0xBFC00000;
20207
20208#ifndef CONFIG_USER_ONLY
20209    mmu_init(env, def);
20210#endif
20211    fpu_init(env, def);
20212    mvp_init(env, def);
20213
20214    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20215
20216    return cpu;
20217}
20218
20219bool cpu_supports_cps_smp(const char *cpu_model)
20220{
20221    const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20222    if (!def) {
20223        return false;
20224    }
20225
20226    return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20227}
20228
20229void cpu_set_exception_base(int vp_index, target_ulong address)
20230{
20231    MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20232    vp->env.exception_base = address;
20233}
20234
20235void cpu_state_reset(CPUMIPSState *env)
20236{
20237    MIPSCPU *cpu = mips_env_get_cpu(env);
20238    CPUState *cs = CPU(cpu);
20239
20240    /* Reset registers to their default values */
20241    env->CP0_PRid = env->cpu_model->CP0_PRid;
20242    env->CP0_Config0 = env->cpu_model->CP0_Config0;
20243#ifdef TARGET_WORDS_BIGENDIAN
20244    env->CP0_Config0 |= (1 << CP0C0_BE);
20245#endif
20246    env->CP0_Config1 = env->cpu_model->CP0_Config1;
20247    env->CP0_Config2 = env->cpu_model->CP0_Config2;
20248    env->CP0_Config3 = env->cpu_model->CP0_Config3;
20249    env->CP0_Config4 = env->cpu_model->CP0_Config4;
20250    env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20251    env->CP0_Config5 = env->cpu_model->CP0_Config5;
20252    env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20253    env->CP0_Config6 = env->cpu_model->CP0_Config6;
20254    env->CP0_Config7 = env->cpu_model->CP0_Config7;
20255    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20256                                 << env->cpu_model->CP0_LLAddr_shift;
20257    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20258    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20259    env->CCRes = env->cpu_model->CCRes;
20260    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20261    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20262    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20263    env->current_tc = 0;
20264    env->SEGBITS = env->cpu_model->SEGBITS;
20265    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20266#if defined(TARGET_MIPS64)
20267    if (env->cpu_model->insn_flags & ISA_MIPS3) {
20268        env->SEGMask |= 3ULL << 62;
20269    }
20270#endif
20271    env->PABITS = env->cpu_model->PABITS;
20272    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20273    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20274    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20275    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20276    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20277    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20278    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20279    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20280    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20281    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20282    env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20283    env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20284    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20285    env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
20286    env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20287    env->msair = env->cpu_model->MSAIR;
20288    env->insn_flags = env->cpu_model->insn_flags;
20289
20290#if defined(CONFIG_USER_ONLY)
20291    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20292# ifdef TARGET_MIPS64
20293    /* Enable 64-bit register mode.  */
20294    env->CP0_Status |= (1 << CP0St_PX);
20295# endif
20296# ifdef TARGET_ABI_MIPSN64
20297    /* Enable 64-bit address mode.  */
20298    env->CP0_Status |= (1 << CP0St_UX);
20299# endif
20300    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20301       hardware registers.  */
20302    env->CP0_HWREna |= 0x0000000F;
20303    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20304        env->CP0_Status |= (1 << CP0St_CU1);
20305    }
20306    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20307        env->CP0_Status |= (1 << CP0St_MX);
20308    }
20309# if defined(TARGET_MIPS64)
20310    /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20311    if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20312        (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20313        env->CP0_Status |= (1 << CP0St_FR);
20314    }
20315# endif
20316#else
20317    if (env->hflags & MIPS_HFLAG_BMASK) {
20318        /* If the exception was raised from a delay slot,
20319           come back to the jump.  */
20320        env->CP0_ErrorEPC = (env->active_tc.PC
20321                             - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20322    } else {
20323        env->CP0_ErrorEPC = env->active_tc.PC;
20324    }
20325    env->active_tc.PC = env->exception_base;
20326    env->CP0_Random = env->tlb->nb_tlb - 1;
20327    env->tlb->tlb_in_use = env->tlb->nb_tlb;
20328    env->CP0_Wired = 0;
20329    env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20330    env->CP0_EBase = (cs->cpu_index & 0x3FF);
20331    if (kvm_enabled()) {
20332        env->CP0_EBase |= 0x40000000;
20333    } else {
20334        env->CP0_EBase |= 0x80000000;
20335    }
20336    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20337        env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20338    }
20339    env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20340                                 0x3ff : 0xff;
20341    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20342    /* vectored interrupts not implemented, timer on int 7,
20343       no performance counters. */
20344    env->CP0_IntCtl = 0xe0000000;
20345    {
20346        int i;
20347
20348        for (i = 0; i < 7; i++) {
20349            env->CP0_WatchLo[i] = 0;
20350            env->CP0_WatchHi[i] = 0x80000000;
20351        }
20352        env->CP0_WatchLo[7] = 0;
20353        env->CP0_WatchHi[7] = 0;
20354    }
20355    /* Count register increments in debug mode, EJTAG version 1 */
20356    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20357
20358    cpu_mips_store_count(env, 1);
20359
20360    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20361        int i;
20362
20363        /* Only TC0 on VPE 0 starts as active.  */
20364        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20365            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20366            env->tcs[i].CP0_TCHalt = 1;
20367        }
20368        env->active_tc.CP0_TCHalt = 1;
20369        cs->halted = 1;
20370
20371        if (cs->cpu_index == 0) {
20372            /* VPE0 starts up enabled.  */
20373            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20374            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20375
20376            /* TC0 starts up unhalted.  */
20377            cs->halted = 0;
20378            env->active_tc.CP0_TCHalt = 0;
20379            env->tcs[0].CP0_TCHalt = 0;
20380            /* With thread 0 active.  */
20381            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20382            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20383        }
20384    }
20385#endif
20386    if ((env->insn_flags & ISA_MIPS32R6) &&
20387        (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20388        /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20389        env->CP0_Status |= (1 << CP0St_FR);
20390    }
20391
20392    /* MSA */
20393    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20394        msa_reset(env);
20395    }
20396
20397    compute_hflags(env);
20398    restore_fp_status(env);
20399    restore_pamask(env);
20400    cs->exception_index = EXCP_NONE;
20401
20402    if (semihosting_get_argc()) {
20403        /* UHI interface can be used to obtain argc and argv */
20404        env->active_tc.gpr[4] = -1;
20405    }
20406}
20407
20408void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20409                          target_ulong *data)
20410{
20411    env->active_tc.PC = data[0];
20412    env->hflags &= ~MIPS_HFLAG_BMASK;
20413    env->hflags |= data[1];
20414    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20415    case MIPS_HFLAG_BR:
20416        break;
20417    case MIPS_HFLAG_BC:
20418    case MIPS_HFLAG_BL:
20419    case MIPS_HFLAG_B:
20420        env->btarget = data[2];
20421        break;
20422    }
20423}
20424